summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-11-09 21:46:53 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-11-09 21:46:53 (GMT)
commitd9daad0ec3e3220c778177bb17d67158bde9c5aa (patch)
treed466de2143d81f0a20c3203193a7f2371c1ef48e
parent5b03f39a9dceac181abe304eb9be7647f6f166fb (diff)
parente1bcbc5bcf3d6015cacc717c31f96d2230890e88 (diff)
downloadQt-d9daad0ec3e3220c778177bb17d67158bde9c5aa.zip
Qt-d9daad0ec3e3220c778177bb17d67158bde9c5aa.tar.gz
Qt-d9daad0ec3e3220c778177bb17d67158bde9c5aa.tar.bz2
Merge branch 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into master-integration
* 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-1: Add autotests for setting non-Object as prototype value Revert new flaky test compile fix for namespaced Qt Ensured that the document nodes are sorted in the generated index. Make qsTr() work with Unicode (non-Latin-1) strings Add autotest that checks return value of QScriptContext::throwXXX() Improve autotest coverage of QScriptEngineDebugger Add benchmark for emitting signals from QtScript Split monolithic QtScript autotest into smaller tests
-rw-r--r--examples/webkit/imageanalyzer/imageanalyzer.h4
-rw-r--r--examples/webkit/imageanalyzer/mainwindow.h2
-rw-r--r--src/script/api/qscriptengine.cpp18
-rw-r--r--tests/auto/qscriptcontext/tst_qscriptcontext.cpp49
-rw-r--r--tests/auto/qscriptengine/idtranslatable-unicode.js5
-rw-r--r--tests/auto/qscriptengine/qscriptengine.qrc2
-rw-r--r--tests/auto/qscriptengine/translatable-unicode.js9
-rw-r--r--tests/auto/qscriptengine/translations/idtranslatable-unicode.qmbin0 -> 209 bytes
-rw-r--r--tests/auto/qscriptengine/translations/idtranslatable-unicode.ts26
-rw-r--r--tests/auto/qscriptengine/translations/translatable-unicode.qmbin0 -> 322 bytes
-rw-r--r--tests/auto/qscriptengine/translations/translatable-unicode.ts37
-rw-r--r--tests/auto/qscriptengine/tst_qscriptengine.cpp91
-rw-r--r--tests/auto/qscriptenginedebugger/tst_qscriptenginedebugger.cpp94
-rw-r--r--tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp57
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.cpp48
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.h2
-rw-r--r--tests/benchmarks/script/qscriptqobject/tst_qscriptqobject.cpp28
-rw-r--r--tools/qdoc3/tree.cpp71
18 files changed, 517 insertions, 26 deletions
diff --git a/examples/webkit/imageanalyzer/imageanalyzer.h b/examples/webkit/imageanalyzer/imageanalyzer.h
index 1bb25dc..5a96909 100644
--- a/examples/webkit/imageanalyzer/imageanalyzer.h
+++ b/examples/webkit/imageanalyzer/imageanalyzer.h
@@ -38,15 +38,17 @@
**
****************************************************************************/
-
#ifndef IMAGEANALYZER_H
#define IMAGEANALYZER_H
+
#include <QFutureWatcher>
#include <QtGui>
+QT_BEGIN_NAMESPACE
class QNetworkAccessManager;
class QNetworkReply;
class QNetworkDiskCache;
+QT_END_NAMESPACE
//! [ ImageAnalyzer - public interface ]
class ImageAnalyzer : public QObject
diff --git a/examples/webkit/imageanalyzer/mainwindow.h b/examples/webkit/imageanalyzer/mainwindow.h
index 076e586..3c943dc 100644
--- a/examples/webkit/imageanalyzer/mainwindow.h
+++ b/examples/webkit/imageanalyzer/mainwindow.h
@@ -45,7 +45,9 @@
#include <QWebView>
class ImageAnalyzer;
+QT_BEGIN_NAMESPACE
class QNetworkDiskCache;
+QT_END_NAMESPACE
class MainWin : public QWebView
{
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index 2d5e5f4..69abcad 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -808,7 +808,7 @@ JSC::JSValue JSC_HOST_CALL functionQsTranslate(JSC::ExecState *exec, JSC::JSObje
JSC::UString comment;
if (args.size() > 2)
comment = args.at(2).toString(exec);
- QCoreApplication::Encoding encoding = QCoreApplication::CodecForTr;
+ QCoreApplication::Encoding encoding = QCoreApplication::UnicodeUTF8;
if (args.size() > 3) {
JSC::UString encStr = args.at(3).toString(exec);
if (encStr == "CodecForTr")
@@ -824,9 +824,9 @@ JSC::JSValue JSC_HOST_CALL functionQsTranslate(JSC::ExecState *exec, JSC::JSObje
#endif
JSC::UString result;
#ifndef QT_NO_QOBJECT
- result = QCoreApplication::translate(QScript::convertToLatin1(context).constData(),
- QScript::convertToLatin1(text).constData(),
- QScript::convertToLatin1(comment).constData(),
+ result = QCoreApplication::translate(context.UTF8String().c_str(),
+ text.UTF8String().c_str(),
+ comment.UTF8String().c_str(),
encoding, n);
#else
result = text;
@@ -878,10 +878,10 @@ JSC::JSValue JSC_HOST_CALL functionQsTr(JSC::ExecState *exec, JSC::JSObject*, JS
#endif
JSC::UString result;
#ifndef QT_NO_QOBJECT
- result = QCoreApplication::translate(QScript::convertToLatin1(context).constData(),
- QScript::convertToLatin1(text).constData(),
- QScript::convertToLatin1(comment).constData(),
- QCoreApplication::CodecForTr, n);
+ result = QCoreApplication::translate(context.UTF8String().c_str(),
+ text.UTF8String().c_str(),
+ comment.UTF8String().c_str(),
+ QCoreApplication::UnicodeUTF8, n);
#else
result = text;
#endif
@@ -907,7 +907,7 @@ JSC::JSValue JSC_HOST_CALL functionQsTrId(JSC::ExecState *exec, JSC::JSObject*,
int n = -1;
if (args.size() > 1)
n = args.at(1).toInt32(exec);
- return JSC::jsString(exec, qtTrId(QScript::convertToLatin1(id).constData(), n));
+ return JSC::jsString(exec, qtTrId(id.UTF8String().c_str(), n));
}
JSC::JSValue JSC_HOST_CALL functionQsTrIdNoOp(JSC::ExecState *, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args)
diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
index cbcd16a..5e7ede8 100644
--- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
+++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
@@ -50,6 +50,7 @@
//TESTED_FILES=
Q_DECLARE_METATYPE(QScriptValueList)
+Q_DECLARE_METATYPE(QScriptContext::Error)
QT_BEGIN_NAMESPACE
extern bool qt_script_isJITEnabled();
@@ -91,6 +92,10 @@ private slots:
void qobjectAsActivationObject();
void parentContextCallee_QT2270();
void popNativeContextScope();
+ void throwErrorInGlobalContext();
+ void throwErrorWithTypeInGlobalContext_data();
+ void throwErrorWithTypeInGlobalContext();
+ void throwValueInGlobalContext();
};
tst_QScriptContext::tst_QScriptContext()
@@ -1323,5 +1328,49 @@ void tst_QScriptContext::parentContextCallee_QT2270()
QVERIFY(callee.equals(fun));
}
+void tst_QScriptContext::throwErrorInGlobalContext()
+{
+ QScriptEngine eng;
+ QScriptValue ret = eng.currentContext()->throwError("foo");
+ QVERIFY(ret.isError());
+ QVERIFY(eng.hasUncaughtException());
+ QVERIFY(eng.uncaughtException().strictlyEquals(ret));
+ QCOMPARE(ret.toString(), QString::fromLatin1("Error: foo"));
+}
+
+void tst_QScriptContext::throwErrorWithTypeInGlobalContext_data()
+{
+ QTest::addColumn<QScriptContext::Error>("error");
+ QTest::addColumn<QString>("stringRepresentation");
+ QTest::newRow("ReferenceError") << QScriptContext::ReferenceError << QString::fromLatin1("ReferenceError: foo");
+ QTest::newRow("SyntaxError") << QScriptContext::SyntaxError << QString::fromLatin1("SyntaxError: foo");
+ QTest::newRow("TypeError") << QScriptContext::TypeError << QString::fromLatin1("TypeError: foo");
+ QTest::newRow("RangeError") << QScriptContext::RangeError << QString::fromLatin1("RangeError: foo");
+ QTest::newRow("URIError") << QScriptContext::URIError << QString::fromLatin1("URIError: foo");
+ QTest::newRow("UnknownError") << QScriptContext::UnknownError << QString::fromLatin1("Error: foo");
+}
+
+void tst_QScriptContext::throwErrorWithTypeInGlobalContext()
+{
+ QFETCH(QScriptContext::Error, error);
+ QFETCH(QString, stringRepresentation);
+ QScriptEngine eng;
+ QScriptValue ret = eng.currentContext()->throwError(error, "foo");
+ QVERIFY(ret.isError());
+ QVERIFY(eng.hasUncaughtException());
+ QVERIFY(eng.uncaughtException().strictlyEquals(ret));
+ QCOMPARE(ret.toString(), stringRepresentation);
+}
+
+void tst_QScriptContext::throwValueInGlobalContext()
+{
+ QScriptEngine eng;
+ QScriptValue val(&eng, 123);
+ QScriptValue ret = eng.currentContext()->throwValue(val);
+ QVERIFY(ret.strictlyEquals(val));
+ QVERIFY(eng.hasUncaughtException());
+ QVERIFY(eng.uncaughtException().strictlyEquals(val));
+}
+
QTEST_MAIN(tst_QScriptContext)
#include "tst_qscriptcontext.moc"
diff --git a/tests/auto/qscriptengine/idtranslatable-unicode.js b/tests/auto/qscriptengine/idtranslatable-unicode.js
new file mode 100644
index 0000000..e17d617
--- /dev/null
+++ b/tests/auto/qscriptengine/idtranslatable-unicode.js
@@ -0,0 +1,5 @@
+qsTrId('\u01F8\u01D2\u0199\u01D0\u01E1');
+
+QT_TRID_NOOP("\u0191\u01CE\u0211\u0229\u019C\u018E\u019A\u01D0");
+
+qsTrId("\u0181\u01A1\u0213\u018F\u018C", 10);
diff --git a/tests/auto/qscriptengine/qscriptengine.qrc b/tests/auto/qscriptengine/qscriptengine.qrc
index fa55a5b..d05d115 100644
--- a/tests/auto/qscriptengine/qscriptengine.qrc
+++ b/tests/auto/qscriptengine/qscriptengine.qrc
@@ -2,5 +2,7 @@
<qresource>
<file>translations/translatable_la.qm</file>
<file>translations/idtranslatable_la.qm</file>
+ <file>translations/translatable-unicode.qm</file>
+ <file>translations/idtranslatable-unicode.qm</file>
</qresource>
</RCC>
diff --git a/tests/auto/qscriptengine/translatable-unicode.js b/tests/auto/qscriptengine/translatable-unicode.js
new file mode 100644
index 0000000..afe2aff
--- /dev/null
+++ b/tests/auto/qscriptengine/translatable-unicode.js
@@ -0,0 +1,9 @@
+qsTr("H\u2082O");
+qsTranslate("\u010C\u0101\u011F\u0115", "CO\u2082");
+
+var unicode_strings = [
+ QT_TR_NOOP("\u0391\u0392\u0393"),
+ QT_TRANSLATE_NOOP("\u010C\u0101\u011F\u0115", "\u0414\u0415\u0416")
+];
+
+qsTr("H\u2082O", "not the same H\u2082O");
diff --git a/tests/auto/qscriptengine/translations/idtranslatable-unicode.qm b/tests/auto/qscriptengine/translations/idtranslatable-unicode.qm
new file mode 100644
index 0000000..8c5fb91
--- /dev/null
+++ b/tests/auto/qscriptengine/translations/idtranslatable-unicode.qm
Binary files differ
diff --git a/tests/auto/qscriptengine/translations/idtranslatable-unicode.ts b/tests/auto/qscriptengine/translations/idtranslatable-unicode.ts
new file mode 100644
index 0000000..74ebf43
--- /dev/null
+++ b/tests/auto/qscriptengine/translations/idtranslatable-unicode.ts
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="nb_NO">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name></name>
+ <message id="Ǹǒƙǐǡ">
+ <location filename="idtranslatable-unicode.js" line="1"/>
+ <source></source>
+ <translation>Ƨưƈȼȝȿș</translation>
+ </message>
+ <message id="ƑǎȑȩƜƎƚǐ">
+ <location filename="idtranslatable-unicode.js" line="3"/>
+ <source></source>
+ <translation>Ǡȡȋȅȕ</translation>
+ </message>
+ <message id="ƁơȓƏƌ" numerus="yes">
+ <location filename="idtranslatable-unicode.js" line="5"/>
+ <source></source>
+ <translation>
+ <numerusform>Ƒưǹ</numerusform>
+ <numerusform>%n ƒơǒ(ș)</numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/qscriptengine/translations/translatable-unicode.qm b/tests/auto/qscriptengine/translations/translatable-unicode.qm
new file mode 100644
index 0000000..aa75ce6
--- /dev/null
+++ b/tests/auto/qscriptengine/translations/translatable-unicode.qm
Binary files differ
diff --git a/tests/auto/qscriptengine/translations/translatable-unicode.ts b/tests/auto/qscriptengine/translations/translatable-unicode.ts
new file mode 100644
index 0000000..1b8b4d2
--- /dev/null
+++ b/tests/auto/qscriptengine/translations/translatable-unicode.ts
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>translatable-unicode</name>
+ <message>
+ <location filename="translatable-unicode.js" line="1"/>
+ <source>H₂O</source>
+ <translation>ͻͼͽ</translation>
+ </message>
+ <message>
+ <location filename="translatable-unicode.js" line="5"/>
+ <source>ΑΒΓ</source>
+ <translation>ӜҴѼ</translation>
+ </message>
+ <message>
+ <location filename="translatable-unicode.js" line="9"/>
+ <source>H₂O</source>
+ <comment>not the same H₂O</comment>
+ <translation>ԶՊՒ</translation>
+ </message>
+</context>
+<context>
+ <name>Čāğĕ</name>
+ <message>
+ <location filename="translatable-unicode.js" line="2"/>
+ <source>CO₂</source>
+ <translation>בךע</translation>
+ </message>
+ <message>
+ <location filename="translatable-unicode.js" line="6"/>
+ <source>ДЕЖ</source>
+ <translation>خسس</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp
index 5f38c22..d529b8b 100644
--- a/tests/auto/qscriptengine/tst_qscriptengine.cpp
+++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp
@@ -186,6 +186,10 @@ private slots:
void translationContext_data();
void translationContext();
void translateScriptIdBased();
+ void translateScriptUnicode_data();
+ void translateScriptUnicode();
+ void translateScriptUnicodeIdBased_data();
+ void translateScriptUnicodeIdBased();
void functionScopes();
void nativeFunctionScopes();
void evaluateProgram();
@@ -4950,6 +4954,93 @@ void tst_QScriptEngine::translateScriptIdBased()
QString::fromLatin1("qtn_foo_bar")); // Doesn't have plural
}
+// How to add a new test row:
+// - Find a nice list of Unicode characters to choose from
+// - Write source string/context/comment in .js using Unicode escape sequences (\uABCD)
+// - Update corresponding .ts file (e.g. lupdate foo.js -ts foo.ts -codecfortr UTF-8)
+// - Enter translation in Linguist
+// - Update corresponding .qm file (e.g. lrelease foo.ts)
+// - Evaluate script that performs translation; make sure the correct result is returned
+// (e.g. by setting the resulting string as the text of a QLabel and visually verifying
+// that it looks the same as what you entered in Linguist :-) )
+// - Generate the expectedTranslation column data using toUtf8().toHex()
+void tst_QScriptEngine::translateScriptUnicode_data()
+{
+ QTest::addColumn<QString>("expression");
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QString>("expectedTranslation");
+
+ QString fileName = QString::fromLatin1("translatable-unicode.js");
+ QTest::newRow("qsTr('H\\u2082O')@translatable-unicode.js")
+ << QString::fromLatin1("qsTr('H\\u2082O')") << fileName << QString::fromUtf8("\xcd\xbb\xcd\xbc\xcd\xbd");
+ QTest::newRow("qsTranslate('\\u010C\\u0101\\u011F\\u0115', 'CO\\u2082')@translatable-unicode.js")
+ << QString::fromLatin1("qsTranslate('\\u010C\\u0101\\u011F\\u0115', 'CO\\u2082')") << fileName << QString::fromUtf8("\xd7\x91\xd7\x9a\xd7\xa2");
+ QTest::newRow("qsTr('\\u0391\\u0392\\u0393')@translatable-unicode.js")
+ << QString::fromLatin1("qsTr('\\u0391\\u0392\\u0393')") << fileName << QString::fromUtf8("\xd3\x9c\xd2\xb4\xd1\xbc");
+ QTest::newRow("qsTranslate('\\u010C\\u0101\\u011F\\u0115', '\\u0414\\u0415\\u0416')@translatable-unicode.js")
+ << QString::fromLatin1("qsTranslate('\\u010C\\u0101\\u011F\\u0115', '\\u0414\\u0415\\u0416')") << fileName << QString::fromUtf8("\xd8\xae\xd8\xb3\xd8\xb3");
+ QTest::newRow("qsTr('H\\u2082O', 'not the same H\\u2082O')@translatable-unicode.js")
+ << QString::fromLatin1("qsTr('H\\u2082O', 'not the same H\\u2082O')") << fileName << QString::fromUtf8("\xd4\xb6\xd5\x8a\xd5\x92");
+ QTest::newRow("qsTr('H\\u2082O')")
+ << QString::fromLatin1("qsTr('H\\u2082O')") << QString() << QString::fromUtf8("\x48\xe2\x82\x82\x4f");
+ QTest::newRow("qsTranslate('\\u010C\\u0101\\u011F\\u0115', 'CO\\u2082')")
+ << QString::fromLatin1("qsTranslate('\\u010C\\u0101\\u011F\\u0115', 'CO\\u2082')") << QString() << QString::fromUtf8("\xd7\x91\xd7\x9a\xd7\xa2");
+}
+
+void tst_QScriptEngine::translateScriptUnicode()
+{
+ QFETCH(QString, expression);
+ QFETCH(QString, fileName);
+ QFETCH(QString, expectedTranslation);
+
+ QScriptEngine engine;
+
+ QTranslator translator;
+ QVERIFY(translator.load(":/translations/translatable-unicode"));
+ QCoreApplication::instance()->installTranslator(&translator);
+ engine.installTranslatorFunctions();
+
+ QCOMPARE(engine.evaluate(expression, fileName).toString(), expectedTranslation);
+ QVERIFY(!engine.hasUncaughtException());
+
+ QCoreApplication::instance()->removeTranslator(&translator);
+}
+
+void tst_QScriptEngine::translateScriptUnicodeIdBased_data()
+{
+ QTest::addColumn<QString>("expression");
+ QTest::addColumn<QString>("expectedTranslation");
+
+ QTest::newRow("qsTrId('\\u01F8\\u01D2\\u0199\\u01D0\\u01E1'')")
+ << QString::fromLatin1("qsTrId('\\u01F8\\u01D2\\u0199\\u01D0\\u01E1')") << QString::fromUtf8("\xc6\xa7\xc6\xb0\xc6\x88\xc8\xbc\xc8\x9d\xc8\xbf\xc8\x99");
+ QTest::newRow("qsTrId('\\u0191\\u01CE\\u0211\\u0229\\u019C\\u018E\\u019A\\u01D0')")
+ << QString::fromLatin1("qsTrId('\\u0191\\u01CE\\u0211\\u0229\\u019C\\u018E\\u019A\\u01D0')") << QString::fromUtf8("\xc7\xa0\xc8\xa1\xc8\x8b\xc8\x85\xc8\x95");
+ QTest::newRow("qsTrId('\\u0181\\u01A1\\u0213\\u018F\\u018C', 10)")
+ << QString::fromLatin1("qsTrId('\\u0181\\u01A1\\u0213\\u018F\\u018C', 10)") << QString::fromUtf8("\x31\x30\x20\xc6\x92\xc6\xa1\xc7\x92\x28\xc8\x99\x29");
+ QTest::newRow("qsTrId('\\u0181\\u01A1\\u0213\\u018F\\u018C')")
+ << QString::fromLatin1("qsTrId('\\u0181\\u01A1\\u0213\\u018F\\u018C')") << QString::fromUtf8("\xc6\x91\xc6\xb0\xc7\xb9");
+ QTest::newRow("qsTrId('\\u01CD\\u0180\\u01A8\\u0190\\u019E\\u01AB')")
+ << QString::fromLatin1("qsTrId('\\u01CD\\u0180\\u01A8\\u0190\\u019E\\u01AB')") << QString::fromUtf8("\xc7\x8d\xc6\x80\xc6\xa8\xc6\x90\xc6\x9e\xc6\xab");
+}
+
+void tst_QScriptEngine::translateScriptUnicodeIdBased()
+{
+ QFETCH(QString, expression);
+ QFETCH(QString, expectedTranslation);
+
+ QScriptEngine engine;
+
+ QTranslator translator;
+ QVERIFY(translator.load(":/translations/idtranslatable-unicode"));
+ QCoreApplication::instance()->installTranslator(&translator);
+ engine.installTranslatorFunctions();
+
+ QCOMPARE(engine.evaluate(expression).toString(), expectedTranslation);
+ QVERIFY(!engine.hasUncaughtException());
+
+ QCoreApplication::instance()->removeTranslator(&translator);
+}
+
void tst_QScriptEngine::functionScopes()
{
QScriptEngine eng;
diff --git a/tests/auto/qscriptenginedebugger/tst_qscriptenginedebugger.cpp b/tests/auto/qscriptenginedebugger/tst_qscriptenginedebugger.cpp
index c5e4954..6b49858 100644
--- a/tests/auto/qscriptenginedebugger/tst_qscriptenginedebugger.cpp
+++ b/tests/auto/qscriptenginedebugger/tst_qscriptenginedebugger.cpp
@@ -50,24 +50,11 @@
#include <qmenu.h>
#include <qplaintextedit.h>
#include <qtoolbar.h>
+#include "../../shared/util.h"
//TESTED_CLASS=
//TESTED_FILES=
-// Will try to wait for the condition while allowing event processing
-#define QTRY_COMPARE(__expr, __expected) \
- do { \
- const int __step = 50; \
- const int __timeout = 5000; \
- if ((__expr) != (__expected)) { \
- QTest::qWait(0); \
- } \
- for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \
- QTest::qWait(__step); \
- } \
- QCOMPARE(__expr, __expected); \
- } while(0)
-
// Can't use QTest::qWait() because it causes event loop to hang on some platforms
static void qsWait(int ms)
{
@@ -89,6 +76,9 @@ public:
tst_QScriptEngineDebugger();
virtual ~tst_QScriptEngineDebugger();
+protected slots:
+ void recordDebuggerStateAndContinue();
+
private slots:
void attachAndDetach();
void action();
@@ -97,6 +87,11 @@ private slots:
void debuggerSignals();
void consoleCommands();
void multithreadedDebugging();
+ void autoShowStandardWindow();
+ void standardWindowOwnership();
+
+private:
+ QScriptEngineDebugger::DebuggerState m_recordedDebuggerState;
};
tst_QScriptEngineDebugger::tst_QScriptEngineDebugger()
@@ -107,6 +102,14 @@ tst_QScriptEngineDebugger::~tst_QScriptEngineDebugger()
{
}
+void tst_QScriptEngineDebugger::recordDebuggerStateAndContinue()
+{
+ QScriptEngineDebugger *debugger = qobject_cast<QScriptEngineDebugger*>(sender());
+ Q_ASSERT(debugger != 0);
+ m_recordedDebuggerState = debugger->state();
+ debugger->action(QScriptEngineDebugger::ContinueAction)->trigger();
+}
+
void tst_QScriptEngineDebugger::attachAndDetach()
{
#if defined(Q_OS_WINCE) && _WIN32_WCE < 0x600
@@ -784,5 +787,68 @@ void tst_QScriptEngineDebugger::multithreadedDebugging()
QTRY_COMPARE(threadFinishedSpy.count(), 1);
}
+void tst_QScriptEngineDebugger::autoShowStandardWindow()
+{
+ {
+ QScriptEngine engine;
+ QScriptEngineDebugger debugger;
+ QCOMPARE(debugger.autoShowStandardWindow(), true);
+ debugger.attachTo(&engine);
+ QObject::connect(&debugger, SIGNAL(evaluationSuspended()),
+ debugger.action(QScriptEngineDebugger::ContinueAction),
+ SLOT(trigger()));
+ engine.evaluate("debugger");
+ QTRY_VERIFY(debugger.standardWindow()->isVisible());
+
+ debugger.setAutoShowStandardWindow(true);
+ QCOMPARE(debugger.autoShowStandardWindow(), true);
+
+ debugger.setAutoShowStandardWindow(false);
+ QCOMPARE(debugger.autoShowStandardWindow(), false);
+
+ debugger.setAutoShowStandardWindow(true);
+ QCOMPARE(debugger.autoShowStandardWindow(), true);
+
+ debugger.standardWindow()->hide();
+
+ engine.evaluate("debugger");
+ QTRY_VERIFY(debugger.standardWindow()->isVisible());
+ }
+
+ {
+ QScriptEngine engine;
+ QScriptEngineDebugger debugger;
+ debugger.setAutoShowStandardWindow(false);
+ debugger.attachTo(&engine);
+ QObject::connect(&debugger, SIGNAL(evaluationSuspended()),
+ debugger.action(QScriptEngineDebugger::ContinueAction),
+ SLOT(trigger()));
+ QSignalSpy evaluationResumedSpy(&debugger, SIGNAL(evaluationResumed()));
+ engine.evaluate("debugger");
+ QTRY_COMPARE(evaluationResumedSpy.count(), 1);
+ QVERIFY(!debugger.standardWindow()->isVisible());
+ }
+}
+
+void tst_QScriptEngineDebugger::standardWindowOwnership()
+{
+ QScriptEngine engine;
+ QPointer<QMainWindow> win;
+ {
+ QScriptEngineDebugger debugger;
+ win = debugger.standardWindow();
+ }
+ QVERIFY(win == 0);
+
+ // Reparent the window.
+ QWidget widget;
+ {
+ QScriptEngineDebugger debugger;
+ win = debugger.standardWindow();
+ win->setParent(&widget);
+ }
+ QVERIFY(win != 0);
+}
+
QTEST_MAIN(tst_QScriptEngineDebugger)
#include "tst_qscriptenginedebugger.moc"
diff --git a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp
index 1562118..29934d5 100644
--- a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp
+++ b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp
@@ -528,6 +528,20 @@ protected slots:
private slots:
void registeredTypes();
void getSetStaticProperty();
+ void getSetStaticProperty_propertyFlags();
+ void getSetStaticProperty_changeInCpp();
+ void getSetStaticProperty_changeInJS();
+ void getSetStaticProperty_compatibleVariantTypes();
+ void getSetStaticProperty_conversion();
+ void getSetStaticProperty_delete();
+ void getSetStaticProperty_nonScriptable();
+ void getSetStaticProperty_writeOnly();
+ void getSetStaticProperty_readOnly();
+ void getSetStaticProperty_enum();
+ void getSetStaticProperty_qflags();
+ void getSetStaticProperty_pointerDeref();
+ void getSetStaticProperty_customGetterSetter();
+ void getSetStaticProperty_methodPersistence();
void getSetDynamicProperty();
void getSetChildren();
void callQtInvokable();
@@ -655,7 +669,10 @@ void tst_QScriptExtQObject::getSetStaticProperty()
QCOMPARE(m_engine->evaluate("myObject.stringListProperty[1]").isString(), true);
QCOMPARE(m_engine->evaluate("myObject.stringListProperty[1]").toString(),
QLatin1String("zag"));
+}
+void tst_QScriptExtQObject::getSetStaticProperty_propertyFlags()
+{
// default flags for "normal" properties
{
QScriptValue mobj = m_engine->globalObject().property("myObject");
@@ -677,7 +694,10 @@ void tst_QScriptExtQObject::getSetStaticProperty()
QVERIFY(!(mobj.propertyFlags("mySlot()") & QScriptValue::SkipInEnumeration));
QVERIFY(mobj.propertyFlags("mySlot()") & QScriptValue::QObjectMember);
}
+}
+void tst_QScriptExtQObject::getSetStaticProperty_changeInCpp()
+{
// property change in C++ should be reflected in script
m_myObject->setIntProperty(456);
QCOMPARE(m_engine->evaluate("myObject.intProperty")
@@ -701,7 +721,10 @@ void tst_QScriptExtQObject::getSetStaticProperty()
m_myObject->setStringProperty(QLatin1String("zab"));
QCOMPARE(m_engine->evaluate("myObject.stringProperty")
.equals(QScriptValue(m_engine, QLatin1String("zab"))), true);
+}
+void tst_QScriptExtQObject::getSetStaticProperty_changeInJS()
+{
// property change in script should be reflected in C++
QCOMPARE(m_engine->evaluate("myObject.intProperty = 123")
.strictlyEquals(QScriptValue(m_engine, 123)), true);
@@ -784,7 +807,10 @@ void tst_QScriptExtQObject::getSetStaticProperty()
<< QLatin1String("two")
<< QLatin1String("true"));
}
+}
+void tst_QScriptExtQObject::getSetStaticProperty_compatibleVariantTypes()
+{
// test setting properties where we can't convert the type natively but where the
// types happen to be compatible variant types already
{
@@ -803,7 +829,10 @@ void tst_QScriptExtQObject::getSetStaticProperty()
mobj.setProperty("propWithCustomType", m_engine->newVariant(qVariantFromValue(t)));
QVERIFY(m_myObject->propWithCustomType().string == t.string);
}
+}
+void tst_QScriptExtQObject::getSetStaticProperty_conversion()
+{
// test that we do value conversion if necessary when setting properties
{
QScriptValue br = m_engine->evaluate("myObject.brushProperty");
@@ -823,28 +852,41 @@ void tst_QScriptExtQObject::getSetStaticProperty()
m_engine->globalObject().setProperty("myColor", QScriptValue());
}
+}
+void tst_QScriptExtQObject::getSetStaticProperty_delete()
+{
// try to delete
QCOMPARE(m_engine->evaluate("delete myObject.intProperty").toBoolean(), false);
QCOMPARE(m_engine->evaluate("myObject.intProperty").toNumber(), 123.0);
+ m_myObject->setVariantProperty(42);
QCOMPARE(m_engine->evaluate("delete myObject.variantProperty").toBoolean(), false);
QCOMPARE(m_engine->evaluate("myObject.variantProperty").toNumber(), 42.0);
+}
+void tst_QScriptExtQObject::getSetStaticProperty_nonScriptable()
+{
// non-scriptable property
QCOMPARE(m_myObject->hiddenProperty(), 456.0);
QCOMPARE(m_engine->evaluate("myObject.hiddenProperty").isUndefined(), true);
QCOMPARE(m_engine->evaluate("myObject.hiddenProperty = 123;"
"myObject.hiddenProperty").toInt32(), 123);
QCOMPARE(m_myObject->hiddenProperty(), 456.0);
+}
+void tst_QScriptExtQObject::getSetStaticProperty_writeOnly()
+{
// write-only property
QCOMPARE(m_myObject->writeOnlyProperty(), 789);
QCOMPARE(m_engine->evaluate("myObject.writeOnlyProperty").isUndefined(), true);
QCOMPARE(m_engine->evaluate("myObject.writeOnlyProperty = 123;"
"myObject.writeOnlyProperty").isUndefined(), true);
QCOMPARE(m_myObject->writeOnlyProperty(), 123);
+}
+void tst_QScriptExtQObject::getSetStaticProperty_readOnly()
+{
// read-only property
QCOMPARE(m_myObject->readOnlyProperty(), 987);
QCOMPARE(m_engine->evaluate("myObject.readOnlyProperty").toInt32(), 987);
@@ -856,7 +898,10 @@ void tst_QScriptExtQObject::getSetStaticProperty()
QCOMPARE(mobj.propertyFlags("readOnlyProperty") & QScriptValue::ReadOnly,
QScriptValue::ReadOnly);
}
+}
+void tst_QScriptExtQObject::getSetStaticProperty_enum()
+{
// enum property
QCOMPARE(m_myObject->enumProperty(), MyQObject::BarPolicy);
{
@@ -881,7 +926,10 @@ void tst_QScriptExtQObject::getSetStaticProperty()
QCOMPARE(m_myObject->enumProperty(), MyQObject::BazPolicy);
m_engine->evaluate("myObject.enumProperty = 'nada'");
QCOMPARE(m_myObject->enumProperty(), (MyQObject::Policy)-1);
+}
+void tst_QScriptExtQObject::getSetStaticProperty_qflags()
+{
// flags property
QCOMPARE(m_myObject->flagsProperty(), MyQObject::FooAbility);
{
@@ -900,7 +948,10 @@ void tst_QScriptExtQObject::getSetStaticProperty()
m_engine->evaluate("myObject.flagsProperty = 'ScoobyDoo'");
// ### ouch! Shouldn't QMetaProperty::write() rather not change the value...?
QCOMPARE(m_myObject->flagsProperty(), (MyQObject::Ability)-1);
+}
+void tst_QScriptExtQObject::getSetStaticProperty_pointerDeref()
+{
// auto-dereferencing of pointers
{
QBrush b = QColor(0xCA, 0xFE, 0xBA, 0xBE);
@@ -920,7 +971,10 @@ void tst_QScriptExtQObject::getSetStaticProperty()
}
m_engine->globalObject().setProperty("brushPointer", QScriptValue());
}
+}
+void tst_QScriptExtQObject::getSetStaticProperty_customGetterSetter()
+{
// install custom property getter+setter
{
QScriptValue mobj = m_engine->globalObject().property("myObject");
@@ -930,7 +984,10 @@ void tst_QScriptExtQObject::getSetStaticProperty()
mobj.setProperty("intProperty", 321);
QCOMPARE(mobj.property("intProperty").toInt32(), 321);
}
+}
+void tst_QScriptExtQObject::getSetStaticProperty_methodPersistence()
+{
// method properties are persistent
{
QScriptValue slot = m_engine->evaluate("myObject.mySlot");
diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
index be51cf2..528b20e 100644
--- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
+++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
@@ -2332,6 +2332,54 @@ void tst_QScriptValue::getSetPrototype_twoEngines()
}
+void tst_QScriptValue::getSetPrototype_null()
+{
+ QScriptEngine eng;
+ QScriptValue object = eng.newObject();
+ object.setPrototype(QScriptValue(QScriptValue::NullValue));
+ QVERIFY(object.prototype().isNull());
+
+ QScriptValue newProto = eng.newObject();
+ object.setPrototype(newProto);
+ QVERIFY(object.prototype().equals(newProto));
+
+ object.setPrototype(QScriptValue(&eng, QScriptValue::NullValue));
+ QVERIFY(object.prototype().isNull());
+}
+
+void tst_QScriptValue::getSetPrototype_notObjectOrNull()
+{
+ QScriptEngine eng;
+ QScriptValue object = eng.newObject();
+ QScriptValue originalProto = object.prototype();
+
+ QEXPECT_FAIL("", "QTBUG-15154: QScriptValue::setPrototype() allows a non-Object value to be set as prototype", Abort);
+
+ // bool
+ object.setPrototype(true);
+ QVERIFY(object.prototype().equals(originalProto));
+ object.setPrototype(QScriptValue(&eng, true));
+ QVERIFY(object.prototype().equals(originalProto));
+
+ // number
+ object.setPrototype(123);
+ QVERIFY(object.prototype().equals(originalProto));
+ object.setPrototype(QScriptValue(&eng, 123));
+ QVERIFY(object.prototype().equals(originalProto));
+
+ // string
+ object.setPrototype("foo");
+ QVERIFY(object.prototype().equals(originalProto));
+ object.setPrototype(QScriptValue(&eng, "foo"));
+ QVERIFY(object.prototype().equals(originalProto));
+
+ // undefined
+ object.setPrototype(QScriptValue(QScriptValue::UndefinedValue));
+ QVERIFY(object.prototype().equals(originalProto));
+ object.setPrototype(QScriptValue(&eng, QScriptValue::UndefinedValue));
+ QVERIFY(object.prototype().equals(originalProto));
+}
+
void tst_QScriptValue::getSetPrototype()
{
QScriptEngine eng;
diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.h b/tests/auto/qscriptvalue/tst_qscriptvalue.h
index 45a109e..c6b2202 100644
--- a/tests/auto/qscriptvalue/tst_qscriptvalue.h
+++ b/tests/auto/qscriptvalue/tst_qscriptvalue.h
@@ -115,6 +115,8 @@ private slots:
void getSetPrototype_eval();
void getSetPrototype_invalidPrototype();
void getSetPrototype_twoEngines();
+ void getSetPrototype_null();
+ void getSetPrototype_notObjectOrNull();
void getSetPrototype();
void getSetScope();
void getSetProperty_HooliganTask162051();
diff --git a/tests/benchmarks/script/qscriptqobject/tst_qscriptqobject.cpp b/tests/benchmarks/script/qscriptqobject/tst_qscriptqobject.cpp
index e68db06..62f3c2a 100644
--- a/tests/benchmarks/script/qscriptqobject/tst_qscriptqobject.cpp
+++ b/tests/benchmarks/script/qscriptqobject/tst_qscriptqobject.cpp
@@ -309,6 +309,9 @@ private slots:
void qobjectSignalHandler();
void customTypeSignalHandler();
+ void emitSignal_data();
+ void emitSignal();
+
void readButtonMetaProperty_data();
void readButtonMetaProperty();
@@ -948,6 +951,31 @@ void tst_QScriptQObject::customTypeSignalHandler()
}
}
+void tst_QScriptQObject::emitSignal_data()
+{
+ QTest::addColumn<QString>("propertyName");
+ QTest::addColumn<QString>("arguments");
+
+ QTest::newRow("voidSignal()") << "voidSignal" << "";
+
+ QTest::newRow("boolSignal(true)") << "boolSignal" << "true";
+ QTest::newRow("intSignal(123)") << "intSignal" << "123";
+ QTest::newRow("doubleSignal(123)") << "doubleSignal" << "123";
+ QTest::newRow("stringSignal('hello')") << "stringSignal" << "'hello'";
+ QTest::newRow("variantSignal(123)") << "variantSignal" << "123";
+ QTest::newRow("qobjectSignal(this)") << "qobjectSignal" << "this"; // assumes 'this' is a QObject
+}
+
+void tst_QScriptQObject::emitSignal()
+{
+ QFETCH(QString, propertyName);
+ QFETCH(QString, arguments);
+
+ QScriptEngine engine;
+ SignalTestObject testObject;
+ callMethodHelper(engine, &testObject, propertyName, arguments);
+}
+
void tst_QScriptQObject::readButtonMetaProperty_data()
{
readMetaProperty_dataHelper(&QPushButton::staticMetaObject);
diff --git a/tools/qdoc3/tree.cpp b/tools/qdoc3/tree.cpp
index 540ffa9..d1e2c60 100644
--- a/tools/qdoc3/tree.cpp
+++ b/tools/qdoc3/tree.cpp
@@ -1543,8 +1543,72 @@ bool Tree::generateIndexSection(QXmlStreamWriter &writer,
return true;
}
+
/*!
- */
+ Returns true if the node \a n1 is less than node \a n2.
+ The comparison is performed by comparing properties of the nodes in order
+ of increasing complexity.
+*/
+bool compareNodes(const Node *n1, const Node *n2)
+{
+ // Private nodes can occur in any order since they won't normally be
+ // written to the index.
+ if (n1->access() == Node::Private && n2->access() == Node::Private)
+ return true;
+
+ if (n1->location().filePath() < n2->location().filePath())
+ return true;
+ else if (n1->location().filePath() > n2->location().filePath())
+ return false;
+
+ if (n1->type() < n2->type())
+ return true;
+ else if (n1->type() > n2->type())
+ return false;
+
+ if (n1->name() < n2->name())
+ return true;
+ else if (n1->name() > n2->name())
+ return false;
+
+ if (n1->access() < n2->access())
+ return true;
+ else if (n1->access() > n2->access())
+ return false;
+
+ if (n1->type() == Node::Function && n2->type() == Node::Function) {
+ const FunctionNode *f1 = static_cast<const FunctionNode *>(n1);
+ const FunctionNode *f2 = static_cast<const FunctionNode *>(n2);
+
+ if (f1->isConst() < f2->isConst())
+ return true;
+ else if (f1->isConst() > f2->isConst())
+ return false;
+
+ if (f1->signature() < f2->signature())
+ return true;
+ else if (f1->signature() > f2->signature())
+ return false;
+ }
+
+ if (n1->type() == Node::Fake && n2->type() == Node::Fake) {
+ const FakeNode *f1 = static_cast<const FakeNode *>(n1);
+ const FakeNode *f2 = static_cast<const FakeNode *>(n2);
+ if (f1->fullTitle() < f2->fullTitle())
+ return true;
+ else if (f1->fullTitle() > f2->fullTitle())
+ return false;
+ }
+
+ return false;
+}
+
+/*!
+ Generate index sections for the child nodes of the given \a node
+ using the \a writer specified. If \a generateInternalNodes is true,
+ nodes marked as internal will be included in the index; otherwise,
+ they will be omitted.
+*/
void Tree::generateIndexSections(QXmlStreamWriter &writer,
const Node *node,
bool generateInternalNodes) const
@@ -1554,7 +1618,10 @@ void Tree::generateIndexSections(QXmlStreamWriter &writer,
if (node->isInnerNode()) {
const InnerNode *inner = static_cast<const InnerNode *>(node);
- foreach (const Node *child, inner->childNodes()) {
+ NodeList cnodes = inner->childNodes();
+ qSort(cnodes.begin(), cnodes.end(), compareNodes);
+
+ foreach (const Node *child, cnodes) {
/*
Don't generate anything for a QML property group node.
It is just a place holder for a collection of QML property