Bug 1439772 - Avoid truncating operands when reporting failure for Assert.deepEqual r?mikedeboer
MozReview-Commit-ID: 1hlYFE3Xcwn
--- a/testing/modules/Assert.jsm
+++ b/testing/modules/Assert.jsm
@@ -82,44 +82,46 @@ function getMessage(error, prefix = "")
}
try {
expected = JSON.stringify(error.expected, replacer);
} catch (ex) {
expected = Object.prototype.toString.call(error.expected);
}
let message = prefix;
if (error.operator) {
- message += (prefix ? " - " : "") + truncate(actual) + " " + error.operator +
- " " + truncate(expected);
+ let truncateLength = error.truncate ? kTruncateLength : Infinity;
+ message += (prefix ? " - " : "") + truncate(actual, truncateLength) + " " +
+ error.operator + " " + truncate(expected, truncateLength);
}
return message;
}
/**
* 2. The AssertionError is defined in assert.
*
* Example:
* new assert.AssertionError({
* message: message,
* actual: actual,
* expected: expected,
- * operator: operator
+ * operator: operator,
+ * truncate: truncate
* });
*
* At present only the four keys mentioned above are used and
* understood by the spec. Implementations or sub modules can pass
* other keys to the AssertionError's constructor - they will be
* ignored.
*/
Assert.AssertionError = function(options) {
this.name = "AssertionError";
this.actual = options.actual;
this.expected = options.expected;
this.operator = options.operator;
- this.message = getMessage(this, options.message);
+ this.message = getMessage(this, options.message, options.truncate);
// The part of the stack that comes from this module is not interesting.
let stack = Components.stack;
do {
stack = stack.asyncCaller || stack.caller;
} while (stack && stack.filename && stack.filename.includes("Assert.jsm"));
this.stack = stack;
};
@@ -183,23 +185,26 @@ proto.setReporter = function(reporterFun
* @param actual
* (mixed) The result of evaluating the assertion
* @param expected (optional)
* (mixed) Expected result from the test author
* @param message (optional)
* (string) Short explanation of the expected result
* @param operator (optional)
* (string) Operation qualifier used by the assertion method (ex: '==')
+ * @param truncate (optional) [true]
+ * (boolean) Whether or not `actual` and `expected` should be truncated when printing
*/
-proto.report = function(failed, actual, expected, message, operator) {
+proto.report = function(failed, actual, expected, message, operator, truncate = true) {
let err = new Assert.AssertionError({
message,
actual,
expected,
- operator
+ operator,
+ truncate
});
if (!this._reporter) {
// If no custom reporter is set, throw the error.
if (failed) {
throw err;
}
} else {
this._reporter(failed ? err : null, err.message, err.stack);
@@ -264,32 +269,32 @@ proto.notEqual = function notEqual(actua
* @param actual
* (mixed) Test subject to be evaluated as equivalent to `expected`, including nested properties
* @param expected
* (mixed) Test reference to evaluate against `actual`
* @param message (optional)
* (string) Short explanation of the expected result
*/
proto.deepEqual = function deepEqual(actual, expected, message) {
- this.report(!ObjectUtils.deepEqual(actual, expected), actual, expected, message, "deepEqual");
+ this.report(!ObjectUtils.deepEqual(actual, expected), actual, expected, message, "deepEqual", false);
};
/**
* 8. The non-equivalence assertion tests for any deep inequality.
* assert.notDeepEqual(actual, expected, message_opt);
*
* @param actual
* (mixed) Test subject to be evaluated as NOT equivalent to `expected`, including nested properties
* @param expected
* (mixed) Test reference to evaluate against `actual`
* @param message (optional)
* (string) Short explanation of the expected result
*/
proto.notDeepEqual = function notDeepEqual(actual, expected, message) {
- this.report(ObjectUtils.deepEqual(actual, expected), actual, expected, message, "notDeepEqual");
+ this.report(ObjectUtils.deepEqual(actual, expected), actual, expected, message, "notDeepEqual", false);
};
/**
* 9. The strict equality assertion tests strict equality, as determined by ===.
* assert.strictEqual(actual, expected, message_opt);
*
* @param actual
* (mixed) Test subject to be evaluated as strictly equivalent to `expected`
--- a/testing/modules/tests/xpcshell/test_assert.js
+++ b/testing/modules/tests/xpcshell/test_assert.js
@@ -265,16 +265,28 @@ function run_test() {
}
try {
assert.equal(1, 2, "oh no");
} catch (e) {
assert.equal(e.toString().split("\n")[0], "AssertionError: oh no - 1 == 2");
}
+ // Need to JSON.stringify so that their length is > 128 characters.
+ let longArray0 = Array.from(Array(50), (v, i) => i);
+ let longArray1 = longArray0.concat([51]);
+ try {
+ assert.deepEqual(longArray0, longArray1);
+ } catch (e) {
+ let message = e.toString();
+ // Just check that they're both entirely present in the message
+ assert.ok(message.includes(JSON.stringify(longArray0)));
+ assert.ok(message.includes(JSON.stringify(longArray1)));
+ }
+
// Test XPCShell-test integration:
ok(true, "OK, this went well");
deepEqual(/a/g, /a/g, "deep equal should work on RegExp");
deepEqual(/a/igm, /a/igm, "deep equal should work on RegExp");
deepEqual({a: 4, b: "1"}, {b: "1", a: 4}, "deep equal should work on regular Object");
deepEqual(a1, a2, "deep equal should work on Array with Object properties");
// Test robustness of reporting: