tst_dumpers.cpp 144 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
Bill King's avatar
Bill King committed
2
**
hjk's avatar
hjk committed
3
4
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
Bill King's avatar
Bill King committed
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
Bill King's avatar
Bill King committed
7
**
hjk's avatar
hjk committed
8
9
10
11
12
13
14
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
Bill King's avatar
Bill King committed
15
16
**
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17
18
19
20
21
22
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Bill King's avatar
Bill King committed
23
**
hjk's avatar
hjk committed
24
25
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
Bill King's avatar
Bill King committed
26
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
28
****************************************************************************/
Bill King's avatar
Bill King committed
29

hjk's avatar
hjk committed
30
#include "debuggerprotocol.h"
31
32
#include "watchdata.h"
#include "watchutils.h"
33

34
#include <QtTest>
hjk's avatar
hjk committed
35
36
#include <QTemporaryFile>
#include <QTemporaryDir>
37

38
using namespace Debugger;
hjk's avatar
hjk committed
39
using namespace Internal;
40

41
42
static QByteArray noValue = "\001";

hjk's avatar
hjk committed
43
44
45
46
47
48
49
50
51
52
53
54
static QByteArray nameFromIName(const QByteArray &iname)
{
    int pos = iname.lastIndexOf('.');
    return pos == -1 ? iname : iname.mid(pos + 1);
}

static QByteArray parentIName(const QByteArray &iname)
{
    int pos = iname.lastIndexOf('.');
    return pos == -1 ? QByteArray() : iname.left(pos);
}

55
56
57
58
59
class Check
{
public:
    Check() {}

hjk's avatar
hjk committed
60
61
62
63
64
65
    Check(const QByteArray &iname, const QByteArray &value,
          const QByteArray &type)
        : iname(iname), expectedName(nameFromIName(iname)),
          expectedValue(value), expectedType(type)
    {}

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    Check(const QByteArray &iname, const QByteArray &name,
         const QByteArray &value, const QByteArray &type)
        : iname(iname), expectedName(name),
          expectedValue(value), expectedType(type)
    {}

    QByteArray iname;
    QByteArray expectedName;
    QByteArray expectedValue;
    QByteArray expectedType;
};

class CheckType : public Check
{
public:
    CheckType(const QByteArray &iname, const QByteArray &name,
         const QByteArray &type)
        : Check(iname, name, noValue, type)
    {}
85

hjk's avatar
hjk committed
86
87
88
89
90
91
92
93
94
95
96
97
    CheckType(const QByteArray &iname, const QByteArray &type)
        : Check(iname, noValue, type)
    {}
};

class Profile
{
public:
    Profile(const QByteArray &contents) : contents(contents) {}

public:
    QByteArray contents;
98
99
};

hjk's avatar
hjk committed
100
class Data
101
{
hjk's avatar
hjk committed
102
103
public:
    Data() {}
104
105
    Data(const QByteArray &code)
        : includes("#include <QtCore>"), code(code) {}
106

107
108
    Data(const QByteArray &includes, const QByteArray &code)
        : includes(includes), code(code)
hjk's avatar
hjk committed
109
    {}
110

111
112
113
114
115
116
    const Data &operator%(const Check &check) const
    {
        checks.insert("local." + check.iname, check);
        return *this;
    }

hjk's avatar
hjk committed
117
118
119
120
121
122
    const Data &operator%(const Profile &profile) const
    {
        profileExtra += profile.contents;
        return *this;
    }

hjk's avatar
hjk committed
123
public:
hjk's avatar
hjk committed
124
    mutable QByteArray profileExtra;
hjk's avatar
hjk committed
125
126
    QByteArray includes;
    QByteArray code;
127
    mutable QMap<QByteArray, Check> checks;
hjk's avatar
hjk committed
128
129
};

hjk's avatar
hjk committed
130
Q_DECLARE_METATYPE(Data)
hjk's avatar
hjk committed
131

132
class tst_Dumpers : public QObject
133
134
135
136
{
    Q_OBJECT

public:
137
    tst_Dumpers() {}
138
139

private slots:
hjk's avatar
hjk committed
140
141
    void dumper();
    void dumper_data();
142
143
};

hjk's avatar
hjk committed
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
void tst_Dumpers::dumper()
{
    QFETCH(Data, data);

    bool ok;
    QString cmd;
    QByteArray output;
    QByteArray error;

    QTemporaryDir buildDir(QLatin1String("qt_tst_dumpers_"));
    const bool keepTemp = qgetenv("QTC_KEEP_TEMP").toInt();
    buildDir.setAutoRemove(!keepTemp);
    //qDebug() << "Temp dir: " << buildDir.path();
    QVERIFY(!buildDir.path().isEmpty());

    QFile proFile(buildDir.path() + QLatin1String("/doit.pro"));
    ok = proFile.open(QIODevice::ReadWrite);
    QVERIFY(ok);
    proFile.write("SOURCES = main.cpp\nTARGET = doit\n");
hjk's avatar
hjk committed
163
    proFile.write(data.profileExtra);
hjk's avatar
hjk committed
164
165
166
167
168
    proFile.close();

    QFile source(buildDir.path() + QLatin1String("/main.cpp"));
    ok = source.open(QIODevice::ReadWrite);
    QVERIFY(ok);
hjk's avatar
hjk committed
169
170
171
    source.write(
            "\n\nvoid dummyStatement(...) {}"
            "\n\n" + data.includes +
hjk's avatar
hjk committed
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
            "\n\nvoid stopper() {}"
            "\n\nint main()"
            "\n{"
            "\n    " + data.code +
            "\n    stopper();"
            "\n}\n");
    source.close();

    QProcess qmake;
    qmake.setWorkingDirectory(buildDir.path());
    cmd = QString::fromLatin1("qmake");
    //qDebug() << "Starting qmake: " << cmd;
    qmake.start(cmd);
    ok = qmake.waitForFinished();
    QVERIFY(ok);
    output = qmake.readAllStandardOutput();
    error = qmake.readAllStandardError();
    //qDebug() << "stdout: " << output;
    if (!error.isEmpty()) { qDebug() << error; QVERIFY(false); }

    QProcess make;
    make.setWorkingDirectory(buildDir.path());
    cmd = QString::fromLatin1("make");
    //qDebug() << "Starting make: " << cmd;
    make.start(cmd);
    ok = make.waitForFinished();
    QVERIFY(ok);
    output = make.readAllStandardOutput();
    error = make.readAllStandardError();
    //qDebug() << "stdout: " << output;
    if (!error.isEmpty()) { qDebug() << error; QVERIFY(false); }

    QByteArray dumperDir = DUMPERDIR;

206
207
208
    QSet<QByteArray> expandedINames;
    expandedINames.insert("local");
    foreach (const Check &check, data.checks) {
hjk's avatar
hjk committed
209
210
211
212
213
214
215
        QByteArray parent = check.iname;
        while (true) {
            parent = parentIName(parent);
            if (parent.isEmpty())
                break;
            expandedINames.insert("local." + parent);
        }
216
217
218
219
220
221
222
223
224
    }

    QByteArray expanded;
    foreach (const QByteArray &iname, expandedINames) {
        if (!expanded.isEmpty())
            expanded.append(',');
        expanded += iname;
    }

hjk's avatar
hjk committed
225
226
227
228
229
230
231
232
233
234
235
236
    QByteArray cmds =
        "set confirm off\n"
        "file doit\n"
        "break stopper\n"
        "set auto-load python-scripts off\n"
        "python execfile('" + dumperDir + "/bridge.py')\n"
        "python execfile('" + dumperDir + "/dumper.py')\n"
        "python execfile('" + dumperDir + "/qttypes.py')\n"
        "bbsetup\n"
        "run\n"
        "up\n"
        "python print('@%sS@%s@' % ('N', qtNamespace()))\n"
237
        "bb options:fancy,autoderef,dyntype vars: expanded:" + expanded + " typeformats:\n"
hjk's avatar
hjk committed
238
239
240
241
242
243
        "quit\n";

    if (keepTemp) {
        QFile logger(buildDir.path() + QLatin1String("/input.txt"));
        ok = logger.open(QIODevice::ReadWrite);
        logger.write(cmds);
244
    }
ck's avatar
ck committed
245

hjk's avatar
hjk committed
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
    QProcess debugger;
    debugger.setWorkingDirectory(buildDir.path());
    //qDebug() << "Starting debugger ";
    debugger.start(QLatin1String("gdb -i mi -quiet -nx"));
    ok = debugger.waitForStarted();
    debugger.write(cmds);
    ok = debugger.waitForFinished();
    QVERIFY(ok);
    output = debugger.readAllStandardOutput();
    //qDebug() << "stdout: " << output;
    error = debugger.readAllStandardError();
    if (!error.isEmpty()) { qDebug() << error; }

    if (keepTemp) {
        QFile logger(buildDir.path() + QLatin1String("/output.txt"));
        ok = logger.open(QIODevice::ReadWrite);
        logger.write("=== STDOUT ===\n");
        logger.write(output);
        logger.write("\n=== STDERR ===\n");
        logger.write(error);
ck's avatar
ck committed
266
267
    }

hjk's avatar
hjk committed
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
    int pos1 = output.indexOf("data=");
    QVERIFY(pos1 != -1);
    int pos2 = output.indexOf(",typeinfo", pos1);
    QVERIFY(pos2 != -1);
    QByteArray contents = output.mid(pos1, pos2 - pos1);
    contents.replace("\\\"", "\"");

    int pos3 = output.indexOf("@NS@");
    QVERIFY(pos3 != -1);
    pos3 += sizeof("@NS@") - 1;
    int pos4 = output.indexOf("@", pos3);
    QVERIFY(pos4 != -1);
    QByteArray nameSpace = output.mid(pos3, pos4 - pos3);
    //qDebug() << "FOUND NS: " << nameSpace;
    if (nameSpace == "::")
        nameSpace.clear();

    GdbMi actual;
    actual.fromString(contents);
    ok = false;
288
289
290
291
    WatchData local;
    local.iname = "local";

    QList<WatchData> list;
hjk's avatar
hjk committed
292
    foreach (const GdbMi &child, actual.children()) {
293
294
295
296
297
298
299
300
301
        WatchData dummy;
        dummy.iname = child.findChild("iname").data();
        dummy.name = QLatin1String(child.findChild("name").data());
        parseWatchData(expandedINames, dummy, child, &list);
    }

    foreach (const WatchData &item, list) {
        if (data.checks.contains(item.iname)) {
            Check check = data.checks.take(item.iname);
hjk's avatar
hjk committed
302
303
304
305
306
307
308
            check.expectedValue.replace(' ', "");
            check.expectedType.replace('@', nameSpace);
            check.expectedType.replace(' ', "");
            QByteArray actualValue = item.value.toLatin1();
            actualValue.replace(' ', "");
            QByteArray actualType = item.type;
            actualType.replace(' ', "");
309
            if (item.name.toLatin1() != check.expectedName) {
hjk's avatar
hjk committed
310
                qDebug() << "INAME        : " << item.iname;
311
312
                qDebug() << "NAME ACTUAL  : " << item.name;
                qDebug() << "NAME EXPECTED: " << check.expectedName;
hjk's avatar
hjk committed
313
                qDebug() << "CONTENTS     : " << contents;
hjk's avatar
hjk committed
314
                QVERIFY(false);
ck's avatar
ck committed
315
            }
hjk's avatar
hjk committed
316
317
            if (check.expectedValue != noValue && actualValue != check.expectedValue) {
                qDebug() << "INAME         : " << item.iname;
318
319
                qDebug() << "VALUE ACTUAL  : " << item.value;
                qDebug() << "VALUE EXPECTED: " << check.expectedValue;
hjk's avatar
hjk committed
320
                qDebug() << "CONTENTS      : " << contents;
hjk's avatar
hjk committed
321
                QVERIFY(false);
ck's avatar
ck committed
322
            }
hjk's avatar
hjk committed
323
324
            if (check.expectedType != noValue && actualType != check.expectedType) {
                qDebug() << "INAME        : " << item.iname;
325
326
                qDebug() << "TYPE ACTUAL  : " << item.type;
                qDebug() << "TYPE EXPECTED: " << check.expectedType;
hjk's avatar
hjk committed
327
                qDebug() << "CONTENTS     : " << contents;
hjk's avatar
hjk committed
328
                QVERIFY(false);
329
            }
ck's avatar
ck committed
330
331
        }
    }
332
333
334
335
336

    if (!data.checks.isEmpty()) {
        qDebug() << "SOME TESTS NOT EXECUTED: ";
        foreach (const Check &check, data.checks)
            qDebug() << "  TEST NOT FOUND FOR INAME: " << check.iname;
hjk's avatar
hjk committed
337
338
        qDebug() << "CONTENTS     : " << contents;
        qDebug() << "EXPANDED     : " << expanded;
339
340
        QVERIFY(false);
    }
ck's avatar
ck committed
341
342
}

hjk's avatar
hjk committed
343
void tst_Dumpers::dumper_data()
ck's avatar
ck committed
344
{
hjk's avatar
hjk committed
345
    QTest::addColumn<Data>("data");
ck's avatar
ck committed
346

hjk's avatar
hjk committed
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
    QByteArray fooData =
            "#include <QMap>\n"
            "class Foo\n"
            "{\n"
            "public:\n"
            "    Foo(int i = 0)\n"
            "        : a(i), b(2)\n"
            "    {}\n"
            "    virtual ~Foo()\n"
            "    {\n"
            "        a = 5;\n"
            "    }\n"
            "    void doit()\n"
            "    {\n"
            "        static QObject ob;\n"
            "        m[\"1\"] = \"2\";\n"
            "        h[&ob] = m.begin();\n"
            "        --b;\n"
            "    }\n"
            "public:\n"
            "    int a, b;\n"
            "    char x[6];\n"
            "private:\n"
            "    typedef QMap<QString, QString> Map;\n"
            "    Map m;\n"
            "    QHash<QObject *, Map::iterator> h;\n"
            "};";
374
375

    QTest::newRow("AnonymousStruct")
376
377
378
379
380
381
            << Data("union {\n"
                    "     struct { int i; int b; };\n"
                    "     struct { float f; };\n"
                    "     double d;\n"
                    " } a = { { 42, 43 } };\n (void)a;")
               % CheckType("a", "a", "union {...}")
hjk's avatar
hjk committed
382
383
384
385
               % Check("a.b", "43", "int")
               % Check("a.d", "9.1245819032257467e-313", "double")
               % Check("a.f", "5.88545355e-44", "float")
               % Check("a.i", "42", "int");
386
387
388

    QTest::newRow("QByteArray0")
            << Data("QByteArray ba;")
hjk's avatar
hjk committed
389
               % Check("ba", "ba", "\"\"", "@QByteArray");
390
391

    QTest::newRow("QByteArray1")
hjk's avatar
hjk committed
392
            << Data("QByteArray ba = \"Hello\\\"World\";\n"
393
394
395
                    "ba += char(0);\n"
                    "ba += 1;\n"
                    "ba += 2;\n")
hjk's avatar
hjk committed
396
397
398
399
400
               % Check("ba", "\"Hello\"World\"", "@QByteArray")
               % Check("ba.0", "[0]", "72", "char")
               % Check("ba.11", "[11]", "0", "char")
               % Check("ba.12", "[12]", "1", "char")
               % Check("ba.13", "[13]", "2", "char");
401
402
403
404
405
406
407

    QTest::newRow("QByteArray2")
            << Data("QByteArray ba;\n"
                    "for (int i = 256; --i >= 0; )\n"
                    "    ba.append(char(i));\n"
                    "QString s(10000, 'x');\n"
                    "std::string ss(10000, 'c');")
hjk's avatar
hjk committed
408
409
410
               % CheckType("ba", "@QByteArray")
               % Check("s", '"' + QByteArray(10000, 'x') + '"', "@QString")
               % Check("ss", '"' + QByteArray(10000, 'c') + '"', "std::string");
411
412
413
414
415
416
417
418

    QTest::newRow("QByteArray3")
            << Data("const char *str1 = \"\356\";\n"
                    "const char *str2 = \"\xee\";\n"
                    "const char *str3 = \"\\ee\";\n"
                    "QByteArray buf1(str1);\n"
                    "QByteArray buf2(str2);\n"
                    "QByteArray buf3(str3);\n")
hjk's avatar
hjk committed
419
420
421
422
               % Check("buf1", "\"î\"", "@QByteArray")
               % Check("buf2", "\"î\"", "@QByteArray")
               % Check("buf3", "\"\ee\"", "@ByteArray")
               % CheckType("str1", "char *");
423
424
425
426
427

    QTest::newRow("QByteArray4")
            << Data("char data[] = { 'H', 'e', 'l', 'l', 'o' };\n"
                    "QByteArray ba1 = QByteArray::fromRawData(data, 4);\n"
                    "QByteArray ba2 = QByteArray::fromRawData(data + 1, 4);\n")
hjk's avatar
hjk committed
428
429
               % Check("ba1", "\"Hell\"", "@QByteArray")
               % Check("ba2", "\"ello\"", "@QByteArray");
430
431
432

    QTest::newRow("QDate0")
            << Data("QDate date;\n")
hjk's avatar
hjk committed
433
434
435
436
437
               % CheckType("date", "@QDate")
               % Check("date.(ISO)", "", "@QString")
               % Check("date.(Locale)", "", "@QString")
               % Check("date.(SystemLocale)", "", "@QString")
               % Check("date.toString", "", "@QString");
438
439
440
441

    QTest::newRow("QDate1")
            << Data("QDate date;\n"
                    "date.setDate(1980, 1, 1);\n")
hjk's avatar
hjk committed
442
443
444
445
446
               % CheckType("date", "@QDate")
               % Check("date.(ISO)", "\"1980-01-01\"", "@QString")
               % CheckType("date.(Locale)", "@QString")
               % CheckType("date.(SystemLocale)", "@QString")
               % Check("date.toString", "\"Tue Jan 1 1980\"", "@QString");
447
448

    QTest::newRow("QTime0")
hjk's avatar
hjk committed
449
450
451
452
453
454
455
            << Data("#include <QTime>\n",
                    "QTime time;\n")
               % CheckType("time", "@QTime")
               % Check("time.(ISO)", "", "@QString")
               % CheckType("time.(Locale)", "@QString")
               % CheckType("time.(SystemLocale)", "@QString")
               % Check("time.toString", "", "@QString");
456
457

    QTest::newRow("QTime1")
hjk's avatar
hjk committed
458
459
460
461
462
463
464
            << Data("#include <QTime>\n",
                    "QTime time(13, 15, 32);")
               % Check("time", "13:15:32", "@QTime")
               % Check("time.(ISO)", "\"13:15:32\"", "@QString")
               % CheckType("time.(Locale)", "@QString")
               % CheckType("time.(SystemLocale)", "@QString")
               % Check("time.toString", "\"13:15:32\"", "@QString");
465
466

    QTest::newRow("QDateTime")
hjk's avatar
hjk committed
467
468
469
470
471
472
473
474
            << Data("#include <QDateTime>\n",
                    "QDateTime date;\n")
               % CheckType("date", "@QDateTime")
               % Check("date.(ISO)", "", "@QString")
               % Check("date.(Locale)", "", "@QString")
               % Check("date.(SystemLocale)", "", "@QString")
               % Check("date.toString", "\"\"", "@QString")
               % Check("date.toUTC", "", "@QDateTime");
475
476
477

    QTest::newRow("QDir")
#ifdef Q_OS_WIN
hjk's avatar
hjk committed
478
479
480
481
482
            << Data("#include <QDir>\n",
                    "QDir dir(\"C:\\\\Program Files\");")
               % Check("dir", "C:/Program Files", "@QDir")
               % Check("dir.absolutePath", "C:/Program Files", "@QString")
               % Check("dir.canonicalPath", "C:/Program Files", "@QString");
483
#else
hjk's avatar
hjk committed
484
485
486
487
488
            << Data("#include <QDir>\n",
                    "QDir dir(\"/tmp\"); QString s = dir.absolutePath();")
               % Check("dir", "/tmp", "@QDir")
               % Check("dir.absolutePath", "/tmp", "@QString")
               % Check("dir.canonicalPath", "/tmp", "@QString");
489
490
491
492
#endif

    QTest::newRow("QFileInfo")
#ifdef Q_OS_WIN
hjk's avatar
hjk committed
493
494
495
            << Data("#include <QFile>\n"
                    "#include <QFileInfo>\n",
                    "QFile file(\"C:\\\\Program Files\\t\");\n"
496
497
498
499
500
501
502
                    "file.setObjectName(\"A QFile instance\");\n"
                    "QFileInfo fi(\"C:\\Program Files\\tt\");\n"
                    "QString s = fi.absoluteFilePath();\n")
               % Check("fi", "C:/Program Files/tt", "QFileInfo")
               % Check("file", "C:\Program Files\t", "QFile")
               % Check("s", "C:/Program Files/tt", "QString");
#else
hjk's avatar
hjk committed
503
504
505
            << Data("#include <QFile>\n"
                    "#include <QFileInfo>\n",
                    "QFile file(\"/tmp/t\");\n"
506
507
508
                    "file.setObjectName(\"A QFile instance\");\n"
                    "QFileInfo fi(\"/tmp/tt\");\n"
                    "QString s = fi.absoluteFilePath();\n")
hjk's avatar
hjk committed
509
510
511
               % Check("fi", "/tmp/tt", "@QFileInfo")
               % Check("file", "/tmp/t", "@QFile")
               % Check("s", "/tmp/tt", "@QString");
512
513
514
#endif

    QTest::newRow("QHash1")
hjk's avatar
hjk committed
515
516
            << Data("#include <QHash>\n",
                    "QHash<QString, QList<int> > hash;\n"
517
518
519
                    "hash.insert(\"Hallo\", QList<int>());\n"
                    "hash.insert(\"Welt\", QList<int>() << 1);\n"
                    "hash.insert(\"!\", QList<int>() << 1 << 2);\n")
hjk's avatar
hjk committed
520
521
522
523
524
525
526
               % Check("hash", "<3 items>", "@QHash<@QString, @QList<int> >")
               % Check("hash.0", "[0]", "", "@QHashNode<@QString, @QList<int>>")
               % Check("hash.0.key", "\"Hallo\"", "@QString")
               % Check("hash.0.value", "<0 items>", "@QList<int>")
               % Check("hash.1", "[1]", "", "@QHashNode<@QString, @QList<int>>")
               % Check("hash.1.key", "key", "\"Welt\"", "@QString")
               % Check("hash.1.value", "value", "<1 items>", "@QList<int>")
527
               % Check("hash.1.value.0", "0", "1", "int")
hjk's avatar
hjk committed
528
529
530
               % Check("hash.2", "[2]", "", "@QHashNode<@QString, @QList<int>>")
               % Check("hash.2.key", "key", "\"!\"", "@QString")
               % Check("hash.2.value", "value", "<2 items>", "@QList<int>")
531
532
533
534
               % Check("hash.2.value.0", "0", "1", "int")
               % Check("hash.2.value.1", "1", "2", "int");

    QTest::newRow("QHash2")
hjk's avatar
hjk committed
535
536
            << Data("#include <QHash>\n",
                    "QHash<int, float> hash;\n"
537
538
539
540
541
542
543
                    "hash[11] = 11.0;\n"
                    "hash[22] = 22.0;\n")
               % Check("hash", "hash", "<2 items>", "QHash<int, float>")
               % Check("hash.22", "22", "22", "float")
               % Check("hash.11", "11", "11", "float");

    QTest::newRow("QHash3")
hjk's avatar
hjk committed
544
545
            << Data("#include <QHash>\n",
                    "QHash<QString, int> hash;\n"
546
547
548
549
550
551
552
553
554
555
                    "hash[\"22.0\"] = 22.0;\n"
                    "hash[\"123.0\"] = 22.0;\n"
                    "hash[\"111111ss111128.0\"] = 28.0;\n"
                    "hash[\"11124.0\"] = 22.0;\n"
                    "hash[\"1111125.0\"] = 22.0;\n"
                    "hash[\"11111126.0\"] = 22.0;\n"
                    "hash[\"111111127.0\"] = 27.0;\n"
                    "hash[\"111111111128.0\"] = 28.0;\n"
                    "hash[\"111111111111111111129.0\"] = 29.0;\n")
               % Check("hash", "hash", "<9 items>", "QHash<QString, int>")
hjk's avatar
hjk committed
556
               % Check("hash.0", "0", "", "@QHashNode<QString, int>")
557
               % Check("hash.0.key", "key", "\"123.0\"", "QString")
hjk's avatar
hjk committed
558
               % Check("hash.0.value", "22", "int")
559
560
561
562
563
               % Check("hash.8", "", "", "QHashNode<QString, int>")
               % Check("hash.8.key", "key", "\"11124.0\"", "QString")
               % Check("hash.8.value", "value", "22", "int");

    QTest::newRow("QHash4")
hjk's avatar
hjk committed
564
565
            << Data("#include <QHash>\n",
                    "QHash<QByteArray, float> hash;\n"
566
567
568
569
570
571
572
573
574
                    "hash[\"22.0\"] = 22.0;\n"
                    "hash[\"123.0\"] = 22.0;\n"
                    "hash[\"111111ss111128.0\"] = 28.0;\n"
                    "hash[\"11124.0\"] = 22.0;\n"
                    "hash[\"1111125.0\"] = 22.0;\n"
                    "hash[\"11111126.0\"] = 22.0;\n"
                    "hash[\"111111127.0\"] = 27.0;\n"
                    "hash[\"111111111128.0\"] = 28.0;\n"
                    "hash[\"111111111111111111129.0\"] = 29.0;\n")
hjk's avatar
hjk committed
575
576
577
578
579
580
581
               % Check("hash", "<9 items>", "@QHash<@QByteArray, float>")
               % Check("hash.0", "[0]", "@QHashNode<@QByteArray, float>")
               % Check("hash.0.key", "\"123.0\"", "@QByteArray")
               % Check("hash.0.value", "22", "float")
               % Check("hash.8", "[8]", "@QHashNode<@QByteArray, float>")
               % Check("hash.8.key", "\"11124.0\"", "@QByteArray")
               % Check("hash.8.value", "22", "float");
582
583

    QTest::newRow("QHash5")
hjk's avatar
hjk committed
584
585
            << Data("#include <QHash>\n",
                    "QHash<int, QString> hash;\n"
586
                    "hash[22] = \"22.0\";\n")
hjk's avatar
hjk committed
587
588
589
590
               % Check("hash", "<1 items>", "@QHash<int, @QString>")
               % Check("hash.0", "", "@QHashNode<int, @QString>")
               % Check("hash.0.key", "22", "int")
               % Check("hash.0.value", "\"22.0\"", "@QString");
591
592

    QTest::newRow("QHash6")
hjk's avatar
hjk committed
593
594
            << Data("#include <QHash>\n" + fooData,
                    "QHash<QString, Foo> hash;\n"
595
596
                    "hash[\"22.0\"] = Foo(22);\n"
                    "hash[\"33.0\"] = Foo(33);\n")
hjk's avatar
hjk committed
597
598
599
600
601
602
603
604
               % Check("hash", "<2 items>", "@QHash<@QString, Foo>")
               % Check("hash.0", "", "@QHashNode<@QString, Foo>")
               % Check("hash.0.key", "\"22.0\"", "@QString")
               % CheckType("hash.0.value", "Foo")
               % Check("hash.0.value.a", "22", "int")
               % Check("hash.1", "", "@QHashNode<@QString, Foo>")
               % Check("hash.1.key", "\"33.0\"", "@QString")
               % CheckType("hash.1.value", "Foo");
605
606

    QTest::newRow("QHash7")
hjk's avatar
hjk committed
607
608
            << Data("#include <QHash>\n",
                    "QObject ob;\n"
609
610
611
612
                    "QHash<QString, QPointer<QObject> > hash;\n"
                    "hash.insert(\"Hallo\", QPointer<QObject>(&ob));\n"
                    "hash.insert(\"Welt\", QPointer<QObject>(&ob));\n"
                    "hash.insert(\".\", QPointer<QObject>(&ob));\n")
hjk's avatar
hjk committed
613
614
615
616
617
618
619
620
               % Check("hash", "<3 items>", "@QHash<@QString, @QPointer<@QObject>>")
               % Check("hash.0", "", "@QHashNode<@QString, @QPointer<@QObject>>")
               % Check("hash.0.key", "\"Hallo\"", "@QString")
               % CheckType("hash.0.value", "@QPointer<QObject>")
               % CheckType("hash.0.value.o", "@QObject")
               % Check("hash.2", "", "@QHashNode<@QString, @QPointer<@QObject>>")
               % Check("hash.2.key", "\".\"", "@QString")
               % CheckType("hash.2.value", "@QPointer<@QObject>");
621
622

    QTest::newRow("QHashIntFloatIterator")
hjk's avatar
hjk committed
623
624
            << Data("#include <QHash>\n",
                    "typedef QHash<int, float> Hash;\n"
625
626
627
628
629
630
631
632
633
634
635
636
637
                    "Hash hash;\n"
                    "hash[11] = 11.0;\n"
                    "hash[22] = 22.0;\n"
                    "hash[33] = 33.0;\n"
                    "hash[44] = 44.0;\n"
                    "hash[55] = 55.0;\n"
                    "hash[66] = 66.0;\n"
                    "Hash::iterator it1 = hash.begin();\n"
                    "Hash::iterator it2 = it1; ++it2;\n"
                    "Hash::iterator it3 = it2; ++it3;\n"
                    "Hash::iterator it4 = it3; ++it4;\n"
                    "Hash::iterator it5 = it4; ++it5;\n"
                    "Hash::iterator it6 = it5; ++it6;\n")
hjk's avatar
hjk committed
638
639
640
641
642
643
               % Check("hash", "<6 items>", "qhash::Hash")
               % Check("hash.11", "11", "float")
               % Check("it1.key", "55", "int")
               % Check("it1.value", "55", "float")
               % Check("it6.key", "33", "int")
               % Check("it6.value", "33", "float");
644
645

    QTest::newRow("QHostAddress")
hjk's avatar
hjk committed
646
647
            << Data("#include <QHostAddress>\n",
                    "QHostAddress ha1(129u * 256u * 256u * 256u + 130u);\n"
648
                    "QHostAddress ha2(\"127.0.0.1\");\n")
hjk's avatar
hjk committed
649
650
651
               % Profile("QT += network\n")
               % Check("ha1", "129.0.0.130", "@QHostAddress")
               % Check("ha2", "\"127.0.0.1\"", "@QHostAddress");
652
653
654
655
656
657
658
659

    QTest::newRow("QImage")
            << Data("#include <QImage>\n"
                    "#include <QPainter>\n",
                    "QImage im(QSize(200, 200), QImage::Format_RGB32);\n"
                    "im.fill(QColor(200, 100, 130).rgba());\n"
                    "QPainter pain;\n"
                    "pain.begin(&im);\n")
hjk's avatar
hjk committed
660
661
               % Check("im", "(200x200)", "@QImage")
               % CheckType("pain", "@QPainter");
662
663
664
665
666
667
668
669
670
671
672
673
674

    QTest::newRow("QPixmap")
            << Data("#include <QImage>\n"
                    "#include <QPainter>\n"
                    "#include <QPixmap>\n"
                    ,
                    "QImage im(QSize(200, 200), QImage::Format_RGB32);\n"
                    "im.fill(QColor(200, 100, 130).rgba());\n"
                    "QPainter pain;\n"
                    "pain.begin(&im);\n"
                    "pain.drawLine(2, 2, 130, 130);\n"
                    "pain.end();\n"
                    "QPixmap pm = QPixmap::fromImage(im);\n")
hjk's avatar
hjk committed
675
676
677
               % Check("im", "(200x200)", "@QImage")
               % CheckType("pain", "@QPainter")
               % Check("pm", "(200x200)", "@QPixmap");
678
679
680
681
682

    QTest::newRow("QLinkedListInt")
            << Data("QLinkedList<int> list;\n"
                    "list.append(101);\n"
                    "list.append(102);\n")
hjk's avatar
hjk committed
683
684
685
               % Check("list", "<2 items>", "@QLinkedList<int>")
               % Check("list.0", "101", "int")
               % Check("list.1", "102", "int");
686
687
688
689
690

    QTest::newRow("QLinkedListUInt")
            << Data("QLinkedList<uint> list;\n"
                    "list.append(103);\n"
                    "list.append(104);\n")
hjk's avatar
hjk committed
691
692
693
               % Check("list", "<2 items>", "@QLinkedList<unsigned int>")
               % Check("list.0", "103", "unsigned int")
               % Check("list.1", "104", "unsigned int");
694
695

    QTest::newRow("QLinkedListFooStar")
hjk's avatar
hjk committed
696
697
            << Data("#include <QLinkedList>\n" + fooData,
                    "QLinkedList<Foo *> list;\n"
698
699
700
                    "list.append(new Foo(1));\n"
                    "list.append(0);\n"
                    "list.append(new Foo(3));\n")
hjk's avatar
hjk committed
701
702
703
704
705
706
               % Check("list", "<3 items>", "@QLinkedList<Foo*>")
               % CheckType("list.0", "Foo")
               % Check("list.0.a", "1", "int")
               % Check("list.1", "0x0", "Foo *")
               % CheckType("list.2", "Foo")
               % Check("list.2.a", "3", "int");
707
708
709
710
711

    QTest::newRow("QLinkedListULongLong")
            << Data("QLinkedList<qulonglong> list;\n"
                    "list.append(42);\n"
                    "list.append(43);\n")
hjk's avatar
hjk committed
712
713
714
               % Check("list", "<2 items>", "@QLinkedList<unsigned long long>")
               % Check("list.0", "[0]", "42", "unsigned long long")
               % Check("list.1", "[1]", "43", "unsigned long long");
715
716

    QTest::newRow("QLinkedListFoo")
hjk's avatar
hjk committed
717
718
            << Data("#include <QLinkedList>\n" + fooData,
                    "QLinkedList<Foo> list;\n"
719
720
                    "list.append(Foo(1));\n"
                    "list.append(Foo(2));\n")
hjk's avatar
hjk committed
721
722
723
724
725
               % Check("list", "<2 items>", "@QLinkedList<Foo>")
               % CheckType("list.0", "[0]", "Foo")
               % Check("list.0.a", "1", "int")
               % CheckType("list.1", "[1]", "Foo")
               % Check("list.1.a", "2", "int");
726
727
728
729
730

    QTest::newRow("QLinkedListStdString")
            << Data("QLinkedList<std::string> list;\n"
                    "list.push_back(\"aa\");\n"
                    "list.push_back(\"bb\");\n")
hjk's avatar
hjk committed
731
732
733
               % Check("list", "<2 items>", "@QLinkedList<std::string>")
               % Check("list.0", "[0]", "\"aa\"", "std::string")
               % Check("list.1", "[1]", "\"bb\"", "std::string");
734
735
736
737
738

    QTest::newRow("QListInt")
            << Data("QList<int> big;\n"
                    "for (int i = 0; i < 10000; ++i)\n"
                    "    big.push_back(i);\n")
hjk's avatar
hjk committed
739
740
741
               % Check("big", "<10000 items>", "@QList<int>")
               % Check("big.0", "[0]", "0", "int")
               % Check("big.1999", "[1999]", "1999", "int");
742
743
744
745
746
747
748

    QTest::newRow("QListIntTakeFirst")
            << Data("QList<int> l;\n"
                    "l.append(0);\n"
                    "l.append(1);\n"
                    "l.append(2);\n"
                    "l.takeFirst();\n")
hjk's avatar
hjk committed
749
750
               % Check("l", "<2 items>", "@QList<int>")
               % Check("l.0", "[0]", "1", "int");
751
752
753
754
755
756
757

    QTest::newRow("QListStringTakeFirst")
            << Data("QList<QString> l;\n"
                    "l.append(\"0\");\n"
                    "l.append(\"1\");\n"
                    "l.append(\"2\");\n"
                    "l.takeFirst();\n")
hjk's avatar
hjk committed
758
759
               % Check("l", "<2 items>", "@QList<@QString>")
               % Check("l.0", "\"1\"", "@QString");
760
761
762
763
764
765
766

    QTest::newRow("QStringListTakeFirst")
            << Data("QStringList l;\n"
                    "l.append(\"0\");\n"
                    "l.append(\"1\");\n"
                    "l.append(\"2\");\n"
                    "l.takeFirst();\n")
hjk's avatar
hjk committed
767
768
               % Check("l", "<2 items>", "@QStringList")
               % Check("l.0", "\"1\"", "@QString");
769
770
771
772
773
774

    QTest::newRow("QListIntStar")
            << Data("QList<int *> l0, l;\n"
                    "l.append(new int(1));\n"
                    "l.append(new int(2));\n"
                    "l.append(new int(3));\n")
hjk's avatar
hjk committed
775
776
777
778
               % Check("l0", "<0 items>", "@QList<int*>")
               % Check("l", "<3 items>", "@QList<int*>")
               % CheckType("l.0", "int")
               % CheckType("l.2", "int");
779
780
781
782
783
784

    QTest::newRow("QListUInt")
            << Data("QList<uint> l0,l;\n"
                    "l.append(101);\n"
                    "l.append(102);\n"
                    "l.append(102);\n")
hjk's avatar
hjk committed
785
786
787
788
               % Check("l0", "<0 items>", "@QList<unsigned int>")
               % Check("l", "<3 items>", "@QList<unsigned int>")
               % Check("l.0", "101", "unsigned int")
               % Check("l.2", "102", "unsigned int");
789
790
791
792
793
794

    QTest::newRow("QListUShort")
            << Data("QList<ushort> l0,l;\n"
                    "l.append(101);\n"
                    "l.append(102);\n"
                    "l.append(102);\n")
hjk's avatar
hjk committed
795
796
797
798
               % Check("l0", "<0 items>", "@QList<unsigned short>")
               % Check("l", "<3 items>", "@QList<unsigned short>")
               % Check("l.0", "101", "unsigned short")
               % Check("l.2", "102", "unsigned short");
799
800
801
802
803
804

    QTest::newRow("QListQChar")
            << Data("QList<QChar> l0, l;\n"
                    "l.append(QChar('a'));\n"
                    "l.append(QChar('b'));\n"
                    "l.append(QChar('c'));\n")
hjk's avatar
hjk committed
805
806
807
808
               % Check("l0", "<0 items>", "@QList<@QChar>")
               % Check("l", "<3 items>", "@QList<@QChar>")
               % Check("l.0", "'a' (97)", "@QChar")
               % Check("l.2", "'c' (99)", "@QChar");
809
810
811
812
813
814

    QTest::newRow("QListQULongLong")
            << Data("QList<qulonglong> l0, l;\n"
                    "l.append(101);\n"
                    "l.append(102);\n"
                    "l.append(102);\n")
hjk's avatar
hjk committed
815
816
817
818
               % Check("l0", "<0 items>", "@QList<unsigned long long>")
               % Check("l", "<3 items>", "@QList<unsigned long long>")
               % CheckType("l.0", "unsigned long long")
               % CheckType("l.2", "unsigned long long");
819
820
821
822
823
824
825

    QTest::newRow("QListStdString")
            << Data("QList<std::string> l0, l;\n"
                    "l.push_back(\"aa\");\n"
                    "l.push_back(\"bb\");\n"
                    "l.push_back(\"cc\");\n"
                    "l.push_back(\"dd\");")
hjk's avatar
hjk committed
826
827
828
829
               % Check("l0", "<0 items>", "@QList<std::string>")
               % Check("l", "<4 items>", "@QList<std::string>")
               % CheckType("l.0", "std::string")
               % Check("l.3", "\"dd\"", "std::string");
830
831

   QTest::newRow("QListFoo")
hjk's avatar
hjk committed
832
833
            << Data("#include <QList>\n" + fooData,
                    "QList<Foo> l0, l;\n"
834
835
                    "for (int i = 0; i < 100; ++i)\n"
                    "    l.push_back(i + 15);\n")
hjk's avatar
hjk committed
836
837
838
839
               % Check("l0", "<0 items>", "@QList<Foo>")
               % Check("l", "<100 items>", "@QList<Foo>")
               % Check("l.0", "", "Foo")
               % Check("l.99", "", "Foo");
840
841
842
843
844
845
846
847
848

   QTest::newRow("QListReverse")
           << Data("QList<int> l = QList<int>() << 1 << 2 << 3;\n"
                   "typedef std::reverse_iterator<QList<int>::iterator> Reverse;\n"
                   "Reverse rit(l.end());\n"
                   "Reverse rend(l.begin());\n"
                   "QList<int> r;\n"
                   "while (rit != rend)\n"
                   "    r.append(*rit++);\n")
hjk's avatar
hjk committed
849
850
851
852
853
854
855
856
857
858
              % Check("l", "<3 items>", "@QList<int>")
              % Check("l.0", "1", "int")
              % Check("l.1", "2", "int")
              % Check("l.2", "3", "int")
              % Check("r", "<3 items>", "@QList<int>")
              % Check("r.0", "3", "int")
              % Check("r.1", "2", "int")
              % Check("r.2", "1", "int")
              % Check("rend", "", "Reverse")
              % Check("rit", "", "Reverse");
859
860
861
862

   QTest::newRow("QLocale")
           << Data("QLocale loc = QLocale::system();\n"
                   "QLocale::MeasurementSystem m = loc.measurementSystem();\n")
hjk's avatar
hjk committed
863
864
              % Check("loc", "", "@QLocale")
              % Check("m", "", "@QLocale::MeasurementSystem");
865
866
867
868
869
870


   QTest::newRow("QMapUIntStringList")
           << Data("QMap<uint, QStringList> map;\n"
                   "map[11] = QStringList() << \"11\";\n"
                   "map[22] = QStringList() << \"22\";\n")
hjk's avatar
hjk committed
871
872
873
874
875
876
877
878
879
              % Check("map", "<2 items>", "@QMap<unsigned int, @QStringList>")
              % Check("map.0", "", "@QMapNode<unsigned int, @QStringList>")
              % Check("map.0.key", "11", "unsigned int")
              % Check("map.0.value", "<1 items>", "@QStringList")
              % Check("map.0.value.0", "\"11\"", "@QString")
              % Check("map.1", "", "@QMapNode<unsigned int, @QStringList>")
              % Check("map.1.key", "22", "unsigned int")
              % Check("map.1.value", "<1 items>", "@QStringList")
              % Check("map.1.value.0", "\"22\"", "@QString");
880
881
882
883
884
885

   QTest::newRow("QMapUIntStringListTypedef")
           << Data("typedef QMap<uint, QStringList> T;\n"
                   "T map;\n"
                   "map[11] = QStringList() << \"11\";\n"
                   "map[22] = QStringList() << \"22\";\n")
hjk's avatar
hjk committed
886
              % Check("map", "<2 items>", "T");
887
888
889
890
891

   QTest::newRow("QMapUIntFloat")
           << Data("QMap<uint, float> map;\n"
                   "map[11] = 11.0;\n"
                   "map[22] = 22.0;\n")
hjk's avatar
hjk committed
892
893
894
              % Check("map", "<2 items>", "@QMap<unsigned int, float>")
              % Check("map.11", "11", "float")
              % Check("map.22", "22", "float");
895
896
897
898

   QTest::newRow("QMapStringFloat")
           << Data("QMap<QString, float> map;\n"
                   "map[\"22.0\"] = 22.0;\n")
hjk's avatar
hjk committed
899
900
901
902
              % Check("map", "<1 items>", "@QMap<@QString, float>")
              % Check("map.0", "", "@QMapNode<@QString, float>")
              % Check("map.0.key", "\"22.0\"", "@QString")
              % Check("map.0.value", "22", "float");
903
904
905
906

   QTest::newRow("QMapIntString")
           << Data("QMap<int, QString> map;\n"
                   "map[22] = \"22.0\";\n")
hjk's avatar
hjk committed
907
908
909
910
              % Check("map", "<1 items>", "@QMap<int, @QString>")
              % Check("map.0", "", "@QMapNode<int, @QString>")
              % Check("map.0.key", "22", "int")
              % Check("map.0.value", "\"22.0\"", "@QString");
911
912

   QTest::newRow("QMapStringFoo")
hjk's avatar
hjk committed
913
914
           << Data("#include <QMap>\n" + fooData,
                   "QMap<QString, Foo> map;\n"
915
916
                   "map[\"22.0\"] = Foo(22);\n"
                   "map[\"33.0\"] = Foo(33);\n")
hjk's avatar
hjk committed
917
918
919
920
921
922
923
924
925
              % Check("map", "<2 items>", "@QMap<@QString, Foo>")
              % Check("map.0", "", "@QMapNode<@QString, Foo>")
              % Check("map.0.key", "\"22.0\"", "@QString")
              % Check("map.0.value", "", "Foo")
              % Check("map.0.value.a", "22", "int")
              % Check("map.1", "", "@QMapNode<@QString, Foo>")
              % Check("map.1.key", "\"33.0\"", "@QString")
              % Check("map.1.value", "", "Foo")
              % Check("map.1.value.a", "33", "int");
926
927
928
929
930
931
932

   QTest::newRow("QMapStringPointer")
           << Data("QObject ob;\n"
                   "QMap<QString, QPointer<QObject> > map;\n"
                   "map.insert(\"Hallo\", QPointer<QObject>(&ob));\n"
                   "map.insert(\"Welt\", QPointer<QObject>(&ob));\n"
                   "map.insert(\".\", QPointer<QObject>(&ob));\n")
hjk's avatar
hjk committed
933
934
935
936
937
938
939
940
941
              % Check("map", "<3 items>", "@QMap<@QString, @QPointer<@QObject>>")
              % Check("map.0", "", "@QMapNode<@QString, @QPointer<@QObject>>")
              % Check("map.0.key", ".", "@QString")
              % Check("map.0.value", "", "@QPointer<@QObject>")
              % Check("map.0.value.o", "", "@QObject")
              % Check("map.1", "", "@QMapNode<@QString, @QPointer<@QObject>>")
              % Check("map.1.key", "\"Hallo\"", "@QString")
              % Check("map.2", "", "@QMapNode<@QString, @QPointer<@QObject>>")
              % Check("map.2.key", "\"Welt\"", "@QString");
942
943
944
945
946
947
948
949
950
951
952

   QTest::newRow("QMapStringList")
           << Data("QList<nsA::nsB::SomeType *> x;\n"
                   "x.append(new nsA::nsB::SomeType(1));\n"
                   "x.append(new nsA::nsB::SomeType(2));\n"
                   "x.append(new nsA::nsB::SomeType(3));\n"
                   "QMap<QString, QList<nsA::nsB::SomeType *> > map;\n"
                   "map[\"foo\"] = x;\n"
                   "map[\"bar\"] = x;\n"
                   "map[\"1\"] = x;\n"
                   "map[\"2\"] = x;\n")
hjk's avatar
hjk committed
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
              % Check("map", "<4 items>", "@QMap<@QString, @QList<nsA::nsB::SomeType*>>")
              % Check("map.0", "", "@QMapNode<@QString, @QList<nsA::nsB::SomeType*>>")
              % Check("map.0.key", "\"1\"", "@QString")
              % Check("map.0.value", "<3 items>", "@QList<nsA::nsB::SomeType*>")
              % Check("map.0.value.0", "", "nsA::nsB::SomeType")
              % Check("map.0.value.0.a", "1", "int")
              % Check("map.0.value.1", "", "nsA::nsB::SomeType")
              % Check("map.0.value.1.a", "2", "int")
              % Check("map.0.value.2", "", "nsA::nsB::SomeType")
              % Check("map.0.value.2.a", "3", "int")
              % Check("map.3", "", "@QMapNode<@QString, QList<nsA::nsB::SomeType*>>")
              % Check("map.3.key", "\"foo\"", "@QString")
              % Check("map.3.value", "<3 items>", "@QList<nsA::nsB::SomeType*>")
              % Check("map.3.value.2", "", "nsA::nsB::SomeType")
              % Check("map.3.value.2.a", "3", "int")
              % Check("x", "<3 items>", "@QList<nsA::nsB::SomeType*>");
969
970
971
972
973
974
975
976
977

   QTest::newRow("QMultiMapUintFloat")
           << Data("QMultiMap<uint, float> map;\n"
                   "map.insert(11, 11.0);\n"
                   "map.insert(22, 22.0);\n"
                   "map.insert(22, 33.0);\n"
                   "map.insert(22, 34.0);\n"
                   "map.insert(22, 35.0);\n"
                   "map.insert(22, 36.0);\n")
hjk's avatar
hjk committed
978
979
980
              % Check("map", "<6 items>", "@QMultiMap<unsigned int, float>")
              % Check("map.0", "11", "float")
              % Check("map.5", "22", "float");
981
982
983
984

   QTest::newRow("QMultiMapStringFloat")
           << Data("QMultiMap<QString, float> map;\n"
                   "map.insert(\"22.0\", 22.0);\n")
hjk's avatar
hjk committed
985
986
987
988
              % Check("map", "<1 items>", "@QMultiMap<@QString, float>")
              % Check("map.0", "", "@QMapNode<@QString, float>")
              % Check("map.0.key", "\"22.0\"", "@QString")
              % Check("map.0.value", "22", "float");
989
990
991
992

   QTest::newRow("QMultiMapIntString")
           << Data("QMultiMap<int, QString> map;\n"
                   "map.insert(22, \"22.0\");\n")
hjk's avatar
hjk committed
993
994
995
996
              % Check("map", "<1 items>", "@QMultiMap<int, @QString>")
              % Check("map.0", "", "@QMapNode<int, @QString>")
              % Check("map.0.key", "22", "int")
              % Check("map.0.value", "\"22.0\"", "@QString");
997
998

   QTest::newRow("QMultiMapStringFoo")
hjk's avatar
hjk committed
999
1000
           << Data("#include <QMultiMap>\n" + fooData,
                   "QMultiMap<QString, Foo> map;\n"