diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2555b5a572..8331a39b73 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -290,6 +290,7 @@ Function | Purpose `assert.sameValue(actual, expected, message)` | throw a new Test262Error instance if the first two arguments are not [the same value](https://tc39.github.io/ecma262/#sec-samevalue); accepts an optional string message explaining the scenario and what should have happened `assert.notSameValue(actual, unexpected, message)` | throw a new Test262Error instance if the first two arguments are [the same value](https://tc39.github.io/ecma262/#sec-samevalue); accepts an optional string message explaining the scenario and what should have happened `assert.throws(expectedErrorConstructor, fn, message)` | throw a new Test262Error instance if the provided function does not throw an error or if the constructor of the value thrown does not match the provided constructor; accepts an optional string message explaining the scenario and what should have happened +`assert.compareArray(actual, expected, message)` | throw a new Test262Error instance if the first two arguments have differing `length` or there is an array index less than that length at which their respective elements are not [the same value](https://tc39.github.io/ecma262/#sec-samevalue); accepts an optional string message explaining the scenario and what should have happened `$DONOTEVALUATE()` | throw an exception if the code gets evaluated. This may only be used in [negative test cases for parsing errors](#handling-errors-and-negative-test-cases). `throw "Test262: This statement should not be evaluated.";` | throw an exception if the code gets evaluated. Use this if the test file has the `raw` flag and it's a negative test case for parsing error. diff --git a/harness/assert.js b/harness/assert.js index 70fb490fd9..7ced0cd0b4 100644 --- a/harness/assert.js +++ b/harness/assert.js @@ -101,6 +101,45 @@ assert.throws = function (expectedErrorConstructor, func, message) { throw new Test262Error(message); }; +function isPrimitive(value) { + return !value || (typeof value !== 'object' && typeof value !== 'function'); +} + +assert.compareArray = function (actual, expected, message) { + message = message === undefined ? '' : message; + + if (typeof message === 'symbol') { + message = message.toString(); + } + + if (isPrimitive(actual)) { + assert(false, `Actual argument [${actual}] shouldn't be primitive. ${message}`); + } else if (isPrimitive(expected)) { + assert(false, `Expected argument [${expected}] shouldn't be primitive. ${message}`); + } + var result = compareArray(actual, expected); + if (result) return; + + var format = compareArray.format; + assert(false, `Actual ${format(actual)} and expected ${format(expected)} should have the same contents. ${message}`); +}; + +function compareArray(a, b) { + if (b.length !== a.length) { + return false; + } + for (var i = 0; i < a.length; i++) { + if (!assert._isSameValue(b[i], a[i])) { + return false; + } + } + return true; +} + +compareArray.format = function (arrayLike) { + return `[${Array.prototype.map.call(arrayLike, String).join(', ')}]`; +}; + assert._formatIdentityFreeValue = function formatIdentityFreeValue(value) { switch (value === null ? 'null' : typeof value) { case 'string': diff --git a/harness/compareArray.js b/harness/compareArray.js index 2af35eeae3..dfeef3fe6b 100644 --- a/harness/compareArray.js +++ b/harness/compareArray.js @@ -2,49 +2,6 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- description: | - Compare the contents of two arrays + Deprecated now that compareArray is defined in assert.js. defines: [compareArray] ---*/ - -function compareArray(a, b) { - if (b.length !== a.length) { - return false; - } - - for (var i = 0; i < a.length; i++) { - if (!compareArray.isSameValue(b[i], a[i])) { - return false; - } - } - return true; -} - -compareArray.isSameValue = function(a, b) { - if (a === 0 && b === 0) return 1 / a === 1 / b; - if (a !== a && b !== b) return true; - - return a === b; -}; - -compareArray.format = function(arrayLike) { - return `[${[].map.call(arrayLike, String).join(', ')}]`; -}; - -assert.compareArray = function(actual, expected, message) { - message = message === undefined ? '' : message; - - if (typeof message === 'symbol') { - message = message.toString(); - } - - assert(actual != null, `Actual argument shouldn't be nullish. ${message}`); - assert(expected != null, `Expected argument shouldn't be nullish. ${message}`); - var format = compareArray.format; - var result = compareArray(actual, expected); - - // The following prevents actual and expected from being iterated and evaluated - // more than once unless absolutely necessary. - if (!result) { - assert(false, `Actual ${format(actual)} and expected ${format(expected)} should have the same contents. ${message}`); - } -}; diff --git a/test/harness/compare-array-falsy-arguments.js b/test/harness/compare-array-falsy-arguments.js index 1b17976401..9cbc38acd2 100644 --- a/test/harness/compare-array-falsy-arguments.js +++ b/test/harness/compare-array-falsy-arguments.js @@ -20,9 +20,9 @@ function assertThrows(func, errorMessage) { assert(caught, `Expected ${func} to throw, but it didn't.`); } -assertThrows(() => assert.compareArray(), "Actual argument shouldn't be nullish. "); -assertThrows(() => assert.compareArray(null, []), "Actual argument shouldn't be nullish. "); -assertThrows(() => assert.compareArray(null, [], "foo"), "Actual argument shouldn't be nullish. foo"); +assertThrows(() => assert.compareArray(), "Actual argument [undefined] shouldn't be primitive. "); +assertThrows(() => assert.compareArray(null, []), "Actual argument [null] shouldn't be primitive. "); +assertThrows(() => assert.compareArray(null, [], "foo"), "Actual argument [null] shouldn't be primitive. foo"); -assertThrows(() => assert.compareArray([]), "Expected argument shouldn't be nullish. "); -assertThrows(() => assert.compareArray([], undefined, "foo"), "Expected argument shouldn't be nullish. foo"); +assertThrows(() => assert.compareArray([]), "Expected argument [undefined] shouldn't be primitive. "); +assertThrows(() => assert.compareArray([], undefined, "foo"), "Expected argument [undefined] shouldn't be primitive. foo"); diff --git a/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-replace.js b/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-replace.js index cf4d9e5368..72abd134ff 100644 --- a/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-replace.js +++ b/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-replace.js @@ -4,25 +4,24 @@ /*--- description: Test replace function with duplicate names in alteration. features: [regexp-duplicate-named-groups] -includes: [compareArray.js] ---*/ -assert.compareArray( +assert.sameValue( '2xyy', 'xxyy'.replace(/(?:(?:(?x)|(?y))\k)/, '2$')); -assert.compareArray( +assert.sameValue( 'x2zyyxxy', 'xzzyyxxy'.replace( /(?:(?:(?x)|(?y)|(a)|(?b)|(?z))\k)/, '2$')); -assert.compareArray( +assert.sameValue( '2x(x,)yy', 'xxyy'.replace(/(?:(?:(?x)|(?y))\k)/, '2$($1,$2)')); -assert.compareArray( +assert.sameValue( 'x2z(,,,,z)yyxxy', 'xzzyyxxy'.replace( /(?:(?:(?x)|(?y)|(a)|(?b)|(?z))\k)/, '2$($1,$2,$3,$4,$5)')); -assert.compareArray( +assert.sameValue( '2x2y', 'xxyy'.replace(/(?:(?:(?x)|(?y))\k)/g, '2$')); -assert.compareArray( +assert.sameValue( 'x2z2y2xy', 'xzzyyxxy'.replace( /(?:(?:(?x)|(?y)|(a)|(?b)|(?z))\k)/g, '2$')); diff --git a/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-search.js b/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-search.js index 3796b5bc41..7d3b31b3b4 100644 --- a/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-search.js +++ b/test/staging/built-ins/RegExp/named-groups/duplicate-named-groups-search.js @@ -4,10 +4,9 @@ /*--- description: Test search function with duplicate names in alteration. features: [regexp-duplicate-named-groups] -includes: [compareArray.js] ---*/ -assert.compareArray(3, 'abcxyz'.search(/(?x)|(?y)/)); -assert.compareArray(3, 'abcxyz'.search(/(?y)|(?x)/)); -assert.compareArray(1, 'aybcxyz'.search(/(?x)|(?y)/)); -assert.compareArray(1, 'aybcxyz'.search(/(?y)|(?x)/)); +assert.sameValue(3, 'abcxyz'.search(/(?x)|(?y)/)); +assert.sameValue(3, 'abcxyz'.search(/(?y)|(?x)/)); +assert.sameValue(1, 'aybcxyz'.search(/(?x)|(?y)/)); +assert.sameValue(1, 'aybcxyz'.search(/(?y)|(?x)/)); diff --git a/test/staging/sm/String/AdvanceStringIndex.js b/test/staging/sm/String/AdvanceStringIndex.js index b474c0bee9..ab00180990 100644 --- a/test/staging/sm/String/AdvanceStringIndex.js +++ b/test/staging/sm/String/AdvanceStringIndex.js @@ -21,19 +21,19 @@ assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".match(/\uD83D\uDC38| // ==== String.prototype.replace ==== // empty string replacement (optimized) -assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D|X|/gu, ""), +assert.sameValue("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D|X|/gu, ""), "\uD83D\uDC38\uD83D\uDC39\uD83D\uDC3A"); -assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uDC38|X|/gu, ""), +assert.sameValue("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uDC38|X|/gu, ""), "\uD83D\uDC38\uD83D\uDC39\uD83D\uDC3A"); -assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D\uDC38|X|/gu, ""), +assert.sameValue("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D\uDC38|X|/gu, ""), "\uD83D\uDC39\uD83D\uDC3A"); // non-empty string replacement -assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D|X|/gu, "x"), +assert.sameValue("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D|X|/gu, "x"), "x\uD83D\uDC38x\uD83D\uDC39xx\uD83D\uDC3Ax"); -assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uDC38|X|/gu, "x"), +assert.sameValue("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uDC38|X|/gu, "x"), "x\uD83D\uDC38x\uD83D\uDC39xx\uD83D\uDC3Ax"); -assert.compareArray("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D\uDC38|X|/gu, "x"), +assert.sameValue("\uD83D\uDC38\uD83D\uDC39X\uD83D\uDC3A".replace(/\uD83D\uDC38|X|/gu, "x"), "xx\uD83D\uDC39xx\uD83D\uDC3Ax"); // ==== String.prototype.split ====