mirror of
https://github.com/tc39/test262.git
synced 2025-07-23 05:55:36 +02:00
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
|
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
|
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
|
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
|
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
|
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*.
|
INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS*.
|
||||||
|
|
||||||
Copyright (C) 2012-2013 Ecma International
|
Copyright (C) 2012-2013 Ecma International
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
||||||
following conditions are met:
|
following conditions are met:
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
|
||||||
disclaimer.
|
disclaimer.
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
|
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.
|
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
|
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 without specific prior written permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
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
|
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
|
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
|
(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
|
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
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
DAMAGE.
|
DAMAGE.
|
||||||
|
|
||||||
* Ecma International Standards hereafter means Ecma International Standards as well as Ecma Technical Reports
|
* 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.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
/*---
|
/*---
|
||||||
description: |
|
description: >
|
||||||
Compare two values structurally
|
Compare two values structurally
|
||||||
defines: [assert.deepEqual]
|
defines: [assert.deepEqual]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// @ts-check
|
var deepEqual = (function () {
|
||||||
|
var EQUAL = 1;
|
||||||
var deepEqual = (function () {
|
var NOT_EQUAL = -1;
|
||||||
/**
|
var UNKNOWN = 0;
|
||||||
* @typedef {0} UNKNOWN
|
|
||||||
* @typedef {1} EQUAL
|
function deepEqual(a, b) {
|
||||||
* @typedef {-1} NOT_EQUAL
|
return compareEquality(a, b) === EQUAL;
|
||||||
* @typedef {Map<unknown, Map<unknown, EQUAL | NOT_EQUAL>>} ComparisonCache
|
}
|
||||||
*/
|
|
||||||
|
function compareEquality(a, b, cache) {
|
||||||
/** @type {EQUAL} */
|
return compareIf(a, b, isOptional, compareOptionality)
|
||||||
var EQUAL = 1;
|
|| compareIf(a, b, isPrimitiveEquatable, comparePrimitiveEquality)
|
||||||
|
|| compareIf(a, b, isObjectEquatable, compareObjectEquality, cache)
|
||||||
/** @type {NOT_EQUAL} */
|
|| NOT_EQUAL;
|
||||||
var NOT_EQUAL = -1;
|
}
|
||||||
|
|
||||||
/** @type {UNKNOWN} */
|
function compareIf(a, b, test, compare, cache) {
|
||||||
var UNKNOWN = 0;
|
return !test(a)
|
||||||
|
? !test(b) ? UNKNOWN : NOT_EQUAL
|
||||||
/**
|
: !test(b) ? NOT_EQUAL : cacheComparison(a, b, compare, cache);
|
||||||
* @template T
|
}
|
||||||
* @param {T} a
|
|
||||||
* @param {T} b
|
function tryCompareStrictEquality(a, b) {
|
||||||
* @returns {boolean}
|
return a === b ? EQUAL : UNKNOWN;
|
||||||
*/
|
}
|
||||||
function deepEqual(a, b) {
|
|
||||||
return compareEquality(a, b) === EQUAL;
|
function tryCompareTypeOfEquality(a, b) {
|
||||||
}
|
return typeof a !== typeof b ? NOT_EQUAL : UNKNOWN;
|
||||||
|
}
|
||||||
/**
|
|
||||||
* @param {unknown} a
|
function tryCompareToStringTagEquality(a, b) {
|
||||||
* @param {unknown} b
|
var aTag = Symbol.toStringTag in a ? a[Symbol.toStringTag] : undefined;
|
||||||
* @param {ComparisonCache} [cache]
|
var bTag = Symbol.toStringTag in b ? b[Symbol.toStringTag] : undefined;
|
||||||
* @returns {EQUAL | NOT_EQUAL}
|
return aTag !== bTag ? NOT_EQUAL : UNKNOWN;
|
||||||
*/
|
}
|
||||||
function compareEquality(a, b, cache) {
|
|
||||||
return compareIf(a, b, isOptional, compareOptionality)
|
function isOptional(value) {
|
||||||
|| compareIf(a, b, isPrimitiveEquatable, comparePrimitiveEquality)
|
return value === undefined
|
||||||
|| compareIf(a, b, isObjectEquatable, compareObjectEquality, cache)
|
|| value === null;
|
||||||
|| NOT_EQUAL;
|
}
|
||||||
}
|
|
||||||
|
function compareOptionality(a, b) {
|
||||||
/**
|
return tryCompareStrictEquality(a, b)
|
||||||
* @template T
|
|| NOT_EQUAL;
|
||||||
* @param {unknown} a
|
}
|
||||||
* @param {unknown} b
|
|
||||||
* @param {(value: unknown) => value is T} test
|
function isPrimitiveEquatable(value) {
|
||||||
* @param {(a: T, b: T, cache?: ComparisonCache) => EQUAL | NOT_EQUAL} compare
|
switch (typeof value) {
|
||||||
* @param {ComparisonCache} [cache]
|
case 'string':
|
||||||
* @returns {EQUAL | NOT_EQUAL | UNKNOWN}
|
case 'number':
|
||||||
*/
|
case 'bigint':
|
||||||
function compareIf(a, b, test, compare, cache) {
|
case 'boolean':
|
||||||
return !test(a)
|
case 'symbol':
|
||||||
? !test(b) ? UNKNOWN : NOT_EQUAL
|
return true;
|
||||||
: !test(b) ? NOT_EQUAL : cacheComparison(a, b, compare, cache);
|
default:
|
||||||
}
|
return isBoxed(value);
|
||||||
|
}
|
||||||
/**
|
}
|
||||||
* @returns {EQUAL | UNKNOWN}
|
|
||||||
*/
|
function comparePrimitiveEquality(a, b) {
|
||||||
function tryCompareStrictEquality(a, b) {
|
if (isBoxed(a)) a = a.valueOf();
|
||||||
return a === b ? EQUAL : UNKNOWN;
|
if (isBoxed(b)) b = b.valueOf();
|
||||||
}
|
return tryCompareStrictEquality(a, b)
|
||||||
|
|| tryCompareTypeOfEquality(a, b)
|
||||||
/**
|
|| compareIf(a, b, isNaNEquatable, compareNaNEquality)
|
||||||
* @returns {NOT_EQUAL | UNKNOWN}
|
|| NOT_EQUAL;
|
||||||
*/
|
}
|
||||||
function tryCompareTypeOfEquality(a, b) {
|
|
||||||
return typeof a !== typeof b ? NOT_EQUAL : UNKNOWN;
|
function isNaNEquatable(value) {
|
||||||
}
|
return typeof value === 'number';
|
||||||
|
}
|
||||||
/**
|
|
||||||
* @returns {NOT_EQUAL | UNKNOWN}
|
function compareNaNEquality(a, b) {
|
||||||
*/
|
return isNaN(a) && isNaN(b) ? EQUAL : NOT_EQUAL;
|
||||||
function tryCompareToStringTagEquality(a, b) {
|
}
|
||||||
var aTag = Symbol.toStringTag in a ? a[Symbol.toStringTag] : undefined;
|
|
||||||
var bTag = Symbol.toStringTag in b ? b[Symbol.toStringTag] : undefined;
|
function isObjectEquatable(value) {
|
||||||
return aTag !== bTag ? NOT_EQUAL : UNKNOWN;
|
return typeof value === 'object';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function compareObjectEquality(a, b, cache) {
|
||||||
* @returns {value is null | undefined}
|
if (!cache) cache = new Map();
|
||||||
*/
|
return getCache(cache, a, b)
|
||||||
function isOptional(value) {
|
|| setCache(cache, a, b, EQUAL) // consider equal for now
|
||||||
return value === undefined
|
|| cacheComparison(a, b, tryCompareStrictEquality, cache)
|
||||||
|| value === null;
|
|| cacheComparison(a, b, tryCompareToStringTagEquality, cache)
|
||||||
}
|
|| compareIf(a, b, isValueOfEquatable, compareValueOfEquality)
|
||||||
|
|| compareIf(a, b, isToStringEquatable, compareToStringEquality)
|
||||||
/**
|
|| compareIf(a, b, isArrayLikeEquatable, compareArrayLikeEquality, cache)
|
||||||
* @returns {EQUAL | NOT_EQUAL}
|
|| compareIf(a, b, isStructurallyEquatable, compareStructuralEquality, cache)
|
||||||
*/
|
|| compareIf(a, b, isIterableEquatable, compareIterableEquality, cache)
|
||||||
function compareOptionality(a, b) {
|
|| cacheComparison(a, b, fail, cache);
|
||||||
return tryCompareStrictEquality(a, b)
|
}
|
||||||
|| NOT_EQUAL;
|
|
||||||
}
|
function isBoxed(value) {
|
||||||
|
return value instanceof String
|
||||||
/**
|
|| value instanceof Number
|
||||||
* @returns {value is number | bigint | string | symbol | boolean | undefined}
|
|| value instanceof Boolean
|
||||||
*/
|
|| typeof Symbol === 'function' && value instanceof Symbol
|
||||||
function isPrimitiveEquatable(value) {
|
|| typeof BigInt === 'function' && value instanceof BigInt;
|
||||||
switch (typeof value) {
|
}
|
||||||
case 'string':
|
|
||||||
case 'number':
|
function isValueOfEquatable(value) {
|
||||||
case 'bigint':
|
return value instanceof Date;
|
||||||
case 'boolean':
|
}
|
||||||
case 'symbol':
|
|
||||||
return true;
|
function compareValueOfEquality(a, b) {
|
||||||
default:
|
return compareIf(a.valueOf(), b.valueOf(), isPrimitiveEquatable, comparePrimitiveEquality)
|
||||||
return isBoxed(value);
|
|| NOT_EQUAL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
function isToStringEquatable(value) {
|
||||||
/**
|
return value instanceof RegExp;
|
||||||
* @returns {EQUAL | NOT_EQUAL}
|
}
|
||||||
*/
|
|
||||||
function comparePrimitiveEquality(a, b) {
|
function compareToStringEquality(a, b) {
|
||||||
if (isBoxed(a)) a = a.valueOf();
|
return compareIf(a.toString(), b.toString(), isPrimitiveEquatable, comparePrimitiveEquality)
|
||||||
if (isBoxed(b)) b = b.valueOf();
|
|| NOT_EQUAL;
|
||||||
return tryCompareStrictEquality(a, b)
|
}
|
||||||
|| tryCompareTypeOfEquality(a, b)
|
|
||||||
|| compareIf(a, b, isNaNEquatable, compareNaNEquality)
|
function isArrayLikeEquatable(value) {
|
||||||
|| NOT_EQUAL;
|
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)
|
||||||
* @returns {value is number}
|
|| (typeof Uint32Array === 'function' && value instanceof Uint32Array)
|
||||||
*/
|
|| (typeof Int8Array === 'function' && value instanceof Int8Array)
|
||||||
function isNaNEquatable(value) {
|
|| (typeof Int16Array === 'function' && value instanceof Int16Array)
|
||||||
return typeof value === 'number';
|
|| (typeof Int32Array === 'function' && value instanceof Int32Array)
|
||||||
}
|
|| (typeof Float32Array === 'function' && value instanceof Float32Array)
|
||||||
|
|| (typeof Float64Array === 'function' && value instanceof Float64Array)
|
||||||
/**
|
|| (typeof BigUint64Array === 'function' && value instanceof BigUint64Array)
|
||||||
* @param {number} a
|
|| (typeof BigInt64Array === 'function' && value instanceof BigInt64Array);
|
||||||
* @param {number} b
|
}
|
||||||
* @returns {EQUAL | NOT_EQUAL}
|
|
||||||
*/
|
function compareArrayLikeEquality(a, b, cache) {
|
||||||
function compareNaNEquality(a, b) {
|
if (a.length !== b.length) return NOT_EQUAL;
|
||||||
return isNaN(a) && isNaN(b) ? EQUAL : NOT_EQUAL;
|
for (var i = 0; i < a.length; i++) {
|
||||||
}
|
if (compareEquality(a[i], b[i], cache) === NOT_EQUAL) {
|
||||||
|
return NOT_EQUAL;
|
||||||
/**
|
}
|
||||||
* @returns {value is object}
|
}
|
||||||
*/
|
return EQUAL;
|
||||||
function isObjectEquatable(value) {
|
}
|
||||||
return typeof value === 'object';
|
|
||||||
}
|
function isStructurallyEquatable(value) {
|
||||||
|
return !(typeof Promise === 'function' && value instanceof Promise // only comparable by reference
|
||||||
/**
|
|| typeof WeakMap === 'function' && value instanceof WeakMap // only comparable by reference
|
||||||
* @param {ComparisonCache} cache
|
|| typeof WeakSet === 'function' && value instanceof WeakSet // only comparable by reference
|
||||||
* @returns {EQUAL | NOT_EQUAL}
|
|| typeof Map === 'function' && value instanceof Map // comparable via @@iterator
|
||||||
*/
|
|| typeof Set === 'function' && value instanceof Set); // comparable via @@iterator
|
||||||
function compareObjectEquality(a, b, cache) {
|
}
|
||||||
if (!cache) cache = new Map();
|
|
||||||
return getCache(cache, a, b)
|
function compareStructuralEquality(a, b, cache) {
|
||||||
|| setCache(cache, a, b, EQUAL) // consider equal for now
|
var aKeys = [];
|
||||||
|| cacheComparison(a, b, tryCompareStrictEquality, cache)
|
for (var key in a) aKeys.push(key);
|
||||||
|| cacheComparison(a, b, tryCompareToStringTagEquality, cache)
|
|
||||||
|| compareIf(a, b, isValueOfEquatable, compareValueOfEquality)
|
var bKeys = [];
|
||||||
|| compareIf(a, b, isToStringEquatable, compareToStringEquality)
|
for (var key in b) bKeys.push(key);
|
||||||
|| compareIf(a, b, isArrayLikeEquatable, compareArrayLikeEquality, cache)
|
|
||||||
|| compareIf(a, b, isStructurallyEquatable, compareStructuralEquality, cache)
|
if (aKeys.length !== bKeys.length) {
|
||||||
|| compareIf(a, b, isIterableEquatable, compareIterableEquality, cache)
|
return NOT_EQUAL;
|
||||||
|| cacheComparison(a, b, fail, cache);
|
}
|
||||||
}
|
|
||||||
|
aKeys.sort();
|
||||||
function isBoxed(value) {
|
bKeys.sort();
|
||||||
return value instanceof String
|
|
||||||
|| value instanceof Number
|
for (var i = 0; i < aKeys.length; i++) {
|
||||||
|| value instanceof Boolean
|
var aKey = aKeys[i];
|
||||||
|| typeof Symbol === 'function' && value instanceof Symbol
|
var bKey = bKeys[i];
|
||||||
|| typeof BigInt === 'function' && value instanceof BigInt;
|
if (compareEquality(aKey, bKey, cache) === NOT_EQUAL) {
|
||||||
}
|
return NOT_EQUAL;
|
||||||
|
}
|
||||||
/**
|
if (compareEquality(a[aKey], b[bKey], cache) === NOT_EQUAL) {
|
||||||
* @returns {value is { valueOf(): any }}
|
return NOT_EQUAL;
|
||||||
*/
|
}
|
||||||
function isValueOfEquatable(value) {
|
}
|
||||||
return value instanceof Date;
|
|
||||||
}
|
return compareIf(a, b, isIterableEquatable, compareIterableEquality, cache)
|
||||||
|
|| EQUAL;
|
||||||
/**
|
}
|
||||||
* @param {{ valueOf(): any }} a
|
|
||||||
* @param {{ valueOf(): any }} b
|
function isIterableEquatable(value) {
|
||||||
* @returns {EQUAL | NOT_EQUAL}
|
return typeof Symbol === 'function'
|
||||||
*/
|
&& typeof value[Symbol.iterator] === 'function';
|
||||||
function compareValueOfEquality(a, b) {
|
}
|
||||||
return compareIf(a.valueOf(), b.valueOf(), isPrimitiveEquatable, comparePrimitiveEquality)
|
|
||||||
|| 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
|
||||||
* @returns {value is { toString(): string }}
|
}
|
||||||
*/
|
|
||||||
function isToStringEquatable(value) {
|
var ar, br;
|
||||||
return value instanceof RegExp;
|
while (true) {
|
||||||
}
|
ar = a.next();
|
||||||
|
br = b.next();
|
||||||
/**
|
if (ar.done) {
|
||||||
* @param {{ toString(): string }} a
|
if (br.done) return EQUAL;
|
||||||
* @param {{ toString(): string }} b
|
if (b.return) b.return();
|
||||||
* @returns {EQUAL | NOT_EQUAL}
|
return NOT_EQUAL;
|
||||||
*/
|
}
|
||||||
function compareToStringEquality(a, b) {
|
if (br.done) {
|
||||||
return compareIf(a.toString(), b.toString(), isPrimitiveEquatable, comparePrimitiveEquality)
|
if (a.return) a.return();
|
||||||
|| NOT_EQUAL;
|
return NOT_EQUAL;
|
||||||
}
|
}
|
||||||
|
if (compareEquality(ar.value, br.value, cache) === NOT_EQUAL) {
|
||||||
/**
|
if (a.return) a.return();
|
||||||
* @returns {value is ArrayLike<unknown>}
|
if (b.return) b.return();
|
||||||
*/
|
return 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)
|
function compareIterableEquality(a, b, cache) {
|
||||||
|| (typeof Uint32Array === 'function' && value instanceof Uint32Array)
|
return compareIteratorEquality(a[Symbol.iterator](), b[Symbol.iterator](), cache);
|
||||||
|| (typeof Int8Array === 'function' && value instanceof Int8Array)
|
}
|
||||||
|| (typeof Int16Array === 'function' && value instanceof Int16Array)
|
|
||||||
|| (typeof Int32Array === 'function' && value instanceof Int32Array)
|
function cacheComparison(a, b, compare, cache) {
|
||||||
|| (typeof Float32Array === 'function' && value instanceof Float32Array)
|
var result = compare(a, b, cache);
|
||||||
|| (typeof Float64Array === 'function' && value instanceof Float64Array)
|
if (cache && (result === EQUAL || result === NOT_EQUAL)) {
|
||||||
|| (typeof BigUint64Array === 'function' && value instanceof BigUint64Array)
|
setCache(cache, a, b, /** @type {EQUAL | NOT_EQUAL} */(result));
|
||||||
|| (typeof BigInt64Array === 'function' && value instanceof BigInt64Array);
|
}
|
||||||
}
|
return result;
|
||||||
|
}
|
||||||
/**
|
|
||||||
* @template T
|
function fail() {
|
||||||
* @param {ArrayLike<T>} a
|
return NOT_EQUAL;
|
||||||
* @param {ArrayLike<T>} b
|
}
|
||||||
* @param {ComparisonCache} cache
|
|
||||||
* @returns {EQUAL | NOT_EQUAL}
|
function setCache(cache, left, right, result) {
|
||||||
*/
|
var otherCache;
|
||||||
function compareArrayLikeEquality(a, b, cache) {
|
|
||||||
if (a.length !== b.length) return NOT_EQUAL;
|
otherCache = cache.get(left);
|
||||||
for (var i = 0; i < a.length; i++) {
|
if (!otherCache) cache.set(left, otherCache = new Map());
|
||||||
if (compareEquality(a[i], b[i], cache) === NOT_EQUAL) {
|
otherCache.set(right, result);
|
||||||
return NOT_EQUAL;
|
|
||||||
}
|
otherCache = cache.get(right);
|
||||||
}
|
if (!otherCache) cache.set(right, otherCache = new Map());
|
||||||
return EQUAL;
|
otherCache.set(left, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function getCache(cache, left, right) {
|
||||||
* @template T
|
var otherCache;
|
||||||
* @param {T} value
|
/** @type {EQUAL | NOT_EQUAL | UNKNOWN | undefined} */
|
||||||
* @returns {value is Exclude<T, Promise | WeakMap | WeakSet | Map | Set>}
|
var result;
|
||||||
*/
|
|
||||||
function isStructurallyEquatable(value) {
|
otherCache = cache.get(left);
|
||||||
return !(typeof Promise === 'function' && value instanceof Promise // only comparable by reference
|
result = otherCache && otherCache.get(right);
|
||||||
|| typeof WeakMap === 'function' && value instanceof WeakMap // only comparable by reference
|
if (result) return result;
|
||||||
|| typeof WeakSet === 'function' && value instanceof WeakSet // only comparable by reference
|
|
||||||
|| typeof Map === 'function' && value instanceof Map // comparable via @@iterator
|
otherCache = cache.get(right);
|
||||||
|| typeof Set === 'function' && value instanceof Set); // comparable via @@iterator
|
result = otherCache && otherCache.get(left);
|
||||||
}
|
if (result) return result;
|
||||||
|
|
||||||
/**
|
return UNKNOWN;
|
||||||
* @param {ComparisonCache} cache
|
}
|
||||||
* @returns {EQUAL | NOT_EQUAL}
|
|
||||||
*/
|
return deepEqual;
|
||||||
function compareStructuralEquality(a, b, cache) {
|
})();
|
||||||
var aKeys = [];
|
|
||||||
for (var key in a) aKeys.push(key);
|
assert.deepEqual = function (actual, expected, message) {
|
||||||
|
assert(deepEqual(actual, expected),
|
||||||
var bKeys = [];
|
'Expected ' + assert._formatValue(actual) + ' to be structurally equal to ' + assert._formatValue(expected) + '. ' + (message || ''));
|
||||||
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 || ''));
|
|
||||||
};
|
|
||||||
|
14
harness/types.d.ts
vendored
14
harness/types.d.ts
vendored
@ -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.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// 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.
|
description: A matching element of indices is an Array with exactly two number properties.
|
||||||
esid: sec-getmatchindicesarray
|
esid: sec-getmatchindicesarray
|
||||||
features: [regexp-match-indices]
|
features: [regexp-match-indices]
|
||||||
info: |
|
info: |
|
||||||
GetMatchIndicesArray ( S, match )
|
GetMatchIndicesArray ( S, match )
|
||||||
5. Return CreateArrayFromList(« _match_.[[StartIndex]], _match_.[[EndIndex]] »).
|
5. Return CreateArrayFromList(« _match_.[[StartIndex]], _match_.[[EndIndex]] »).
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
let input = "abcd";
|
||||||
let input = "abcd";
|
let match = /b(c)/.exec(input);
|
||||||
let match = /b(c)/.exec(input);
|
let indices = match.indices;
|
||||||
let indices = match.indices;
|
|
||||||
|
// `indices[0]` is an array
|
||||||
// `indices[0]` is an array
|
assert.sameValue(Object.getPrototypeOf(indices[0]), Array.prototype);
|
||||||
assert.sameValue(Object.getPrototypeOf(indices[0]), Array.prototype);
|
assert.sameValue(indices[0].length, 2);
|
||||||
assert.sameValue(indices[0].length, 2);
|
assert.sameValue(typeof indices[0][0], "number");
|
||||||
assert.sameValue(typeof indices[0][0], "number");
|
assert.sameValue(typeof indices[0][1], "number");
|
||||||
assert.sameValue(typeof indices[0][1], "number");
|
|
||||||
|
// `indices[1]` is an array
|
||||||
// `indices[1]` is an array
|
assert.sameValue(Object.getPrototypeOf(indices[1]), Array.prototype);
|
||||||
assert.sameValue(Object.getPrototypeOf(indices[1]), Array.prototype);
|
assert.sameValue(indices[1].length, 2);
|
||||||
assert.sameValue(indices[1].length, 2);
|
assert.sameValue(typeof indices[1][0], "number");
|
||||||
assert.sameValue(typeof indices[1][0], "number");
|
assert.sameValue(typeof indices[1][1], "number");
|
||||||
assert.sameValue(typeof indices[1][1], "number");
|
|
||||||
|
@ -1,39 +1,38 @@
|
|||||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// 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.
|
description: The properties of the "indices" array correspond to the start/end indices of the same values in the match.
|
||||||
includes: [compareArray.js]
|
includes: [compareArray.js]
|
||||||
esid: sec-makeindicesarray
|
esid: sec-makeindicesarray
|
||||||
features: [regexp-match-indices]
|
features: [regexp-match-indices]
|
||||||
info: |
|
info: |
|
||||||
MakeIndicesArray ( S, indices, groupNames )
|
MakeIndicesArray ( S, indices, groupNames )
|
||||||
4. Let _n_ be the number of elements in _indices_.
|
4. Let _n_ be the number of elements in _indices_.
|
||||||
...
|
...
|
||||||
6. Set _A_ to ! ArrayCreate(_n_).
|
6. Set _A_ to ! ArrayCreate(_n_).
|
||||||
...
|
...
|
||||||
11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
|
11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
|
||||||
a. Let _matchIndices_ be _indices_[_i_].
|
a. Let _matchIndices_ be _indices_[_i_].
|
||||||
b. If _matchIndices_ is not *undefined*, then
|
b. If _matchIndices_ is not *undefined*, then
|
||||||
i. Let _matchIndicesArray_ be ! GetMatchIndicesArray(_S_, _matchIndices_).
|
i. Let _matchIndicesArray_ be ! GetMatchIndicesArray(_S_, _matchIndices_).
|
||||||
c. Else,
|
c. Else,
|
||||||
i. Let _matchIndicesArray_ be *undefined*.
|
i. Let _matchIndicesArray_ be *undefined*.
|
||||||
d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
|
d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
|
||||||
...
|
...
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
let input = "abcd";
|
||||||
let input = "abcd";
|
let match = /b(c)/.exec(input);
|
||||||
let match = /b(c)/.exec(input);
|
let indices = match.indices;
|
||||||
let indices = match.indices;
|
|
||||||
|
// `indices` has the same length as match
|
||||||
// `indices` has the same length as match
|
assert.sameValue(indices.length, match.length);
|
||||||
assert.sameValue(indices.length, match.length);
|
|
||||||
|
// The first element of `indices` contains the start/end indices of the match
|
||||||
// The first element of `indices` contains the start/end indices of the match
|
assert.compareArray(indices[0], [1, 3]);
|
||||||
assert.compareArray(indices[0], [1, 3]);
|
assert.sameValue(input.slice(indices[0][0], indices[0][1]), match[0]);
|
||||||
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
|
||||||
// The second element of `indices` contains the start/end indices of the first capture
|
assert.compareArray(indices[1], [2, 3]);
|
||||||
assert.compareArray(indices[1], [2, 3]);
|
assert.sameValue(input.slice(indices[1][0], indices[1][1]), match[1]);
|
||||||
assert.sameValue(input.slice(indices[1][0], indices[1][1]), match[1]);
|
|
||||||
|
@ -1,76 +1,75 @@
|
|||||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
/*---
|
/*---
|
||||||
description: Basic matching cases with non-unicode matches.
|
description: Basic matching cases with non-unicode matches.
|
||||||
includes: [compareArray.js, propertyHelper.js, deepEqual.js]
|
includes: [compareArray.js, propertyHelper.js, deepEqual.js]
|
||||||
esid: sec-regexpbuiltinexec
|
esid: sec-regexpbuiltinexec
|
||||||
features: [regexp-match-indices]
|
features: [regexp-match-indices]
|
||||||
info: |
|
info: |
|
||||||
Runtime Semantics: RegExpBuiltinExec ( R, S )
|
Runtime Semantics: RegExpBuiltinExec ( R, S )
|
||||||
...
|
...
|
||||||
4. Let _lastIndex_ be ? ToLength(? Get(_R_, `"lastIndex")).
|
4. Let _lastIndex_ be ? ToLength(? Get(_R_, `"lastIndex")).
|
||||||
...
|
...
|
||||||
25. Let _indices_ be a new empty List.
|
25. Let _indices_ be a new empty List.
|
||||||
26. Let _match_ be the Match { [[StartIndex]]: _lastIndex_, [[EndIndex]]: _e_ }.
|
26. Let _match_ be the Match { [[StartIndex]]: _lastIndex_, [[EndIndex]]: _e_ }.
|
||||||
27. Add _match_ as the last element of _indices_.
|
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
|
33. For each integer _i_ such that _i_ > 0 and _i_ <= _n_, in ascending order, do
|
||||||
...
|
...
|
||||||
f. Else,
|
f. Else,
|
||||||
i. Let _captureStart_ be _captureI_'s _startIndex_.
|
i. Let _captureStart_ be _captureI_'s _startIndex_.
|
||||||
ii. Let _captureEnd_ be _captureI_'s _endIndex_.
|
ii. Let _captureEnd_ be _captureI_'s _endIndex_.
|
||||||
...
|
...
|
||||||
iv. Let _capture_ be the Match { [[StartIndex]]: _captureStart_, [[EndIndex]]: _captureEnd_ }.
|
iv. Let _capture_ be the Match { [[StartIndex]]: _captureStart_, [[EndIndex]]: _captureEnd_ }.
|
||||||
v. Append _capture_ to _indices_.
|
v. Append _capture_ to _indices_.
|
||||||
...
|
...
|
||||||
34. Let _indicesArray_ be MakeIndicesArray( _S_, _indices_, _groupNames_).
|
34. Let _indicesArray_ be MakeIndicesArray( _S_, _indices_, _groupNames_).
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
assert.deepEqual([[1, 2], [1, 2]], "bab".match(/(a)/).indices);
|
||||||
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]], "bab".match(/.(a)./).indices);
|
assert.deepEqual([[0, 3], [1, 2], [2, 3]], "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], [1, 3]], "bab".match(/.(\w\w)/).indices);
|
assert.deepEqual([[0, 3], [0, 3]], "bab".match(/(\w\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, 3], [0, 2], [2, 3]], "bab".match(/(\w\w)(\w)/).indices);
|
assert.deepEqual([[0, 2], [0, 2], undefined], "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;
|
||||||
let groups = /(?<a>.)(?<b>.)(?<c>.)\k<c>\k<b>\k<a>/.exec("abccba").indices.groups;
|
assert.compareArray([0, 1], groups.a);
|
||||||
assert.compareArray([0, 1], groups.a);
|
assert.compareArray([1, 2], groups.b);
|
||||||
assert.compareArray([1, 2], groups.b);
|
assert.compareArray([2, 3], groups.c);
|
||||||
assert.compareArray([2, 3], groups.c);
|
verifyProperty(groups, "a", {
|
||||||
verifyProperty(groups, "a", {
|
enumerable: true,
|
||||||
enumerable: true,
|
writable: true,
|
||||||
writable: true,
|
configurable: true
|
||||||
configurable: true
|
});
|
||||||
});
|
verifyProperty(groups, "b", {
|
||||||
verifyProperty(groups, "b", {
|
enumerable: true,
|
||||||
enumerable: true,
|
writable: true,
|
||||||
writable: true,
|
configurable: true
|
||||||
configurable: true
|
});
|
||||||
});
|
verifyProperty(groups, "c", {
|
||||||
verifyProperty(groups, "c", {
|
enumerable: true,
|
||||||
enumerable: true,
|
writable: true,
|
||||||
writable: true,
|
configurable: true
|
||||||
configurable: true
|
});
|
||||||
});
|
|
||||||
|
// "𝐁" is U+1d401 MATHEMATICAL BOLD CAPITAL B
|
||||||
// "𝐁" is U+1d401 MATHEMATICAL BOLD CAPITAL B
|
// - Also representable as the code point "\u{1d401}"
|
||||||
// - Also representable as the code point "\u{1d401}"
|
// - Also representable as the surrogate pair "\uD835\uDC01"
|
||||||
// - Also representable as the surrogate pair "\uD835\uDC01"
|
|
||||||
|
// Verify assumptions:
|
||||||
// Verify assumptions:
|
assert.sameValue("𝐁".length, 2, 'The length of "𝐁" is 2');
|
||||||
assert.sameValue("𝐁".length, 2, 'The length of "𝐁" is 2');
|
assert.sameValue("\u{1d401}".length, 2, 'The length of "\\u{1d401}" 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("\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("𝐁".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("\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.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], "𝐁".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], "\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], "\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], "𝐁".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], "\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)');
|
||||||
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.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
/*---
|
/*---
|
||||||
description: The properties of the "indices" array are created with CreateDataProperty.
|
description: The properties of the "indices" array are created with CreateDataProperty.
|
||||||
includes: [propertyHelper.js]
|
includes: [propertyHelper.js]
|
||||||
esid: sec-makeindicesarray
|
esid: sec-makeindicesarray
|
||||||
features: [regexp-match-indices]
|
features: [regexp-match-indices]
|
||||||
info: |
|
info: |
|
||||||
MakeIndicesArray ( S, indices, groupNames )
|
MakeIndicesArray ( S, indices, groupNames )
|
||||||
11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
|
11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
|
||||||
d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
|
d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
let input = "abcd";
|
||||||
let input = "abcd";
|
let match = /b(c)/.exec(input);
|
||||||
let match = /b(c)/.exec(input);
|
let indices = match.indices;
|
||||||
let indices = match.indices;
|
|
||||||
|
verifyProperty(indices, '0', {
|
||||||
verifyProperty(indices, '0', {
|
enumerable: true,
|
||||||
enumerable: true,
|
configurable: true,
|
||||||
configurable: true,
|
writable: true
|
||||||
writable: true
|
});
|
||||||
});
|
|
||||||
|
verifyProperty(indices, '1', {
|
||||||
verifyProperty(indices, '1', {
|
enumerable: true,
|
||||||
enumerable: true,
|
configurable: true,
|
||||||
configurable: true,
|
writable: true
|
||||||
writable: true
|
});
|
||||||
});
|
|
||||||
|
@ -1,85 +1,84 @@
|
|||||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
/*---
|
/*---
|
||||||
description: Basic matching cases with non-unicode matches.
|
description: Basic matching cases with non-unicode matches.
|
||||||
includes: [compareArray.js, propertyHelper.js, deepEqual.js]
|
includes: [compareArray.js, propertyHelper.js, deepEqual.js]
|
||||||
esid: sec-regexpbuiltinexec
|
esid: sec-regexpbuiltinexec
|
||||||
features: [regexp-match-indices]
|
features: [regexp-match-indices]
|
||||||
info: |
|
info: |
|
||||||
Runtime Semantics: RegExpBuiltinExec ( R, S )
|
Runtime Semantics: RegExpBuiltinExec ( R, S )
|
||||||
...
|
...
|
||||||
4. Let _lastIndex_ be ? ToLength(? Get(_R_, `"lastIndex")).
|
4. Let _lastIndex_ be ? ToLength(? Get(_R_, `"lastIndex")).
|
||||||
...
|
...
|
||||||
16. If _fullUnicode_ is *true*, set _e_ to ! GetStringIndex(_S_, _Input_, _e_).
|
16. If _fullUnicode_ is *true*, set _e_ to ! GetStringIndex(_S_, _Input_, _e_).
|
||||||
...
|
...
|
||||||
25. Let _indices_ be a new empty List.
|
25. Let _indices_ be a new empty List.
|
||||||
26. Let _match_ be the Match { [[StartIndex]]: _lastIndex_, [[EndIndex]]: _e_ }.
|
26. Let _match_ be the Match { [[StartIndex]]: _lastIndex_, [[EndIndex]]: _e_ }.
|
||||||
27. Add _match_ as the last element of _indices_.
|
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
|
33. For each integer _i_ such that _i_ > 0 and _i_ <= _n_, in ascending order, do
|
||||||
...
|
...
|
||||||
f. Else,
|
f. Else,
|
||||||
i. Let _captureStart_ be _captureI_'s _startIndex_.
|
i. Let _captureStart_ be _captureI_'s _startIndex_.
|
||||||
ii. Let _captureEnd_ be _captureI_'s _endIndex_.
|
ii. Let _captureEnd_ be _captureI_'s _endIndex_.
|
||||||
iii. If _fullUnicode_ is *true*, then
|
iii. If _fullUnicode_ is *true*, then
|
||||||
1. Set _captureStart_ to ! GetStringIndex(_S_, _Input_, _captureStart_).
|
1. Set _captureStart_ to ! GetStringIndex(_S_, _Input_, _captureStart_).
|
||||||
1. Set _captureEnd_ to ! GetStringIndex(_S_, _Input_, _captureEnd_).
|
1. Set _captureEnd_ to ! GetStringIndex(_S_, _Input_, _captureEnd_).
|
||||||
iv. Let _capture_ be the Match { [[StartIndex]]: _captureStart_, [[EndIndex]]: _captureEnd_ }.
|
iv. Let _capture_ be the Match { [[StartIndex]]: _captureStart_, [[EndIndex]]: _captureEnd_ }.
|
||||||
v. Append _capture_ to _indices_.
|
v. Append _capture_ to _indices_.
|
||||||
...
|
...
|
||||||
34. Let _indicesArray_ be MakeIndicesArray( _S_, _indices_, _groupNames_).
|
34. Let _indicesArray_ be MakeIndicesArray( _S_, _indices_, _groupNames_).
|
||||||
|
|
||||||
GetStringIndex ( S, Input, e )
|
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_.
|
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_.
|
5. Return _eUTF_.
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
assert.deepEqual([[1, 2], [1, 2]], "bab".match(/(a)/u).indices);
|
||||||
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]], "bab".match(/.(a)./u).indices);
|
assert.deepEqual([[0, 3], [1, 2], [2, 3]], "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], [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, 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, 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);
|
||||||
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;
|
||||||
let groups = /(?<a>.)(?<b>.)(?<c>.)\k<c>\k<b>\k<a>/u.exec("abccba").indices.groups;
|
assert.compareArray([0, 1], groups.a);
|
||||||
assert.compareArray([0, 1], groups.a);
|
assert.compareArray([1, 2], groups.b);
|
||||||
assert.compareArray([1, 2], groups.b);
|
assert.compareArray([2, 3], groups.c);
|
||||||
assert.compareArray([2, 3], groups.c);
|
verifyProperty(groups, "a", {
|
||||||
verifyProperty(groups, "a", {
|
enumerable: true,
|
||||||
enumerable: true,
|
writable: true,
|
||||||
writable: true,
|
configurable: true
|
||||||
configurable: true
|
});
|
||||||
});
|
verifyProperty(groups, "b", {
|
||||||
verifyProperty(groups, "b", {
|
enumerable: true,
|
||||||
enumerable: true,
|
writable: true,
|
||||||
writable: true,
|
configurable: true
|
||||||
configurable: true
|
});
|
||||||
});
|
verifyProperty(groups, "c", {
|
||||||
verifyProperty(groups, "c", {
|
enumerable: true,
|
||||||
enumerable: true,
|
writable: true,
|
||||||
writable: true,
|
configurable: true
|
||||||
configurable: true
|
});
|
||||||
});
|
|
||||||
|
// "𝐁" is U+1d401 MATHEMATICAL BOLD CAPITAL B
|
||||||
// "𝐁" is U+1d401 MATHEMATICAL BOLD CAPITAL B
|
// - Also representable as the code point "\u{1d401}"
|
||||||
// - Also representable as the code point "\u{1d401}"
|
// - Also representable as the surrogate pair "\uD835\uDC01"
|
||||||
// - Also representable as the surrogate pair "\uD835\uDC01"
|
|
||||||
|
// Verify assumptions:
|
||||||
// Verify assumptions:
|
assert.sameValue("𝐁".length, 2, 'The length of "𝐁" is 2');
|
||||||
assert.sameValue("𝐁".length, 2, 'The length of "𝐁" is 2');
|
assert.sameValue("\u{1d401}".length, 2, 'The length of "\\u{1d401}" 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("\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, "𝐁".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, "\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.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], "𝐁".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], "\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], "\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], "𝐁".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], "\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)');
|
||||||
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.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
/*---
|
/*---
|
||||||
description: Basic matching cases with non-unicode matches.
|
description: Basic matching cases with non-unicode matches.
|
||||||
includes: [compareArray.js]
|
includes: [compareArray.js]
|
||||||
esid: sec-makeindicesarray
|
esid: sec-makeindicesarray
|
||||||
features: [regexp-match-indices]
|
features: [regexp-match-indices]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
assert.compareArray([1, 2], /(?<π>a)/u.exec("bab").indices.groups.π);
|
||||||
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], /(?<\u{03C0}>a)/u.exec("bab").indices.groups.π);
|
assert.compareArray([1, 2], /(?<π>a)/u.exec("bab").indices.groups.\u03C0);
|
||||||
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], /(?<\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], /(?<_>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], /(?<_\u200C>a)/u.exec("bab").indices.groups._\u200C);
|
assert.compareArray([1, 2], /(?<_\u200D>a)/u.exec("bab").indices.groups._\u200D);
|
||||||
assert.compareArray([1, 2], /(?<_\u200D>a)/u.exec("bab").indices.groups._\u200D);
|
assert.compareArray([1, 2], /(?<ಠ_ಠ>a)/u.exec("bab").indices.groups.ಠ_ಠ);
|
||||||
assert.compareArray([1, 2], /(?<ಠ_ಠ>a)/u.exec("bab").indices.groups.ಠ_ಠ);
|
|
||||||
|
@ -1,33 +1,32 @@
|
|||||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// 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"
|
description: An unmatched capture in a match corresponds to an unmatched capture in "indices"
|
||||||
esid: sec-makeindicesarray
|
esid: sec-makeindicesarray
|
||||||
features: [regexp-match-indices]
|
features: [regexp-match-indices]
|
||||||
info: |
|
info: |
|
||||||
MakeIndicesArray ( S, indices, groupNames )
|
MakeIndicesArray ( S, indices, groupNames )
|
||||||
4. Let _n_ be the number of elements in _indices_.
|
4. Let _n_ be the number of elements in _indices_.
|
||||||
...
|
...
|
||||||
6. Set _A_ to ! ArrayCreate(_n_).
|
6. Set _A_ to ! ArrayCreate(_n_).
|
||||||
...
|
...
|
||||||
11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
|
11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
|
||||||
a. Let _matchIndices_ be _indices_[_i_].
|
a. Let _matchIndices_ be _indices_[_i_].
|
||||||
b. If _matchIndices_ is not *undefined*, then
|
b. If _matchIndices_ is not *undefined*, then
|
||||||
i. Let _matchIndicesArray_ be ! GetMatchIndicesArray(_S_, _matchIndices_).
|
i. Let _matchIndicesArray_ be ! GetMatchIndicesArray(_S_, _matchIndices_).
|
||||||
c. Else,
|
c. Else,
|
||||||
i. Let _matchIndicesArray_ be *undefined*.
|
i. Let _matchIndicesArray_ be *undefined*.
|
||||||
d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
|
d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
|
||||||
...
|
...
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
let input = "abd";
|
||||||
let input = "abd";
|
let match = /b(c)?/.exec(input);
|
||||||
let match = /b(c)?/.exec(input);
|
let indices = match.indices;
|
||||||
let indices = match.indices;
|
|
||||||
|
// `indices` has the same length as match
|
||||||
// `indices` has the same length as match
|
assert.sameValue(indices.length, match.length);
|
||||||
assert.sameValue(indices.length, match.length);
|
|
||||||
|
// The second element of `indices` should be undefined.
|
||||||
// The second element of `indices` should be undefined.
|
assert.sameValue(indices[1], undefined);
|
||||||
assert.sameValue(indices[1], undefined);
|
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
/*---
|
/*---
|
||||||
description: The "indices" property is an Array.
|
description: The "indices" property is an Array.
|
||||||
esid: sec-makeindicesarray
|
esid: sec-makeindicesarray
|
||||||
features: [regexp-match-indices]
|
features: [regexp-match-indices]
|
||||||
info: |
|
info: |
|
||||||
MakeIndicesArray ( S, indices, groupNames )
|
MakeIndicesArray ( S, indices, groupNames )
|
||||||
6. Set _A_ to ! ArrayCreate(_n_).
|
6. Set _A_ to ! ArrayCreate(_n_).
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
let match = /a/.exec("a");
|
||||||
let match = /a/.exec("a");
|
let indices = match.indices;
|
||||||
let indices = match.indices;
|
|
||||||
|
// `indices` is an array
|
||||||
// `indices` is an array
|
assert.sameValue(Object.getPrototypeOf(indices), Array.prototype);
|
||||||
assert.sameValue(Object.getPrototypeOf(indices), Array.prototype);
|
|
||||||
assert(Array.isArray(indices));
|
assert(Array.isArray(indices));
|
@ -1,30 +1,29 @@
|
|||||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
/*---
|
/*---
|
||||||
description: The "indices" property is created with DefinePropertyOrThrow
|
description: The "indices" property is created with DefinePropertyOrThrow
|
||||||
includes: [propertyHelper.js]
|
includes: [propertyHelper.js]
|
||||||
esid: sec-regexpbuiltinexec
|
esid: sec-regexpbuiltinexec
|
||||||
features: [regexp-match-indices]
|
features: [regexp-match-indices]
|
||||||
info: |
|
info: |
|
||||||
Runtime Semantics: RegExpBuiltinExec ( R, S )
|
Runtime Semantics: RegExpBuiltinExec ( R, S )
|
||||||
34. Let _indicesArray_ be MakeIndicesArray(_S_, _indices_, _groupNames_).
|
34. Let _indicesArray_ be MakeIndicesArray(_S_, _indices_, _groupNames_).
|
||||||
35. Perform ! DefinePropertyOrThrow(_A_, `"indices"`, PropertyDescriptor { [[Value]]: _indicesArray_, [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }).
|
35. Perform ! DefinePropertyOrThrow(_A_, `"indices"`, PropertyDescriptor { [[Value]]: _indicesArray_, [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }).
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
// `indices` is created with Define, not Set.
|
||||||
// `indices` is created with Define, not Set.
|
let counter = 0;
|
||||||
let counter = 0;
|
Object.defineProperty(Array.prototype, "indices", {
|
||||||
Object.defineProperty(Array.prototype, "indices", {
|
set() { counter++; }
|
||||||
set() { counter++; }
|
});
|
||||||
});
|
|
||||||
|
let match = /a/.exec("a");
|
||||||
let match = /a/.exec("a");
|
assert.sameValue(counter, 0);
|
||||||
assert.sameValue(counter, 0);
|
|
||||||
|
// `indices` is a non-writable, non-enumerable, and configurable data-property.
|
||||||
// `indices` is a non-writable, non-enumerable, and configurable data-property.
|
verifyProperty(match, 'indices', {
|
||||||
verifyProperty(match, 'indices', {
|
writable: true,
|
||||||
writable: true,
|
enumerable: true,
|
||||||
enumerable: true,
|
configurable: true
|
||||||
configurable: true
|
});
|
||||||
});
|
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
/*---
|
/*---
|
||||||
description: >
|
description: >
|
||||||
array values compare correctly.
|
array values compare correctly.
|
||||||
includes: [deepEqual.js]
|
includes: [deepEqual.js]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
assert.deepEqual([], []);
|
||||||
assert.deepEqual([], []);
|
assert.deepEqual([1, "a", true], [1, "a", true]);
|
||||||
assert.deepEqual([1, "a", true], [1, "a", true]);
|
|
||||||
|
assert.throws(Test262Error, function () { assert.deepEqual([], [1]); });
|
||||||
assert.throws(Test262Error, function () { assert.deepEqual([], [1]); });
|
assert.throws(Test262Error, function () { assert.deepEqual([1, "a", true], [1, "a", false]); });
|
||||||
assert.throws(Test262Error, function () { assert.deepEqual([1, "a", true], [1, "a", false]); });
|
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
/*---
|
/*---
|
||||||
description: >
|
description: >
|
||||||
values compare correctly with circular references.
|
values compare correctly with circular references.
|
||||||
includes: [deepEqual.js]
|
includes: [deepEqual.js]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
var a = { x: 1 };
|
||||||
var a = { x: 1 };
|
var b = { x: 1 };
|
||||||
var b = { x: 1 };
|
a.a = a;
|
||||||
a.a = a;
|
a.b = b;
|
||||||
a.b = b;
|
b.a = b;
|
||||||
b.a = b;
|
b.b = a;
|
||||||
b.b = a;
|
|
||||||
|
assert.deepEqual(a, b);
|
||||||
assert.deepEqual(a, b);
|
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
// Copyright 2019 Ron Buckton. All rights reserved.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
/*---
|
/*---
|
||||||
description: >
|
description: >
|
||||||
values compare correctly.
|
values compare correctly.
|
||||||
includes: [deepEqual.js]
|
includes: [deepEqual.js]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
assert.deepEqual({ a: { x: 1 }, b: [true] }, { a: { x: 1 }, b: [true] });
|
||||||
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] }); });
|
assert.throws(Test262Error, function () { assert.deepEqual({ a: { x: 1 }, b: [true] }, { a: { x: 1 }, b: [false] }); });
|
||||||
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.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
/*---
|
/*---
|
||||||
description: >
|
description: >
|
||||||
map/set values compare correctly.
|
map/set values compare correctly.
|
||||||
includes: [deepEqual.js]
|
includes: [deepEqual.js]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
assert.deepEqual(new Set(), new Set());
|
||||||
assert.deepEqual(new Set(), new Set());
|
assert.deepEqual(new Set([1, "a", true]), new Set([1, "a", true]));
|
||||||
assert.deepEqual(new Set([1, "a", true]), new Set([1, "a", true]));
|
assert.deepEqual(new Map(), new Map());
|
||||||
assert.deepEqual(new Map(), new Map());
|
assert.deepEqual(new Map([[1, "a"], ["b", true]]), new Map([[1, "a"], ["b", true]]));
|
||||||
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([]), 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 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([]), 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 Map([[1, "a"], ["b", false]])); });
|
assert.throws(Test262Error, function () { assert.deepEqual(new Map([[1, "a"], ["b", true]]), new Set([[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.
|
// Copyright 2019 Ron Buckton. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
/*---
|
/*---
|
||||||
description: >
|
description: >
|
||||||
object values compare correctly.
|
object values compare correctly.
|
||||||
includes: [deepEqual.js]
|
includes: [deepEqual.js]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
|
||||||
assert.deepEqual({}, {});
|
assert.deepEqual({}, {});
|
||||||
assert.deepEqual({ a: 1, b: true }, { a: 1, b: true });
|
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 }); });
|
||||||
assert.throws(Test262Error, function () { assert.deepEqual({ a: 1, b: true }, { a: 1, b: false }); });
|
assert.throws(Test262Error, function () { assert.deepEqual({ a: 1, b: true }, { a: 1, b: false }); });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user