summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSascha Kolewa <sascha.kolewa@nokia.com>2010-12-21 18:21:10 +0100
committerSascha Kolewa <sascha.kolewa@nokia.com>2010-12-21 18:21:10 +0100
commit23788e85d40f983d4be58789e0f979d4dd4cbbe4 (patch)
tree33b5f3976903d6697fdbf08430e9aee7511c3527 /src
parented8735a5cc5eea3c0107e0d0a95447ba6fc11d19 (diff)
Added function to compare objects
Taken over quite some object comparison functionality from QUnit or http://philrathe.com/articles/equiv to compare different types of Javascript objects
Diffstat (limited to 'src')
-rw-r--r--src/imports/testlib/TestCase.qml146
1 files changed, 116 insertions, 30 deletions
diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml
index 6c73c1d..ccaad8f 100644
--- a/src/imports/testlib/TestCase.qml
+++ b/src/imports/testlib/TestCase.qml
@@ -98,55 +98,141 @@ Item {
throw new Error("QtQuickTest::fail")
}
- function qtest_compareInternal(actual, expected) {
- var success = false
-
- if (typeof actual == "number" && typeof expected == "number") {
- // Use a fuzzy compare if the two values are floats
- if (Math.abs(actual - expected) <= 0.00001)
- success = true
- } else if (Array.isArray(actual) && Array.isArray(expected)) {
- success = qtest_compareInternalArrays(actual, expected)
- } else if (typeof actual == "object" && typeof expected == "object") {
- // Does the expected value look like a vector3d?
- if ("x" in expected && "y" in expected && "z" in expected) {
- if (Math.abs(actual.x - expected.x) <= 0.00001 &&
- Math.abs(actual.y - expected.y) <= 0.00001 &&
- Math.abs(actual.z - expected.z) <= 0.00001) {
- success = true
- }
- } else if (qtest_compareInternalObjects(actual, expected)) {
- success = true
+ // Determine what is o.
+ // Discussions and reference: http://philrathe.com/articles/equiv
+ // Test suites: http://philrathe.com/tests/equiv
+ // Author: Philippe Rathé <prathe@gmail.com>
+ function qtest_typeof(o) {
+ if (typeof o === "undefined") {
+ return "undefined";
+
+ // consider: typeof null === object
+ } else if (o === null) {
+ return "null";
+
+ } else if (o.constructor === String) {
+ return "string";
+
+ } else if (o.constructor === Boolean) {
+ return "boolean";
+
+ } else if (o.constructor === Number) {
+
+ if (isNaN(o)) {
+ return "nan";
+ } else {
+ return "number";
}
- } else if (actual == expected) {
- success = true
+ // consider: typeof [] === object
+ } else if (o instanceof Array) {
+ return "array";
+
+ // consider: typeof new Date() === object
+ } else if (o instanceof Date) {
+ return "date";
+
+ // consider: /./ instanceof Object;
+ // /./ instanceof RegExp;
+ // typeof /./ === "function"; // => false in IE and Opera,
+ // true in FF and Safari
+ } else if (o instanceof RegExp) {
+ return "regexp";
+
+ } else if (typeof o === "object") {
+ if ("mapFromItem" in o && "mapToItem" in o) {
+ return "declarativeitem"; // @todo improve detection of declarative items
+ } else if ("x" in o && "y" in o && "z" in o) {
+ return "vector3d"; // Qt3D vector
+ }
+ return "object";
+ } else if (o instanceof Function) {
+ return "function";
+ } else {
+ return undefined;
}
- return success
}
- // Test for equality any JavaScript type.
+ // Test for equality
+ // Large parts contain sources from QUnit or http://philrathe.com
// Discussions and reference: http://philrathe.com/articles/equiv
// Test suites: http://philrathe.com/tests/equiv
// Author: Philippe Rathé <prathe@gmail.com>
- function qtest_compareInternalObjects(a, b) {
+ function qtest_compareInternal(act, exp) {
+ var success = false;
+
+ if (act === exp) {
+ success = true; // catch the most you can
+ } else if (act === null || exp === null || typeof act === "undefined" || typeof exp === "undefined") {
+ success = false; // don't lose time with error prone cases
+ } else {
+ var typeExp = qtest_typeof(exp), typeAct = qtest_typeof(act)
+
+ if (typeExp !== typeAct) {
+ // allow object vs string comparison (e.g. for colors)
+ // else break on different types
+ if ((typeExp === "string" && typeAct === "object") || (typeExp === "object" && typeAct === "string")) {
+ success = (act == exp)
+ }
+ } else if (typeExp === "string" || typeExp === "boolean" || typeExp === "number" ||
+ typeExp === "null" || typeExp === "undefined") {
+ if (exp instanceof act.constructor || act instanceof exp.constructor) {
+ // to catch short annotaion VS 'new' annotation of act declaration
+ // e.g. var i = 1;
+ // var j = new Number(1);
+ success = (act == exp)
+ } else {
+ success = (act === exp)
+ }
+ } else if (typeExp === "nan") {
+ success = isNaN(act);
+ } else if (typeExp == "number") {
+ // Use act fuzzy compare if the two values are floats
+ if (Math.abs(act - exp) <= 0.00001) {
+ success = true
+ }
+ } else if (typeExp === "array") {
+ success = qtest_compareInternalArrays(act, exp)
+ } else if (typeExp === "object") {
+ success = qtest_compareInternalObjects(act, exp)
+ } else if (typeExp === "declarativeitem") {
+ success = qtest_compareInternalObjects(act, exp) // @todo improve comparison of declarative items
+ } else if (typeExp === "vector3d") {
+ success = (Math.abs(act.x - exp.x) <= 0.00001 &&
+ Math.abs(act.y - exp.y) <= 0.00001 &&
+ Math.abs(act.z - exp.z) <= 0.00001)
+ } else if (typeExp === "date") {
+ success = (act.valueOf() === exp.valueOf())
+ } else if (typeExp === "regexp") {
+ success = (act.source === exp.source && // the regex itself
+ act.global === exp.global && // and its modifers (gmi) ...
+ act.ignoreCase === exp.ignoreCase &&
+ act.multiline === exp.multiline)
+ }
+ }
+ return success
+ }
+
+ function qtest_compareInternalObjects(act, exp) {
var i;
var eq = true; // unless we can proove it
var aProperties = [], bProperties = []; // collection of strings
// comparing constructors is more strict than using instanceof
- if (a.constructor !== b.constructor) {
+ if (act.constructor !== exp.constructor) {
return false;
}
- for (i in a) { // be strict: don't ensures hasOwnProperty and go deep
- aProperties.push(i); // collect a's properties
- if (!qtest_compareInternal(a[i], b[i])) {
+ for (i in act) { // be strict: don't ensures hasOwnProperty and go deep
+ aProperties.push(i); // collect act's properties
+
+ if (!qtest_compareInternal(act[i], exp[i])) {
eq = false;
+ break;
}
}
- for (i in b) {
- bProperties.push(i); // collect b's properties
+ for (i in exp) {
+ bProperties.push(i); // collect exp's properties
}
// Ensures identical properties name