summaryrefslogtreecommitdiffstats
path: root/old/interpreter
diff options
context:
space:
mode:
authorDavid Clark <david.a.clark@nokia.com>2010-11-18 16:20:48 +1000
committerDavid Clark <david.a.clark@nokia.com>2010-11-18 16:20:48 +1000
commitc223232bc15106750da632598047a35ad3762723 (patch)
tree403f7aa2c3a5a912edce6feae869046c89d29178 /old/interpreter
parentb984b0b62076067f1f75db5a7eda5aaa2cdaad2a (diff)
Mark repository as deprecatedHEADmaster
Diffstat (limited to 'old/interpreter')
-rw-r--r--old/interpreter/DESCRIPTION1
-rw-r--r--old/interpreter/builtins.js596
-rw-r--r--old/interpreter/config.js72
-rw-r--r--old/interpreter/interpreter.pro60
-rw-r--r--old/interpreter/main.cpp59
-rw-r--r--old/interpreter/qscriptsystemtest.cpp838
-rw-r--r--old/interpreter/qscriptsystemtest.h114
-rw-r--r--old/interpreter/qtscript_bindings.cpp313
-rw-r--r--old/interpreter/qtscript_bindings.h83
-rw-r--r--old/interpreter/qtuitestengineagent.cpp70
-rw-r--r--old/interpreter/qtuitestengineagent.h63
-rw-r--r--old/interpreter/scriptpreprocessor.cpp256
-rw-r--r--old/interpreter/scriptpreprocessor.h58
-rw-r--r--old/interpreter/scripts.qrc6
14 files changed, 2589 insertions, 0 deletions
diff --git a/old/interpreter/DESCRIPTION b/old/interpreter/DESCRIPTION
new file mode 100644
index 0000000..560c597
--- /dev/null
+++ b/old/interpreter/DESCRIPTION
@@ -0,0 +1 @@
+Interpreter for QtUitest scripts.
diff --git a/old/interpreter/builtins.js b/old/interpreter/builtins.js
new file mode 100644
index 0000000..e8f6e10
--- /dev/null
+++ b/old/interpreter/builtins.js
@@ -0,0 +1,596 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ "Builtin" functions available to all tests.
+ This file gets evaluated once at the beginning of every test.
+
+ Documentation for these functions should be placed in qsystemtest.cpp.
+
+ Note, if a function exists with the same name in both here and QSystemTest,
+ the QtScript version takes precedence. To force a call to the QSystemTest
+ function, use ParentTestObject[signature], e.g. see expectMessageBox.
+
+ Note that the exported function needs to be a public slot, AND have at least one
+ parameter. See: runAsManualTest(void)
+*/
+
+/* called before every init() */
+function init_global()
+{
+}
+
+/* called after every cleanup() */
+function cleanup_global()
+{
+}
+
+/* called before every initTestCase() */
+function initTestCase_global()
+{
+}
+
+/* called after every cleanupTestCase() */
+function cleanupTestCase_global()
+{
+ killApplication();
+}
+
+function verify() {
+ if (arguments.length == 0) {
+ fail( "You need to specify at least a boolean expression" );
+ return false;
+ }
+ var msg = "";
+ if (arguments.length > 1) { msg = arguments[1] };
+
+ if (ParentTestObject['runAsManualTest(void)']()) {
+ var description = "verify that MAGIC_DATA";
+ if (msg.length > 0) description = "MAGIC_COMMAND:" + msg;
+ ParentTestObject['manualTest(QString)'](description);
+ return true;
+ }
+
+ return ParentTestObject['verify(bool,QString)'](arguments[0],msg);
+}
+
+function print() {
+ var str = "";
+ for (var i = 0; i < arguments.length; ++i) {
+ if (arguments[i] != undefined) str = str + arguments[i];
+ }
+ ParentTestObject['print(QVariant)'](str);
+}
+
+/* Expect conditionFunction to return true after executing code, or fail with message */
+function _expect(conditionFunction, message) {
+ if (message == undefined) {
+ message = "Expected condition did not become true";
+ }
+ this.__defineSetter__("code", function(code){
+ try {
+ code.apply(this);
+ } catch (e) {
+ if (this.onFail != undefined) {
+ this.onFail.apply(this);
+ }
+ throw e;
+ }
+ if (!conditionFunction.call()) {
+ fail(message);
+ }
+ });
+}
+
+function expect(a,b) {
+ return new _expect(a,b);
+}
+
+function select( item, queryPath ) {
+ if (item != undefined) {
+ if (queryPath == undefined) queryPath = "";
+ ParentTestObject['select(QString,QString)'](item, queryPath);
+ }
+ return true;
+}
+
+function selectIndex( idx, queryPath ) {
+ if (idx instanceof Array) {
+ ParentTestObject['selectIndex(QVariantList,QString)'](idx, queryPath);
+ } else {
+ ParentTestObject['selectIndex(QVariantList,QString)']([idx, 0], queryPath);
+ }
+}
+
+function skip(text, mode) {
+ ParentTestObject['skip(QString,QSystemTest::SkipMode)'](text, mode);
+}
+
+/*
+ Wait for code to return true for up to timeout ms, with given number of intervals,
+ and message on failure
+*/
+function _waitFor(timeout, intervals, message) {
+ if (timeout == undefined) {
+ timeout = 10000;
+ }
+ if (intervals == undefined) {
+ intervals = 20;
+ }
+ if (message == undefined) {
+ message = "Waited-for condition did not become true after " + timeout + " milliseconds";
+ }
+ this.__defineSetter__("code", function(code){
+ ok = code.apply(this);
+ i = 0;
+ while (!ok && i < intervals) {
+ wait(timeout/intervals);
+ ok = code.apply(this);
+ i = i + 1;
+ }
+ if (!ok) {
+ fail(message);
+ }
+ });
+}
+function waitFor(a,b,c) {
+ return new _waitFor(a,b,c);
+}
+
+Array.prototype.isEmpty = function()
+{
+ return (this.length <= 0);
+}
+
+Array.prototype.contains = function()
+{
+ obj = arguments[0];
+
+ if (ParentTestObject['runAsManualTest(void)']()) {
+ var description = " contains " + obj;
+ ParentTestObject['manualTestData(QString)'](description);
+ return true;
+ }
+
+ for (var i=0; i<this.length; i++) {
+ if (this[i] == obj) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Ensure we don't get the 'contains' function when using for-in on arrays
+setFlags(Array.prototype, "contains", QScriptValue.SkipInEnumeration);
+
+Array.prototype.containsOne = function()
+{
+ obj = arguments[0];
+ var count = 0;
+ for (var i=0; i<this.length; i++) {
+ if (this[i] == obj) {
+ count++;
+ }
+ }
+ return count == 1;
+}
+// Ensure we don't get the 'containsOne' function when using for-in on arrays
+setFlags(Array.prototype, "containsOne", QScriptValue.SkipInEnumeration);
+
+String.prototype.contains = function()
+{
+ var obj = arguments[0];
+ if (arguments[1] != undefined) {
+ obj = arguments[1];
+ }
+
+ if (obj instanceof Date) {
+ var strs = [];
+ strs.push(obj.toString("ddd, M/d/yy"));
+ strs.push(obj.toString("dddd, MMMM d, yyyy"));
+ strs.push(obj.toString("ddd, d MMM"));
+ strs.push(obj.toString("dd/MM/yyyy"));
+
+ if (ParentTestObject['runAsManualTest(void)']()) {
+ var description = " contains date " + strs[i];
+ ParentTestObject['manualTestData(QString)'](description);
+ return true;
+ }
+
+ for (var i = 0; i < strs.length; ++i) {
+ if (this.toString().contains(strs[i])) return true;
+ }
+ return false;
+ } else if (obj instanceof RegExp) {
+ if (ParentTestObject['runAsManualTest(void)']()) {
+ var description = " contains " + obj;
+ ParentTestObject['manualTestData(QString)'](description);
+ return true;
+ }
+
+ return obj.test(this.toString());
+ } else {
+ if (ParentTestObject['runAsManualTest(void)']()) {
+ var description = " contains " + obj;
+ ParentTestObject['manualTestData(QString)'](description);
+ return true;
+ }
+
+ var ref = this.toString();
+ return (-1 != ref.indexOf(obj));
+ }
+}
+
+String.prototype.toDate = function()
+{
+ var obj = this.toString();
+ return toDate(obj);
+}
+
+String.prototype.startsWith = function()
+{
+ var obj = arguments[0];
+ var ref = this.toString();
+ return ref.indexOf( obj ) == 0;
+}
+
+String.prototype.left = function()
+{
+ var start = 0;
+ var end = arguments[0];
+ var ref = this.toString();
+ return ref.slice( start, end );
+}
+
+String.prototype.right = function()
+{
+ var ref = this.toString();
+ var start = ref.length - arguments[0];
+ return ref.slice( start );
+}
+
+String.prototype.mid = function()
+{
+ var start = arguments[0];
+ var end = arguments[1]+1;
+ var ref = this.toString();
+ return ref.slice( start, end );
+}
+
+String.prototype.toValue = function()
+{
+ var ret = 0;
+ var ref = this.toString();
+ for (var i=0; i<ref.length; i++) {
+ var ch = ref.charAt(i);
+ if (ch == '-') {
+ ret = ret * -1;
+ } else {
+ ret = ret * 10;
+ if (ch == '0') {
+ } else if (ch == '1') {
+ ret = ret + 1;
+ } else if (ch == '2') {
+ ret = ret + 2;
+ } else if (ch == '3') {
+ ret = ret + 3;
+ } else if (ch == '4') {
+ ret = ret + 4;
+ } else if (ch == '5') {
+ ret = ret + 5;
+ } else if (ch == '6') {
+ ret = ret + 6;
+ } else if (ch == '7') {
+ ret = ret + 7;
+ } else if (ch == '8') {
+ ret = ret + 8;
+ } else if (ch == '9') {
+ ret = ret + 9;
+ } else {
+ fail( "ERROR: Couldn't convert '" + ref + "' into a value." );
+ return undefined;
+ }
+ }
+ }
+ return ret;
+}
+
+function anyDefined()
+{
+ for (var i = 0; i < arguments.length; ++i) {
+ if (arguments[i] != undefined) return true;
+ }
+ return false;
+}
+
+function tabBar(index)
+{
+ if (index == undefined) {
+ index = 0;
+ }
+
+ if (ParentTestObject['runAsManualTest(void)']()) {
+ if (index == 0) {
+ // In 99% of the cases there will be only one tabbar in an app
+ // so we can get something like:
+ // select 'foobar' from 'tabBar'
+ return "tabBar";
+ } else {
+ // In the remaining 1% we get something like:
+ // select 'foobar' from '2nd tabBar'
+ return (index+1) + "nd tabBar";
+ }
+ }
+
+ var tabBars = findByProperty( { inherits: "QTabBar" } );
+ if (tabBars[index] == undefined) {
+ fail( "ERROR: Tab widget not found." );
+ return undefined;
+ }
+ return tabBars[index];
+}
+
+function menuBar(index)
+{
+ if (index == undefined) {
+ index = 0;
+ }
+
+ if (ParentTestObject['runAsManualTest(void)']()) {
+ if (index == 0) {
+ // In 99% of the cases there will be only one menubar in an app
+ // so we can get something like:
+ // select 'foobar' from 'menuBar'
+ return "menuBar";
+ } else {
+ // In the remaining 1% we get something like:
+ // select 'foobar' from '2nd menuBar'
+ return (index+1) + "nd menuBar";
+ }
+ }
+
+
+ var menuBars = findByProperty( { inherits: "QMenuBar" } );
+ if (menuBars[index] == undefined) {
+ fail( "ERROR: MenuBar widget not found." );
+ return undefined;
+ }
+ return menuBars[index];
+}
+
+// Convert twiki markup to HTML for display in prompts
+function twiki(text) {
+ var lines = text.split("\n");
+ var result = [];
+ var listType = [];
+ var currLevel = 0;
+ var rowNumber = 0;
+ var inListItem = false;
+ var inTable = false;
+ var inVerbatim = false;
+ var liRegExp = /((?: )+)(\*|(?:[1AaIi]).)\s*(.*)/;
+ var liContRegExp = /(?: )\s*(.*)/;
+ var tableRegExp = /\s*\|(\s*)(.*)(\s*)\|\s*$/;
+
+ for (var i=0; i < lines.length; i++) {
+ var line = lines[i];
+
+ // Verbatim
+ if (inVerbatim) {
+ if (line.match(/\<\s*\/\s*verbatim\s*\>/)) {
+ inVerbatim = false;
+ result.push("</pre>");
+ } else {
+ result.push(line);
+ }
+ continue;
+ } else if (line.match(/\<\s*verbatim\s*\>/)) {
+ inVerbatim = true;
+ result.push("<pre>");
+ continue;
+ }
+
+ // Simple replacements
+ // Headings
+ line = line.replace(/---\+(?:!!)? +(.*)/, "<h1>$1</h1>");
+ line = line.replace(/---\+\+(?:!!)? +(.*)/, "<h2>$1</h2>");
+ line = line.replace(/---\+\+\+(?:!!)? +(.*)/, "<h3>$1</h3>");
+ line = line.replace(/---\+\+\+\+(?:!!)? +(.*)/, "<h4>$1</h4>");
+ line = line.replace(/---\+\+\+\+\+(?:!!)? +(.*)/, "<h5>$1</h5>");
+ line = line.replace(/---\+\+\+\+\+\+(?:!!)? +(.*)/, "<h6>$1</h6>");
+
+ // Misc
+ line = line.replace(/---[-]*/g, "<hr />");
+ line = line.replace(/^$/, "<p />");
+ line = line.replace(/!([A-Z]\w*)/g, "$1");
+ line = line.replace(/%TOC%/g, "");
+ line = line.replace(/%BB%/g, "<br />&#8226;");
+
+ // Links and anchors
+ line = line.replace(/^\#([A-Z]\w*)/, "<a name=\"$1\"></a><p />");
+ line = line.replace(/\[\[\#([A-Z]\w*)\]\[(.*)\]\]/g, "<a href=\"#$1\">$2</a>");
+ line = line.replace(/\[\[\#([A-Z]\w*)\]\]/g, "<a href=\"#$1\">#$1</a>");
+
+// line = line.replace(/\[\[(.*?)\]\[(.*?)\]\]/g, "<a href=\"$1\">$2</a>");
+// line = line.replace(/\[\[(.*?)\]\]/g, "<a href=\"$1\">$1</a>");
+ line = line.replace(/\[\[(.*?)\]\[(.*?)\]\]/g, "$2");
+ line = line.replace(/\[\[(.*?)\]\]/g, "$1");
+
+ // Text style
+ line = line.replace(/^\*(\S.*?\S)\*(?!\w)/, "<b>$1</b>");
+ line = line.replace(/([^\w])\*(\S.*?\S)\*(?!\w)/g, "$1<b>$2</b>");
+ line = line.replace(/^__(.*?\S)__(?!\w)/g, "<b><i>$2</i></b>");
+ line = line.replace(/([^\w])__(.*?\S)__(?!\w)/g, "$1<b><i>$2</i></b>");
+ line = line.replace(/^_([^_]*?\S)_(?!\w)/, "<i>$1</i>");
+ line = line.replace(/([^\w])_([^_]*?\S)_(?!\w)/g, "$1<i>$2</i>");
+ line = line.replace(/^==(.*?\S)==(?!\w)/g, "<b><code>$1</code></b>");
+ line = line.replace(/([^\w])==(.*?\S)==(?!\w)/g, "$1<b><code>$2</code></b>");
+ line = line.replace(/^=(.*?\S)=(?!\w)/, "<code>$1</code>");
+ line = line.replace(/([^\w])=(.*?\S)=(?!\w)/g, "$1<code>$2</code>");
+ line = line.replace(/%(.*)%(.*)%ENDCOLOR%/g, "<font color=\"$1\">$2<\/font>");
+
+ // Tables
+ tableMatch = tableRegExp.exec(line);
+ if (tableMatch) {
+ if (inTable) {
+ rowNumber++;
+ if (rowNumber%2) {
+ result.push("</tr>\n<tr bgcolor=\"#f2f2f2\">");
+ } else {
+ result.push("</tr>\n<tr bgcolor=\"#e0e0e0\">");
+ }
+ } else {
+ inTable = true;
+ rowNumber = 0;
+ result.push("<table>\n<tr bgcolor=\"#e0e0e0\">");
+ }
+
+ var cellRegExp = /\|(\s*)(\<b\>)?(.*?)(\<\/b\>)?(\s*)(?=\|)/g;
+ var trLine = "";
+ while (cell = cellRegExp.exec(line)) {
+ var left = cell[1].length;
+ var right = cell[5].length;
+ var align = "left";
+ if (left > 1 && left == right) {
+ align = "center";
+ } else if (left > right) {
+ align = "right";
+ }
+ if (cell[2] && cell[4]) {
+ trLine += "<th bgcolor=\"#404040\"><font color=\"white\">" + cell[3] + "</font></th>";
+ } else {
+ trLine += "<td align=\"" + align + "\">" + cell[3] + "</td>";
+ }
+ }
+ line = trLine;
+ result.push(line);
+ continue;
+ } else {
+ if (inTable) {
+ result.push("</tr></table>");
+ inTable = false;
+ }
+ }
+
+ // List Items
+ liMatch = liRegExp.exec(line);
+ level = (liMatch ? liMatch[1].length/3 : 0);
+ liType = (level ? (liMatch[2] == "*" ? "ul" : "ol") : null);
+
+ // List item continuation
+ if (inListItem) {
+ if (!liMatch) {
+ liContMatch = liContRegExp.exec(line);
+ if (!liContMatch) {
+ inListItem = false;
+ result.push("</li>");
+ } else {
+ line = liContMatch[1];
+ level = currLevel;
+ }
+ } else {
+ inListItem = false;
+ result.push("</li>");
+ }
+ }
+
+ // Change of list indentation level
+ if (level > currLevel) {
+ for (var j = currLevel; j < level; j++) {
+ result.push("<" + liType + (liType == "ol" ? " type=\"" + liMatch[2][0] + "\"" : "") + ">");
+ listType.push(liType);
+ }
+ } else {
+ for (var j = level; j < currLevel; j++) {
+ prevLiType = listType.pop();
+ result.push("</" + prevLiType + ">");
+ }
+ if (liMatch && listType.length && listType[listType.length - 1] != liType) {
+ // Change of list item type (from unordered to ordered, or vice-versa)
+ result.push("</" + listType.pop() + ">");
+ result.push("<" + liType + (liType == "ol" ? " type=\"" + liMatch[2][0] + "\"" : "") + ">");
+ listType.push(liType);
+ }
+ }
+ currLevel = level;
+
+ if (liMatch) {
+ line = line.replace(liRegExp, "<li" + (liType == "ol" ? " type=\"" + liMatch[2][0] + "\"" : "") + ">" + liMatch[3]);
+ inListItem = true;
+ }
+
+ result.push(line);
+ }
+
+ return(result.join("\n"));
+}
+
+// Support object-oriented syntax for widget interaction
+String.prototype.focusWidget = function() { return focusWidget(this); }
+String.prototype.getSelectedText = function() { return getSelectedText(this); }
+String.prototype.getText = function() { return getText(this); }
+String.prototype.getSelectedValue = function() { return getSelectedValue(this); }
+String.prototype.getValue = function() { return getValue(this); }
+String.prototype.getList = function() { return getList(this); }
+String.prototype.getLabels = function() { return getLabels(this); }
+String.prototype.currentTitle = function() { return currentTitle(this); }
+String.prototype.getGeometry = function() { return getGeometry(this); }
+String.prototype.setProperty = function(name, value) { setProperty(this, name, value); }
+String.prototype.getProperty = function(name) { return getProperty(this, name); }
+String.prototype.keyPress = function(key) { keyPress(key, this); }
+String.prototype.keyRelease = function(key) { keyRelease(key, this); }
+String.prototype.keyClick = function(key) { keyClick(key, this); }
+String.prototype.keyClickHold = function(key, duration) { keyClickHold(key, duration, this); }
+String.prototype.mouseClick = function() { mouseClick(this); }
+String.prototype.mouseClickHold = function(duration) { mouseClickHold(this, duration); }
+String.prototype.mousePress = function() { mousePress(this); }
+String.prototype.mouseRelease = function() { mouseRelease(this); }
+String.prototype.enter = function(value, mode) { enter(value, this, mode) }
+String.prototype.select = function(item) { select(item, this); }
+String.prototype.selectIndex = function(idx) { selectIndex(idx, this); }
+String.prototype.activate = function() { activate(this); }
+String.prototype.isVisible = function() { return isVisible(this); }
+String.prototype.isEnabled = function() { return isEnabled(this); }
+String.prototype.isChecked = function() { return isChecked(this); }
+String.prototype.setChecked = function(doCheck) { setChecked(doCheck, this); }
+String.prototype.checkState = function() { return checkState(this); }
+String.prototype.setCheckState = function(state) { setCheckState(state, this); }
+String.prototype.saveScreen = function(name) { saveScreen(name, this); }
diff --git a/old/interpreter/config.js b/old/interpreter/config.js
new file mode 100644
index 0000000..8679467
--- /dev/null
+++ b/old/interpreter/config.js
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* Internal configuration for QtUiTest. */
+
+/* Preprocessor configuration. */
+preprocess = {
+ /* A list of mappings from function names, to strings which should
+ * be appended after the function. */
+ functionAppends: {}
+}
+
+/* A list of files containing "builtin" functions to be made accessible
+ * to all tests. */
+builtin_files = [ "builtins.js" ];
+
+/* code_setters: a list of special functions which have syntax like:
+ * myFunction(a,b,c) {
+ * some code;
+ * }
+ * This is not valid ecmascript. In reality, the code expands to:
+ * myFunction,a,b,c).code = function() {
+ * some code;
+ * }
+ * Where a setter is defined for property "code" which makes the magic
+ * happen. The functions are implemented in builtins.js.
+ */
+code_setters = [
+ "waitFor",
+ "expect"
+]
+for (var i = 0; i < code_setters.length; ++i)
+ preprocess.functionAppends[code_setters[i]] = ".code = function() ";
+
diff --git a/old/interpreter/interpreter.pro b/old/interpreter/interpreter.pro
new file mode 100644
index 0000000..0c9705f
--- /dev/null
+++ b/old/interpreter/interpreter.pro
@@ -0,0 +1,60 @@
+SOURCES +=\
+ main.cpp \
+ qscriptsystemtest.cpp \
+ qtscript_bindings.cpp \
+ qtuitestengineagent.cpp \
+ scriptpreprocessor.cpp
+
+HEADERS +=\
+ qscriptsystemtest.h \
+ scriptpreprocessor.h \
+ qtuitestengineagent.h \
+ qtscript_bindings.h
+
+RESOURCES += scripts.qrc
+DEFINES += QTUITESTRUNNER_TARGET
+TEMPLATE=app
+VPATH+=$$PWD
+INCLUDEPATH+=$$PWD
+INCLUDEPATH+=$$SRCROOT
+INCLUDEPATH+=$$SRCROOT/libqsystemtest
+QT+=script network
+CONFIG+=qtestlib
+TARGET=qtuitestrunner
+
+!symbian {
+ MOC_DIR=$$OUT_PWD/.moc
+ OBJECTS_DIR=$$OUT_PWD/.obj
+ DESTDIR=$$BUILDROOT/bin
+ target.path=$$[QT_INSTALL_BINS]
+ INSTALLS+=target
+}
+
+#symbian {
+# TARGET.EPOCALLOWDLLDATA=1
+# TARGET.CAPABILITY += AllFiles ReadDeviceData ReadUserData SwEvent WriteUserData
+# MOC_DIR=$$OUT_PWD/moc
+# OBJECTS_DIR=$$OUT_PWD/obj
+# LIBS += -L$$OUT_PWD -lqsystemtest
+#}
+
+win32 {
+ CONFIG(debug,debug|release): LIBS+=-L$$BUILDROOT/libqsystemtest/debug -lqsystemtestd
+ CONFIG(release,debug|release):LIBS+=-L$$BUILDROOT/libqsystemtest/release -lqsystemtest
+ target.path=$$[QT_INSTALL_BINS]
+ INSTALLS+=target
+ !equals(QMAKE_CXX, "g++") {
+ DEFINES+=strcasecmp=_stricmp
+ }
+}
+
+!win32:!symbian:!mac {
+ LIBS += -L$$BUILDROOT/lib -lqsystemtest -lBotan -lCore
+}
+
+mac {
+ CONFIG-=app_bundle
+ CONFIG(debug,debug|release): LIBS += -L$$BUILDROOT/lib -lqsystemtest_debug
+ CONFIG(release,debug|release): LIBS += -L$$BUILDROOT/lib -lqsystemtest
+}
+
diff --git a/old/interpreter/main.cpp b/old/interpreter/main.cpp
new file mode 100644
index 0000000..3867727
--- /dev/null
+++ b/old/interpreter/main.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qscriptsystemtest.h"
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ bool guiEnabled = true;
+
+ // If in auto mode, don't need a GUI connection.
+ for (int i = 1; i < argc; ++i) {
+ if (!strcasecmp(argv[i], "-auto")) {
+ guiEnabled = false;
+ }
+ }
+
+ QApplication app(argc, argv, guiEnabled);
+ QScriptSystemTest tc;
+ return tc.exec(argc, argv);
+}
diff --git a/old/interpreter/qscriptsystemtest.cpp b/old/interpreter/qscriptsystemtest.cpp
new file mode 100644
index 0000000..641bfb4
--- /dev/null
+++ b/old/interpreter/qscriptsystemtest.cpp
@@ -0,0 +1,838 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qscriptsystemtest.h"
+#include "scriptpreprocessor.h"
+
+#include <QScriptEngine>
+#include <QScriptValue>
+#include <QScriptValueIterator>
+#include <QScriptContextInfo>
+
+//#include <qtestprotocol_p.h>
+#include <qtestide.h>
+#include <QtTest/QtTest>
+
+#include "qtscript_bindings.h"
+#include "qtuitestengineagent.h"
+
+#include <QDebug>
+
+QStringList builtins;
+
+Q_DECLARE_METATYPE(QVariant)
+Q_DECLARE_METATYPE(QList<qint64>)
+
+template <typename Tp>
+QScriptValue qScriptValueFromQObject(QScriptEngine *engine, Tp const &qobject)
+{
+ return engine->newQObject(qobject, QScriptEngine::AutoOwnership);
+}
+
+template <typename Tp>
+void qScriptValueToQObject(const QScriptValue &value, Tp &qobject)
+{ qobject = qobject_cast<Tp>(value.toQObject());
+}
+
+template <typename Tp>
+int qScriptRegisterQObjectMetaType(
+ QScriptEngine *engine,
+ const QScriptValue &prototype = QScriptValue(),
+ Tp * /* dummy */ = 0
+ )
+{
+ return qScriptRegisterMetaType<Tp>(engine, qScriptValueFromQObject,
+ qScriptValueToQObject, prototype);
+}
+
+void setupEnums(QScriptEngine *engine) {
+ QScriptValue qsvObject = engine->newObject();
+#define S(val) qsvObject.setProperty(#val, engine->toScriptValue((int)QScriptValue::val));
+ S(PropertySetter);S(ReadOnly);S(Undeletable);S(SkipInEnumeration);
+ S(PropertyGetter);S(QObjectMember);S(KeepExistingFlags);S(UserRange);
+#undef S
+ engine->globalObject().setProperty("QScriptValue", qsvObject );
+}
+
+static QScriptValue dateToString(QScriptContext *ctx, QScriptEngine *eng)
+{
+ QDateTime dt = ctx->thisObject().toDateTime();
+ QString fmt = ctx->argument(0).toString();
+
+ return eng->toScriptValue(dt.toString(fmt));
+}
+
+static QString findIncludeScript(const QString& name)
+{
+ QList<QDir> includeDirs;
+ foreach (QByteArray const& split, qgetenv("QTUITEST_INCLUDE_PATH").split(':')) {
+ if (split.isEmpty()) continue;
+ QDir dir(split);
+ if (dir.exists()) includeDirs << dir;
+ }
+
+ foreach (QDir const& dir, includeDirs) {
+ QString file = dir.canonicalPath() + "/" + name;
+ if (QFile::exists(file)) {
+ return file;
+ }
+ }
+
+ return QString();
+}
+
+// Include a single script into an engine.
+static QScriptValue includeScriptFunction
+ (QScriptEngine *engine, const QString& name)
+{
+ // Find the script, relative to the entry script.
+ QString script;
+ QtScript::getLocation(engine->currentContext(), &script, 0);
+ QString directory = QFileInfo(QFileInfo(script).canonicalFilePath()).dir().canonicalPath();
+ QDir dir(directory);
+ QFileInfo file(dir, name);
+ QString filename = name;
+ if (file.exists()) filename = file.canonicalFilePath();
+
+ // Check if the script has already been loaded.
+ static const char includesProperty[] = "_qtuitest_includes";
+ QStringList included = qscriptvalue_cast<QStringList>(engine->globalObject().property(includesProperty));
+ if (included.contains(filename)) {
+ return QScriptValue();
+ }
+
+ // Try to load the script into memory.
+ QFile scriptFile(filename);
+ if (!scriptFile.exists() || !scriptFile.open(QIODevice::ReadOnly)) {
+ int pos = directory.indexOf("/interpreter");
+ if (pos > 0) {
+ directory = directory.left(pos) + "/tests/shared";
+ QDir dir(directory);
+ QFileInfo file(dir, name);
+ filename = file.filePath();
+ scriptFile.setFileName(filename);
+ } else {
+ scriptFile.setFileName(findIncludeScript(filename));
+ }
+ }
+
+ if (!scriptFile.exists() || (!scriptFile.isOpen() && !scriptFile.open(QIODevice::ReadOnly))) {
+ return engine->currentContext()->throwError("Could not find " + name + " in either the shared or testcase directory");
+ }
+
+ QString contents = QTextStream(&scriptFile).readAll();
+ scriptFile.close();
+
+ contents.prepend("with(ParentTestMetaObject) {");
+ contents.append("\n}");
+
+ ScriptPreprocessor().preprocess(contents);
+
+ // Evaluate the contents of the script.
+ engine->pushContext()->setActivationObject(engine->globalObject());
+ // Note that we have included this script.
+ if (!engine->globalObject().property(includesProperty).isValid()) {
+ engine->globalObject().setProperty(includesProperty, engine->newArray());
+ }
+ engine->globalObject().property(includesProperty).setProperty(
+ engine->globalObject().property(includesProperty).property("length").toUInt32(),
+ qScriptValueFromValue(engine, filename));
+ QScriptValue ret = engine->evaluate(contents, filename);
+ engine->popContext();
+
+ return ret;
+}
+
+// Implementation of the "include()" function in scripts, which imports scripts.
+static QScriptValue includeFunction
+ (QScriptContext *context, QScriptEngine *engine)
+{
+ QScriptValue value;
+ if (context->argumentCount() == 0) {
+ return context->throwError
+ ("script name must be supplied to include()");
+ }
+ value = context->argument(0);
+ if (!value.isString()) {
+ return context->throwError
+ ("invalid script name supplied to include()");
+ }
+
+ QString name = value.toString();
+ if (name.contains(QChar('*'))) {
+ //FIXME: This path doesn't look in the tests/shared/ directory.
+ // Expand the wildcard and include all matching scripts.
+ QString script;
+ QtScript::getLocation(context, &script, 0);
+ QDir dir(QFileInfo(script).dir());
+ QStringList files = dir.entryList(QStringList(name));
+ foreach (QString filename, files) {
+ value = includeScriptFunction(engine, dir.filePath(filename));
+ if (engine->hasUncaughtException())
+ return value;
+ }
+ return engine->undefinedValue();
+ } else {
+ // Include a single script file.
+ return includeScriptFunction(engine, name);
+ }
+}
+
+static QScriptValue setFlags
+ (QScriptContext *context, QScriptEngine* /*engine*/)
+{
+ Q_ASSERT(context);
+ if (context->argumentCount() != 3) {
+ return context->throwError
+ ("setFlags() needs three arguments");
+ }
+ QScriptValue o = context->argument(0);
+ if (!o.isObject()) return QScriptValue();
+ QString name = context->argument(1).toString();
+ int flags = context->argument(2).toInt32();
+
+ o.setProperty(name, o.property(name), QFlag(flags));
+ return QScriptValue();
+}
+
+
+QScriptSystemTest::QScriptSystemTest()
+ : m_engine(0),
+ m_agent(0),
+ m_contextDepth(0),
+ testObject(0),
+ m_checkOnly(false)
+{
+}
+
+QScriptSystemTest::~QScriptSystemTest()
+{
+}
+
+void QScriptSystemTest::initEngine(bool createNewEngine)
+{
+ if (m_engine) {
+ if (createNewEngine) {
+ delete m_engine;
+ } else {
+ return;
+ }
+ }
+
+ m_engine = new QScriptEngine();
+ m_agent = new QtUiTestEngineAgent(m_engine, this);
+
+ // Ensure we process events periodically.
+ m_engine->setProcessEventsInterval(100);
+
+ m_engine->importExtension("qt.core");
+ setupEnums(m_engine);
+
+ // include() imports scripts directly into the parent script.
+ m_engine->globalObject().setProperty
+ ("include", m_engine->newFunction(includeFunction, 1));
+ m_engine->globalObject().setProperty
+ ("setFlags", m_engine->newFunction(setFlags, 3));
+
+
+ m_engine->globalObject().setProperty("_dateToString", m_engine->newFunction(dateToString));
+ m_engine->evaluate("_old_date_toString = Date.prototype.toString;"
+ "Date.prototype.toString = function() {"
+ " if (arguments[0] == undefined)"
+ " return _old_date_toString.apply(this, arguments);"
+ " return _dateToString.apply(this, arguments);"
+ "}");
+
+ m_engine->globalObject().setProperty("ParentTestObject", m_engine->newQObject(this));
+ m_engine->globalObject().setProperty("ParentTestMetaObject", m_engine->newQMetaObject(metaObject()));
+
+ loadBuiltins(m_engine);
+ importIntoGlobalNamespace(m_engine, "ParentTestObject");
+}
+
+QString QScriptSystemTest::testCaseName() const
+{
+ if (testObject)
+ return testObject->metaObject()->className();
+ return QAbstractTest::testCaseName();
+}
+
+void QScriptSystemTest::loadBuiltins(QScriptEngine *engine)
+{
+ QScriptEngine configEngine;
+ QScriptSystemTest::loadInternalScript("config.js", &configEngine);
+ for (int i = 0; i < configEngine.globalObject().property("builtin_files").property("length").toInt32(); ++i) {
+ QString file = configEngine.globalObject().property("builtin_files").property(i).toString();
+ QtScript::addInternalFile( QScriptSystemTest::loadInternalScript(file, engine, true) );
+ }
+}
+
+void QScriptSystemTest::importIntoGlobalNamespace(QScriptEngine *engine, QString const& object)
+{
+ QScriptValue obj = engine->globalObject().property(object);
+
+ QScriptValueIterator it(obj);
+ while (it.hasNext()) {
+ it.next();
+ QString name = it.name();
+
+ // Transform name of enter(QString,QString) to enter
+ if (it.value().isFunction() && name.contains('(')) {
+ name = name.left(name.indexOf('('));
+ }
+
+ // Import this property into the global object iff one doesn't already
+ // exist with this name
+ if (engine->globalObject().property(name).isValid()) continue;
+
+ // For functions, to keep the QObject slot resolution working right, we
+ // must wrap the property instead of simply copying it.
+ if (it.value().isFunction()) {
+ engine->evaluate(QString("%1 = function(){ return %2.%1.apply(this, arguments); };")
+ .arg(name)
+ .arg(object));
+ } else {
+ engine->globalObject().setProperty(name, it.value());
+ }
+ }
+}
+
+QString QScriptSystemTest::loadInternalScript(QString const &name, QScriptEngine *engine, bool withParentObject)
+{
+ QString filename = QFileInfo(QString::fromAscii(__FILE__)).absolutePath() + "/" + name;
+ if (!QFileInfo(filename).exists()) filename = ":/" + name;
+ QFile f(filename);
+ QString data;
+ if (!f.open(QIODevice::ReadOnly) || (data = QTextStream(&f).readAll()).isEmpty()) {
+ qWarning("QtUiTest: Couldn't load config file '%s' (using '%s')", qPrintable(name), qPrintable(filename));
+ return QString();
+ }
+
+ if (withParentObject) {
+ data.prepend("with(ParentTestMetaObject) {");
+ data.append("\n}");
+ }
+
+ QScriptValue e = engine->evaluate(data, filename);
+ if (e.isError()) {
+ QString backtrace = engine->uncaughtExceptionBacktrace().join("\n");
+ qWarning("In QtUiTest config file %s:\n%s\n%s", qPrintable(filename), qPrintable(e.toString()),
+ qPrintable(backtrace));
+ }
+ builtins << filename;
+ return filename;
+}
+
+QScriptValue variantToScriptValue(QScriptEngine *engine, const QVariant &v)
+{
+ QScriptValue ret;
+ if (v.isNull()) {
+ ret = QScriptValue( engine, QScriptValue::NullValue );
+ } else if (v.canConvert<QStringList>()) {
+ ret = engine->toScriptValue(v.value<QStringList>());
+ } else if (v.canConvert<qreal>()) {
+ ret = engine->toScriptValue(v.value<qreal>());
+ } else if (v.canConvert<int>()) {
+ ret = engine->toScriptValue(v.value<int>());
+ } else if (v.canConvert<QString>()) {
+ ret = engine->toScriptValue(v.value<QString>());
+ } else {
+ ret = engine->newVariant(v);
+ }
+ return ret;
+}
+
+void variantFromScriptValue(const QScriptValue &obj, QVariant &v)
+{
+ v = obj.toVariant();
+}
+
+QString QScriptSystemTest::currentFile()
+{
+ QString fileName = QString();
+ int lineNumber = 0;
+
+ QtScript::getLocation(m_engine->currentContext(), &fileName, &lineNumber);
+
+ return fileName;
+}
+
+int QScriptSystemTest::currentLine()
+{
+ QString fileName = QString();
+ int lineNumber = 0;
+
+ QtScript::getLocation(m_engine->currentContext(), &fileName, &lineNumber);
+
+ return lineNumber;
+}
+
+void QScriptSystemTest::outputBacktrace()
+{
+ QScriptContext *ctx = m_engine->currentContext();
+ QString bt("Backtrace:");
+ while (ctx) {
+ QScriptContextInfo ctxInfo(ctx);
+ QString fn = ctxInfo.fileName();
+ int ln = ctxInfo.lineNumber();
+ if (!fn.isEmpty() && ln != -1)
+ bt += "\n " + fn + "(" + QString::number(ln) + ")";
+ ctx = ctx->parentContext();
+ }
+ QDebug(QtDebugMsg) << qPrintable(bt);
+}
+
+void QScriptSystemTest::skip(QString const &message, QSystemTest::SkipMode mode)
+{
+ QSystemTest::skip(message, mode);
+ m_engine->evaluate("throw new QTestFailure('QSKIP');");
+}
+
+bool QScriptSystemTest::fail(QString const &message)
+{
+ bool ret = QSystemTest::fail( message );
+ if (!ret) {
+ outputBacktrace();
+ m_engine->evaluate("throw new QTestFailure('QFAIL');");
+ }
+ return ret;
+}
+
+void QScriptSystemTest::verify(bool statement, QString const &message)
+{
+ if (!QTest::qVerify(statement, "<statement>", qPrintable(message), qPrintable(currentFile()), currentLine() )) {
+ outputBacktrace();
+ m_engine->evaluate("throw new QTestFailure('QFAIL');");
+ }
+}
+
+void QScriptSystemTest::compare(const QString &actual, const QString &expected)
+{
+ if (QSystemTest::runAsManualTest()) {
+ QString act;
+ if (actual == "MAGIC_DATA" || actual.contains("'")) act = actual;
+ else act = "'" + actual + "'";
+ QString exp;
+ if (expected == "MAGIC_DATA" || expected.contains("'")) exp = expected;
+ else exp = "'" + expected + "'";
+ manualTest( QString("verify that %1 is equal to %2").arg(act).arg(exp));
+ return;
+ }
+
+ if (!QTest::qCompare( actual, expected, qPrintable(actual), qPrintable(expected), qPrintable(currentFile()), currentLine() )) {
+ outputBacktrace();
+ m_engine->evaluate("throw new QTestFailure('QFAIL');");
+ }
+}
+
+void QScriptSystemTest::compare(const QStringList &actual, const QStringList &expected)
+{
+ if (QSystemTest::runAsManualTest()) {
+ QString act = actual.count() > 0 ? actual[0] : "";
+ QString exp = expected.count() > 0 ? expected[0] : "";
+ manualTest( QString("verify that %1 is equal to %2").arg(act).arg(exp));
+ return;
+ }
+
+ if (!QTest::qCompare( actual.count(), expected.count(), qPrintable(actual.join("\n")), qPrintable(expected.join("\n")), qPrintable(currentFile()), currentLine() )) {
+ outputBacktrace();
+ m_engine->evaluate("throw new QTestFailure('QFAIL');");
+ return;
+ }
+
+ for (int i=0; i<actual.count(); i++) {
+ if (!QTest::qCompare( actual[i], expected[i], qPrintable(actual[i]), qPrintable(expected[i]), qPrintable(currentFile()), currentLine() )) {
+ outputBacktrace();
+ m_engine->evaluate("throw new QTestFailure('QFAIL');");
+ }
+ }
+}
+
+bool QScriptSystemTest::isFailExpected()
+{
+ return (expect_fail_function == currentTestFunction() && expect_fail_datatag == currentDataTag());
+}
+
+void QScriptSystemTest::expectFail( const QString &reason )
+{
+ expect_fail_function = currentTestFunction();
+ expect_fail_datatag = currentDataTag();
+ expect_fail_reason = reason;
+ int line = currentLine();
+
+ if (testObject) {
+ testObject->setProperty("expectFailLineNumber", line);
+ }
+
+ bool ok = QTest::qExpectFail(currentDataTag().toLatin1(), reason.toLatin1(),
+ QTest::TestFailMode(1),//mode),
+ qPrintable(currentFile()), line);
+ if (!ok)
+ m_engine->evaluate("throw new QTestFailure('QFAIL');");
+}
+
+bool QScriptSystemTest::setQueryError( const QTestMessage &message )
+{
+ QString errorString = message["status"].toString();
+ QVariant response = message["_q_inResponseTo"];
+ if (response.isValid()) {
+ errorString += QString("\nIn response to message: %2").arg(response.toString());
+ }
+ return setQueryError( errorString );
+}
+
+bool QScriptSystemTest::setQueryError( const QString &errString )
+{
+ if (queryFailed()) return false;
+ QSystemTest::setQueryError(errString);
+ bool ret = fail(errString);
+ if (!ret) {
+ m_engine->evaluate("throw new QTestFailure('QFAIL');");
+ }
+ return ret;
+}
+
+int QScriptSystemTest::runTest(const QString &fname, const QStringList &parameters,
+ const QStringList &environment)
+{
+ m_env = environment;
+ bool createNewEngine = filename == fname;
+ filename = fname;
+
+ QFile file(filename);
+ if (!file.open(QFile::ReadOnly)) {
+ qDebug() << "Can't open " << filename;
+ return -1;
+ }
+
+ QTextStream stream(&file);
+ QString script = stream.readAll();
+
+ ScriptPreprocessor().preprocess(script);
+
+ initEngine(createNewEngine);
+
+ // Allow shebangs without giving syntax errors.
+ if (script.startsWith("#!")) script.prepend("//");
+ script.prepend("with(ParentTestMetaObject){");
+ script.append("\n}");
+
+ QtScriptTest tc(filename, script, m_engine);
+
+ if (tc.status() != QtScriptTest::StatusNormal) {
+ return -1;
+ }
+
+ testObject = &tc;
+
+ qScriptRegisterMetaType(m_engine, variantToScriptValue, variantFromScriptValue);
+ qScriptRegisterSequenceMetaType<QList<qint64> >(m_engine);
+
+ // Only set up the test data path if not explicitly set by user
+ if (!QCoreApplication::arguments().contains("-data")) {
+ setupTestDataPath(qPrintable(filename));
+ }
+
+ enableQueryWarnings(false);
+
+ // If we get here, the syntax of the script is definitely OK
+ // (a syntax error causes a qFatal in the QtScriptTest ctor).
+ if (m_checkOnly)
+ return 0;
+
+ // If an IDE is connected, set the agent to enable script debugging
+ if (QTestIDE::instance()->isConnected()) {
+ m_engine->setAgent(m_agent);
+ }
+
+ if (QTest::testObject()) {
+ qDebug() << "Test already in progress?";
+ return -1;
+ }
+ int retval = QTest::qExec(&tc, parameters);
+
+ testObject = 0;
+
+ // After a full test run, QTestLib sometimes returns 0 or sometimes returns
+ // the number of test failures, depending on how it was compiled. In both
+ // cases, a negative number denotes an error.
+ // We don't want test failures to affect the exit code.
+ return (retval < 0) ? retval : 0;
+}
+
+/*!
+ \internal
+ Send a raw message from within script to the connected system.
+
+ This can be used to extend the API for new messages on the target device
+ without modifying QSystemTest.
+
+ If the message doesn't elicit a response of "OK", the current test fails.
+*/
+QVariantMap QScriptSystemTest::sendRaw(const QString& event, const QScriptValue& object)
+{
+ QVariantMap ret;
+ if (object.isValid() && !object.isObject()) {
+ setQueryError("Second argument to sendRaw must be an object.");
+ return ret;
+ }
+ if (event.isEmpty()) {
+ setQueryError("First argument to sendRaw cannot be an empty string.");
+ return ret;
+ }
+
+ QTestMessage message(event);
+
+ // Treat object like a variant map and load it into message.
+ QScriptValueIterator it(object);
+ while (it.hasNext()) {
+ it.next();
+ QScriptValue v = it.value();
+ // Map must be flat; we don't handle objects within objects.
+ if (v.isObject() && !v.isArray()) {
+ setQueryError("Object passed to sendRaw must not have any child objects.");
+ return ret;
+ }
+ // toVariant appears to flatten stringlists into strings, which we don't want.
+ if (v.isArray()) {
+ QVariantList list;
+ for (int i = 0, max = qscriptvalue_cast<int>(v.property("length")); i < max; ++i)
+ list << v.property(i).toVariant();
+ message[it.name()] = list;
+ } else {
+ message[it.name()] = v.toVariant();
+ }
+ }
+
+ QTestMessage reply;
+ if (!doQuery(message, QString(), &reply)) {
+ setQueryError("Raw " + event + " message failed: " + reply["status"].toString());
+ return ret;
+ }
+
+ foreach (QString const& key, reply.keys())
+ ret[key] = reply[key];
+ return ret;
+}
+
+//#ifndef QTCREATOR_QTEST
+/*!
+ \internal
+ Print any special usage information which should be shown when test is launched
+ with -help.
+*/
+void QScriptSystemTest::printUsage() const
+{
+ QSystemTest::printUsage();
+ qWarning(
+ " Script options:\n"
+ " -c : Check the syntax of the test only. Returns a non-zero exit code if the test\n"
+ " contains any syntax errors.\n"
+ );
+}
+//#endif
+
+/*!
+ \internal
+ If \a func is a function, install it as a handler for all messages received from the test
+ system.
+
+ Whenever a new message is received, \a func will be called with two arguments.
+ The first is the message event as a string.
+ The second is an object containing one property for each parameter of the message.
+
+ If \a func returns true, processing of the message ends.
+*/
+void QScriptSystemTest::installMessageHandler(const QScriptValue& func)
+{
+ if (!func.isFunction()) {
+ setQueryError("Argument to installMessageHandler must be a function.");
+ return;
+ }
+ m_messageHandlers << func;
+}
+
+
+QString qDumpScriptValue(QString const& name, QScriptValue const& v, int indent = 0)
+{
+ const QString spc = QString().fill(' ', indent);
+
+ QString ret;
+
+ ret += spc + name + ": ";
+ if (name != "global" && v.engine()->globalObject().strictlyEquals(v))
+ ret += "global";
+ else if (v.isBoolean())
+ ret += "Boolean:" + v.toString();
+ else if (v.isDate())
+ ret += "Date:" + v.toString();
+ else if (v.isFunction())
+ ret += "Function";
+ else if (v.isNull())
+ ret += "null";
+ else if (v.isNumber())
+ ret += "Number:" + v.toString();
+ else if (v.isString())
+ ret += "String:" + v.toString();
+ else if (v.isUndefined())
+ ret += "undef";
+ else {
+ QString inner;
+ QScriptValueIterator it(v);
+ QString sep;
+ while (it.hasNext()) {
+ it.next();
+ inner += sep + qDumpScriptValue(it.name(), it.value(), indent+2);
+ sep = ",\n";
+ }
+ if (inner.isEmpty()) {
+ ret += "{}";
+ } else {
+ ret += "{\n" + inner + "\n" + spc + "} /* " + name + " */";
+ }
+ }
+
+ return ret;
+}
+
+/*!
+ \internal
+ Write out most of the state of the script engine to stderr.
+*/
+void QScriptSystemTest::dumpEngine()
+{
+ QString state;
+
+ {
+ QScriptContext* ctx = m_engine->currentContext();
+ state += "context: {";
+ int i = 0;
+ QString sep;
+ while (ctx) {
+ state += QString("%1\n %2: {\n").arg(sep).arg(i++);
+ state += " toString: " + ctx->toString() + "\n";
+ state += qDumpScriptValue("activationObject", ctx->activationObject(), 4) + ",\n";
+ state += qDumpScriptValue("thisObject", ctx->thisObject(), 4) + "\n";
+ state += " }";
+ sep = ",";
+ ctx = ctx->parentContext();
+ }
+ state += "\n};\n";
+ }
+
+ state += qDumpScriptValue("global", m_engine->globalObject());
+ state += ";";
+
+ fprintf(stderr, "%s\n", qPrintable(state));
+}
+
+/*!
+ \internal
+ Passes the test message through any installed QtScript message handlers.
+ If none of them handle the message, it will be passed to the superclass.
+*/
+void QScriptSystemTest::processMessage(const QTestMessage& message)
+{
+ if (m_messageHandlers.count()) {
+ QVariantMap map;
+ foreach (QString const& key, message.keys())
+ map[key] = message[key];
+
+ QScriptValueList args;
+ args << m_engine->toScriptValue(message.event());
+ args << m_engine->toScriptValue(map);
+
+ for (int i = 0; i < m_messageHandlers.count(); ++i) {
+ QScriptValue out = m_messageHandlers[i].call(QScriptValue(), args);
+ if (out.isBoolean() && out.toBoolean())
+ return;
+ }
+ }
+
+ QSystemTest::processMessage(message);
+}
+
+/*!
+ \internal
+ Processes the command line parameters.
+*/
+void QScriptSystemTest::processCommandLine( QStringList &args )
+{
+ QMutableStringListIterator it(args);
+
+ while (it.hasNext()) {
+ QString arg = it.next();
+ if (!arg.compare("-c", Qt::CaseInsensitive)) {
+ m_checkOnly = true;
+ it.remove();
+ }
+ }
+
+ QSystemTest::processCommandLine(args);
+}
+
+void QScriptSystemTest::scriptPositionChange(qint64 scriptId, int line, int column)
+{
+ Q_UNUSED(scriptId);
+ Q_UNUSED(line);
+ Q_UNUSED(column);
+
+ QScriptContextInfo ctxInfo(m_engine->currentContext());
+ if (!ctxInfo.fileName().isEmpty() && !builtins.contains(ctxInfo.fileName())) {
+ QString functionName;
+ if (ctxInfo.functionName().isEmpty()) {
+ functionName = currentTestFunction();
+ } else {
+ functionName = ctxInfo.functionName();
+ }
+ if (QTestIDE::instance()->queryBreakpoint(ctxInfo.fileName(), ctxInfo.lineNumber(), functionName, m_contextDepth)) {
+ QTestIDE::instance()->breakpointContext(m_engine->currentContext());
+ }
+ }
+}
+
+void QScriptSystemTest::scriptContextChange(bool isNew)
+{
+ if (isNew)
+ ++m_contextDepth;
+ else
+ --m_contextDepth;
+} \ No newline at end of file
diff --git a/old/interpreter/qscriptsystemtest.h b/old/interpreter/qscriptsystemtest.h
new file mode 100644
index 0000000..bc270af
--- /dev/null
+++ b/old/interpreter/qscriptsystemtest.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSCRIPTSYSTEMTEST_H
+#define QSCRIPTSYSTEMTEST_H
+
+#include <qsystemtest.h>
+#include <QScriptEngine>
+#include <QScriptEngineAgent>
+#include <QVariantMap>
+
+class QTestMessage;
+
+class QTUITESTRUNNER_EXPORT QScriptSystemTest
+ : public QSystemTest
+{
+Q_OBJECT
+public:
+ QScriptSystemTest();
+ virtual ~QScriptSystemTest();
+
+ static QString loadInternalScript(QString const &name, QScriptEngine *engine, bool withParentObject = false);
+ static void loadBuiltins(QScriptEngine *engine);
+ static void importIntoGlobalNamespace(QScriptEngine*, QString const&);
+
+ virtual QString testCaseName() const;
+ void scriptPositionChange(qint64, int, int);
+ void scriptContextChange(bool);
+
+ virtual int runTest(const QString &fname, const QStringList &parameters,
+ const QStringList &environment);
+
+public slots:
+ virtual bool fail(QString const &message);
+ virtual void expectFail( const QString &reason );
+ virtual void skip(QString const &message, QSystemTest::SkipMode mode = QSystemTest::SkipSingle);
+ virtual void verify(bool statement, QString const &message = QString());
+ virtual void compare(const QString &actual, const QString &expected);
+ virtual void compare(const QStringList &actual, const QStringList &expected);
+
+ QVariantMap sendRaw(const QString&, const QScriptValue& = QScriptValue());
+ void installMessageHandler(const QScriptValue&);
+
+ void dumpEngine();
+
+protected:
+ virtual void initEngine(bool);
+ virtual QString currentFile();
+ virtual int currentLine();
+ virtual void outputBacktrace();
+
+ virtual bool setQueryError( const QTestMessage &message );
+ virtual bool setQueryError( const QString &errString );
+
+ virtual void printUsage() const;
+ virtual void processCommandLine(QStringList&);
+
+ virtual bool isFailExpected();
+
+ virtual void processMessage(const QTestMessage& message);
+
+private:
+ QString filename;
+ QScriptEngine *m_engine;
+ QScriptEngineAgent *m_agent;
+ int m_contextDepth;
+ QList<QScriptValue> m_messageHandlers;
+ QObject* testObject;
+ QString expect_fail_function;
+ QString expect_fail_datatag;
+ QString expect_fail_reason;
+ bool m_checkOnly;
+ QStringList m_builtins;
+};
+
+#endif
diff --git a/old/interpreter/qtscript_bindings.cpp b/old/interpreter/qtscript_bindings.cpp
new file mode 100644
index 0000000..dc66659
--- /dev/null
+++ b/old/interpreter/qtscript_bindings.cpp
@@ -0,0 +1,313 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include <qtestide.h>
+#include "qscriptengine.h"
+#include "qscriptvalue.h"
+#include "qscriptvalueiterator.h"
+#include "qscriptcontext.h"
+#include "qscriptcontextinfo.h"
+
+#include "qtscript_bindings.h"
+
+QStringList builtinFiles;
+
+void QtScript::addInternalFile(QString const &filename)
+{
+ builtinFiles << filename;
+}
+
+static QString readFile(const QString &filename)
+{
+ QFile file(filename);
+ if (!file.open(QFile::ReadOnly))
+ return QString();
+ QTextStream stream(&file);
+ return stream.readAll();
+}
+
+static void appendCString(QVector<char> *v, const char *s)
+{
+ char c;
+ do {
+ c = *(s++);
+ *v << c;
+ } while (c != '\0');
+}
+
+void QtScript::getLocation(QScriptContext *ctx, QString *fileName, int *lineNumber)
+{
+ Q_ASSERT(ctx);
+ if (fileName) *fileName = QString();
+ if (lineNumber) *lineNumber = 0;
+
+ while (ctx) {
+ QScriptContextInfo ctxInfo(ctx);
+ QString fn = ctxInfo.fileName();
+ if (!fn.isEmpty() && !builtinFiles.contains(fn)) {
+ if (fileName) *fileName = fn;
+ if (lineNumber) *lineNumber = ctxInfo.lineNumber();
+ return;
+ }
+ ctx = ctx->parentContext();
+ }
+}
+
+QMetaObject QtScriptTest::staticMetaObject;
+
+Q_GLOBAL_STATIC(QVector<uint>, qt_meta_data_QtScriptTest)
+Q_GLOBAL_STATIC(QVector<char>, qt_meta_stringdata_QtScriptTest)
+
+const QMetaObject *QtScriptTest::metaObject() const
+{
+ return &staticMetaObject;
+}
+
+void *QtScriptTest::qt_metacast(const char *_clname)
+{
+ if (!_clname) return 0;
+ if (!strcmp(_clname, qt_meta_stringdata_QtScriptTest()->constData()))
+ return static_cast<void*>(const_cast<QtScriptTest*>(this));
+ return QObject::qt_metacast(_clname);
+}
+
+int QtScriptTest::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+ _id = QObject::qt_metacall(_c, _id, _a);
+ if (_id < 0)
+ return _id;
+ if (_c == QMetaObject::InvokeMetaMethod) {
+ const QMetaObject *mo = metaObject();
+ QMetaMethod method = mo->method(mo->methodOffset() + _id);
+ QByteArray sig = method.signature();
+ QString name = sig.left(sig.lastIndexOf('('));
+ QScriptValue testcase = m_engine->globalObject().property("testcase");
+ QScriptValue val = testcase.property(name);
+ if (name.endsWith("_data")) {
+ QTest::addColumn<int>("dummy");
+ QScriptValueIterator it(val);
+ while (it.hasNext()) {
+ it.next();
+ QString tag = it.name();
+ QTest::newRow(tag.toLatin1());
+ }
+ } else {
+ QScriptValue args;
+ QScriptValue data = testcase.property(name + "_data");
+ if (data.isObject()) {
+ QString tag = QTest::currentDataTag();
+ QScriptValue v = data.property(tag);
+ if (v.isValid()) {
+ if (v.isArray()) {
+ args = v;
+ } else {
+ args = m_engine->newArray();
+ args.setProperty(0, v);
+ }
+ }
+ }
+ if (!args.isArray())
+ args = m_engine->newArray();
+ QScriptValue ret;
+ if (name == "init") {
+ ret = m_engine->evaluate("init_global();");
+ }
+ else if (name == "initTestCase") {
+ ret = m_engine->evaluate("initTestCase_global();");
+ }
+ else if (name != "cleanup" && name != "cleanupTestCase") {
+ m_engine->evaluate("qtuitest_pre_test_function();");
+ }
+ if (!ret.isError() || ret.property("name").toString() == "QTestFailure") {
+ ret = val.call(m_engine->globalObject(), args);
+ QTest::compare_helper( true, "expectFail() not followed by a test statement",
+ m_testFilePath.toAscii(), property("expectFailLineNumber").toInt() );
+ }
+ if (name != "init" && name != "initTestCase" && name != "cleanup" && name != "cleanupTestCase") {
+ m_engine->evaluate("qtuitest_post_test_function();");
+ }
+ if (name == "cleanup") {
+ m_engine->evaluate("cleanup_global();");
+ }
+ else if (name == "cleanupTestCase") {
+ m_engine->evaluate("cleanupTestCase_global();");
+ }
+ if (ret.isError() && (ret.property("name").toString() != "QTestFailure")) {
+ QString backtrace = m_engine->uncaughtExceptionBacktrace().join("\n");
+ QString message = ret.toString()
+ // xxx makes the failure message look cluttered; correct fix
+ // xxx is to implement proper generic saving of backtrace info
+ // xxx in test results
+ // + "\n" + backtrace
+ ;
+ QString fileName = "unknown";
+ int lineNumber = -1;
+ QRegExp locationRe("@([^:]+):([0-9]+)");
+ if (-1 != locationRe.indexIn(backtrace)) {
+ fileName = locationRe.cap(1);
+ lineNumber = locationRe.cap(2).toInt();
+ }
+ QTest::qFail(qPrintable(message), qPrintable(fileName), lineNumber);
+ }
+ }
+
+ _id = -1;
+ }
+ return _id;
+}
+
+QtScriptTest::QtScriptTest(QString const &testFilePath, QString const &scriptData, QScriptEngine *engine)
+ : QObject(), m_testFilePath(testFilePath), m_engine(engine), m_status(StatusNotStarted)
+{
+ if (m_testFilePath.isEmpty())
+ m_testFilePath = qgetenv("Q_TEST_FILE");
+ if (m_testFilePath.isEmpty())
+ m_testFilePath="testcase.js";
+
+// m_engine->importExtension("qt.core");
+
+ QScriptValue qtestObject = m_engine->newObject();
+ qtestObject.setProperty("SkipSingle", QScriptValue(m_engine, QTest::SkipSingle));
+ qtestObject.setProperty("SkipAll", QScriptValue(m_engine, QTest::SkipAll));
+ qtestObject.setProperty("Abort", QScriptValue(m_engine, QTest::Abort));
+ qtestObject.setProperty("Continue", QScriptValue(m_engine, QTest::Continue));
+ m_engine->globalObject().setProperty("QTest", qtestObject);
+
+ m_engine->evaluate("function QTestFailure() { Error.apply(this, arguments); }"
+ "QTestFailure.prototype = new Error();"
+ "QTestFailure.prototype.name = 'QTestFailure';");
+
+ QStringList slotNames;
+ QString script = scriptData;
+ if (script.isEmpty()) script = readFile(m_testFilePath);
+ if (!script.isEmpty()) {
+ QScriptSyntaxCheckResult synChk = m_engine->checkSyntax(script);
+ if (synChk.state() != QScriptSyntaxCheckResult::Valid) {
+ QTestIDE::instance()->scriptSyntaxError(synChk.errorMessage(), m_testFilePath, synChk.errorLineNumber());
+ m_status = StatusSyntaxError;
+ return;
+ }
+
+ QScriptValue ret = m_engine->evaluate(script, m_testFilePath);
+ QString error;
+ if (m_engine->hasUncaughtException()) {
+ error = m_engine->uncaughtException().toString();
+ } else if (ret.isError()) {
+ error = ret.toString();
+ }
+ if (!error.isEmpty()) {
+ QString backtrace = m_engine->uncaughtExceptionBacktrace().join("\n");
+ qWarning("%s\n%s", qPrintable(error), qPrintable(backtrace));
+ m_status = StatusException;
+ return;
+ }
+ QScriptValue testcase = m_engine->globalObject().property("testcase");
+ QScriptValueIterator it(testcase);
+ while (it.hasNext()) {
+ it.next();
+ QScriptValue val = it.value();
+ if (val.isFunction() || (val.isObject() && it.name().endsWith("_data")))
+ slotNames << it.name();
+ }
+
+ QStringList requiredSlots;
+ requiredSlots
+ << "init"
+ << "cleanup"
+ << "initTestCase"
+ << "cleanupTestCase";
+
+ foreach (QString required, requiredSlots) {
+ if (!slotNames.contains(required)) {
+ m_engine->evaluate("testcase." + required + " = function() {}");
+ slotNames << required;
+ }
+ }
+ } else {
+ qWarning("*** Failed to read testcase!");
+ }
+
+ QVector<uint> *data = qt_meta_data_QtScriptTest();
+ data->clear();
+ // content:
+ *data << 1 // revision
+ << 0 // classname
+ << 0 << 0 // classinfo
+ << slotNames.count() << 10 // methods
+ << 0 << 0 // properties
+ << 0 << 0 // enums/sets
+ ;
+
+ QString testcaseName = QFileInfo(m_testFilePath).baseName();
+
+ QVector<char> *stringdata = qt_meta_stringdata_QtScriptTest();
+ stringdata->clear();
+ appendCString(stringdata, testcaseName.toLocal8Bit() );
+ int namelen = stringdata->size();
+ appendCString(stringdata, "");
+
+ // slots: signature, parameters, type, tag, flags
+ foreach (QString slotName, slotNames) {
+ QString slot = slotName + QLatin1String("()");
+ *data << stringdata->size() << namelen << namelen << namelen << 0x08;
+ appendCString(stringdata, slot.toLatin1());
+ }
+ *data << 0; // eod
+
+ // initialize staticMetaObject
+ staticMetaObject.d.superdata = &QObject::staticMetaObject;
+ staticMetaObject.d.stringdata = stringdata->constData();
+ staticMetaObject.d.data = data->constData();
+ staticMetaObject.d.extradata = 0;
+
+ m_status = StatusNormal;
+}
+
+QtScriptTest::~QtScriptTest()
+{
+}
+
+QtScriptTest::Status QtScriptTest::status()
+{
+ return m_status;
+} \ No newline at end of file
diff --git a/old/interpreter/qtscript_bindings.h b/old/interpreter/qtscript_bindings.h
new file mode 100644
index 0000000..b60f746
--- /dev/null
+++ b/old/interpreter/qtscript_bindings.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTSCRIPT_BINDINGS_H
+#define QTSCRIPT_BINDINGS_H
+
+namespace QtScript {
+ void getLocation(QScriptContext*,QString*,int*);
+ void addInternalFile(QString const&);
+};
+
+class QtScriptTest : public QObject
+{
+
+public:
+
+ enum Status
+ {
+ StatusNotStarted,
+ StatusNormal,
+ StatusSyntaxError,
+ StatusException
+ };
+
+ QtScriptTest(QString const &testFilePath = QString(), QString const &scriptData = QString(), QScriptEngine *engine = 0);
+ virtual ~QtScriptTest();
+
+ static QMetaObject staticMetaObject;
+ virtual const QMetaObject *metaObject() const;
+ virtual void *qt_metacast(const char *);
+ virtual int qt_metacall(QMetaObject::Call, int, void **argv);
+
+ QString testFilePath() const { return m_testFilePath; }
+
+ QScriptEngine* engine() { return m_engine; }
+ Status status();
+
+private:
+ QString m_testFilePath;
+ QScriptEngine* m_engine;
+ Status m_status;
+};
+
+#endif
+
diff --git a/old/interpreter/qtuitestengineagent.cpp b/old/interpreter/qtuitestengineagent.cpp
new file mode 100644
index 0000000..44dade0
--- /dev/null
+++ b/old/interpreter/qtuitestengineagent.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtuitestengineagent.h"
+#include <QDebug>
+#include <QScriptEngine>
+#include <QScriptContextInfo>
+#include <QScriptValueIterator>
+
+QtUiTestEngineAgent::QtUiTestEngineAgent(QScriptEngine *engine, QScriptSystemTest *sysTest)
+ : QScriptEngineAgent(engine), m_systemTest(sysTest)
+{
+}
+
+QtUiTestEngineAgent::~QtUiTestEngineAgent()
+{
+}
+
+void QtUiTestEngineAgent::positionChange(qint64 scriptId, int line, int column)
+{
+ m_systemTest->scriptPositionChange(scriptId, line, column);
+}
+
+void QtUiTestEngineAgent::contextPush()
+{
+ m_systemTest->scriptContextChange(true);
+}
+
+void QtUiTestEngineAgent::contextPop()
+{
+ m_systemTest->scriptContextChange(false);
+} \ No newline at end of file
diff --git a/old/interpreter/qtuitestengineagent.h b/old/interpreter/qtuitestengineagent.h
new file mode 100644
index 0000000..e610ffc
--- /dev/null
+++ b/old/interpreter/qtuitestengineagent.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTUITESTENGINEAGENT_H
+#define QTUITESTENGINEAGENT_H
+
+#include <QScriptEngineAgent>
+#include "qscriptsystemtest.h"
+
+class QtUiTestEngineAgent : public QScriptEngineAgent
+{
+
+public:
+ QtUiTestEngineAgent(QScriptEngine*,QScriptSystemTest*);
+ ~QtUiTestEngineAgent();
+ virtual void positionChange(qint64, int, int);
+ virtual void contextPush();
+ virtual void contextPop();
+
+private:
+ QScriptSystemTest *m_systemTest;
+
+};
+
+#endif
diff --git a/old/interpreter/scriptpreprocessor.cpp b/old/interpreter/scriptpreprocessor.cpp
new file mode 100644
index 0000000..42a413b
--- /dev/null
+++ b/old/interpreter/scriptpreprocessor.cpp
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "scriptpreprocessor.h"
+#include "qscriptsystemtest.h"
+
+#include <QScriptEngine>
+#include <QScriptValue>
+#include <QScriptValueIterator>
+#include <QByteArray>
+
+ScriptPreprocessor::ScriptPreprocessor()
+{
+ QScriptEngine engine;
+ QScriptSystemTest::loadInternalScript("config.js", &engine);
+
+ QScriptValue settings = engine.globalObject().property("preprocess");
+ if (!settings.isObject()) return;
+
+ /* The documentation for the following settings objects is in config.js */
+
+ {
+ QScriptValueIterator it(settings.property("functionAppends"));
+ while (it.hasNext()) {
+ it.next();
+ functionAppends[it.name()] = it.value().toString();
+ }
+ }
+}
+
+void ScriptPreprocessor::preprocess(QString &script)
+{
+ QString out;
+ out.reserve(script.size());
+
+ bool in_singleline_comment = false;
+ bool in_multiline_comment = false;
+ bool in_singlequote_literal = false;
+ bool in_doublequote_literal = false;
+
+ const char singlequote = '\'';
+ const char doublequote = '"';
+ const char brace_open = '(';
+ const char brace_close = ')';
+ const char curlybrace_open = '{';
+ const char curlybrace_close = '}';
+ const char newline = '\n';
+ const char cr = '\r';
+ const char backslash = '\\';
+ const char forwardslash = '/';
+ const char asterisk = '*';
+
+ QString identifier_chars = "_";
+ for (char c = '0'; c <= '9'; ++c) identifier_chars.append(c);
+ for (char c = 'a'; c <= 'z'; ++c) identifier_chars.append(c);
+ for (char c = 'A'; c <= 'Z'; ++c) identifier_chars.append(c);
+
+ int braces = 0;
+ int curlybraces = 0;
+
+ QString function_append;
+ int function_append_braces = 0;
+
+ for (int i = 0; i < script.count(); ++i) {
+ QChar c1 = script[i];//.toLatin1();
+ QChar c2 = script[i+1];//.toLatin1(); // OK; QByteArray is always null-terminated.
+
+ if (in_singleline_comment) {
+ if (newline == c1) {
+ in_singleline_comment = false;
+ out.append(c1);
+ continue;
+ }
+ out.append(c1);
+ continue;
+ }
+
+ if (in_multiline_comment) {
+ if (asterisk == c1 && forwardslash == c2) {
+ in_multiline_comment = false;
+ out.append(c1);
+ out.append(c2);
+ ++i;
+ continue;
+ }
+ out.append(c1);
+ continue;
+ }
+
+ if (in_singlequote_literal) {
+ if (backslash == c1) {
+ out.append(c1);
+ out.append(c2);
+ ++i;
+ continue;
+ }
+ if (singlequote == c1) {
+ in_singlequote_literal = false;
+ out.append(c1);
+ continue;
+ }
+ if (cr == c1 && newline == c2) {
+ out.append("\\n\'+\r\n\'");
+ ++i;
+ continue;
+ }
+ if (newline == c1) {
+ out.append("\\n\'+\n\'");
+ continue;
+ }
+ out.append(c1);
+ continue;
+ }
+
+ if (in_doublequote_literal) {
+ if (backslash == c1) {
+ out.append(c1);
+ out.append(c2);
+ ++i;
+ continue;
+ }
+ if (doublequote == c1) {
+ in_doublequote_literal = false;
+ out.append(c1);
+ continue;
+ }
+ if (cr == c1 && newline == c2) {
+ out.append("\\n\"+\r\n\"");
+ ++i;
+ continue;
+ }
+ if (newline == c1) {
+ out.append("\\n\"+\n\"");
+ continue;
+ }
+ out.append(c1);
+ continue;
+ }
+
+ switch(c1.toLatin1()) {
+
+ case singlequote:
+ in_singlequote_literal = true;
+ out.append(c1);
+ continue;
+
+ case doublequote:
+ in_doublequote_literal = true;
+ out.append(c1);
+ continue;
+
+ case forwardslash:
+ out.append(c1);
+ if (c2 == forwardslash) {
+ in_singleline_comment = true;
+ out.append(c2);
+ ++i;
+ }
+ if (c2 == asterisk) {
+ in_multiline_comment = true;
+ out.append(c2);
+ ++i;
+ }
+ continue;
+
+ case brace_open:
+ ++braces;
+ out.append(c1);
+ continue;
+
+ case brace_close:
+ --braces;
+ out.append(c1);
+ if (!function_append.isEmpty() && function_append_braces == braces) {
+ out.append(function_append);
+ function_append = QString();
+ }
+ continue;
+
+ case curlybrace_open:
+ ++curlybraces;
+ out.append(c1);
+ continue;
+
+ case curlybrace_close:
+ --curlybraces;
+ out.append(c1);
+ continue;
+
+ default:
+ // Look ahead to next non-identifier character
+ int tok_len;
+ for (tok_len = 0; i + tok_len < script.count() && identifier_chars.contains(script[i+tok_len]); ++tok_len) {}
+ if (tok_len < 2) {
+ out.append(c1);
+ continue;
+ }
+ QString tok = script.mid(i, tok_len);
+
+ // Apply preprocessing rules
+
+ // 1. Function appends - text placed immediately after the closing
+ // bracket of a function invocation.
+ if (functionAppends.contains(tok)) {
+ function_append = functionAppends[tok];
+ function_append_braces = braces;
+ }
+
+ out.append(tok);
+ i += tok_len - 1;
+ continue;
+ }
+ }
+
+ out.squeeze();
+
+ script = out;
+}
diff --git a/old/interpreter/scriptpreprocessor.h b/old/interpreter/scriptpreprocessor.h
new file mode 100644
index 0000000..31046f9
--- /dev/null
+++ b/old/interpreter/scriptpreprocessor.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCRIPTPREPROCESSOR_H
+#define SCRIPTPREPROCESSOR_H
+
+#include <QMap>
+#include <QString>
+
+class ScriptPreprocessor
+{
+public:
+ ScriptPreprocessor();
+ void preprocess(QString &script);
+
+private:
+ QMap<QString, QString> functionAppends;
+};
+
+#endif
diff --git a/old/interpreter/scripts.qrc b/old/interpreter/scripts.qrc
new file mode 100644
index 0000000..3baa62e
--- /dev/null
+++ b/old/interpreter/scripts.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>builtins.js</file>
+ <file>config.js</file>
+</qresource>
+</RCC>