~ubuntu-branches/ubuntu/raring/qtscript-opensource-src/raring

« back to all changes in this revision

Viewing changes to tests/auto/qscriptjstestsuite/tst_qscriptjstestsuite.cpp

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-06 08:11:37 UTC
  • Revision ID: package-import@ubuntu.com-20130206081137-vipd9uzeow4achs2
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the test suite of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
 
 
43
#include "abstracttestsuite.h"
 
44
#include <QtTest/QtTest>
 
45
 
 
46
#include <QtScript>
 
47
 
 
48
#if defined(Q_OS_SYMBIAN)
 
49
# define SRCDIR "."
 
50
#endif
 
51
 
 
52
struct TestRecord
 
53
{
 
54
    TestRecord() : lineNumber(-1) { }
 
55
    TestRecord(const QString &desc,
 
56
               bool pass,
 
57
               const QString &act,
 
58
               const QString &exp,
 
59
               const QString &fn, int ln)
 
60
        : description(desc), passed(pass),
 
61
          actual(act), expected(exp),
 
62
          fileName(fn), lineNumber(ln)
 
63
        { }
 
64
    TestRecord(const QString &skipReason, const QString &fn)
 
65
        : description(skipReason), actual("QSKIP"),
 
66
          fileName(fn), lineNumber(-1)
 
67
        { }
 
68
    QString description;
 
69
    bool passed;
 
70
    QString actual;
 
71
    QString expected;
 
72
    QString fileName;
 
73
    int lineNumber;
 
74
};
 
75
 
 
76
Q_DECLARE_METATYPE(TestRecord)
 
77
 
 
78
struct FailureItem
 
79
{
 
80
    enum Action {
 
81
        ExpectFail,
 
82
        Skip
 
83
    };
 
84
    FailureItem(Action act, const QRegExp &rx, const QString &desc, const QString &msg)
 
85
        : action(act), pathRegExp(rx), description(desc), message(msg)
 
86
        { }
 
87
 
 
88
    Action action;
 
89
    QRegExp pathRegExp;
 
90
    QString description;
 
91
    QString message;
 
92
};
 
93
 
 
94
class tst_QScriptJSTestSuite : public AbstractTestSuite
 
95
{
 
96
 
 
97
public:
 
98
    tst_QScriptJSTestSuite();
 
99
    virtual ~tst_QScriptJSTestSuite();
 
100
 
 
101
protected:
 
102
    virtual void configData(TestConfig::Mode mode, const QStringList &parts);
 
103
    virtual void writeSkipConfigFile(QTextStream &);
 
104
    virtual void writeExpectFailConfigFile(QTextStream &);
 
105
    virtual void runTestFunction(int testIndex);
 
106
 
 
107
private:
 
108
    void addExpectedFailure(const QString &fileName, const QString &description, const QString &message);
 
109
    void addExpectedFailure(const QRegExp &path, const QString &description, const QString &message);
 
110
    void addSkip(const QString &fileName, const QString &description, const QString &message);
 
111
    void addSkip(const QRegExp &path, const QString &description, const QString &message);
 
112
    bool isExpectedFailure(const QString &fileName, const QString &description,
 
113
                           QString *message, FailureItem::Action *action) const;
 
114
    void addFileExclusion(const QString &fileName, const QString &message);
 
115
    void addFileExclusion(const QRegExp &rx, const QString &message);
 
116
    bool isExcludedFile(const QString &fileName, QString *message) const;
 
117
 
 
118
    QList<QString> subSuitePaths;
 
119
    QList<FailureItem> expectedFailures;
 
120
    QList<QPair<QRegExp, QString> > fileExclusions;
 
121
};
 
122
 
 
123
static QScriptValue qscript_void(QScriptContext *, QScriptEngine *eng)
 
124
{
 
125
    return eng->undefinedValue();
 
126
}
 
127
 
 
128
static QScriptValue qscript_quit(QScriptContext *ctx, QScriptEngine *)
 
129
{
 
130
    return ctx->throwError("Test quit");
 
131
}
 
132
 
 
133
static QString optionsToString(int options)
 
134
{
 
135
    QSet<QString> set;
 
136
    if (options & 1)
 
137
        set.insert("strict");
 
138
    if (options & 2)
 
139
        set.insert("werror");
 
140
    if (options & 4)
 
141
        set.insert("atline");
 
142
    if (options & 8)
 
143
        set.insert("xml");
 
144
    return QStringList(set.values()).join(",");
 
145
}
 
146
 
 
147
static QScriptValue qscript_options(QScriptContext *ctx, QScriptEngine *)
 
148
{
 
149
    static QHash<QString, int> stringToFlagHash;
 
150
    if (stringToFlagHash.isEmpty()) {
 
151
        stringToFlagHash["strict"] = 1;
 
152
        stringToFlagHash["werror"] = 2;
 
153
        stringToFlagHash["atline"] = 4;
 
154
        stringToFlagHash["xml"] = 8;
 
155
    }
 
156
    QScriptValue callee = ctx->callee();
 
157
    int opts = callee.data().toInt32();
 
158
    QString result = optionsToString(opts);
 
159
    for (int i = 0; i < ctx->argumentCount(); ++i)
 
160
        opts |= stringToFlagHash.value(ctx->argument(0).toString());
 
161
    callee.setData(opts);
 
162
    return result;
 
163
}
 
164
 
 
165
static QScriptValue qscript_TestCase(QScriptContext *ctx, QScriptEngine *eng)
 
166
{
 
167
    QScriptValue origTestCaseCtor = ctx->callee().data();
 
168
    QScriptValue kase = ctx->thisObject();
 
169
    QScriptValue ret = origTestCaseCtor.call(kase, ctx->argumentsObject());
 
170
    QScriptContextInfo info(ctx->parentContext());
 
171
    kase.setProperty("__lineNumber__", QScriptValue(eng, info.lineNumber()));
 
172
    return ret;
 
173
}
 
174
 
 
175
void tst_QScriptJSTestSuite::runTestFunction(int testIndex)
 
176
{
 
177
    if (!(testIndex & 1)) {
 
178
        // data
 
179
        QTest::addColumn<TestRecord>("record");
 
180
        bool hasData = false;
 
181
 
 
182
        QString testsShellPath = testsDir.absoluteFilePath("shell.js");
 
183
        QString testsShellContents = readFile(testsShellPath);
 
184
 
 
185
        QDir subSuiteDir(subSuitePaths.at(testIndex / 2));
 
186
        QString subSuiteShellPath = subSuiteDir.absoluteFilePath("shell.js");
 
187
        QString subSuiteShellContents = readFile(subSuiteShellPath);
 
188
 
 
189
        QDir testSuiteDir(subSuiteDir);
 
190
        testSuiteDir.cdUp();
 
191
        QString suiteJsrefPath = testSuiteDir.absoluteFilePath("jsref.js");
 
192
        QString suiteJsrefContents = readFile(suiteJsrefPath);
 
193
        QString suiteShellPath = testSuiteDir.absoluteFilePath("shell.js");
 
194
        QString suiteShellContents = readFile(suiteShellPath);
 
195
 
 
196
        QFileInfoList testFileInfos = subSuiteDir.entryInfoList(QStringList() << "*.js", QDir::Files);
 
197
        foreach (QFileInfo tfi, testFileInfos) {
 
198
            if ((tfi.fileName() == "shell.js") || (tfi.fileName() == "browser.js"))
 
199
                continue;
 
200
 
 
201
            QString abspath = tfi.absoluteFilePath();
 
202
            QString relpath = testsDir.relativeFilePath(abspath);
 
203
            QString excludeMessage;
 
204
            if (isExcludedFile(relpath, &excludeMessage)) {
 
205
                QTest::newRow(relpath.toLatin1()) << TestRecord(excludeMessage, relpath);
 
206
                continue;
 
207
            }
 
208
 
 
209
            QScriptEngine eng;
 
210
            QScriptValue global = eng.globalObject();
 
211
            global.setProperty("print", eng.newFunction(qscript_void));
 
212
            global.setProperty("quit", eng.newFunction(qscript_quit));
 
213
            global.setProperty("options", eng.newFunction(qscript_options));
 
214
 
 
215
            eng.evaluate(testsShellContents, testsShellPath);
 
216
            if (eng.hasUncaughtException()) {
 
217
                QStringList bt = eng.uncaughtExceptionBacktrace();
 
218
                QString err = eng.uncaughtException().toString();
 
219
                qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
 
220
                break;
 
221
            }
 
222
 
 
223
            eng.evaluate(suiteJsrefContents, suiteJsrefPath);
 
224
            if (eng.hasUncaughtException()) {
 
225
                QStringList bt = eng.uncaughtExceptionBacktrace();
 
226
                QString err = eng.uncaughtException().toString();
 
227
                qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
 
228
                break;
 
229
            }
 
230
 
 
231
            eng.evaluate(suiteShellContents, suiteShellPath);
 
232
            if (eng.hasUncaughtException()) {
 
233
                QStringList bt = eng.uncaughtExceptionBacktrace();
 
234
                QString err = eng.uncaughtException().toString();
 
235
                qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
 
236
                break;
 
237
            }
 
238
 
 
239
            eng.evaluate(subSuiteShellContents, subSuiteShellPath);
 
240
            if (eng.hasUncaughtException()) {
 
241
                QStringList bt = eng.uncaughtExceptionBacktrace();
 
242
                QString err = eng.uncaughtException().toString();
 
243
                qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n")));
 
244
                break;
 
245
            }
 
246
 
 
247
            QScriptValue origTestCaseCtor = global.property("TestCase");
 
248
            QScriptValue myTestCaseCtor = eng.newFunction(qscript_TestCase);
 
249
            myTestCaseCtor.setData(origTestCaseCtor);
 
250
            global.setProperty("TestCase", myTestCaseCtor);
 
251
 
 
252
            global.setProperty("gTestfile", tfi.fileName());
 
253
            global.setProperty("gTestsuite", testSuiteDir.dirName());
 
254
            global.setProperty("gTestsubsuite", subSuiteDir.dirName());
 
255
            QString testFileContents = readFile(abspath);
 
256
//                qDebug() << relpath;
 
257
            eng.evaluate(testFileContents, abspath);
 
258
            if (eng.hasUncaughtException() && !relpath.endsWith("-n.js")) {
 
259
                QStringList bt = eng.uncaughtExceptionBacktrace();
 
260
                QString err = eng.uncaughtException().toString();
 
261
                qWarning("%s\n%s\n", qPrintable(err), qPrintable(bt.join("\n")));
 
262
                continue;
 
263
            }
 
264
 
 
265
            QScriptValue testcases = global.property("testcases");
 
266
            if (!testcases.isArray())
 
267
                testcases = global.property("gTestcases");
 
268
            int count = testcases.property("length").toInt32();
 
269
            if (count == 0)
 
270
                continue;
 
271
 
 
272
            hasData = true;
 
273
            QString title = global.property("TITLE").toString();
 
274
            for (int i = 0; i < count; ++i) {
 
275
                QScriptValue kase = testcases.property(i);
 
276
                QString description = kase.property("description").toString();
 
277
                QScriptValue expect = kase.property("expect");
 
278
                QScriptValue actual = kase.property("actual");
 
279
                bool passed = kase.property("passed").toBoolean();
 
280
                int lineNumber = kase.property("__lineNumber__").toInt32();
 
281
 
 
282
                TestRecord rec(description, passed,
 
283
                               actual.toString(), expect.toString(),
 
284
                               relpath, lineNumber);
 
285
 
 
286
                QTest::newRow(description.toLatin1()) << rec;
 
287
            }
 
288
        }
 
289
        if (!hasData)
 
290
            QTest::newRow("") << TestRecord(); // dummy
 
291
    } else {
 
292
        QFETCH(TestRecord, record);
 
293
        if ((record.lineNumber == -1) && (record.actual == "QSKIP")) {
 
294
            QTest::qSkip(record.description.toLatin1(), record.fileName.toLatin1(), -1);
 
295
        } else {
 
296
            QString msg;
 
297
            FailureItem::Action failAct;
 
298
            bool expectFail = isExpectedFailure(record.fileName, record.description, &msg, &failAct);
 
299
            if (expectFail) {
 
300
                switch (failAct) {
 
301
                case FailureItem::ExpectFail:
 
302
                    QTest::qExpectFail("", msg.toLatin1(),
 
303
                                       QTest::Continue, record.fileName.toLatin1(),
 
304
                                       record.lineNumber);
 
305
                    break;
 
306
                case FailureItem::Skip:
 
307
                    QTest::qSkip(msg.toLatin1(), record.fileName.toLatin1(), record.lineNumber);
 
308
                    break;
 
309
                }
 
310
            }
 
311
            if (!expectFail || (failAct == FailureItem::ExpectFail)) {
 
312
                if (!record.passed) {
 
313
                    if (!expectFail && shouldGenerateExpectedFailures) {
 
314
                        addExpectedFailure(record.fileName,
 
315
                                           record.description,
 
316
                                           QString());
 
317
                    }
 
318
                    QTest::qCompare(record.actual, record.expected, "actual", "expect",
 
319
                                    record.fileName.toLatin1(), record.lineNumber);
 
320
                } else {
 
321
                    QTest::qCompare(record.actual, record.actual, "actual", "expect",
 
322
                                    record.fileName.toLatin1(), record.lineNumber);
 
323
                }
 
324
            }
 
325
        }
 
326
    }
 
327
}
 
328
 
 
329
tst_QScriptJSTestSuite::tst_QScriptJSTestSuite()
 
330
    : AbstractTestSuite("tst_QScriptJsTestSuite",
 
331
                        QString::fromLatin1("%0/tests").arg(SRCDIR),
 
332
                        ":/")
 
333
{
 
334
// don't execute any tests on slow machines
 
335
#if !defined(Q_OS_IRIX)
 
336
    // do all the test suites
 
337
    QFileInfoList testSuiteDirInfos = testsDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
 
338
    foreach (QFileInfo tsdi, testSuiteDirInfos) {
 
339
        QDir testSuiteDir(tsdi.absoluteFilePath());
 
340
        // do all the dirs in the test suite
 
341
        QFileInfoList subSuiteDirInfos = testSuiteDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
 
342
        foreach (QFileInfo ssdi, subSuiteDirInfos) {
 
343
            subSuitePaths.append(ssdi.absoluteFilePath());
 
344
            QString function = QString::fromLatin1("%0/%1")
 
345
                               .arg(testSuiteDir.dirName()).arg(ssdi.fileName());
 
346
            addTestFunction(function, CreateDataFunction);
 
347
        }
 
348
    }
 
349
#endif
 
350
 
 
351
    finalizeMetaObject();
 
352
}
 
353
 
 
354
tst_QScriptJSTestSuite::~tst_QScriptJSTestSuite()
 
355
{
 
356
}
 
357
 
 
358
void tst_QScriptJSTestSuite::configData(TestConfig::Mode mode, const QStringList &parts)
 
359
{
 
360
    switch (mode) {
 
361
    case TestConfig::Skip:
 
362
        addFileExclusion(parts.at(0), parts.value(1));
 
363
        break;
 
364
 
 
365
    case TestConfig::ExpectFail:
 
366
        addExpectedFailure(parts.at(0), parts.value(1), parts.value(2));
 
367
        break;
 
368
    }
 
369
}
 
370
 
 
371
void tst_QScriptJSTestSuite::writeSkipConfigFile(QTextStream &stream)
 
372
{
 
373
    stream << QString::fromLatin1("# testcase | message") << endl;
 
374
}
 
375
 
 
376
void tst_QScriptJSTestSuite::writeExpectFailConfigFile(QTextStream &stream)
 
377
{
 
378
    stream << QString::fromLatin1("# testcase | description | message") << endl;
 
379
    for (int i = 0; i < expectedFailures.size(); ++i) {
 
380
        const FailureItem &fail = expectedFailures.at(i);
 
381
        if (fail.pathRegExp.pattern().isEmpty())
 
382
            continue;
 
383
        stream << QString::fromLatin1("%0 | %1")
 
384
            .arg(fail.pathRegExp.pattern())
 
385
            .arg(escape(fail.description));
 
386
        if (!fail.message.isEmpty())
 
387
            stream << QString::fromLatin1(" | %0").arg(escape(fail.message));
 
388
        stream << endl;
 
389
    }
 
390
}
 
391
 
 
392
void tst_QScriptJSTestSuite::addExpectedFailure(const QRegExp &path, const QString &description, const QString &message)
 
393
{
 
394
    expectedFailures.append(FailureItem(FailureItem::ExpectFail, path, description, message));
 
395
}
 
396
 
 
397
void tst_QScriptJSTestSuite::addExpectedFailure(const QString &fileName, const QString &description, const QString &message)
 
398
{
 
399
    expectedFailures.append(FailureItem(FailureItem::ExpectFail, QRegExp(fileName), description, message));
 
400
}
 
401
 
 
402
void tst_QScriptJSTestSuite::addSkip(const QRegExp &path, const QString &description, const QString &message)
 
403
{
 
404
    expectedFailures.append(FailureItem(FailureItem::Skip, path, description, message));
 
405
}
 
406
 
 
407
void tst_QScriptJSTestSuite::addSkip(const QString &fileName, const QString &description, const QString &message)
 
408
{
 
409
    expectedFailures.append(FailureItem(FailureItem::Skip, QRegExp(fileName), description, message));
 
410
}
 
411
 
 
412
bool tst_QScriptJSTestSuite::isExpectedFailure(const QString &fileName, const QString &description,
 
413
                                  QString *message, FailureItem::Action *action) const
 
414
{
 
415
    for (int i = 0; i < expectedFailures.size(); ++i) {
 
416
        QRegExp pathRegExp = expectedFailures.at(i).pathRegExp;
 
417
        if (pathRegExp.indexIn(fileName) != -1) {
 
418
            if (description == expectedFailures.at(i).description) {
 
419
                if (message)
 
420
                    *message = expectedFailures.at(i).message;
 
421
                if (action)
 
422
                    *action = expectedFailures.at(i).action;
 
423
                return true;
 
424
            }
 
425
        }
 
426
    }
 
427
    return false;
 
428
}
 
429
 
 
430
void tst_QScriptJSTestSuite::addFileExclusion(const QString &fileName, const QString &message)
 
431
{
 
432
    fileExclusions.append(qMakePair(QRegExp(fileName), message));
 
433
}
 
434
 
 
435
void tst_QScriptJSTestSuite::addFileExclusion(const QRegExp &rx, const QString &message)
 
436
{
 
437
    fileExclusions.append(qMakePair(rx, message));
 
438
}
 
439
 
 
440
bool tst_QScriptJSTestSuite::isExcludedFile(const QString &fileName, QString *message) const
 
441
{
 
442
    for (int i = 0; i < fileExclusions.size(); ++i) {
 
443
        QRegExp copy = fileExclusions.at(i).first;
 
444
        if (copy.indexIn(fileName) != -1) {
 
445
            if (message)
 
446
                *message = fileExclusions.at(i).second;
 
447
            return true;
 
448
    }
 
449
    }
 
450
    return false;
 
451
}
 
452
 
 
453
QTEST_MAIN(tst_QScriptJSTestSuite)