Bug 667076 - Add a CHECK_EQUAL for testing whether non-jsval types are equal and report expected and observed values on failure (r=luke)

--HG--
extra : rebase_source : fb98cbdcaa63abbfe718d3dfc5b3ac1b0d3a64da
This commit is contained in:
Steve Fink 2011-06-24 13:11:28 -07:00
parent 6e50bf2c00
commit 5a2aad9f3f
15 changed files with 124 additions and 55 deletions

View File

@ -73,8 +73,8 @@ BEGIN_TEST(testCustomIterator_bug612523)
"j;", &result);
CHECK(JSVAL_IS_INT(result));
CHECK(JSVAL_TO_INT(result) == 100);
CHECK(count == 101);
CHECK_EQUAL(JSVAL_TO_INT(result), 100);
CHECK_EQUAL(count, 101);
return true;
}

View File

@ -26,8 +26,8 @@ BEGIN_TEST(testDebugger_bug519719)
"function f(g) { for (var i = 0; i < 9; i++) call(g); }\n"
"f(Math.sin);\n" // record loop, starting in f
"f(Math.cos);\n"); // side exit in f -> call
CHECK(callCount[0] == 20);
CHECK(callCount[1] == 20);
CHECK_EQUAL(callCount[0], 20);
CHECK_EQUAL(callCount[1], 20);
return true;
}
END_TEST(testDebugger_bug519719)

View File

@ -61,37 +61,46 @@ BEGIN_TEST(testFuncCallback_bug507012)
// Check whether JS_Execute() tracking works
EXEC("42");
CHECK(enters == 1 && leaves == 1 && depth == 0);
CHECK_EQUAL(enters, 1);
CHECK_EQUAL(leaves, 1);
CHECK_EQUAL(depth, 0);
interpreted = enters = leaves = depth = 0;
// Check whether the basic function tracking works
EXEC("f(1)");
CHECK(enters == 1+1 && leaves == 1+1 && depth == 0);
CHECK_EQUAL(enters, 1+1);
CHECK_EQUAL(leaves, 1+1);
CHECK_EQUAL(depth, 0);
// Can we switch to a different callback?
enters = 777;
JS_SetFunctionCallback(cx, funcTransition2);
EXEC("f(1)");
CHECK(called2 && enters == 777);
CHECK(called2);
CHECK_EQUAL(enters, 777);
// Check whether we can turn off function tracing
JS_SetFunctionCallback(cx, NULL);
EXEC("f(1)");
CHECK(enters == 777);
CHECK_EQUAL(enters, 777);
interpreted = enters = leaves = depth = 0;
// Check nested invocations
JS_SetFunctionCallback(cx, funcTransition);
enters = leaves = depth = 0;
EXEC("f(3)");
CHECK(enters == 1+3 && leaves == 1+3 && depth == 0);
CHECK_EQUAL(enters, 1+3);
CHECK_EQUAL(leaves, 1+3);
CHECK_EQUAL(depth, 0);
interpreted = enters = leaves = depth = 0;
// Check calls invoked while running on trace
EXEC("function g () { ++x; }");
interpreted = enters = leaves = depth = 0;
EXEC("for (i = 0; i < 50; ++i) { g(); }");
CHECK(enters == 1+50 && leaves == 1+50 && depth == 0);
CHECK_EQUAL(enters, 1+50);
CHECK_EQUAL(leaves, 1+50);
CHECK_EQUAL(depth, 0);
// If this fails, it means that the code was interpreted rather
// than trace-JITted, and so is not testing what it's supposed to
@ -111,10 +120,10 @@ BEGIN_TEST(testFuncCallback_bug507012)
interpreted = enters = leaves = depth = overlays = 0;
EXEC("42.5");
CHECK(enters == 1);
CHECK(leaves == 1);
CHECK(depth == 0);
CHECK(overlays == enters + leaves);
CHECK_EQUAL(enters, 1);
CHECK_EQUAL(leaves, 1);
CHECK_EQUAL(depth, 0);
CHECK_EQUAL(overlays, enters + leaves);
interpreted = enters = leaves = depth = overlays = 0;
#endif

View File

@ -68,7 +68,7 @@ BEGIN_TEST(testGCChunkAlloc)
/* Check that we get OOM. */
CHECK(!ok);
CHECK(!JS_IsExceptionPending(cx));
CHECK(errorCount == 1);
CHECK_EQUAL(errorCount, 1);
CHECK(!customGCChunkAllocator.pool);
JS_GC(cx);
JS_ToggleOptions(cx, JSOPTION_JIT);
@ -79,7 +79,7 @@ BEGIN_TEST(testGCChunkAlloc)
" array.push({});"
" }"
"})();", root.addr());
CHECK(errorCount == 1);
CHECK_EQUAL(errorCount, 1);
return true;
}

View File

@ -60,7 +60,7 @@ BEGIN_TEST(testIsAboutToBeFinalized_bug528645)
--checkPointersStaticStrings;
}
}
CHECK(checkPointersStaticStrings == 0);
CHECK_EQUAL(checkPointersStaticStrings, 0);
free(checkPointers);
checkPointers = NULL;

View File

@ -57,7 +57,7 @@ BEGIN_TEST(testNewObject_1)
CHECK(JS_IsArrayObject(cx, obj));
jsuint len;
CHECK(JS_GetArrayLength(cx, obj, &len));
CHECK(len == 0);
CHECK_EQUAL(len, 0);
// With one argument.
argv[0] = INT_TO_JSVAL(4);
@ -66,7 +66,7 @@ BEGIN_TEST(testNewObject_1)
rt = OBJECT_TO_JSVAL(obj);
CHECK(JS_IsArrayObject(cx, obj));
CHECK(JS_GetArrayLength(cx, obj, &len));
CHECK(len == 4);
CHECK_EQUAL(len, 4);
// With N arguments.
for (size_t i = 0; i < N; i++)
@ -76,7 +76,7 @@ BEGIN_TEST(testNewObject_1)
rt = OBJECT_TO_JSVAL(obj);
CHECK(JS_IsArrayObject(cx, obj));
CHECK(JS_GetArrayLength(cx, obj, &len));
CHECK(len == N);
CHECK_EQUAL(len, N);
CHECK(JS_GetElement(cx, obj, N - 1, &v));
CHECK_SAME(v, INT_TO_JSVAL(N - 1));

View File

@ -29,7 +29,7 @@ BEGIN_TEST(testPropCache_bug505798)
EXEC("var arr = [x, y];\n"
"for (var i = 0; i < arr.length; i++)\n"
" arr[i].p = 1;\n");
CHECK(g_counter == 1);
CHECK_EQUAL(g_counter, 1);
return true;
}
END_TEST(testPropCache_bug505798)

View File

@ -24,15 +24,15 @@ BEGIN_TEST(testGetRegExpFlags)
EVAL("/foopy/", val.addr());
obj = JSVAL_TO_OBJECT(val.value());
CHECK(JS_GetRegExpFlags(cx, obj) == 0);
CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), 0);
EVAL("/foopy/g", val.addr());
obj = JSVAL_TO_OBJECT(val.value());
CHECK(JS_GetRegExpFlags(cx, obj) == JSREG_GLOB);
CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), JSREG_GLOB);
EVAL("/foopy/gi", val.addr());
obj = JSVAL_TO_OBJECT(val.value());
CHECK(JS_GetRegExpFlags(cx, obj) == (JSREG_FOLD | JSREG_GLOB));
CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), (JSREG_FOLD | JSREG_GLOB));
return true;
}

View File

@ -22,14 +22,14 @@ BEGIN_TEST(testRegExpInstanceProperties)
JS_GC(cx);
CHECK(regexpProto->getCompartment()->initialRegExpShape == NULL);
CHECK_EQUAL(regexpProto->getCompartment()->initialRegExpShape, NULL);
jsval regexp;
EVAL("/foopy/", &regexp);
JSObject *robj = JSVAL_TO_OBJECT(regexp);
CHECK(robj->lastProperty());
CHECK(robj->getCompartment()->initialRegExpShape == robj->lastProperty());
CHECK_EQUAL(robj->getCompartment()->initialRegExpShape, robj->lastProperty());
return true;
}

View File

@ -42,9 +42,9 @@ BEGIN_TEST(testResolveRecursion)
/* Start the essence of the test via invoking the first resolve hook. */
jsval v;
EVAL("obj1.x", &v);
CHECK(v == JSVAL_FALSE);
CHECK(resolveEntryCount == 4);
CHECK(resolveExitCount == 4);
CHECK_SAME(v, JSVAL_FALSE);
CHECK_EQUAL(resolveEntryCount, 4);
CHECK_EQUAL(resolveExitCount, 4);
return true;
}
@ -69,9 +69,9 @@ struct AutoIncrCounters {
bool
doResolve(JSObject *obj, jsid id, uintN flags, JSObject **objp)
{
CHECK(resolveExitCount == 0);
CHECK_EQUAL(resolveExitCount, 0);
AutoIncrCounters incr(this);
CHECK(obj == obj1 || obj == obj2);
CHECK_EQUAL(obj, obj1 || obj == obj2);
CHECK(JSID_IS_STRING(id));
@ -81,31 +81,31 @@ doResolve(JSObject *obj, jsid id, uintN flags, JSObject **objp)
if (JS_FlatStringEqualsAscii(str, "x")) {
if (obj == obj1) {
/* First resolve hook invocation. */
CHECK(resolveEntryCount == 1);
CHECK_EQUAL(resolveEntryCount, 1);
EVAL("obj2.y = true", &v);
CHECK(v == JSVAL_TRUE);
CHECK_SAME(v, JSVAL_TRUE);
CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_FALSE, NULL, NULL, 0));
*objp = obj;
return true;
}
if (obj == obj2) {
CHECK(resolveEntryCount == 4);
CHECK_EQUAL(resolveEntryCount, 4);
*objp = NULL;
return true;
}
} else if (JS_FlatStringEqualsAscii(str, "y")) {
if (obj == obj2) {
CHECK(resolveEntryCount == 2);
CHECK_EQUAL(resolveEntryCount, 2);
CHECK(JS_DefinePropertyById(cx, obj, id, JSVAL_NULL, NULL, NULL, 0));
EVAL("obj1.x", &v);
CHECK(JSVAL_IS_VOID(v));
EVAL("obj1.y", &v);
CHECK(v == JSVAL_ZERO);
CHECK_SAME(v, JSVAL_ZERO);
*objp = obj;
return true;
}
if (obj == obj1) {
CHECK(resolveEntryCount == 3);
CHECK_EQUAL(resolveEntryCount, 3);
EVAL("obj1.x", &v);
CHECK(JSVAL_IS_VOID(v));
EVAL("obj1.y", &v);
@ -115,7 +115,7 @@ doResolve(JSObject *obj, jsid id, uintN flags, JSObject **objp)
EVAL("obj2.x", &v);
CHECK(JSVAL_IS_VOID(v));
EVAL("obj1.y = 0", &v);
CHECK(v == JSVAL_ZERO);
CHECK_SAME(v, JSVAL_ZERO);
*objp = obj;
return true;
}

View File

@ -22,7 +22,7 @@ BEGIN_TEST(testStringBuffer_finishString)
JSAtom *finishedAtom = buffer.finishAtom();
CHECK(finishedAtom);
CHECK(atom == finishedAtom);
CHECK_EQUAL(atom, finishedAtom);
return true;
}
END_TEST(testStringBuffer_finishString)

View File

@ -37,7 +37,7 @@ BEGIN_TEST(testTrap_gc)
jsvalRoot v2(cx);
CHECK(JS_ExecuteScript(cx, global, scriptObj, v2.addr()));
CHECK(JSVAL_IS_OBJECT(v2));
CHECK(emptyTrapCallCount == 0);
CHECK_EQUAL(emptyTrapCallCount, 0);
// Disable JIT for debugging
JS_SetOptions(cx, JS_GetOptions(cx) & ~JSOPTION_JIT);
@ -70,7 +70,7 @@ BEGIN_TEST(testTrap_gc)
// execute
CHECK(JS_ExecuteScript(cx, global, scriptObj, v2.addr()));
CHECK(emptyTrapCallCount == 11);
CHECK_EQUAL(emptyTrapCallCount, 11);
JS_GC(cx);

View File

@ -11,10 +11,10 @@ BEGIN_TEST(testUTF8_bug589917)
size_t utf8_len = sizeof(output_buffer);
CHECK(JS_EncodeCharacters(cx, surrogate_pair, 2, output_buffer, &utf8_len));
CHECK(utf8_len == 4);
CHECK_EQUAL(utf8_len, 4);
CHECK(JS_EncodeCharacters(cx, surrogate_pair, 2, NULL, &utf8_len));
CHECK(utf8_len == 4);
CHECK_EQUAL(utf8_len, 4);
return true;
}

View File

@ -101,9 +101,9 @@ struct VersionFixture : public JSAPITest
}
bool toggleXML(bool shouldEnable) {
CHECK(hasXML() == !shouldEnable);
CHECK_EQUAL(hasXML(), !shouldEnable);
JS_ToggleOptions(cx, JSOPTION_XML);
CHECK(hasXML() == shouldEnable);
CHECK_EQUAL(hasXML(), shouldEnable);
return true;
}
@ -218,13 +218,13 @@ END_FIXTURE_TEST(VersionFixture, testOptionsAreUsedForVersionFlags)
BEGIN_FIXTURE_TEST(VersionFixture, testEntryLosesOverride)
{
EXEC("overrideVersion15(); evalScriptVersion16('checkOverride(false); captureVersion()');");
CHECK(captured == JSVERSION_1_6);
CHECK_EQUAL(captured, JSVERSION_1_6);
/*
* Override gets propagated to default version as non-override when you leave the VM's execute
* call.
*/
CHECK(JS_GetVersion(cx) == JSVERSION_1_5);
CHECK_EQUAL(JS_GetVersion(cx), JSVERSION_1_5);
CHECK(!cx->isVersionOverridden());
return true;
}
@ -238,28 +238,28 @@ END_FIXTURE_TEST(VersionFixture, testEntryLosesOverride)
*/
BEGIN_FIXTURE_TEST(VersionFixture, testReturnLosesOverride)
{
CHECK(JS_GetVersion(cx) == JSVERSION_ECMA_5);
CHECK_EQUAL(JS_GetVersion(cx), JSVERSION_ECMA_5);
EXEC(
"checkOverride(false);"
"evalScriptVersion16('overrideVersion15();');"
"checkOverride(false);"
"captureVersion();"
);
CHECK(captured == JSVERSION_ECMA_5);
CHECK_EQUAL(captured, JSVERSION_ECMA_5);
return true;
}
END_FIXTURE_TEST(VersionFixture, testReturnLosesOverride)
BEGIN_FIXTURE_TEST(VersionFixture, testEvalPropagatesOverride)
{
CHECK(JS_GetVersion(cx) == JSVERSION_ECMA_5);
CHECK_EQUAL(JS_GetVersion(cx), JSVERSION_ECMA_5);
EXEC(
"checkOverride(false);"
"eval('overrideVersion15();');"
"checkOverride(true);"
"captureVersion();"
);
CHECK(captured == JSVERSION_1_5);
CHECK_EQUAL(captured, JSVERSION_1_5);
return true;
}
END_FIXTURE_TEST(VersionFixture, testEvalPropagatesOverride)

View File

@ -172,7 +172,7 @@ class JSAPITest
fail(bytes, filename, lineno);
}
JSAPITestString toSource(jsval v) {
JSAPITestString jsvalToSource(jsval v) {
JSString *str = JS_ValueToSource(cx, v);
if (str) {
JSAutoByteString bytes(cx, str);
@ -183,9 +183,63 @@ class JSAPITest
return JSAPITestString("<<error converting value to string>>");
}
#define CHECK_SAME(actual, expected) \
JSAPITestString toSource(long v) {
char buf[40];
sprintf(buf, "%ld", v);
return JSAPITestString(buf);
}
JSAPITestString toSource(unsigned long v) {
char buf[40];
sprintf(buf, "%lu", v);
return JSAPITestString(buf);
}
JSAPITestString toSource(unsigned int v) {
return toSource((unsigned long)v);
}
JSAPITestString toSource(int v) {
return toSource((long)v);
}
JSAPITestString toSource(bool v) {
return JSAPITestString(v ? "true" : "false");
}
JSAPITestString toSource(JSAtom *v) {
return jsvalToSource(STRING_TO_JSVAL((JSString*)v));
}
JSAPITestString toSource(JSVersion v) {
return JSAPITestString(JS_VersionToString(v));
}
template<typename T>
bool checkEqual(const T &actual, const T &expected,
const char *actualExpr, const char *expectedExpr,
const char *filename, int lineno) {
return (actual == expected) ||
fail(JSAPITestString("CHECK_EQUAL failed: expected (") +
expectedExpr + ") = " + toSource(expected) +
", got (" + actualExpr + ") = " + toSource(actual), filename, lineno);
}
// There are many cases where the static types of 'actual' and 'expected'
// are not identical, and C++ is understandably cautious about automatic
// coercions. So catch those cases and forcibly coerce, then use the
// identical-type specialization. This may do bad things if the types are
// actually *not* compatible.
template<typename T, typename U>
bool checkEqual(const T &actual, const U &expected,
const char *actualExpr, const char *expectedExpr,
const char *filename, int lineno) {
return checkEqual(U(actual), expected, actualExpr, expectedExpr, filename, lineno);
}
#define CHECK_EQUAL(actual, expected) \
do { \
if (!checkSame(actual, expected, #actual, #expected, __FILE__, __LINE__)) \
if (!checkEqual(actual, expected, #actual, #expected, __FILE__, __LINE__)) \
return false; \
} while (false)
@ -196,9 +250,15 @@ class JSAPITest
return (JS_SameValue(cx, actual, expected, &same) && same) ||
fail(JSAPITestString("CHECK_SAME failed: expected JS_SameValue(cx, ") +
actualExpr + ", " + expectedExpr + "), got !JS_SameValue(cx, " +
toSource(actual) + ", " + toSource(expected) + ")", filename, lineno);
jsvalToSource(actual) + ", " + jsvalToSource(expected) + ")", filename, lineno);
}
#define CHECK_SAME(actual, expected) \
do { \
if (!checkSame(actual, expected, #actual, #expected, __FILE__, __LINE__)) \
return false; \
} while (false)
#define CHECK(expr) \
do { \
if (!(expr)) \