aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-07-01 16:31:05 +1000
committerQt by Nokia <qt-info@nokia.com>2011-07-01 08:32:43 +0200
commit628a5cd0669dbfb6a4f2b60f5b59b044f8ca2bbb (patch)
tree5c6a7dc2b130b71c1d029fb2f051d63728928b60 /tests
parentce8a1ef6f1a2868c6e4c19a56e94ca623b6b9889 (diff)
Variants should compare as equal
We need to implement an object comparison callback to ensure that two variants with identical values (although different JS objects) compare as equal. We also add a v8 autotest for this callback. Change-Id: Idd1ab602d31b398a937d4df4a7bd091aa205de24 Reviewed-on: http://codereview.qt.nokia.com/989 Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/declarative/v8/tst_v8.cpp6
-rw-r--r--tests/auto/declarative/v8/v8main.cpp1
-rw-r--r--tests/auto/declarative/v8/v8test.cpp176
-rw-r--r--tests/auto/declarative/v8/v8test.h1
4 files changed, 182 insertions, 2 deletions
diff --git a/tests/auto/declarative/v8/tst_v8.cpp b/tests/auto/declarative/v8/tst_v8.cpp
index 4749da02f0..32d100e968 100644
--- a/tests/auto/declarative/v8/tst_v8.cpp
+++ b/tests/auto/declarative/v8/tst_v8.cpp
@@ -54,6 +54,7 @@ private slots:
void cleanupTestCase() {}
void eval();
+ void userobjectcompare();
};
void tst_v8::eval()
@@ -61,6 +62,11 @@ void tst_v8::eval()
QVERIFY(v8test_eval());
}
+void tst_v8::userobjectcompare()
+{
+ QVERIFY(v8test_userobjectcompare());
+}
+
int main(int argc, char *argv[])
{
V8::SetFlagsFromCommandLine(&argc, argv, true);
diff --git a/tests/auto/declarative/v8/v8main.cpp b/tests/auto/declarative/v8/v8main.cpp
index bf37e2d3a5..5930f53f90 100644
--- a/tests/auto/declarative/v8/v8main.cpp
+++ b/tests/auto/declarative/v8/v8main.cpp
@@ -11,6 +11,7 @@ int main(int argc, char *argv[])
v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
RUN_TEST(eval);
+ RUN_TEST(userobjectcompare);
return -1;
}
diff --git a/tests/auto/declarative/v8/v8test.cpp b/tests/auto/declarative/v8/v8test.cpp
index 9b80b08550..27d39c5970 100644
--- a/tests/auto/declarative/v8/v8test.cpp
+++ b/tests/auto/declarative/v8/v8test.cpp
@@ -48,6 +48,7 @@ using namespace v8;
#define VERIFY(expr) { \
if (!(expr)) { \
+ fprintf(stderr, "FAIL: %s:%d %s\n", __FILE__, __LINE__, # expr); \
_testPassed = false; \
goto cleanup; \
} \
@@ -59,11 +60,11 @@ bool v8test_eval()
BEGINTEST();
HandleScope handle_scope;
- v8::Persistent<v8::Context> context = Context::New();
+ Persistent<Context> context = Context::New();
Context::Scope context_scope(context);
Local<Object> qmlglobal = Object::New();
- qmlglobal->Set(String::New("a"), v8::Integer::New(1922));
+ qmlglobal->Set(String::New("a"), Integer::New(1922));
Local<Script> script = Script::Compile(String::New("eval(\"a\")"), NULL, NULL,
Handle<String>(), Script::QmlMode);
@@ -80,3 +81,174 @@ cleanup:
ENDTEST();
}
+static int userObjectComparisonCalled = 0;
+static bool userObjectComparisonReturn = false;
+static Local<Object> expectedLhs;
+static Local<Object> expectedRhs;
+static bool expectedObjectsCompared = false;
+
+#define SET_EXPECTED(lhs, rhs) { \
+ expectedObjectsCompared = false; \
+ expectedLhs = lhs; \
+ expectedRhs = rhs; \
+}
+
+static bool UserObjectComparison(Local<Object> lhs, Local<Object> rhs)
+{
+ userObjectComparisonCalled++;
+
+ expectedObjectsCompared = (lhs == expectedLhs && rhs == expectedRhs);
+
+ return userObjectComparisonReturn;
+}
+
+inline bool runscript(const char *source) {
+ Local<Script> script = Script::Compile(String::New(source));
+ Local<Value> result = script->Run();
+ return result->BooleanValue();
+}
+
+bool v8test_userobjectcompare()
+{
+ BEGINTEST();
+
+ HandleScope handle_scope;
+ Persistent<Context> context = Context::New();
+ Context::Scope context_scope(context);
+
+ V8::SetUserObjectComparisonCallbackFunction(UserObjectComparison);
+
+ Local<ObjectTemplate> ot = ObjectTemplate::New();
+ ot->MarkAsUseUserObjectComparison();
+
+ Local<Object> uoc1 = ot->NewInstance();
+ Local<Object> uoc2 = ot->NewInstance();
+ context->Global()->Set(String::New("uoc1a"), uoc1);
+ context->Global()->Set(String::New("uoc1b"), uoc1);
+ context->Global()->Set(String::New("uoc2"), uoc2);
+ Local<Object> obj1 = Object::New();
+ context->Global()->Set(String::New("obj1a"), obj1);
+ context->Global()->Set(String::New("obj1b"), obj1);
+ context->Global()->Set(String::New("obj2"), Object::New());
+ Local<String> string1 = String::New("Hello World");
+ context->Global()->Set(String::New("string1a"), string1);
+ context->Global()->Set(String::New("string1b"), string1);
+ context->Global()->Set(String::New("string2"), v8::String::New("Goodbye World"));
+
+ // XXX Opportunity for optimization - don't invoke user callback if objects are
+ // equal.
+#if 0
+ userObjectComparisonCalled = 0; userObjectComparisonReturn = false;
+ VERIFY(true == runscript("uoc1a == uoc1b"));
+ VERIFY(userObjectComparisonCalled == 0);
+#endif
+
+ // Comparing two uoc objects invokes uoc
+ userObjectComparisonCalled = 0;
+ userObjectComparisonReturn = false;
+ VERIFY(false == runscript("uoc1a == uoc2"));
+ VERIFY(userObjectComparisonCalled == 1);
+
+ VERIFY(false == runscript("uoc2 == uoc1a"));
+ VERIFY(userObjectComparisonCalled == 2);
+ userObjectComparisonReturn = true;
+ VERIFY(true == runscript("uoc1a == uoc2"));
+ VERIFY(userObjectComparisonCalled == 3);
+ VERIFY(true == runscript("uoc2 == uoc1a"));
+ VERIFY(userObjectComparisonCalled == 4);
+
+ // != on two uoc object invokes uoc
+ userObjectComparisonCalled = 0;
+ userObjectComparisonReturn = false;
+ VERIFY(true == runscript("uoc1a != uoc2"));
+ VERIFY(userObjectComparisonCalled == 1);
+ VERIFY(true == runscript("uoc2 != uoc1a"));
+ VERIFY(userObjectComparisonCalled == 2);
+ userObjectComparisonReturn = true;
+ VERIFY(false == runscript("uoc1a != uoc2"));
+ VERIFY(userObjectComparisonCalled == 3);
+ VERIFY(false == runscript("uoc2 != uoc1a"));
+ VERIFY(userObjectComparisonCalled == 4);
+
+ // Comparison against a non-object doesn't invoke uoc
+ userObjectComparisonCalled = 0;
+ userObjectComparisonReturn = false;
+ VERIFY(false == runscript("uoc1a == string1a"));
+ VERIFY(userObjectComparisonCalled == 0);
+ VERIFY(false == runscript("string1a == uoc1a"));
+ VERIFY(userObjectComparisonCalled == 0);
+ VERIFY(false == runscript("2 == uoc1a"));
+ VERIFY(userObjectComparisonCalled == 0);
+ VERIFY(true == runscript("uoc1a != string1a"));
+ VERIFY(userObjectComparisonCalled == 0);
+ VERIFY(true == runscript("string1a != uoc1a"));
+ VERIFY(userObjectComparisonCalled == 0);
+ VERIFY(true == runscript("2 != uoc1a"));
+ VERIFY(userObjectComparisonCalled == 0);
+
+ // Comparison against a non-uoc-object still invokes uoc
+ userObjectComparisonCalled = 0;
+ userObjectComparisonReturn = false;
+ VERIFY(false == runscript("uoc1a == obj1a"));
+ VERIFY(userObjectComparisonCalled == 1);
+ VERIFY(false == runscript("obj1a == uoc1a"));
+ VERIFY(userObjectComparisonCalled == 2);
+ userObjectComparisonReturn = true;
+ VERIFY(true == runscript("uoc1a == obj1a"));
+ VERIFY(userObjectComparisonCalled == 3);
+ VERIFY(true == runscript("obj1a == uoc1a"));
+ VERIFY(userObjectComparisonCalled == 4);
+
+ // != comparison against a non-uoc-object still invokes uoc
+ userObjectComparisonCalled = 0;
+ userObjectComparisonReturn = false;
+ VERIFY(true == runscript("uoc1a != obj1a"));
+ VERIFY(userObjectComparisonCalled == 1);
+ VERIFY(true == runscript("obj1a != uoc1a"));
+ VERIFY(userObjectComparisonCalled == 2);
+ userObjectComparisonReturn = true;
+ VERIFY(false == runscript("uoc1a != obj1a"));
+ VERIFY(userObjectComparisonCalled == 3);
+ VERIFY(false == runscript("obj1a != uoc1a"));
+ VERIFY(userObjectComparisonCalled == 4);
+
+ // Comparing two non-uoc objects does not invoke uoc
+ userObjectComparisonCalled = 0;
+ userObjectComparisonReturn = false;
+ VERIFY(true == runscript("obj1a == obj1a"));
+ VERIFY(true == runscript("obj1a == obj1b"));
+ VERIFY(false == runscript("obj1a == obj2"));
+ VERIFY(false == runscript("obj1a == string1a"));
+ VERIFY(true == runscript("string1a == string1a"));
+ VERIFY(true == runscript("string1a == string1b"));
+ VERIFY(false == runscript("string1a == string2"));
+ VERIFY(userObjectComparisonCalled == 0);
+
+ // Correct lhs and rhs passed to uoc
+ userObjectComparisonCalled = 0;
+ userObjectComparisonReturn = false;
+ SET_EXPECTED(uoc1, uoc2);
+ VERIFY(false == runscript("uoc1a == uoc2"));
+ VERIFY(true == expectedObjectsCompared);
+ SET_EXPECTED(uoc2, uoc1);
+ VERIFY(false == runscript("uoc2 == uoc1a"));
+ VERIFY(true == expectedObjectsCompared);
+ SET_EXPECTED(uoc1, uoc2);
+ VERIFY(true == runscript("uoc1a != uoc2"));
+ VERIFY(true == expectedObjectsCompared);
+ SET_EXPECTED(uoc2, uoc1);
+ VERIFY(true == runscript("uoc2 != uoc1a"));
+ VERIFY(true == expectedObjectsCompared);
+ SET_EXPECTED(uoc1, obj1);
+ VERIFY(false == runscript("uoc1a == obj1a"));
+ VERIFY(true == expectedObjectsCompared);
+ SET_EXPECTED(obj1, uoc1);
+ VERIFY(false == runscript("obj1a == uoc1a"));
+ VERIFY(true == expectedObjectsCompared);
+
+cleanup:
+ V8::SetUserObjectComparisonCallbackFunction(0);
+ context.Dispose();
+
+ ENDTEST();
+}
diff --git a/tests/auto/declarative/v8/v8test.h b/tests/auto/declarative/v8/v8test.h
index f8878467ed..31acefc8b3 100644
--- a/tests/auto/declarative/v8/v8test.h
+++ b/tests/auto/declarative/v8/v8test.h
@@ -45,6 +45,7 @@
#include "../../../../src/3rdparty/v8/include/v8.h"
bool v8test_eval();
+bool v8test_userobjectcompare();
#endif // V8TEST_H