# HG changeset patch # User Chris Cannam # Date 1417448578 0 # Node ID eecf544bed921d6e479490f2cd359e1f9affc902 # Parent 1888ca033a84ab2bff6180d53c8b30ef38df338d Unit tests for StringBits::splitQuoted diff -r 1888ca033a84 -r eecf544bed92 base/StringBits.cpp --- a/base/StringBits.cpp Mon Dec 01 10:18:55 2014 +0000 +++ b/base/StringBits.cpp Mon Dec 01 15:42:58 2014 +0000 @@ -20,6 +20,10 @@ #include "StringBits.h" +#include "Debug.h" + +using namespace std; + double StringBits::stringToDoubleLocaleFree(QString s, bool *ok) { @@ -73,6 +77,11 @@ QStringList tokens; QString tok; + // sep -> just seen a field separator (or start of line) + // unq -> in an unquoted field + // q1 -> in a single-quoted field + // q2 -> in a double-quoted field + enum { sep, unq, q1, q2 } mode = sep; for (int i = 0; i < s.length(); ++i) { @@ -117,86 +126,19 @@ } } - if (tok != "" || mode != sep) tokens << tok; + if (tok != "" || mode != sep) { + if (mode == q1) { + tokens << ("'" + tok); // turns out it wasn't quoted after all + } else if (mode == q2) { + tokens << ("\"" + tok); + } else { + tokens << tok; + } + } + return tokens; } -/* - -void testSplit() -{ - QStringList tests; - tests << "a b c d"; - tests << "a \"b c\" d"; - tests << "a 'b c' d"; - tests << "a \"b c\\\" d\""; - tests << "a 'b c\\' d'"; - tests << "a \"b c' d\""; - tests << "a 'b c\" d'"; - tests << "aa 'bb cc\" dd'"; - tests << "a'a 'bb' \\\"cc\" dd\\\""; - tests << " a'a \\\' 'bb' \' \\\"cc\" ' dd\\\" '"; - - for (int j = 0; j < tests.size(); ++j) { - cout << endl; - cout << tests[j] << endl; - cout << "->" << endl << "("; - QStringList l = splitQuoted(tests[j], ' '); - for (int i = 0; i < l.size(); ++i) { - if (i > 0) cout << ";"; - cout << l[i]; - } - cout << ")" << endl; - } -} - -*/ - -/* - Results: - -a b c d --> -(a;b;c;d) - -a "b c" d --> -(a;b c;d) - -a 'b c' d --> -(a;b c;d) - -a "b c\" d" --> -(a;b c" d) - -a 'b c\' d' --> -(a;b c' d) - -a "b c' d" --> -(a;b c' d) - -a 'b c" d' --> -(a;b c" d) - -aa 'bb cc" dd' --> -(aa;bb cc" dd) - -a'a 'bb' \"cc" dd\" --> -(a'a;bb;"cc";dd") - - a'a \' 'bb' ' \"cc" ' dd\" ' --> -(a'a;';bb; "cc" ;dd";) - -*/ - QStringList StringBits::split(QString line, QChar separator, bool quoted) { diff -r 1888ca033a84 -r eecf544bed92 base/test/TestStringBits.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/test/TestStringBits.h Mon Dec 01 15:42:58 2014 +0000 @@ -0,0 +1,203 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef TEST_STRINGBITS_H +#define TEST_STRINGBITS_H + +#include "../StringBits.h" + +#include +#include +#include + +#include + +using namespace std; + +class TestStringBits : public QObject +{ + Q_OBJECT + +private: + void testSplitQuoted(QString in, QStringList out) { + // Only suitable where the output strings do not have + // consecutive spaces in them + QCOMPARE(StringBits::splitQuoted(in, ' '), out); + QString in2(in); + in2.replace(' ', ','); + QStringList out2; + foreach (QString o, out) { + out2 << o.replace(' ', ','); + } + QCOMPARE(StringBits::splitQuoted(in2, ','), out2); + } + +private slots: + void simple() { + QString in = "a b c d"; + QStringList out; + out << "a" << "b" << "c" << "d"; + testSplitQuoted(in, out); + } + + void dquoted() { + QString in = "a \"b c\" d"; + QStringList out; + out << "a" << "b c" << "d"; + testSplitQuoted(in, out); + } + + void drunon() { + QString in = "a \"b c\"d e"; + QStringList out; + out << "a" << "b cd" << "e"; + testSplitQuoted(in, out); + } + + void squoted() { + QString in = "a 'b c' d"; + QStringList out; + out << "a" << "b c" << "d"; + testSplitQuoted(in, out); + } + + void srunon() { + QString in = "a 'b c'd e"; + QStringList out; + out << "a" << "b cd" << "e"; + testSplitQuoted(in, out); + } + + void dempty() { + QString in = "\"\" \"\" \"\""; + QStringList out; + out << "" << "" << ""; + testSplitQuoted(in, out); + } + + void sempty() { + QString in = "'' '' ''"; + QStringList out; + out << "" << "" << ""; + testSplitQuoted(in, out); + } + + void descaped() { + QString in = "a \"b c\\\" d\""; + QStringList out; + out << "a" << "b c\" d"; + testSplitQuoted(in, out); + } + + void sescaped() { + QString in = "a 'b c\\' d'"; + QStringList out; + out << "a" << "b c' d"; + testSplitQuoted(in, out); + } + + void dnested() { + QString in = "a \"b c' d\""; + QStringList out; + out << "a" << "b c' d"; + testSplitQuoted(in, out); + } + + void snested() { + QString in = "a 'b c\" d'"; + QStringList out; + out << "a" << "b c\" d"; + testSplitQuoted(in, out); + } + + void snested2() { + QString in = "aa 'bb cc\" dd'"; + QStringList out; + out << "aa" << "bb cc\" dd"; + testSplitQuoted(in, out); + } + + void qquoted() { + QString in = "a'a 'bb' \\\"cc\" dd\\\""; + QStringList out; + out << "a'a" << "bb" << "\"cc\"" << "dd\""; + testSplitQuoted(in, out); + } + + void multispace() { + QString in = " a'a \\' 'bb' ' \\\"cc\" ' dd\\\" '"; + QStringList out; + out << "a'a" << "'" << "bb" << " \"cc\" " << "dd\"" << "'"; + QCOMPARE(StringBits::splitQuoted(in, ' '), out); + + QString in2 = ",,a'a,\\',,,,,,,,,'bb',,,,',,,,,,\\\"cc\",',dd\\\",'"; + QStringList out2; + out2 << "" << "" << "a'a" << "'" << "" << "" << "" << "" << "" << "" + << "" << "" << "bb" << "" << "" << "" << ",,,,,,\"cc\"," + << "dd\"" << "'"; + QCOMPARE(StringBits::splitQuoted(in2, ','), out2); + } +}; + +#endif + +/* r928 +Config: Using QtTest library 5.3.2, Qt 5.3.2 +PASS : TestStringBits::initTestCase() +PASS : TestStringBits::simple() +PASS : TestStringBits::dquoted() +PASS : TestStringBits::squoted() +PASS : TestStringBits::descaped() +FAIL! : TestStringBits::sescaped() Compared lists have different sizes. + Actual (StringBits::splitQuoted(in, ' ')) size: 3 + Expected (out) size: 2 + Loc: [o/../TestStringBits.h(65)] +PASS : TestStringBits::dnested() +PASS : TestStringBits::snested() +PASS : TestStringBits::snested2() +PASS : TestStringBits::qquoted() +FAIL! : TestStringBits::multispace() Compared lists differ at index 1. + Actual (StringBits::splitQuoted(in, ' ')): " " + Expected (out): "'" + Loc: [o/../TestStringBits.h(100)] +FAIL! : TestStringBits::qcommas() Compared lists have different sizes. + Actual (StringBits::splitQuoted(in, ',')) size: 4 + Expected (out) size: 3 + Loc: [o/../TestStringBits.h(107)] +PASS : TestStringBits::cleanupTestCase() +Totals: 10 passed, 3 failed, 0 skipped +*/ + +/*curr +PASS : TestStringBits::initTestCase() +PASS : TestStringBits::simple() +PASS : TestStringBits::dquoted() +PASS : TestStringBits::squoted() +PASS : TestStringBits::descaped() +FAIL! : TestStringBits::sescaped() Compared lists have different sizes. + Actual (StringBits::splitQuoted(in, ' ')) size: 3 + Expected (out) size: 2 + Loc: [o/../TestStringBits.h(65)] +PASS : TestStringBits::dnested() +PASS : TestStringBits::snested() +PASS : TestStringBits::snested2() +PASS : TestStringBits::qquoted() +FAIL! : TestStringBits::multispace() Compared lists have different sizes. + Actual (StringBits::splitQuoted(in, ' ')) size: 5 + Expected (out) size: 6 + Loc: [o/../TestStringBits.h(100)] +PASS : TestStringBits::qcommas() +PASS : TestStringBits::cleanupTestCase() +Totals: 11 passed, 2 failed, 0 skipped +*/ diff -r 1888ca033a84 -r eecf544bed92 base/test/main.cpp --- a/base/test/main.cpp Mon Dec 01 10:18:55 2014 +0000 +++ b/base/test/main.cpp Mon Dec 01 15:42:58 2014 +0000 @@ -14,6 +14,7 @@ #include "TestRangeMapper.h" #include "TestPitch.h" #include "TestRealTime.h" +#include "TestStringBits.h" #include @@ -42,6 +43,11 @@ if (QTest::qExec(&t, argc, argv) == 0) ++good; else ++bad; } + { + TestStringBits t; + if (QTest::qExec(&t, argc, argv) == 0) ++good; + else ++bad; + } if (bad > 0) { cerr << "\n********* " << bad << " test suite(s) failed!\n" << endl; diff -r 1888ca033a84 -r eecf544bed92 base/test/test.pro --- a/base/test/test.pro Mon Dec 01 10:18:55 2014 +0000 +++ b/base/test/test.pro Mon Dec 01 15:42:58 2014 +0000 @@ -49,7 +49,7 @@ OBJECTS_DIR = o MOC_DIR = o -HEADERS += TestRangeMapper.h TestPitch.h TestRealTime.h +HEADERS += TestRangeMapper.h TestPitch.h TestRealTime.h TestStringBits.h SOURCES += main.cpp win* {