mirror of https://github.com/tc39/test262.git
Whitespace cleanups. CRLF => LF
This commit is contained in:
parent
bb6ce7e435
commit
d49777de27
54
LICENSE
54
LICENSE
|
@ -1,28 +1,28 @@
|
|||
The << Software identified by reference to the Ecma Standard* ("Software)">> is protected by copyright and is being
|
||||
made available under the "BSD License", included below. This Software may be subject to third party rights (rights
|
||||
from parties other than Ecma International), including patent rights, and no licenses under such third party rights
|
||||
are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA
|
||||
CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT http://www.ecma-international.org/memento/codeofconduct.htm FOR
|
||||
INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS*.
|
||||
|
||||
Copyright (C) 2012-2013 Ecma International
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
The << Software identified by reference to the Ecma Standard* ("Software)">> is protected by copyright and is being
|
||||
made available under the "BSD License", included below. This Software may be subject to third party rights (rights
|
||||
from parties other than Ecma International), including patent rights, and no licenses under such third party rights
|
||||
are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA
|
||||
CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT http://www.ecma-international.org/memento/codeofconduct.htm FOR
|
||||
INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS*.
|
||||
|
||||
Copyright (C) 2012-2013 Ecma International
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
* Ecma International Standards hereafter means Ecma International Standards as well as Ecma Technical Reports
|
|
@ -1,415 +1,273 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: |
|
||||
Compare two values structurally
|
||||
defines: [assert.deepEqual]
|
||||
---*/
|
||||
|
||||
// @ts-check
|
||||
|
||||
var deepEqual = (function () {
|
||||
/**
|
||||
* @typedef {0} UNKNOWN
|
||||
* @typedef {1} EQUAL
|
||||
* @typedef {-1} NOT_EQUAL
|
||||
* @typedef {Map<unknown, Map<unknown, EQUAL | NOT_EQUAL>>} ComparisonCache
|
||||
*/
|
||||
|
||||
/** @type {EQUAL} */
|
||||
var EQUAL = 1;
|
||||
|
||||
/** @type {NOT_EQUAL} */
|
||||
var NOT_EQUAL = -1;
|
||||
|
||||
/** @type {UNKNOWN} */
|
||||
var UNKNOWN = 0;
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T} a
|
||||
* @param {T} b
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function deepEqual(a, b) {
|
||||
return compareEquality(a, b) === EQUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {unknown} a
|
||||
* @param {unknown} b
|
||||
* @param {ComparisonCache} [cache]
|
||||
* @returns {EQUAL | NOT_EQUAL}
|
||||
*/
|
||||
function compareEquality(a, b, cache) {
|
||||
return compareIf(a, b, isOptional, compareOptionality)
|
||||
|| compareIf(a, b, isPrimitiveEquatable, comparePrimitiveEquality)
|
||||
|| compareIf(a, b, isObjectEquatable, compareObjectEquality, cache)
|
||||
|| NOT_EQUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {unknown} a
|
||||
* @param {unknown} b
|
||||
* @param {(value: unknown) => value is T} test
|
||||
* @param {(a: T, b: T, cache?: ComparisonCache) => EQUAL | NOT_EQUAL} compare
|
||||
* @param {ComparisonCache} [cache]
|
||||
* @returns {EQUAL | NOT_EQUAL | UNKNOWN}
|
||||
*/
|
||||
function compareIf(a, b, test, compare, cache) {
|
||||
return !test(a)
|
||||
? !test(b) ? UNKNOWN : NOT_EQUAL
|
||||
: !test(b) ? NOT_EQUAL : cacheComparison(a, b, compare, cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {EQUAL | UNKNOWN}
|
||||
*/
|
||||
function tryCompareStrictEquality(a, b) {
|
||||
return a === b ? EQUAL : UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {NOT_EQUAL | UNKNOWN}
|
||||
*/
|
||||
function tryCompareTypeOfEquality(a, b) {
|
||||
return typeof a !== typeof b ? NOT_EQUAL : UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {NOT_EQUAL | UNKNOWN}
|
||||
*/
|
||||
function tryCompareToStringTagEquality(a, b) {
|
||||
var aTag = Symbol.toStringTag in a ? a[Symbol.toStringTag] : undefined;
|
||||
var bTag = Symbol.toStringTag in b ? b[Symbol.toStringTag] : undefined;
|
||||
return aTag !== bTag ? NOT_EQUAL : UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {value is null | undefined}
|
||||
*/
|
||||
function isOptional(value) {
|
||||
return value === undefined
|
||||
|| value === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {EQUAL | NOT_EQUAL}
|
||||
*/
|
||||
function compareOptionality(a, b) {
|
||||
return tryCompareStrictEquality(a, b)
|
||||
|| NOT_EQUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {value is number | bigint | string | symbol | boolean | undefined}
|
||||
*/
|
||||
function isPrimitiveEquatable(value) {
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
case 'number':
|
||||
case 'bigint':
|
||||
case 'boolean':
|
||||
case 'symbol':
|
||||
return true;
|
||||
default:
|
||||
return isBoxed(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {EQUAL | NOT_EQUAL}
|
||||
*/
|
||||
function comparePrimitiveEquality(a, b) {
|
||||
if (isBoxed(a)) a = a.valueOf();
|
||||
if (isBoxed(b)) b = b.valueOf();
|
||||
return tryCompareStrictEquality(a, b)
|
||||
|| tryCompareTypeOfEquality(a, b)
|
||||
|| compareIf(a, b, isNaNEquatable, compareNaNEquality)
|
||||
|| NOT_EQUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {value is number}
|
||||
*/
|
||||
function isNaNEquatable(value) {
|
||||
return typeof value === 'number';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} a
|
||||
* @param {number} b
|
||||
* @returns {EQUAL | NOT_EQUAL}
|
||||
*/
|
||||
function compareNaNEquality(a, b) {
|
||||
return isNaN(a) && isNaN(b) ? EQUAL : NOT_EQUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {value is object}
|
||||
*/
|
||||
function isObjectEquatable(value) {
|
||||
return typeof value === 'object';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ComparisonCache} cache
|
||||
* @returns {EQUAL | NOT_EQUAL}
|
||||
*/
|
||||
function compareObjectEquality(a, b, cache) {
|
||||
if (!cache) cache = new Map();
|
||||
return getCache(cache, a, b)
|
||||
|| setCache(cache, a, b, EQUAL) // consider equal for now
|
||||
|| cacheComparison(a, b, tryCompareStrictEquality, cache)
|
||||
|| cacheComparison(a, b, tryCompareToStringTagEquality, cache)
|
||||
|| compareIf(a, b, isValueOfEquatable, compareValueOfEquality)
|
||||
|| compareIf(a, b, isToStringEquatable, compareToStringEquality)
|
||||
|| compareIf(a, b, isArrayLikeEquatable, compareArrayLikeEquality, cache)
|
||||
|| compareIf(a, b, isStructurallyEquatable, compareStructuralEquality, cache)
|
||||
|| compareIf(a, b, isIterableEquatable, compareIterableEquality, cache)
|
||||
|| cacheComparison(a, b, fail, cache);
|
||||
}
|
||||
|
||||
function isBoxed(value) {
|
||||
return value instanceof String
|
||||
|| value instanceof Number
|
||||
|| value instanceof Boolean
|
||||
|| typeof Symbol === 'function' && value instanceof Symbol
|
||||
|| typeof BigInt === 'function' && value instanceof BigInt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {value is { valueOf(): any }}
|
||||
*/
|
||||
function isValueOfEquatable(value) {
|
||||
return value instanceof Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ valueOf(): any }} a
|
||||
* @param {{ valueOf(): any }} b
|
||||
* @returns {EQUAL | NOT_EQUAL}
|
||||
*/
|
||||
function compareValueOfEquality(a, b) {
|
||||
return compareIf(a.valueOf(), b.valueOf(), isPrimitiveEquatable, comparePrimitiveEquality)
|
||||
|| NOT_EQUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {value is { toString(): string }}
|
||||
*/
|
||||
function isToStringEquatable(value) {
|
||||
return value instanceof RegExp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ toString(): string }} a
|
||||
* @param {{ toString(): string }} b
|
||||
* @returns {EQUAL | NOT_EQUAL}
|
||||
*/
|
||||
function compareToStringEquality(a, b) {
|
||||
return compareIf(a.toString(), b.toString(), isPrimitiveEquatable, comparePrimitiveEquality)
|
||||
|| NOT_EQUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {value is ArrayLike<unknown>}
|
||||
*/
|
||||
function isArrayLikeEquatable(value) {
|
||||
return (Array.isArray ? Array.isArray(value) : value instanceof Array)
|
||||
|| (typeof Uint8Array === 'function' && value instanceof Uint8Array)
|
||||
|| (typeof Uint8ClampedArray === 'function' && value instanceof Uint8ClampedArray)
|
||||
|| (typeof Uint16Array === 'function' && value instanceof Uint16Array)
|
||||
|| (typeof Uint32Array === 'function' && value instanceof Uint32Array)
|
||||
|| (typeof Int8Array === 'function' && value instanceof Int8Array)
|
||||
|| (typeof Int16Array === 'function' && value instanceof Int16Array)
|
||||
|| (typeof Int32Array === 'function' && value instanceof Int32Array)
|
||||
|| (typeof Float32Array === 'function' && value instanceof Float32Array)
|
||||
|| (typeof Float64Array === 'function' && value instanceof Float64Array)
|
||||
|| (typeof BigUint64Array === 'function' && value instanceof BigUint64Array)
|
||||
|| (typeof BigInt64Array === 'function' && value instanceof BigInt64Array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {ArrayLike<T>} a
|
||||
* @param {ArrayLike<T>} b
|
||||
* @param {ComparisonCache} cache
|
||||
* @returns {EQUAL | NOT_EQUAL}
|
||||
*/
|
||||
function compareArrayLikeEquality(a, b, cache) {
|
||||
if (a.length !== b.length) return NOT_EQUAL;
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
if (compareEquality(a[i], b[i], cache) === NOT_EQUAL) {
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
}
|
||||
return EQUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T} value
|
||||
* @returns {value is Exclude<T, Promise | WeakMap | WeakSet | Map | Set>}
|
||||
*/
|
||||
function isStructurallyEquatable(value) {
|
||||
return !(typeof Promise === 'function' && value instanceof Promise // only comparable by reference
|
||||
|| typeof WeakMap === 'function' && value instanceof WeakMap // only comparable by reference
|
||||
|| typeof WeakSet === 'function' && value instanceof WeakSet // only comparable by reference
|
||||
|| typeof Map === 'function' && value instanceof Map // comparable via @@iterator
|
||||
|| typeof Set === 'function' && value instanceof Set); // comparable via @@iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ComparisonCache} cache
|
||||
* @returns {EQUAL | NOT_EQUAL}
|
||||
*/
|
||||
function compareStructuralEquality(a, b, cache) {
|
||||
var aKeys = [];
|
||||
for (var key in a) aKeys.push(key);
|
||||
|
||||
var bKeys = [];
|
||||
for (var key in b) bKeys.push(key);
|
||||
|
||||
if (aKeys.length !== bKeys.length) {
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
|
||||
aKeys.sort();
|
||||
bKeys.sort();
|
||||
|
||||
for (var i = 0; i < aKeys.length; i++) {
|
||||
var aKey = aKeys[i];
|
||||
var bKey = bKeys[i];
|
||||
if (compareEquality(aKey, bKey, cache) === NOT_EQUAL) {
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
if (compareEquality(a[aKey], b[bKey], cache) === NOT_EQUAL) {
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
}
|
||||
|
||||
return compareIf(a, b, isIterableEquatable, compareIterableEquality, cache)
|
||||
|| EQUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {value is Iterable<unknown>}
|
||||
*/
|
||||
function isIterableEquatable(value) {
|
||||
return typeof Symbol === 'function'
|
||||
&& typeof value[Symbol.iterator] === 'function';
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {Iterator<T>} a
|
||||
* @param {Iterator<T>} b
|
||||
* @param {ComparisonCache} cache
|
||||
* @returns {EQUAL | NOT_EQUAL}
|
||||
*/
|
||||
function compareIteratorEquality(a, b, cache) {
|
||||
if (typeof Map === 'function' && a instanceof Map && b instanceof Map ||
|
||||
typeof Set === 'function' && a instanceof Set && b instanceof Set) {
|
||||
if (a.size !== b.size) return NOT_EQUAL; // exit early if we detect a difference in size
|
||||
}
|
||||
|
||||
var ar, br;
|
||||
while (true) {
|
||||
ar = a.next();
|
||||
br = b.next();
|
||||
if (ar.done) {
|
||||
if (br.done) return EQUAL;
|
||||
if (b.return) b.return();
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
if (br.done) {
|
||||
if (a.return) a.return();
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
if (compareEquality(ar.value, br.value, cache) === NOT_EQUAL) {
|
||||
if (a.return) a.return();
|
||||
if (b.return) b.return();
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {Iterable<T>} a
|
||||
* @param {Iterable<T>} b
|
||||
* @param {ComparisonCache} cache
|
||||
* @returns {EQUAL | NOT_EQUAL}
|
||||
*/
|
||||
function compareIterableEquality(a, b, cache) {
|
||||
return compareIteratorEquality(a[Symbol.iterator](), b[Symbol.iterator](), cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @template {EQUAL | NOT_EQUAL | UNKNOWN} R
|
||||
* @param {(a: T, b: T, circular?: ComparisonCache) => R} compare
|
||||
* @param {ComparisonCache} [cache]
|
||||
*/
|
||||
function cacheComparison(a, b, compare, cache) {
|
||||
var result = compare(a, b, cache);
|
||||
if (cache && (result === EQUAL || result === NOT_EQUAL)) {
|
||||
setCache(cache, a, b, /** @type {EQUAL | NOT_EQUAL} */(result));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function fail() {
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {EQUAL | NOT_EQUAL} result
|
||||
* @param {ComparisonCache} cache
|
||||
*/
|
||||
function setCache(cache, left, right, result) {
|
||||
var otherCache;
|
||||
|
||||
otherCache = cache.get(left);
|
||||
if (!otherCache) cache.set(left, otherCache = new Map());
|
||||
otherCache.set(right, result);
|
||||
|
||||
otherCache = cache.get(right);
|
||||
if (!otherCache) cache.set(right, otherCache = new Map());
|
||||
otherCache.set(left, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ComparisonCache} cache
|
||||
*/
|
||||
function getCache(cache, left, right) {
|
||||
var otherCache;
|
||||
/** @type {EQUAL | NOT_EQUAL | UNKNOWN | undefined} */
|
||||
var result;
|
||||
|
||||
otherCache = cache.get(left);
|
||||
result = otherCache && otherCache.get(right);
|
||||
if (result) return result;
|
||||
|
||||
otherCache = cache.get(right);
|
||||
result = otherCache && otherCache.get(left);
|
||||
if (result) return result;
|
||||
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
return deepEqual;
|
||||
})();
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T} actual
|
||||
* @param {T} expected
|
||||
* @param {string} [message]
|
||||
*/
|
||||
assert.deepEqual = function (actual, expected, message) {
|
||||
assert(deepEqual(actual, expected),
|
||||
'Expected ' + assert._formatValue(actual) + ' to be structurally equal to ' + assert._formatValue(expected) + '. ' + (message || ''));
|
||||
};
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
description: >
|
||||
Compare two values structurally
|
||||
defines: [assert.deepEqual]
|
||||
---*/
|
||||
|
||||
var deepEqual = (function () {
|
||||
var EQUAL = 1;
|
||||
var NOT_EQUAL = -1;
|
||||
var UNKNOWN = 0;
|
||||
|
||||
function deepEqual(a, b) {
|
||||
return compareEquality(a, b) === EQUAL;
|
||||
}
|
||||
|
||||
function compareEquality(a, b, cache) {
|
||||
return compareIf(a, b, isOptional, compareOptionality)
|
||||
|| compareIf(a, b, isPrimitiveEquatable, comparePrimitiveEquality)
|
||||
|| compareIf(a, b, isObjectEquatable, compareObjectEquality, cache)
|
||||
|| NOT_EQUAL;
|
||||
}
|
||||
|
||||
function compareIf(a, b, test, compare, cache) {
|
||||
return !test(a)
|
||||
? !test(b) ? UNKNOWN : NOT_EQUAL
|
||||
: !test(b) ? NOT_EQUAL : cacheComparison(a, b, compare, cache);
|
||||
}
|
||||
|
||||
function tryCompareStrictEquality(a, b) {
|
||||
return a === b ? EQUAL : UNKNOWN;
|
||||
}
|
||||
|
||||
function tryCompareTypeOfEquality(a, b) {
|
||||
return typeof a !== typeof b ? NOT_EQUAL : UNKNOWN;
|
||||
}
|
||||
|
||||
function tryCompareToStringTagEquality(a, b) {
|
||||
var aTag = Symbol.toStringTag in a ? a[Symbol.toStringTag] : undefined;
|
||||
var bTag = Symbol.toStringTag in b ? b[Symbol.toStringTag] : undefined;
|
||||
return aTag !== bTag ? NOT_EQUAL : UNKNOWN;
|
||||
}
|
||||
|
||||
function isOptional(value) {
|
||||
return value === undefined
|
||||
|| value === null;
|
||||
}
|
||||
|
||||
function compareOptionality(a, b) {
|
||||
return tryCompareStrictEquality(a, b)
|
||||
|| NOT_EQUAL;
|
||||
}
|
||||
|
||||
function isPrimitiveEquatable(value) {
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
case 'number':
|
||||
case 'bigint':
|
||||
case 'boolean':
|
||||
case 'symbol':
|
||||
return true;
|
||||
default:
|
||||
return isBoxed(value);
|
||||
}
|
||||
}
|
||||
|
||||
function comparePrimitiveEquality(a, b) {
|
||||
if (isBoxed(a)) a = a.valueOf();
|
||||
if (isBoxed(b)) b = b.valueOf();
|
||||
return tryCompareStrictEquality(a, b)
|
||||
|| tryCompareTypeOfEquality(a, b)
|
||||
|| compareIf(a, b, isNaNEquatable, compareNaNEquality)
|
||||
|| NOT_EQUAL;
|
||||
}
|
||||
|
||||
function isNaNEquatable(value) {
|
||||
return typeof value === 'number';
|
||||
}
|
||||
|
||||
function compareNaNEquality(a, b) {
|
||||
return isNaN(a) && isNaN(b) ? EQUAL : NOT_EQUAL;
|
||||
}
|
||||
|
||||
function isObjectEquatable(value) {
|
||||
return typeof value === 'object';
|
||||
}
|
||||
|
||||
function compareObjectEquality(a, b, cache) {
|
||||
if (!cache) cache = new Map();
|
||||
return getCache(cache, a, b)
|
||||
|| setCache(cache, a, b, EQUAL) // consider equal for now
|
||||
|| cacheComparison(a, b, tryCompareStrictEquality, cache)
|
||||
|| cacheComparison(a, b, tryCompareToStringTagEquality, cache)
|
||||
|| compareIf(a, b, isValueOfEquatable, compareValueOfEquality)
|
||||
|| compareIf(a, b, isToStringEquatable, compareToStringEquality)
|
||||
|| compareIf(a, b, isArrayLikeEquatable, compareArrayLikeEquality, cache)
|
||||
|| compareIf(a, b, isStructurallyEquatable, compareStructuralEquality, cache)
|
||||
|| compareIf(a, b, isIterableEquatable, compareIterableEquality, cache)
|
||||
|| cacheComparison(a, b, fail, cache);
|
||||
}
|
||||
|
||||
function isBoxed(value) {
|
||||
return value instanceof String
|
||||
|| value instanceof Number
|
||||
|| value instanceof Boolean
|
||||
|| typeof Symbol === 'function' && value instanceof Symbol
|
||||
|| typeof BigInt === 'function' && value instanceof BigInt;
|
||||
}
|
||||
|
||||
function isValueOfEquatable(value) {
|
||||
return value instanceof Date;
|
||||
}
|
||||
|
||||
function compareValueOfEquality(a, b) {
|
||||
return compareIf(a.valueOf(), b.valueOf(), isPrimitiveEquatable, comparePrimitiveEquality)
|
||||
|| NOT_EQUAL;
|
||||
}
|
||||
|
||||
function isToStringEquatable(value) {
|
||||
return value instanceof RegExp;
|
||||
}
|
||||
|
||||
function compareToStringEquality(a, b) {
|
||||
return compareIf(a.toString(), b.toString(), isPrimitiveEquatable, comparePrimitiveEquality)
|
||||
|| NOT_EQUAL;
|
||||
}
|
||||
|
||||
function isArrayLikeEquatable(value) {
|
||||
return (Array.isArray ? Array.isArray(value) : value instanceof Array)
|
||||
|| (typeof Uint8Array === 'function' && value instanceof Uint8Array)
|
||||
|| (typeof Uint8ClampedArray === 'function' && value instanceof Uint8ClampedArray)
|
||||
|| (typeof Uint16Array === 'function' && value instanceof Uint16Array)
|
||||
|| (typeof Uint32Array === 'function' && value instanceof Uint32Array)
|
||||
|| (typeof Int8Array === 'function' && value instanceof Int8Array)
|
||||
|| (typeof Int16Array === 'function' && value instanceof Int16Array)
|
||||
|| (typeof Int32Array === 'function' && value instanceof Int32Array)
|
||||
|| (typeof Float32Array === 'function' && value instanceof Float32Array)
|
||||
|| (typeof Float64Array === 'function' && value instanceof Float64Array)
|
||||
|| (typeof BigUint64Array === 'function' && value instanceof BigUint64Array)
|
||||
|| (typeof BigInt64Array === 'function' && value instanceof BigInt64Array);
|
||||
}
|
||||
|
||||
function compareArrayLikeEquality(a, b, cache) {
|
||||
if (a.length !== b.length) return NOT_EQUAL;
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
if (compareEquality(a[i], b[i], cache) === NOT_EQUAL) {
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
}
|
||||
return EQUAL;
|
||||
}
|
||||
|
||||
function isStructurallyEquatable(value) {
|
||||
return !(typeof Promise === 'function' && value instanceof Promise // only comparable by reference
|
||||
|| typeof WeakMap === 'function' && value instanceof WeakMap // only comparable by reference
|
||||
|| typeof WeakSet === 'function' && value instanceof WeakSet // only comparable by reference
|
||||
|| typeof Map === 'function' && value instanceof Map // comparable via @@iterator
|
||||
|| typeof Set === 'function' && value instanceof Set); // comparable via @@iterator
|
||||
}
|
||||
|
||||
function compareStructuralEquality(a, b, cache) {
|
||||
var aKeys = [];
|
||||
for (var key in a) aKeys.push(key);
|
||||
|
||||
var bKeys = [];
|
||||
for (var key in b) bKeys.push(key);
|
||||
|
||||
if (aKeys.length !== bKeys.length) {
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
|
||||
aKeys.sort();
|
||||
bKeys.sort();
|
||||
|
||||
for (var i = 0; i < aKeys.length; i++) {
|
||||
var aKey = aKeys[i];
|
||||
var bKey = bKeys[i];
|
||||
if (compareEquality(aKey, bKey, cache) === NOT_EQUAL) {
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
if (compareEquality(a[aKey], b[bKey], cache) === NOT_EQUAL) {
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
}
|
||||
|
||||
return compareIf(a, b, isIterableEquatable, compareIterableEquality, cache)
|
||||
|| EQUAL;
|
||||
}
|
||||
|
||||
function isIterableEquatable(value) {
|
||||
return typeof Symbol === 'function'
|
||||
&& typeof value[Symbol.iterator] === 'function';
|
||||
}
|
||||
|
||||
function compareIteratorEquality(a, b, cache) {
|
||||
if (typeof Map === 'function' && a instanceof Map && b instanceof Map ||
|
||||
typeof Set === 'function' && a instanceof Set && b instanceof Set) {
|
||||
if (a.size !== b.size) return NOT_EQUAL; // exit early if we detect a difference in size
|
||||
}
|
||||
|
||||
var ar, br;
|
||||
while (true) {
|
||||
ar = a.next();
|
||||
br = b.next();
|
||||
if (ar.done) {
|
||||
if (br.done) return EQUAL;
|
||||
if (b.return) b.return();
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
if (br.done) {
|
||||
if (a.return) a.return();
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
if (compareEquality(ar.value, br.value, cache) === NOT_EQUAL) {
|
||||
if (a.return) a.return();
|
||||
if (b.return) b.return();
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function compareIterableEquality(a, b, cache) {
|
||||
return compareIteratorEquality(a[Symbol.iterator](), b[Symbol.iterator](), cache);
|
||||
}
|
||||
|
||||
function cacheComparison(a, b, compare, cache) {
|
||||
var result = compare(a, b, cache);
|
||||
if (cache && (result === EQUAL || result === NOT_EQUAL)) {
|
||||
setCache(cache, a, b, /** @type {EQUAL | NOT_EQUAL} */(result));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function fail() {
|
||||
return NOT_EQUAL;
|
||||
}
|
||||
|
||||
function setCache(cache, left, right, result) {
|
||||
var otherCache;
|
||||
|
||||
otherCache = cache.get(left);
|
||||
if (!otherCache) cache.set(left, otherCache = new Map());
|
||||
otherCache.set(right, result);
|
||||
|
||||
otherCache = cache.get(right);
|
||||
if (!otherCache) cache.set(right, otherCache = new Map());
|
||||
otherCache.set(left, result);
|
||||
}
|
||||
|
||||
function getCache(cache, left, right) {
|
||||
var otherCache;
|
||||
/** @type {EQUAL | NOT_EQUAL | UNKNOWN | undefined} */
|
||||
var result;
|
||||
|
||||
otherCache = cache.get(left);
|
||||
result = otherCache && otherCache.get(right);
|
||||
if (result) return result;
|
||||
|
||||
otherCache = cache.get(right);
|
||||
result = otherCache && otherCache.get(left);
|
||||
if (result) return result;
|
||||
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
return deepEqual;
|
||||
})();
|
||||
|
||||
assert.deepEqual = function (actual, expected, message) {
|
||||
assert(deepEqual(actual, expected),
|
||||
'Expected ' + assert._formatValue(actual) + ' to be structurally equal to ' + assert._formatValue(expected) + '. ' + (message || ''));
|
||||
};
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
declare function $ERROR(text: string): void;
|
||||
|
||||
// Proposal: regexp-match-indices
|
||||
interface RegExpExecArray {
|
||||
indices: RegExpIndicesArray;
|
||||
}
|
||||
|
||||
interface RegExpMatchArray {
|
||||
indices: RegExpIndicesArray;
|
||||
}
|
||||
|
||||
interface RegExpIndicesArray extends Array<[number, number]> {
|
||||
groups?: { [group: string]: [number, number] };
|
||||
}
|
|
@ -1,28 +1,27 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: A matching element of indices is an Array with exactly two number properties.
|
||||
esid: sec-getmatchindicesarray
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
GetMatchIndicesArray ( S, match )
|
||||
5. Return CreateArrayFromList(« _match_.[[StartIndex]], _match_.[[EndIndex]] »).
|
||||
---*/
|
||||
|
||||
|
||||
let input = "abcd";
|
||||
let match = /b(c)/.exec(input);
|
||||
let indices = match.indices;
|
||||
|
||||
// `indices[0]` is an array
|
||||
assert.sameValue(Object.getPrototypeOf(indices[0]), Array.prototype);
|
||||
assert.sameValue(indices[0].length, 2);
|
||||
assert.sameValue(typeof indices[0][0], "number");
|
||||
assert.sameValue(typeof indices[0][1], "number");
|
||||
|
||||
// `indices[1]` is an array
|
||||
assert.sameValue(Object.getPrototypeOf(indices[1]), Array.prototype);
|
||||
assert.sameValue(indices[1].length, 2);
|
||||
assert.sameValue(typeof indices[1][0], "number");
|
||||
assert.sameValue(typeof indices[1][1], "number");
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: A matching element of indices is an Array with exactly two number properties.
|
||||
esid: sec-getmatchindicesarray
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
GetMatchIndicesArray ( S, match )
|
||||
5. Return CreateArrayFromList(« _match_.[[StartIndex]], _match_.[[EndIndex]] »).
|
||||
---*/
|
||||
|
||||
let input = "abcd";
|
||||
let match = /b(c)/.exec(input);
|
||||
let indices = match.indices;
|
||||
|
||||
// `indices[0]` is an array
|
||||
assert.sameValue(Object.getPrototypeOf(indices[0]), Array.prototype);
|
||||
assert.sameValue(indices[0].length, 2);
|
||||
assert.sameValue(typeof indices[0][0], "number");
|
||||
assert.sameValue(typeof indices[0][1], "number");
|
||||
|
||||
// `indices[1]` is an array
|
||||
assert.sameValue(Object.getPrototypeOf(indices[1]), Array.prototype);
|
||||
assert.sameValue(indices[1].length, 2);
|
||||
assert.sameValue(typeof indices[1][0], "number");
|
||||
assert.sameValue(typeof indices[1][1], "number");
|
||||
|
|
|
@ -1,39 +1,38 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: The properties of the "indices" array correspond to the start/end indices of the same values in the match.
|
||||
includes: [compareArray.js]
|
||||
esid: sec-makeindicesarray
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
MakeIndicesArray ( S, indices, groupNames )
|
||||
4. Let _n_ be the number of elements in _indices_.
|
||||
...
|
||||
6. Set _A_ to ! ArrayCreate(_n_).
|
||||
...
|
||||
11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
|
||||
a. Let _matchIndices_ be _indices_[_i_].
|
||||
b. If _matchIndices_ is not *undefined*, then
|
||||
i. Let _matchIndicesArray_ be ! GetMatchIndicesArray(_S_, _matchIndices_).
|
||||
c. Else,
|
||||
i. Let _matchIndicesArray_ be *undefined*.
|
||||
d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
|
||||
...
|
||||
---*/
|
||||
|
||||
|
||||
let input = "abcd";
|
||||
let match = /b(c)/.exec(input);
|
||||
let indices = match.indices;
|
||||
|
||||
// `indices` has the same length as match
|
||||
assert.sameValue(indices.length, match.length);
|
||||
|
||||
// The first element of `indices` contains the start/end indices of the match
|
||||
assert.compareArray(indices[0], [1, 3]);
|
||||
assert.sameValue(input.slice(indices[0][0], indices[0][1]), match[0]);
|
||||
|
||||
// The second element of `indices` contains the start/end indices of the first capture
|
||||
assert.compareArray(indices[1], [2, 3]);
|
||||
assert.sameValue(input.slice(indices[1][0], indices[1][1]), match[1]);
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: The properties of the "indices" array correspond to the start/end indices of the same values in the match.
|
||||
includes: [compareArray.js]
|
||||
esid: sec-makeindicesarray
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
MakeIndicesArray ( S, indices, groupNames )
|
||||
4. Let _n_ be the number of elements in _indices_.
|
||||
...
|
||||
6. Set _A_ to ! ArrayCreate(_n_).
|
||||
...
|
||||
11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
|
||||
a. Let _matchIndices_ be _indices_[_i_].
|
||||
b. If _matchIndices_ is not *undefined*, then
|
||||
i. Let _matchIndicesArray_ be ! GetMatchIndicesArray(_S_, _matchIndices_).
|
||||
c. Else,
|
||||
i. Let _matchIndicesArray_ be *undefined*.
|
||||
d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
|
||||
...
|
||||
---*/
|
||||
|
||||
let input = "abcd";
|
||||
let match = /b(c)/.exec(input);
|
||||
let indices = match.indices;
|
||||
|
||||
// `indices` has the same length as match
|
||||
assert.sameValue(indices.length, match.length);
|
||||
|
||||
// The first element of `indices` contains the start/end indices of the match
|
||||
assert.compareArray(indices[0], [1, 3]);
|
||||
assert.sameValue(input.slice(indices[0][0], indices[0][1]), match[0]);
|
||||
|
||||
// The second element of `indices` contains the start/end indices of the first capture
|
||||
assert.compareArray(indices[1], [2, 3]);
|
||||
assert.sameValue(input.slice(indices[1][0], indices[1][1]), match[1]);
|
||||
|
|
|
@ -1,76 +1,75 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Basic matching cases with non-unicode matches.
|
||||
includes: [compareArray.js, propertyHelper.js, deepEqual.js]
|
||||
esid: sec-regexpbuiltinexec
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
Runtime Semantics: RegExpBuiltinExec ( R, S )
|
||||
...
|
||||
4. Let _lastIndex_ be ? ToLength(? Get(_R_, `"lastIndex")).
|
||||
...
|
||||
25. Let _indices_ be a new empty List.
|
||||
26. Let _match_ be the Match { [[StartIndex]]: _lastIndex_, [[EndIndex]]: _e_ }.
|
||||
27. Add _match_ as the last element of _indices_.
|
||||
...
|
||||
33. For each integer _i_ such that _i_ > 0 and _i_ <= _n_, in ascending order, do
|
||||
...
|
||||
f. Else,
|
||||
i. Let _captureStart_ be _captureI_'s _startIndex_.
|
||||
ii. Let _captureEnd_ be _captureI_'s _endIndex_.
|
||||
...
|
||||
iv. Let _capture_ be the Match { [[StartIndex]]: _captureStart_, [[EndIndex]]: _captureEnd_ }.
|
||||
v. Append _capture_ to _indices_.
|
||||
...
|
||||
34. Let _indicesArray_ be MakeIndicesArray( _S_, _indices_, _groupNames_).
|
||||
---*/
|
||||
|
||||
|
||||
assert.deepEqual([[1, 2], [1, 2]], "bab".match(/(a)/).indices);
|
||||
assert.deepEqual([[0, 3], [1, 2]], "bab".match(/.(a)./).indices);
|
||||
assert.deepEqual([[0, 3], [1, 2], [2, 3]], "bab".match(/.(a)(.)/).indices);
|
||||
assert.deepEqual([[0, 3], [1, 3]], "bab".match(/.(\w\w)/).indices);
|
||||
assert.deepEqual([[0, 3], [0, 3]], "bab".match(/(\w\w\w)/).indices);
|
||||
assert.deepEqual([[0, 3], [0, 2], [2, 3]], "bab".match(/(\w\w)(\w)/).indices);
|
||||
assert.deepEqual([[0, 2], [0, 2], undefined], "bab".match(/(\w\w)(\W)?/).indices);
|
||||
|
||||
let groups = /(?<a>.)(?<b>.)(?<c>.)\k<c>\k<b>\k<a>/.exec("abccba").indices.groups;
|
||||
assert.compareArray([0, 1], groups.a);
|
||||
assert.compareArray([1, 2], groups.b);
|
||||
assert.compareArray([2, 3], groups.c);
|
||||
verifyProperty(groups, "a", {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
verifyProperty(groups, "b", {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
verifyProperty(groups, "c", {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
// "𝐁" is U+1d401 MATHEMATICAL BOLD CAPITAL B
|
||||
// - Also representable as the code point "\u{1d401}"
|
||||
// - Also representable as the surrogate pair "\uD835\uDC01"
|
||||
|
||||
// Verify assumptions:
|
||||
assert.sameValue("𝐁".length, 2, 'The length of "𝐁" is 2');
|
||||
assert.sameValue("\u{1d401}".length, 2, 'The length of "\\u{1d401}" is 2');
|
||||
assert.sameValue("\uD835\uDC01".length, 2, 'The length of "\\uD835\\uDC01" is 2');
|
||||
assert.sameValue("𝐁".match(/./)[0].length, 1, 'The length of a single code unit match against "𝐁" is 1 (without /u flag)');
|
||||
assert.sameValue("\u{1d401}".match(/./)[0].length, 1, 'The length of a single code unit match against "\\u{1d401}" is 1 (without /u flag)');
|
||||
assert.sameValue("\uD835\uDC01".match(/./)[0].length, 1, 'The length of a single code unit match against "\\ud835\\udc01" is 1 (without /u flag)');
|
||||
|
||||
assert.compareArray([0, 1], "𝐁".match(/./).indices[0], 'Indices for non-unicode match against "𝐁" (without /u flag)');
|
||||
assert.compareArray([0, 1], "\u{1d401}".match(/./).indices[0], 'Indices for non-unicode match against "\\u{1d401}" (without /u flag)');
|
||||
assert.compareArray([0, 1], "\uD835\uDC01".match(/./).indices[0], 'Indices for non-unicode match against "\\ud835\\udc01" (without /u flag)');
|
||||
assert.compareArray([0, 1], "𝐁".match(/(?<a>.)/).indices.groups.a, 'Indices for non-unicode match against "𝐁" in groups.a (without /u flag)');
|
||||
assert.compareArray([0, 1], "\u{1d401}".match(/(?<a>.)/).indices.groups.a, 'Indices for non-unicode match against "\\u{1d401}" in groups.a (without /u flag)');
|
||||
assert.compareArray([0, 1], "\uD835\uDC01".match(/(?<a>.)/).indices.groups.a, 'Indices for non-unicode match against "\\ud835\\udc01" in groups.a (without /u flag)');
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Basic matching cases with non-unicode matches.
|
||||
includes: [compareArray.js, propertyHelper.js, deepEqual.js]
|
||||
esid: sec-regexpbuiltinexec
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
Runtime Semantics: RegExpBuiltinExec ( R, S )
|
||||
...
|
||||
4. Let _lastIndex_ be ? ToLength(? Get(_R_, `"lastIndex")).
|
||||
...
|
||||
25. Let _indices_ be a new empty List.
|
||||
26. Let _match_ be the Match { [[StartIndex]]: _lastIndex_, [[EndIndex]]: _e_ }.
|
||||
27. Add _match_ as the last element of _indices_.
|
||||
...
|
||||
33. For each integer _i_ such that _i_ > 0 and _i_ <= _n_, in ascending order, do
|
||||
...
|
||||
f. Else,
|
||||
i. Let _captureStart_ be _captureI_'s _startIndex_.
|
||||
ii. Let _captureEnd_ be _captureI_'s _endIndex_.
|
||||
...
|
||||
iv. Let _capture_ be the Match { [[StartIndex]]: _captureStart_, [[EndIndex]]: _captureEnd_ }.
|
||||
v. Append _capture_ to _indices_.
|
||||
...
|
||||
34. Let _indicesArray_ be MakeIndicesArray( _S_, _indices_, _groupNames_).
|
||||
---*/
|
||||
|
||||
assert.deepEqual([[1, 2], [1, 2]], "bab".match(/(a)/).indices);
|
||||
assert.deepEqual([[0, 3], [1, 2]], "bab".match(/.(a)./).indices);
|
||||
assert.deepEqual([[0, 3], [1, 2], [2, 3]], "bab".match(/.(a)(.)/).indices);
|
||||
assert.deepEqual([[0, 3], [1, 3]], "bab".match(/.(\w\w)/).indices);
|
||||
assert.deepEqual([[0, 3], [0, 3]], "bab".match(/(\w\w\w)/).indices);
|
||||
assert.deepEqual([[0, 3], [0, 2], [2, 3]], "bab".match(/(\w\w)(\w)/).indices);
|
||||
assert.deepEqual([[0, 2], [0, 2], undefined], "bab".match(/(\w\w)(\W)?/).indices);
|
||||
|
||||
let groups = /(?<a>.)(?<b>.)(?<c>.)\k<c>\k<b>\k<a>/.exec("abccba").indices.groups;
|
||||
assert.compareArray([0, 1], groups.a);
|
||||
assert.compareArray([1, 2], groups.b);
|
||||
assert.compareArray([2, 3], groups.c);
|
||||
verifyProperty(groups, "a", {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
verifyProperty(groups, "b", {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
verifyProperty(groups, "c", {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
// "𝐁" is U+1d401 MATHEMATICAL BOLD CAPITAL B
|
||||
// - Also representable as the code point "\u{1d401}"
|
||||
// - Also representable as the surrogate pair "\uD835\uDC01"
|
||||
|
||||
// Verify assumptions:
|
||||
assert.sameValue("𝐁".length, 2, 'The length of "𝐁" is 2');
|
||||
assert.sameValue("\u{1d401}".length, 2, 'The length of "\\u{1d401}" is 2');
|
||||
assert.sameValue("\uD835\uDC01".length, 2, 'The length of "\\uD835\\uDC01" is 2');
|
||||
assert.sameValue("𝐁".match(/./)[0].length, 1, 'The length of a single code unit match against "𝐁" is 1 (without /u flag)');
|
||||
assert.sameValue("\u{1d401}".match(/./)[0].length, 1, 'The length of a single code unit match against "\\u{1d401}" is 1 (without /u flag)');
|
||||
assert.sameValue("\uD835\uDC01".match(/./)[0].length, 1, 'The length of a single code unit match against "\\ud835\\udc01" is 1 (without /u flag)');
|
||||
|
||||
assert.compareArray([0, 1], "𝐁".match(/./).indices[0], 'Indices for non-unicode match against "𝐁" (without /u flag)');
|
||||
assert.compareArray([0, 1], "\u{1d401}".match(/./).indices[0], 'Indices for non-unicode match against "\\u{1d401}" (without /u flag)');
|
||||
assert.compareArray([0, 1], "\uD835\uDC01".match(/./).indices[0], 'Indices for non-unicode match against "\\ud835\\udc01" (without /u flag)');
|
||||
assert.compareArray([0, 1], "𝐁".match(/(?<a>.)/).indices.groups.a, 'Indices for non-unicode match against "𝐁" in groups.a (without /u flag)');
|
||||
assert.compareArray([0, 1], "\u{1d401}".match(/(?<a>.)/).indices.groups.a, 'Indices for non-unicode match against "\\u{1d401}" in groups.a (without /u flag)');
|
||||
assert.compareArray([0, 1], "\uD835\uDC01".match(/(?<a>.)/).indices.groups.a, 'Indices for non-unicode match against "\\ud835\\udc01" in groups.a (without /u flag)');
|
||||
|
|
|
@ -1,30 +1,29 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: The properties of the "indices" array are created with CreateDataProperty.
|
||||
includes: [propertyHelper.js]
|
||||
esid: sec-makeindicesarray
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
MakeIndicesArray ( S, indices, groupNames )
|
||||
11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
|
||||
d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
|
||||
---*/
|
||||
|
||||
|
||||
let input = "abcd";
|
||||
let match = /b(c)/.exec(input);
|
||||
let indices = match.indices;
|
||||
|
||||
verifyProperty(indices, '0', {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
|
||||
verifyProperty(indices, '1', {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: The properties of the "indices" array are created with CreateDataProperty.
|
||||
includes: [propertyHelper.js]
|
||||
esid: sec-makeindicesarray
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
MakeIndicesArray ( S, indices, groupNames )
|
||||
11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
|
||||
d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
|
||||
---*/
|
||||
|
||||
let input = "abcd";
|
||||
let match = /b(c)/.exec(input);
|
||||
let indices = match.indices;
|
||||
|
||||
verifyProperty(indices, '0', {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
|
||||
verifyProperty(indices, '1', {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
|
|
|
@ -1,85 +1,84 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Basic matching cases with non-unicode matches.
|
||||
includes: [compareArray.js, propertyHelper.js, deepEqual.js]
|
||||
esid: sec-regexpbuiltinexec
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
Runtime Semantics: RegExpBuiltinExec ( R, S )
|
||||
...
|
||||
4. Let _lastIndex_ be ? ToLength(? Get(_R_, `"lastIndex")).
|
||||
...
|
||||
16. If _fullUnicode_ is *true*, set _e_ to ! GetStringIndex(_S_, _Input_, _e_).
|
||||
...
|
||||
25. Let _indices_ be a new empty List.
|
||||
26. Let _match_ be the Match { [[StartIndex]]: _lastIndex_, [[EndIndex]]: _e_ }.
|
||||
27. Add _match_ as the last element of _indices_.
|
||||
...
|
||||
33. For each integer _i_ such that _i_ > 0 and _i_ <= _n_, in ascending order, do
|
||||
...
|
||||
f. Else,
|
||||
i. Let _captureStart_ be _captureI_'s _startIndex_.
|
||||
ii. Let _captureEnd_ be _captureI_'s _endIndex_.
|
||||
iii. If _fullUnicode_ is *true*, then
|
||||
1. Set _captureStart_ to ! GetStringIndex(_S_, _Input_, _captureStart_).
|
||||
1. Set _captureEnd_ to ! GetStringIndex(_S_, _Input_, _captureEnd_).
|
||||
iv. Let _capture_ be the Match { [[StartIndex]]: _captureStart_, [[EndIndex]]: _captureEnd_ }.
|
||||
v. Append _capture_ to _indices_.
|
||||
...
|
||||
34. Let _indicesArray_ be MakeIndicesArray( _S_, _indices_, _groupNames_).
|
||||
|
||||
GetStringIndex ( S, Input, e )
|
||||
...
|
||||
4. Let _eUTF_ be the smallest index into _S_ that corresponds to the character at element _e_ of _Input_. If _e_ is greater than or equal to the number of elements in _Input_, then _eUTF_ is the number of code units in _S_.
|
||||
5. Return _eUTF_.
|
||||
---*/
|
||||
|
||||
|
||||
assert.deepEqual([[1, 2], [1, 2]], "bab".match(/(a)/u).indices);
|
||||
assert.deepEqual([[0, 3], [1, 2]], "bab".match(/.(a)./u).indices);
|
||||
assert.deepEqual([[0, 3], [1, 2], [2, 3]], "bab".match(/.(a)(.)/u).indices);
|
||||
assert.deepEqual([[0, 3], [1, 3]], "bab".match(/.(\w\w)/u).indices);
|
||||
assert.deepEqual([[0, 3], [0, 3]], "bab".match(/(\w\w\w)/u).indices);
|
||||
assert.deepEqual([[0, 3], [0, 2], [2, 3]], "bab".match(/(\w\w)(\w)/u).indices);
|
||||
assert.deepEqual([[0, 2], [0, 2], undefined], "bab".match(/(\w\w)(\W)?/u).indices);
|
||||
|
||||
let groups = /(?<a>.)(?<b>.)(?<c>.)\k<c>\k<b>\k<a>/u.exec("abccba").indices.groups;
|
||||
assert.compareArray([0, 1], groups.a);
|
||||
assert.compareArray([1, 2], groups.b);
|
||||
assert.compareArray([2, 3], groups.c);
|
||||
verifyProperty(groups, "a", {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
verifyProperty(groups, "b", {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
verifyProperty(groups, "c", {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
// "𝐁" is U+1d401 MATHEMATICAL BOLD CAPITAL B
|
||||
// - Also representable as the code point "\u{1d401}"
|
||||
// - Also representable as the surrogate pair "\uD835\uDC01"
|
||||
|
||||
// Verify assumptions:
|
||||
assert.sameValue("𝐁".length, 2, 'The length of "𝐁" is 2');
|
||||
assert.sameValue("\u{1d401}".length, 2, 'The length of "\\u{1d401}" is 2');
|
||||
assert.sameValue("\uD835\uDC01".length, 2, 'The length of "\\uD835\\uDC01" is 2');
|
||||
assert.sameValue(2, "𝐁".match(/./u)[0].length, 'The length of a single code point match against "𝐁" is 2 (with /u flag)');
|
||||
assert.sameValue(2, "\u{1d401}".match(/./u)[0].length, 'The length of a single code point match against "\\u{1d401}" is 2 (with /u flag)');
|
||||
assert.sameValue(2, "\uD835\uDC01".match(/./u)[0].length, 'The length of a single code point match against "\\ud835\\udc01" is 2 (with /u flag)');
|
||||
|
||||
assert.compareArray([0, 2], "𝐁".match(/./u).indices[0], 'Indices for unicode match against "𝐁" (with /u flag)');
|
||||
assert.compareArray([0, 2], "\u{1d401}".match(/./u).indices[0], 'Indices for unicode match against \\u{1d401} (with /u flag)');
|
||||
assert.compareArray([0, 2], "\uD835\uDC01".match(/./u).indices[0], 'Indices for unicode match against \\ud835\\udc01 (with /u flag)');
|
||||
assert.compareArray([0, 2], "𝐁".match(/(?<a>.)/u).indices.groups.a, 'Indices for unicode match against 𝐁 in groups.a (with /u flag)');
|
||||
assert.compareArray([0, 2], "\u{1d401}".match(/(?<a>.)/u).indices.groups.a, 'Indices for unicode match against \\u{1d401} in groups.a (with /u flag)');
|
||||
assert.compareArray([0, 2], "\uD835\uDC01".match(/(?<a>.)/u).indices.groups.a, 'Indices for unicode match against \\ud835\\udc01 in groups.a (with /u flag)');
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Basic matching cases with non-unicode matches.
|
||||
includes: [compareArray.js, propertyHelper.js, deepEqual.js]
|
||||
esid: sec-regexpbuiltinexec
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
Runtime Semantics: RegExpBuiltinExec ( R, S )
|
||||
...
|
||||
4. Let _lastIndex_ be ? ToLength(? Get(_R_, `"lastIndex")).
|
||||
...
|
||||
16. If _fullUnicode_ is *true*, set _e_ to ! GetStringIndex(_S_, _Input_, _e_).
|
||||
...
|
||||
25. Let _indices_ be a new empty List.
|
||||
26. Let _match_ be the Match { [[StartIndex]]: _lastIndex_, [[EndIndex]]: _e_ }.
|
||||
27. Add _match_ as the last element of _indices_.
|
||||
...
|
||||
33. For each integer _i_ such that _i_ > 0 and _i_ <= _n_, in ascending order, do
|
||||
...
|
||||
f. Else,
|
||||
i. Let _captureStart_ be _captureI_'s _startIndex_.
|
||||
ii. Let _captureEnd_ be _captureI_'s _endIndex_.
|
||||
iii. If _fullUnicode_ is *true*, then
|
||||
1. Set _captureStart_ to ! GetStringIndex(_S_, _Input_, _captureStart_).
|
||||
1. Set _captureEnd_ to ! GetStringIndex(_S_, _Input_, _captureEnd_).
|
||||
iv. Let _capture_ be the Match { [[StartIndex]]: _captureStart_, [[EndIndex]]: _captureEnd_ }.
|
||||
v. Append _capture_ to _indices_.
|
||||
...
|
||||
34. Let _indicesArray_ be MakeIndicesArray( _S_, _indices_, _groupNames_).
|
||||
|
||||
GetStringIndex ( S, Input, e )
|
||||
...
|
||||
4. Let _eUTF_ be the smallest index into _S_ that corresponds to the character at element _e_ of _Input_. If _e_ is greater than or equal to the number of elements in _Input_, then _eUTF_ is the number of code units in _S_.
|
||||
5. Return _eUTF_.
|
||||
---*/
|
||||
|
||||
assert.deepEqual([[1, 2], [1, 2]], "bab".match(/(a)/u).indices);
|
||||
assert.deepEqual([[0, 3], [1, 2]], "bab".match(/.(a)./u).indices);
|
||||
assert.deepEqual([[0, 3], [1, 2], [2, 3]], "bab".match(/.(a)(.)/u).indices);
|
||||
assert.deepEqual([[0, 3], [1, 3]], "bab".match(/.(\w\w)/u).indices);
|
||||
assert.deepEqual([[0, 3], [0, 3]], "bab".match(/(\w\w\w)/u).indices);
|
||||
assert.deepEqual([[0, 3], [0, 2], [2, 3]], "bab".match(/(\w\w)(\w)/u).indices);
|
||||
assert.deepEqual([[0, 2], [0, 2], undefined], "bab".match(/(\w\w)(\W)?/u).indices);
|
||||
|
||||
let groups = /(?<a>.)(?<b>.)(?<c>.)\k<c>\k<b>\k<a>/u.exec("abccba").indices.groups;
|
||||
assert.compareArray([0, 1], groups.a);
|
||||
assert.compareArray([1, 2], groups.b);
|
||||
assert.compareArray([2, 3], groups.c);
|
||||
verifyProperty(groups, "a", {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
verifyProperty(groups, "b", {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
verifyProperty(groups, "c", {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
// "𝐁" is U+1d401 MATHEMATICAL BOLD CAPITAL B
|
||||
// - Also representable as the code point "\u{1d401}"
|
||||
// - Also representable as the surrogate pair "\uD835\uDC01"
|
||||
|
||||
// Verify assumptions:
|
||||
assert.sameValue("𝐁".length, 2, 'The length of "𝐁" is 2');
|
||||
assert.sameValue("\u{1d401}".length, 2, 'The length of "\\u{1d401}" is 2');
|
||||
assert.sameValue("\uD835\uDC01".length, 2, 'The length of "\\uD835\\uDC01" is 2');
|
||||
assert.sameValue(2, "𝐁".match(/./u)[0].length, 'The length of a single code point match against "𝐁" is 2 (with /u flag)');
|
||||
assert.sameValue(2, "\u{1d401}".match(/./u)[0].length, 'The length of a single code point match against "\\u{1d401}" is 2 (with /u flag)');
|
||||
assert.sameValue(2, "\uD835\uDC01".match(/./u)[0].length, 'The length of a single code point match against "\\ud835\\udc01" is 2 (with /u flag)');
|
||||
|
||||
assert.compareArray([0, 2], "𝐁".match(/./u).indices[0], 'Indices for unicode match against "𝐁" (with /u flag)');
|
||||
assert.compareArray([0, 2], "\u{1d401}".match(/./u).indices[0], 'Indices for unicode match against \\u{1d401} (with /u flag)');
|
||||
assert.compareArray([0, 2], "\uD835\uDC01".match(/./u).indices[0], 'Indices for unicode match against \\ud835\\udc01 (with /u flag)');
|
||||
assert.compareArray([0, 2], "𝐁".match(/(?<a>.)/u).indices.groups.a, 'Indices for unicode match against 𝐁 in groups.a (with /u flag)');
|
||||
assert.compareArray([0, 2], "\u{1d401}".match(/(?<a>.)/u).indices.groups.a, 'Indices for unicode match against \\u{1d401} in groups.a (with /u flag)');
|
||||
assert.compareArray([0, 2], "\uD835\uDC01".match(/(?<a>.)/u).indices.groups.a, 'Indices for unicode match against \\ud835\\udc01 in groups.a (with /u flag)');
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Basic matching cases with non-unicode matches.
|
||||
includes: [compareArray.js]
|
||||
esid: sec-makeindicesarray
|
||||
features: [regexp-match-indices]
|
||||
---*/
|
||||
|
||||
|
||||
assert.compareArray([1, 2], /(?<π>a)/u.exec("bab").indices.groups.π);
|
||||
assert.compareArray([1, 2], /(?<\u{03C0}>a)/u.exec("bab").indices.groups.π);
|
||||
assert.compareArray([1, 2], /(?<π>a)/u.exec("bab").indices.groups.\u03C0);
|
||||
assert.compareArray([1, 2], /(?<\u{03C0}>a)/u.exec("bab").indices.groups.\u03C0);
|
||||
assert.compareArray([1, 2], /(?<$>a)/u.exec("bab").indices.groups.$);
|
||||
assert.compareArray([1, 2], /(?<_>a)/u.exec("bab").indices.groups._);
|
||||
assert.compareArray([1, 2], /(?<$𐒤>a)/u.exec("bab").indices.groups.$𐒤);
|
||||
assert.compareArray([1, 2], /(?<_\u200C>a)/u.exec("bab").indices.groups._\u200C);
|
||||
assert.compareArray([1, 2], /(?<_\u200D>a)/u.exec("bab").indices.groups._\u200D);
|
||||
assert.compareArray([1, 2], /(?<ಠ_ಠ>a)/u.exec("bab").indices.groups.ಠ_ಠ);
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: Basic matching cases with non-unicode matches.
|
||||
includes: [compareArray.js]
|
||||
esid: sec-makeindicesarray
|
||||
features: [regexp-match-indices]
|
||||
---*/
|
||||
|
||||
assert.compareArray([1, 2], /(?<π>a)/u.exec("bab").indices.groups.π);
|
||||
assert.compareArray([1, 2], /(?<\u{03C0}>a)/u.exec("bab").indices.groups.π);
|
||||
assert.compareArray([1, 2], /(?<π>a)/u.exec("bab").indices.groups.\u03C0);
|
||||
assert.compareArray([1, 2], /(?<\u{03C0}>a)/u.exec("bab").indices.groups.\u03C0);
|
||||
assert.compareArray([1, 2], /(?<$>a)/u.exec("bab").indices.groups.$);
|
||||
assert.compareArray([1, 2], /(?<_>a)/u.exec("bab").indices.groups._);
|
||||
assert.compareArray([1, 2], /(?<$𐒤>a)/u.exec("bab").indices.groups.$𐒤);
|
||||
assert.compareArray([1, 2], /(?<_\u200C>a)/u.exec("bab").indices.groups._\u200C);
|
||||
assert.compareArray([1, 2], /(?<_\u200D>a)/u.exec("bab").indices.groups._\u200D);
|
||||
assert.compareArray([1, 2], /(?<ಠ_ಠ>a)/u.exec("bab").indices.groups.ಠ_ಠ);
|
||||
|
|
|
@ -1,33 +1,32 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: An unmatched capture in a match corresponds to an unmatched capture in "indices"
|
||||
esid: sec-makeindicesarray
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
MakeIndicesArray ( S, indices, groupNames )
|
||||
4. Let _n_ be the number of elements in _indices_.
|
||||
...
|
||||
6. Set _A_ to ! ArrayCreate(_n_).
|
||||
...
|
||||
11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
|
||||
a. Let _matchIndices_ be _indices_[_i_].
|
||||
b. If _matchIndices_ is not *undefined*, then
|
||||
i. Let _matchIndicesArray_ be ! GetMatchIndicesArray(_S_, _matchIndices_).
|
||||
c. Else,
|
||||
i. Let _matchIndicesArray_ be *undefined*.
|
||||
d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
|
||||
...
|
||||
---*/
|
||||
|
||||
|
||||
let input = "abd";
|
||||
let match = /b(c)?/.exec(input);
|
||||
let indices = match.indices;
|
||||
|
||||
// `indices` has the same length as match
|
||||
assert.sameValue(indices.length, match.length);
|
||||
|
||||
// The second element of `indices` should be undefined.
|
||||
assert.sameValue(indices[1], undefined);
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: An unmatched capture in a match corresponds to an unmatched capture in "indices"
|
||||
esid: sec-makeindicesarray
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
MakeIndicesArray ( S, indices, groupNames )
|
||||
4. Let _n_ be the number of elements in _indices_.
|
||||
...
|
||||
6. Set _A_ to ! ArrayCreate(_n_).
|
||||
...
|
||||
11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
|
||||
a. Let _matchIndices_ be _indices_[_i_].
|
||||
b. If _matchIndices_ is not *undefined*, then
|
||||
i. Let _matchIndicesArray_ be ! GetMatchIndicesArray(_S_, _matchIndices_).
|
||||
c. Else,
|
||||
i. Let _matchIndicesArray_ be *undefined*.
|
||||
d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
|
||||
...
|
||||
---*/
|
||||
|
||||
let input = "abd";
|
||||
let match = /b(c)?/.exec(input);
|
||||
let indices = match.indices;
|
||||
|
||||
// `indices` has the same length as match
|
||||
assert.sameValue(indices.length, match.length);
|
||||
|
||||
// The second element of `indices` should be undefined.
|
||||
assert.sameValue(indices[1], undefined);
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: The "indices" property is an Array.
|
||||
esid: sec-makeindicesarray
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
MakeIndicesArray ( S, indices, groupNames )
|
||||
6. Set _A_ to ! ArrayCreate(_n_).
|
||||
---*/
|
||||
|
||||
|
||||
let match = /a/.exec("a");
|
||||
let indices = match.indices;
|
||||
|
||||
// `indices` is an array
|
||||
assert.sameValue(Object.getPrototypeOf(indices), Array.prototype);
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: The "indices" property is an Array.
|
||||
esid: sec-makeindicesarray
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
MakeIndicesArray ( S, indices, groupNames )
|
||||
6. Set _A_ to ! ArrayCreate(_n_).
|
||||
---*/
|
||||
|
||||
let match = /a/.exec("a");
|
||||
let indices = match.indices;
|
||||
|
||||
// `indices` is an array
|
||||
assert.sameValue(Object.getPrototypeOf(indices), Array.prototype);
|
||||
assert(Array.isArray(indices));
|
|
@ -1,30 +1,29 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: The "indices" property is created with DefinePropertyOrThrow
|
||||
includes: [propertyHelper.js]
|
||||
esid: sec-regexpbuiltinexec
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
Runtime Semantics: RegExpBuiltinExec ( R, S )
|
||||
34. Let _indicesArray_ be MakeIndicesArray(_S_, _indices_, _groupNames_).
|
||||
35. Perform ! DefinePropertyOrThrow(_A_, `"indices"`, PropertyDescriptor { [[Value]]: _indicesArray_, [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }).
|
||||
---*/
|
||||
|
||||
|
||||
// `indices` is created with Define, not Set.
|
||||
let counter = 0;
|
||||
Object.defineProperty(Array.prototype, "indices", {
|
||||
set() { counter++; }
|
||||
});
|
||||
|
||||
let match = /a/.exec("a");
|
||||
assert.sameValue(counter, 0);
|
||||
|
||||
// `indices` is a non-writable, non-enumerable, and configurable data-property.
|
||||
verifyProperty(match, 'indices', {
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: The "indices" property is created with DefinePropertyOrThrow
|
||||
includes: [propertyHelper.js]
|
||||
esid: sec-regexpbuiltinexec
|
||||
features: [regexp-match-indices]
|
||||
info: |
|
||||
Runtime Semantics: RegExpBuiltinExec ( R, S )
|
||||
34. Let _indicesArray_ be MakeIndicesArray(_S_, _indices_, _groupNames_).
|
||||
35. Perform ! DefinePropertyOrThrow(_A_, `"indices"`, PropertyDescriptor { [[Value]]: _indicesArray_, [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }).
|
||||
---*/
|
||||
|
||||
// `indices` is created with Define, not Set.
|
||||
let counter = 0;
|
||||
Object.defineProperty(Array.prototype, "indices", {
|
||||
set() { counter++; }
|
||||
});
|
||||
|
||||
let match = /a/.exec("a");
|
||||
assert.sameValue(counter, 0);
|
||||
|
||||
// `indices` is a non-writable, non-enumerable, and configurable data-property.
|
||||
verifyProperty(match, 'indices', {
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
array values compare correctly.
|
||||
includes: [deepEqual.js]
|
||||
---*/
|
||||
|
||||
|
||||
assert.deepEqual([], []);
|
||||
assert.deepEqual([1, "a", true], [1, "a", true]);
|
||||
|
||||
assert.throws(Test262Error, function () { assert.deepEqual([], [1]); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual([1, "a", true], [1, "a", false]); });
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
array values compare correctly.
|
||||
includes: [deepEqual.js]
|
||||
---*/
|
||||
|
||||
assert.deepEqual([], []);
|
||||
assert.deepEqual([1, "a", true], [1, "a", true]);
|
||||
|
||||
assert.throws(Test262Error, function () { assert.deepEqual([], [1]); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual([1, "a", true], [1, "a", false]); });
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
values compare correctly with circular references.
|
||||
includes: [deepEqual.js]
|
||||
---*/
|
||||
|
||||
|
||||
var a = { x: 1 };
|
||||
var b = { x: 1 };
|
||||
a.a = a;
|
||||
a.b = b;
|
||||
b.a = b;
|
||||
b.b = a;
|
||||
|
||||
assert.deepEqual(a, b);
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
values compare correctly with circular references.
|
||||
includes: [deepEqual.js]
|
||||
---*/
|
||||
|
||||
var a = { x: 1 };
|
||||
var b = { x: 1 };
|
||||
a.a = a;
|
||||
a.b = b;
|
||||
b.a = b;
|
||||
b.b = a;
|
||||
|
||||
assert.deepEqual(a, b);
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
values compare correctly.
|
||||
includes: [deepEqual.js]
|
||||
---*/
|
||||
|
||||
|
||||
assert.deepEqual({ a: { x: 1 }, b: [true] }, { a: { x: 1 }, b: [true] });
|
||||
|
||||
assert.throws(Test262Error, function () { assert.deepEqual({}, { a: { x: 1 }, b: [true] }); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual({ a: { x: 1 }, b: [true] }, { a: { x: 1 }, b: [false] }); });
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
values compare correctly.
|
||||
includes: [deepEqual.js]
|
||||
---*/
|
||||
|
||||
assert.deepEqual({ a: { x: 1 }, b: [true] }, { a: { x: 1 }, b: [true] });
|
||||
|
||||
assert.throws(Test262Error, function () { assert.deepEqual({}, { a: { x: 1 }, b: [true] }); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual({ a: { x: 1 }, b: [true] }, { a: { x: 1 }, b: [false] }); });
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
map/set values compare correctly.
|
||||
includes: [deepEqual.js]
|
||||
---*/
|
||||
|
||||
|
||||
assert.deepEqual(new Set(), new Set());
|
||||
assert.deepEqual(new Set([1, "a", true]), new Set([1, "a", true]));
|
||||
assert.deepEqual(new Map(), new Map());
|
||||
assert.deepEqual(new Map([[1, "a"], ["b", true]]), new Map([[1, "a"], ["b", true]]));
|
||||
|
||||
assert.throws(Test262Error, function () { assert.deepEqual(new Set([]), new Set([1])); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual(new Set([1, "a", true]), new Set([1, "a", false])); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual(new Map([]), new Map([[1, "a"], ["b", true]])); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual(new Map([[1, "a"], ["b", true]]), new Map([[1, "a"], ["b", false]])); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual(new Map([[1, "a"], ["b", true]]), new Set([[1, "a"], ["b", false]])); });
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
map/set values compare correctly.
|
||||
includes: [deepEqual.js]
|
||||
---*/
|
||||
|
||||
assert.deepEqual(new Set(), new Set());
|
||||
assert.deepEqual(new Set([1, "a", true]), new Set([1, "a", true]));
|
||||
assert.deepEqual(new Map(), new Map());
|
||||
assert.deepEqual(new Map([[1, "a"], ["b", true]]), new Map([[1, "a"], ["b", true]]));
|
||||
|
||||
assert.throws(Test262Error, function () { assert.deepEqual(new Set([]), new Set([1])); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual(new Set([1, "a", true]), new Set([1, "a", false])); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual(new Map([]), new Map([[1, "a"], ["b", true]])); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual(new Map([[1, "a"], ["b", true]]), new Map([[1, "a"], ["b", false]])); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual(new Map([[1, "a"], ["b", true]]), new Set([[1, "a"], ["b", false]])); });
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
object values compare correctly.
|
||||
includes: [deepEqual.js]
|
||||
---*/
|
||||
|
||||
|
||||
assert.deepEqual({}, {});
|
||||
assert.deepEqual({ a: 1, b: true }, { a: 1, b: true });
|
||||
|
||||
assert.throws(Test262Error, function () { assert.deepEqual({}, { a: 1, b: true }); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual({ a: 1, b: true }, { a: 1, b: false }); });
|
||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
description: >
|
||||
object values compare correctly.
|
||||
includes: [deepEqual.js]
|
||||
---*/
|
||||
|
||||
|
||||
assert.deepEqual({}, {});
|
||||
assert.deepEqual({ a: 1, b: true }, { a: 1, b: true });
|
||||
|
||||
assert.throws(Test262Error, function () { assert.deepEqual({}, { a: 1, b: true }); });
|
||||
assert.throws(Test262Error, function () { assert.deepEqual({ a: 1, b: true }, { a: 1, b: false }); });
|
||||
|
|
Loading…
Reference in New Issue