mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-10 04:48:32 +00:00
test(codemode): add Test262 string coverage (#35940)
This commit is contained in:
parent
99e52303e6
commit
212c9f99ee
5 changed files with 2096 additions and 0 deletions
28
packages/codemode/test/LICENSE.test262
Normal file
28
packages/codemode/test/LICENSE.test262
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
Test262: ECMAScript Test Suite ("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 https://www.ecma-international.org/ipr FOR
|
||||
INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS*.
|
||||
|
||||
Copyright (C) 2012 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
|
||||
580
packages/codemode/test/string-core-test262.test.ts
Normal file
580
packages/codemode/test/string-core-test262.test.ts
Normal file
|
|
@ -0,0 +1,580 @@
|
|||
/*
|
||||
* Portions adapted from Test262 at revision 250f204f23a9249ff204be2baec29600faae7b75:
|
||||
* - test/built-ins/String/prototype/toLowerCase/S15.5.4.16_A2_T1.js
|
||||
* - test/built-ins/String/prototype/toLowerCase/special_casing.js
|
||||
* - test/built-ins/String/prototype/toLowerCase/special_casing_conditional.js
|
||||
* - test/built-ins/String/prototype/toLowerCase/Final_Sigma_U180E.js
|
||||
* - test/built-ins/String/prototype/toLowerCase/supplementary_plane.js
|
||||
* - test/built-ins/String/prototype/toUpperCase/S15.5.4.18_A2_T1.js
|
||||
* - test/built-ins/String/prototype/toUpperCase/special_casing.js
|
||||
* - test/built-ins/String/prototype/toUpperCase/supplementary_plane.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-1.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-2.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-3.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-4.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-5.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-6.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-7.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-8.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-9.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-10.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-11.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-12.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-13.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-3-14.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-1.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-2.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-3.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-4.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-5.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-6.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-8.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-10.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-11.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-12.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-13.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-14.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-16.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-18.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-19.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-20.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-21.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-22.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-24.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-27.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-28.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-29.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-30.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-32.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-34.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-35.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-36.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-37.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-38.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-39.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-40.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-41.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-42.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-43.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-44.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-45.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-46.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-47.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-48.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-49.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-50.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-51.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-52.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-53.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-54.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-55.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-56.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-57.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-58.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-59.js
|
||||
* - test/built-ins/String/prototype/trim/15.5.4.20-4-60.js
|
||||
* - test/built-ins/String/prototype/trim/u180e.js
|
||||
* - test/built-ins/String/prototype/trimStart/this-value-whitespace.js
|
||||
* - test/built-ins/String/prototype/trimStart/this-value-line-terminator.js
|
||||
* - test/built-ins/String/prototype/trimEnd/this-value-whitespace.js
|
||||
* - test/built-ins/String/prototype/trimEnd/this-value-line-terminator.js
|
||||
* - test/built-ins/String/prototype/repeat/repeat-string-n-times.js
|
||||
* - test/built-ins/String/prototype/repeat/empty-string-returns-empty.js
|
||||
* - test/built-ins/String/prototype/repeat/count-is-zero-returns-empty-string.js
|
||||
* - test/built-ins/String/prototype/repeat/count-coerced-to-zero-returns-empty-string.js
|
||||
* - test/built-ins/String/prototype/padStart/fill-string-empty.js
|
||||
* - test/built-ins/String/prototype/padStart/normal-operation.js
|
||||
* - test/built-ins/String/prototype/padStart/fill-string-omitted.js
|
||||
* - test/built-ins/String/prototype/padStart/max-length-not-greater-than-string.js
|
||||
* - test/built-ins/String/prototype/padEnd/fill-string-empty.js
|
||||
* - test/built-ins/String/prototype/padEnd/normal-operation.js
|
||||
* - test/built-ins/String/prototype/padEnd/fill-string-omitted.js
|
||||
* - test/built-ins/String/prototype/padEnd/max-length-not-greater-than-string.js
|
||||
* - test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T4.js
|
||||
* - test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T7.js
|
||||
* - test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T8.js
|
||||
* - test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T1.js
|
||||
* - test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T2.js
|
||||
* - test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T3.js
|
||||
* - test/built-ins/String/prototype/charAt/S9.4_A1.js
|
||||
* - test/built-ins/String/prototype/charAt/S9.4_A2.js
|
||||
* - test/built-ins/String/prototype/charAt/pos-rounding.js
|
||||
* - test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T4.js
|
||||
* - test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T7.js
|
||||
* - test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T8.js
|
||||
* - test/built-ins/String/prototype/charCodeAt/pos-rounding.js
|
||||
* - test/built-ins/String/prototype/codePointAt/return-single-code-unit.js
|
||||
* - test/built-ins/String/prototype/codePointAt/return-first-code-unit.js
|
||||
* - test/built-ins/String/prototype/codePointAt/return-utf16-decode.js
|
||||
* - test/built-ins/String/prototype/codePointAt/return-code-unit-coerced-position.js
|
||||
* - test/built-ins/String/prototype/codePointAt/returns-undefined-on-position-less-than-zero.js
|
||||
* - test/built-ins/String/prototype/codePointAt/returns-undefined-on-position-equal-or-more-than-size.js
|
||||
* - test/built-ins/String/prototype/at/returns-code-unit.js
|
||||
* - test/built-ins/String/prototype/at/returns-item.js
|
||||
* - test/built-ins/String/prototype/at/returns-item-relative-index.js
|
||||
* - test/built-ins/String/prototype/at/returns-undefined-for-out-of-range-index.js
|
||||
* - test/built-ins/String/prototype/at/index-non-numeric-argument-tointeger.js
|
||||
* - test/built-ins/String/prototype/concat/S15.5.4.6_A1_T4.js
|
||||
* - test/built-ins/String/prototype/toString/string-primitive.js
|
||||
* - test/built-ins/String/prototype/normalize/return-normalized-string.js
|
||||
* - test/built-ins/String/prototype/normalize/return-normalized-string-using-default-parameter.js
|
||||
* - test/built-ins/String/prototype/normalize/form-is-not-valid-throws.js
|
||||
* - test/built-ins/String/prototype/localeCompare/15.5.4.9_CE.js
|
||||
* - test/built-ins/String/fromCharCode/S15.5.3.2_A2.js
|
||||
* - test/built-ins/String/fromCharCode/S15.5.3.2_A3_T1.js
|
||||
* - test/built-ins/String/fromCharCode/S9.7_A1.js
|
||||
* - test/built-ins/String/fromCharCode/S9.7_A2.1.js
|
||||
* - test/built-ins/String/fromCharCode/S9.7_A2.2.js
|
||||
* - test/built-ins/String/fromCharCode/S9.7_A3.2_T1.js
|
||||
* - test/built-ins/String/fromCodePoint/arguments-is-empty.js
|
||||
* - test/built-ins/String/fromCodePoint/return-string-value.js
|
||||
* - test/built-ins/String/fromCodePoint/argument-is-not-integer.js
|
||||
* - test/built-ins/String/fromCodePoint/number-is-out-of-range.js
|
||||
*
|
||||
* Copyright 2009 the Sputnik authors. All rights reserved.
|
||||
* Copyright (C) 2009 the Sputnik authors. All rights reserved.
|
||||
* Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
* Copyright 2012 Norbert Lindenberg. All rights reserved.
|
||||
* Copyright 2012 Mozilla Corporation. All rights reserved.
|
||||
* Copyright 2013 Microsoft Corporation. All rights reserved.
|
||||
* Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
* Copyright (C) 2015 André Bargull. All rights reserved.
|
||||
* Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
* Copyright (C) 2016 André Bargull. All rights reserved.
|
||||
* Copyright (C) 2016 Jordan Harband. All rights reserved.
|
||||
* Copyright (C) 2016 Mathias Bynens. All rights reserved.
|
||||
* Copyright (c) 2017 Valerie Young. All rights reserved.
|
||||
* Copyright (C) 2017 Valerie Young. All rights reserved.
|
||||
* Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||
* Copyright (C) 2022 Richard Gibson. All rights reserved.
|
||||
* Test262 portions are governed by the BSD license in LICENSE.test262.
|
||||
*/
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { CodeMode } from "../src/index.js"
|
||||
|
||||
type Argument = string | number | undefined
|
||||
type Outcome = "undefined" | "length" | "RangeError"
|
||||
type Assertion = {
|
||||
label: string
|
||||
input?: string
|
||||
args?: ReadonlyArray<Argument>
|
||||
expected?: string | number
|
||||
outcome?: Outcome
|
||||
}
|
||||
type Vector = {
|
||||
path: string
|
||||
method: string
|
||||
static?: boolean
|
||||
assertions: ReadonlyArray<Assertion>
|
||||
}
|
||||
|
||||
const value = async (code: string) => {
|
||||
const result = await Effect.runPromise(CodeMode.execute({ code, tools: {} }))
|
||||
if (!result.ok) throw new Error(`expected success, got ${result.error.kind}: ${result.error.message}`)
|
||||
return result.value
|
||||
}
|
||||
|
||||
const literal = (input: Argument) => {
|
||||
if (input === undefined) return "undefined"
|
||||
if (typeof input === "string") return JSON.stringify(input)
|
||||
if (Number.isNaN(input)) return "NaN"
|
||||
if (input === Infinity) return "Infinity"
|
||||
if (input === -Infinity) return "-Infinity"
|
||||
if (Object.is(input, -0)) return "-0"
|
||||
return JSON.stringify(input)
|
||||
}
|
||||
|
||||
const vectors: Array<Vector> = []
|
||||
const add = (path: string, method: string, assertions: ReadonlyArray<Assertion>, staticMethod = false) => {
|
||||
vectors.push({ path, method, assertions, static: staticMethod })
|
||||
}
|
||||
const assertion = (label: string, input: string, expected: string | number, args: ReadonlyArray<Argument> = []) => ({
|
||||
label,
|
||||
input,
|
||||
args,
|
||||
expected,
|
||||
})
|
||||
|
||||
add("test/built-ins/String/prototype/toLowerCase/S15.5.4.16_A2_T1.js", "toLowerCase", [
|
||||
assertion("#1 direct value", "Hello, WoRlD!", "hello, world!"),
|
||||
assertion("#2 String value", "Hello, WoRlD!", "hello, world!"),
|
||||
])
|
||||
add("test/built-ins/String/prototype/toLowerCase/special_casing.js", "toLowerCase", [
|
||||
assertion(
|
||||
"103 SpecialCasing mappings",
|
||||
"\u00DF\u0130\uFB00\uFB01\uFB02\uFB03\uFB04\uFB05\uFB06\u0587\uFB13\uFB14\uFB15\uFB16\uFB17\u0149\u0390\u03B0\u01F0\u1E96\u1E97\u1E98\u1E99\u1E9A\u1F50\u1F52\u1F54\u1F56\u1FB6\u1FC6\u1FD2\u1FD3\u1FD6\u1FD7\u1FE2\u1FE3\u1FE4\u1FE6\u1FE7\u1FF6\u1F80\u1F81\u1F82\u1F83\u1F84\u1F85\u1F86\u1F87\u1F88\u1F89\u1F8A\u1F8B\u1F8C\u1F8D\u1F8E\u1F8F\u1F90\u1F91\u1F92\u1F93\u1F94\u1F95\u1F96\u1F97\u1F98\u1F99\u1F9A\u1F9B\u1F9C\u1F9D\u1F9E\u1F9F\u1FA0\u1FA1\u1FA2\u1FA3\u1FA4\u1FA5\u1FA6\u1FA7\u1FA8\u1FA9\u1FAA\u1FAB\u1FAC\u1FAD\u1FAE\u1FAF\u1FB3\u1FBC\u1FC3\u1FCC\u1FF3\u1FFC\u1FB2\u1FB4\u1FC2\u1FC4\u1FF2\u1FF4\u1FB7\u1FC7\u1FF7",
|
||||
"\u00DF\u0069\u0307\uFB00\uFB01\uFB02\uFB03\uFB04\uFB05\uFB06\u0587\uFB13\uFB14\uFB15\uFB16\uFB17\u0149\u0390\u03B0\u01F0\u1E96\u1E97\u1E98\u1E99\u1E9A\u1F50\u1F52\u1F54\u1F56\u1FB6\u1FC6\u1FD2\u1FD3\u1FD6\u1FD7\u1FE2\u1FE3\u1FE4\u1FE6\u1FE7\u1FF6\u1F80\u1F81\u1F82\u1F83\u1F84\u1F85\u1F86\u1F87\u1F80\u1F81\u1F82\u1F83\u1F84\u1F85\u1F86\u1F87\u1F90\u1F91\u1F92\u1F93\u1F94\u1F95\u1F96\u1F97\u1F90\u1F91\u1F92\u1F93\u1F94\u1F95\u1F96\u1F97\u1FA0\u1FA1\u1FA2\u1FA3\u1FA4\u1FA5\u1FA6\u1FA7\u1FA0\u1FA1\u1FA2\u1FA3\u1FA4\u1FA5\u1FA6\u1FA7\u1FB3\u1FB3\u1FC3\u1FC3\u1FF3\u1FF3\u1FB2\u1FB4\u1FC2\u1FC4\u1FF2\u1FF4\u1FB7\u1FC7\u1FF7",
|
||||
),
|
||||
])
|
||||
add("test/built-ins/String/prototype/toLowerCase/special_casing_conditional.js", "toLowerCase", [
|
||||
assertion("single sigma", "\u03A3", "\u03C3"),
|
||||
assertion("preceded by cased", "A\u03A3", "a\u03C2"),
|
||||
assertion("preceded by supplementary cased", "\uD835\uDCA2\u03A3", "\uD835\uDCA2\u03C2"),
|
||||
assertion("preceded by full stop", "A.\u03A3", "a.\u03C2"),
|
||||
assertion("preceded by soft hyphen", "A\u00AD\u03A3", "a\u00AD\u03C2"),
|
||||
assertion("preceded by combining mark", "A\uD834\uDE42\u03A3", "a\uD834\uDE42\u03C2"),
|
||||
assertion("preceded by uncased combining mark", "\u0345\u03A3", "\u0345\u03C3"),
|
||||
assertion("preceded by cased and combining mark", "\u0391\u0345\u03A3", "\u03B1\u0345\u03C2"),
|
||||
assertion("followed by cased", "A\u03A3B", "a\u03C3b"),
|
||||
assertion("followed by supplementary cased", "A\u03A3\uD835\uDCA2", "a\u03C3\uD835\uDCA2"),
|
||||
assertion("followed by full stop and cased", "A\u03A3.b", "a\u03C3.b"),
|
||||
assertion("followed by soft hyphen and cased", "A\u03A3\u00ADB", "a\u03C3\u00ADb"),
|
||||
assertion("followed by combining mark and cased", "A\u03A3\uD834\uDE42B", "a\u03C3\uD834\uDE42b"),
|
||||
assertion("followed by uncased combining mark", "A\u03A3\u0345", "a\u03C2\u0345"),
|
||||
assertion("followed by combining mark and cased Greek", "A\u03A3\u0345\u0391", "a\u03C3\u0345\u03B1"),
|
||||
])
|
||||
add("test/built-ins/String/prototype/toLowerCase/Final_Sigma_U180E.js", "toLowerCase", [
|
||||
assertion("preceded by U+180E", "A\u180E\u03A3", "a\u180E\u03C2"),
|
||||
assertion("preceded by U+180E and followed by cased", "A\u180E\u03A3B", "a\u180E\u03C3b"),
|
||||
assertion("followed by U+180E", "A\u03A3\u180E", "a\u03C2\u180E"),
|
||||
assertion("followed by U+180E and cased", "A\u03A3\u180EB", "a\u03C3\u180Eb"),
|
||||
assertion("surrounded by U+180E", "A\u180E\u03A3\u180E", "a\u180E\u03C2\u180E"),
|
||||
assertion("surrounded by U+180E and followed by cased", "A\u180E\u03A3\u180EB", "a\u180E\u03C3\u180Eb"),
|
||||
])
|
||||
add("test/built-ins/String/prototype/toLowerCase/supplementary_plane.js", "toLowerCase", [
|
||||
assertion(
|
||||
"40 Deseret mappings",
|
||||
"\uD801\uDC00\uD801\uDC01\uD801\uDC02\uD801\uDC03\uD801\uDC04\uD801\uDC05\uD801\uDC06\uD801\uDC07\uD801\uDC08\uD801\uDC09\uD801\uDC0A\uD801\uDC0B\uD801\uDC0C\uD801\uDC0D\uD801\uDC0E\uD801\uDC0F\uD801\uDC10\uD801\uDC11\uD801\uDC12\uD801\uDC13\uD801\uDC14\uD801\uDC15\uD801\uDC16\uD801\uDC17\uD801\uDC18\uD801\uDC19\uD801\uDC1A\uD801\uDC1B\uD801\uDC1C\uD801\uDC1D\uD801\uDC1E\uD801\uDC1F\uD801\uDC20\uD801\uDC21\uD801\uDC22\uD801\uDC23\uD801\uDC24\uD801\uDC25\uD801\uDC26\uD801\uDC27",
|
||||
"\uD801\uDC28\uD801\uDC29\uD801\uDC2A\uD801\uDC2B\uD801\uDC2C\uD801\uDC2D\uD801\uDC2E\uD801\uDC2F\uD801\uDC30\uD801\uDC31\uD801\uDC32\uD801\uDC33\uD801\uDC34\uD801\uDC35\uD801\uDC36\uD801\uDC37\uD801\uDC38\uD801\uDC39\uD801\uDC3A\uD801\uDC3B\uD801\uDC3C\uD801\uDC3D\uD801\uDC3E\uD801\uDC3F\uD801\uDC40\uD801\uDC41\uD801\uDC42\uD801\uDC43\uD801\uDC44\uD801\uDC45\uD801\uDC46\uD801\uDC47\uD801\uDC48\uD801\uDC49\uD801\uDC4A\uD801\uDC4B\uD801\uDC4C\uD801\uDC4D\uD801\uDC4E\uD801\uDC4F",
|
||||
),
|
||||
])
|
||||
add("test/built-ins/String/prototype/toUpperCase/S15.5.4.18_A2_T1.js", "toUpperCase", [
|
||||
assertion("#1 direct value", "Hello, WoRlD!", "HELLO, WORLD!"),
|
||||
assertion("#2 String value", "Hello, WoRlD!", "HELLO, WORLD!"),
|
||||
])
|
||||
add("test/built-ins/String/prototype/toUpperCase/special_casing.js", "toUpperCase", [
|
||||
assertion(
|
||||
"103 SpecialCasing mappings",
|
||||
"\u00DF\u0130\uFB00\uFB01\uFB02\uFB03\uFB04\uFB05\uFB06\u0587\uFB13\uFB14\uFB15\uFB16\uFB17\u0149\u0390\u03B0\u01F0\u1E96\u1E97\u1E98\u1E99\u1E9A\u1F50\u1F52\u1F54\u1F56\u1FB6\u1FC6\u1FD2\u1FD3\u1FD6\u1FD7\u1FE2\u1FE3\u1FE4\u1FE6\u1FE7\u1FF6\u1F80\u1F81\u1F82\u1F83\u1F84\u1F85\u1F86\u1F87\u1F88\u1F89\u1F8A\u1F8B\u1F8C\u1F8D\u1F8E\u1F8F\u1F90\u1F91\u1F92\u1F93\u1F94\u1F95\u1F96\u1F97\u1F98\u1F99\u1F9A\u1F9B\u1F9C\u1F9D\u1F9E\u1F9F\u1FA0\u1FA1\u1FA2\u1FA3\u1FA4\u1FA5\u1FA6\u1FA7\u1FA8\u1FA9\u1FAA\u1FAB\u1FAC\u1FAD\u1FAE\u1FAF\u1FB3\u1FBC\u1FC3\u1FCC\u1FF3\u1FFC\u1FB2\u1FB4\u1FC2\u1FC4\u1FF2\u1FF4\u1FB7\u1FC7\u1FF7",
|
||||
"\u0053\u0053\u0130\u0046\u0046\u0046\u0049\u0046\u004C\u0046\u0046\u0049\u0046\u0046\u004C\u0053\u0054\u0053\u0054\u0535\u0552\u0544\u0546\u0544\u0535\u0544\u053B\u054E\u0546\u0544\u053D\u02BC\u004E\u0399\u0308\u0301\u03A5\u0308\u0301\u004A\u030C\u0048\u0331\u0054\u0308\u0057\u030A\u0059\u030A\u0041\u02BE\u03A5\u0313\u03A5\u0313\u0300\u03A5\u0313\u0301\u03A5\u0313\u0342\u0391\u0342\u0397\u0342\u0399\u0308\u0300\u0399\u0308\u0301\u0399\u0342\u0399\u0308\u0342\u03A5\u0308\u0300\u03A5\u0308\u0301\u03A1\u0313\u03A5\u0342\u03A5\u0308\u0342\u03A9\u0342\u1F08\u0399\u1F09\u0399\u1F0A\u0399\u1F0B\u0399\u1F0C\u0399\u1F0D\u0399\u1F0E\u0399\u1F0F\u0399\u1F08\u0399\u1F09\u0399\u1F0A\u0399\u1F0B\u0399\u1F0C\u0399\u1F0D\u0399\u1F0E\u0399\u1F0F\u0399\u1F28\u0399\u1F29\u0399\u1F2A\u0399\u1F2B\u0399\u1F2C\u0399\u1F2D\u0399\u1F2E\u0399\u1F2F\u0399\u1F28\u0399\u1F29\u0399\u1F2A\u0399\u1F2B\u0399\u1F2C\u0399\u1F2D\u0399\u1F2E\u0399\u1F2F\u0399\u1F68\u0399\u1F69\u0399\u1F6A\u0399\u1F6B\u0399\u1F6C\u0399\u1F6D\u0399\u1F6E\u0399\u1F6F\u0399\u1F68\u0399\u1F69\u0399\u1F6A\u0399\u1F6B\u0399\u1F6C\u0399\u1F6D\u0399\u1F6E\u0399\u1F6F\u0399\u0391\u0399\u0391\u0399\u0397\u0399\u0397\u0399\u03A9\u0399\u03A9\u0399\u1FBA\u0399\u0386\u0399\u1FCA\u0399\u0389\u0399\u1FFA\u0399\u038F\u0399\u0391\u0342\u0399\u0397\u0342\u0399\u03A9\u0342\u0399",
|
||||
),
|
||||
])
|
||||
add("test/built-ins/String/prototype/toUpperCase/supplementary_plane.js", "toUpperCase", [
|
||||
assertion(
|
||||
"40 Deseret mappings",
|
||||
"\uD801\uDC28\uD801\uDC29\uD801\uDC2A\uD801\uDC2B\uD801\uDC2C\uD801\uDC2D\uD801\uDC2E\uD801\uDC2F\uD801\uDC30\uD801\uDC31\uD801\uDC32\uD801\uDC33\uD801\uDC34\uD801\uDC35\uD801\uDC36\uD801\uDC37\uD801\uDC38\uD801\uDC39\uD801\uDC3A\uD801\uDC3B\uD801\uDC3C\uD801\uDC3D\uD801\uDC3E\uD801\uDC3F\uD801\uDC40\uD801\uDC41\uD801\uDC42\uD801\uDC43\uD801\uDC44\uD801\uDC45\uD801\uDC46\uD801\uDC47\uD801\uDC48\uD801\uDC49\uD801\uDC4A\uD801\uDC4B\uD801\uDC4C\uD801\uDC4D\uD801\uDC4E\uD801\uDC4F",
|
||||
"\uD801\uDC00\uD801\uDC01\uD801\uDC02\uD801\uDC03\uD801\uDC04\uD801\uDC05\uD801\uDC06\uD801\uDC07\uD801\uDC08\uD801\uDC09\uD801\uDC0A\uD801\uDC0B\uD801\uDC0C\uD801\uDC0D\uD801\uDC0E\uD801\uDC0F\uD801\uDC10\uD801\uDC11\uD801\uDC12\uD801\uDC13\uD801\uDC14\uD801\uDC15\uD801\uDC16\uD801\uDC17\uD801\uDC18\uD801\uDC19\uD801\uDC1A\uD801\uDC1B\uD801\uDC1C\uD801\uDC1D\uD801\uDC1E\uD801\uDC1F\uD801\uDC20\uD801\uDC21\uD801\uDC22\uD801\uDC23\uD801\uDC24\uD801\uDC25\uD801\uDC26\uD801\uDC27",
|
||||
),
|
||||
])
|
||||
|
||||
const whitespace = "\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF"
|
||||
const lineTerminators = "\u000A\u000D\u2028\u2029"
|
||||
const trim = (file: string, input: string, expected: string) =>
|
||||
add(`test/built-ins/String/prototype/trim/${file}`, "trim", [assertion("upstream assertion", input, expected)])
|
||||
|
||||
trim("15.5.4.20-3-1.js", lineTerminators, "")
|
||||
trim("15.5.4.20-3-2.js", whitespace, "")
|
||||
trim("15.5.4.20-3-3.js", whitespace + lineTerminators, "")
|
||||
trim("15.5.4.20-3-4.js", whitespace + lineTerminators + "abc", "abc")
|
||||
trim("15.5.4.20-3-5.js", "abc" + whitespace + lineTerminators, "abc")
|
||||
trim("15.5.4.20-3-6.js", whitespace + lineTerminators + "abc" + whitespace + lineTerminators, "abc")
|
||||
trim("15.5.4.20-3-7.js", "ab" + whitespace + lineTerminators + "cd", "ab" + whitespace + lineTerminators + "cd")
|
||||
trim("15.5.4.20-3-8.js", "\0\u0000", "\0\u0000")
|
||||
trim("15.5.4.20-3-9.js", "\0", "\0")
|
||||
trim("15.5.4.20-3-10.js", "\u0000", "\u0000")
|
||||
trim("15.5.4.20-3-11.js", "\0\u0000abc", "\0\u0000abc")
|
||||
trim("15.5.4.20-3-12.js", "abc\0\u0000", "abc\0\u0000")
|
||||
trim("15.5.4.20-3-13.js", "\0\u0000abc\0\u0000", "\0\u0000abc\0\u0000")
|
||||
trim("15.5.4.20-3-14.js", "a\0\u0000bc", "a\0\u0000bc")
|
||||
trim("15.5.4.20-4-1.js", "\u0009a bc \u0009", "a bc")
|
||||
trim("15.5.4.20-4-2.js", " \u0009abc \u0009", "abc")
|
||||
trim("15.5.4.20-4-3.js", "\u0009abc", "abc")
|
||||
trim("15.5.4.20-4-4.js", "\u000Babc", "abc")
|
||||
trim("15.5.4.20-4-5.js", "\u000Cabc", "abc")
|
||||
trim("15.5.4.20-4-6.js", "\u0020abc", "abc")
|
||||
trim("15.5.4.20-4-8.js", "\u00A0abc", "abc")
|
||||
trim("15.5.4.20-4-10.js", "\uFEFFabc", "abc")
|
||||
trim("15.5.4.20-4-11.js", "abc\u0009", "abc")
|
||||
trim("15.5.4.20-4-12.js", "abc\u000B", "abc")
|
||||
trim("15.5.4.20-4-13.js", "abc\u000C", "abc")
|
||||
trim("15.5.4.20-4-14.js", "abc\u0020", "abc")
|
||||
trim("15.5.4.20-4-16.js", "abc\u00A0", "abc")
|
||||
trim("15.5.4.20-4-18.js", "abc\uFEFF", "abc")
|
||||
trim("15.5.4.20-4-19.js", "\u0009abc\u0009", "abc")
|
||||
trim("15.5.4.20-4-20.js", "\u000Babc\u000B", "abc")
|
||||
trim("15.5.4.20-4-21.js", "\u000Cabc\u000C", "abc")
|
||||
trim("15.5.4.20-4-22.js", "\u0020abc\u0020", "abc")
|
||||
trim("15.5.4.20-4-24.js", "\u00A0abc\u00A0", "abc")
|
||||
trim("15.5.4.20-4-27.js", "\u0009\u0009", "")
|
||||
trim("15.5.4.20-4-28.js", "\u000B\u000B", "")
|
||||
trim("15.5.4.20-4-29.js", "\u000C\u000C", "")
|
||||
trim("15.5.4.20-4-30.js", "\u0020\u0020", "")
|
||||
trim("15.5.4.20-4-32.js", "\u00A0\u00A0", "")
|
||||
trim("15.5.4.20-4-34.js", "\uFEFF\uFEFF", "")
|
||||
trim("15.5.4.20-4-35.js", "ab\u0009c", "ab\u0009c")
|
||||
trim("15.5.4.20-4-36.js", "ab\u000Bc", "ab\u000Bc")
|
||||
trim("15.5.4.20-4-37.js", "ab\u000Cc", "ab\u000Cc")
|
||||
trim("15.5.4.20-4-38.js", "ab\u0020c", "ab\u0020c")
|
||||
trim("15.5.4.20-4-39.js", "ab\u0085c", "ab\u0085c")
|
||||
trim("15.5.4.20-4-40.js", "ab\u00A0c", "ab\u00A0c")
|
||||
trim("15.5.4.20-4-41.js", "ab\u200Bc", "ab\u200Bc")
|
||||
trim("15.5.4.20-4-42.js", "ab\uFEFFc", "ab\uFEFFc")
|
||||
trim("15.5.4.20-4-43.js", "\u000Aabc", "abc")
|
||||
trim("15.5.4.20-4-44.js", "\u000Dabc", "abc")
|
||||
trim("15.5.4.20-4-45.js", "\u2028abc", "abc")
|
||||
trim("15.5.4.20-4-46.js", "\u2029abc", "abc")
|
||||
trim("15.5.4.20-4-47.js", "abc\u000A", "abc")
|
||||
trim("15.5.4.20-4-48.js", "abc\u000D", "abc")
|
||||
trim("15.5.4.20-4-49.js", "abc\u2028", "abc")
|
||||
trim("15.5.4.20-4-50.js", "abc\u2029", "abc")
|
||||
trim("15.5.4.20-4-51.js", "\u000Aabc\u000A", "abc")
|
||||
trim("15.5.4.20-4-52.js", "\u000Dabc\u000D", "abc")
|
||||
trim("15.5.4.20-4-53.js", "\u2028abc\u2028", "abc")
|
||||
trim("15.5.4.20-4-54.js", "\u2029abc\u2029", "abc")
|
||||
trim("15.5.4.20-4-55.js", "\u000A\u000A", "")
|
||||
trim("15.5.4.20-4-56.js", "\u000D\u000D", "")
|
||||
trim("15.5.4.20-4-57.js", "\u2028\u2028", "")
|
||||
trim("15.5.4.20-4-58.js", "\u2029\u2029", "")
|
||||
trim("15.5.4.20-4-59.js", "\u2029 abc", "abc")
|
||||
trim("15.5.4.20-4-60.js", " ", "")
|
||||
add("test/built-ins/String/prototype/trim/u180e.js", "trim", [
|
||||
assertion("trailing U+180E", "_\u180E", "_\u180E"),
|
||||
assertion("only U+180E", "\u180E", "\u180E"),
|
||||
assertion("leading U+180E", "\u180E_", "\u180E_"),
|
||||
])
|
||||
|
||||
const directionalWhitespace = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF"
|
||||
add("test/built-ins/String/prototype/trimStart/this-value-whitespace.js", "trimStart", [
|
||||
assertion("all whitespace", directionalWhitespace + "a" + directionalWhitespace + "b" + directionalWhitespace, "a" + directionalWhitespace + "b" + directionalWhitespace),
|
||||
])
|
||||
add("test/built-ins/String/prototype/trimStart/this-value-line-terminator.js", "trimStart", [
|
||||
assertion("all line terminators", lineTerminators + "a" + lineTerminators + "b" + lineTerminators, "a" + lineTerminators + "b" + lineTerminators),
|
||||
])
|
||||
add("test/built-ins/String/prototype/trimEnd/this-value-whitespace.js", "trimEnd", [
|
||||
assertion("all whitespace", directionalWhitespace + "a" + directionalWhitespace + "b" + directionalWhitespace, directionalWhitespace + "a" + directionalWhitespace + "b"),
|
||||
])
|
||||
add("test/built-ins/String/prototype/trimEnd/this-value-line-terminator.js", "trimEnd", [
|
||||
assertion("all line terminators", lineTerminators + "a" + lineTerminators + "b" + lineTerminators, lineTerminators + "a" + lineTerminators + "b"),
|
||||
])
|
||||
add("test/built-ins/String/prototype/repeat/repeat-string-n-times.js", "repeat", [
|
||||
assertion("repeat once", "abc", "abc", [1]),
|
||||
assertion("repeat three times", "abc", "abcabcabc", [3]),
|
||||
{ label: "repeat 10000 times length", input: ".", args: [10000], expected: 10000, outcome: "length" },
|
||||
])
|
||||
add("test/built-ins/String/prototype/repeat/empty-string-returns-empty.js", "repeat", [
|
||||
assertion("count 1", "", "", [1]),
|
||||
assertion("count 3", "", "", [3]),
|
||||
assertion("maximum 32-bit count", "", "", [0xffffffff]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/repeat/count-is-zero-returns-empty-string.js", "repeat", [
|
||||
assertion("zero", "foo", "", [0]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/repeat/count-coerced-to-zero-returns-empty-string.js", "repeat", [
|
||||
assertion("fraction truncates to zero", "abc", "", [0.9]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/padStart/fill-string-empty.js", "padStart", [assertion("empty fill", "abc", "abc", [5, ""])])
|
||||
add("test/built-ins/String/prototype/padStart/normal-operation.js", "padStart", [
|
||||
assertion("truncated multi-character fill", "abc", "defdabc", [7, "def"]),
|
||||
assertion("single-character fill", "abc", "**abc", [5, "*"]),
|
||||
assertion("truncated surrogate pair", "abc", "\uD83D\uDCA9\uD83Dabc", [6, "\uD83D\uDCA9"]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/padStart/fill-string-omitted.js", "padStart", [
|
||||
assertion("omitted fill", "abc", " abc", [5]),
|
||||
assertion("undefined fill", "abc", " abc", [5, undefined]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/padStart/max-length-not-greater-than-string.js", "padStart", [
|
||||
assertion("NaN", "abc", "abc", [NaN, "def"]),
|
||||
assertion("negative infinity", "abc", "abc", [-Infinity, "def"]),
|
||||
assertion("zero", "abc", "abc", [0, "def"]),
|
||||
assertion("negative one", "abc", "abc", [-1, "def"]),
|
||||
assertion("equal length", "abc", "abc", [3, "def"]),
|
||||
assertion("fraction truncates", "abc", "abc", [3.9999, "def"]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/padEnd/fill-string-empty.js", "padEnd", [assertion("empty fill", "abc", "abc", [5, ""])])
|
||||
add("test/built-ins/String/prototype/padEnd/normal-operation.js", "padEnd", [
|
||||
assertion("truncated multi-character fill", "abc", "abcdefd", [7, "def"]),
|
||||
assertion("single-character fill", "abc", "abc**", [5, "*"]),
|
||||
assertion("truncated surrogate pair", "abc", "abc\uD83D\uDCA9\uD83D", [6, "\uD83D\uDCA9"]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/padEnd/fill-string-omitted.js", "padEnd", [
|
||||
assertion("omitted fill", "abc", "abc ", [5]),
|
||||
assertion("undefined fill", "abc", "abc ", [5, undefined]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/padEnd/max-length-not-greater-than-string.js", "padEnd", [
|
||||
assertion("NaN", "abc", "abc", [NaN, "def"]),
|
||||
assertion("negative infinity", "abc", "abc", [-Infinity, "def"]),
|
||||
assertion("zero", "abc", "abc", [0, "def"]),
|
||||
assertion("negative one", "abc", "abc", [-1, "def"]),
|
||||
assertion("equal length", "abc", "abc", [3, "def"]),
|
||||
assertion("fraction truncates", "abc", "abc", [3.9999, "def"]),
|
||||
])
|
||||
|
||||
add("test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T4.js", "charAt", [assertion("omitted position", "lego", "l")])
|
||||
add("test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T7.js", "charAt", [assertion("undefined position", "lego", "l", [undefined])])
|
||||
add("test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T8.js", "charAt", [assertion("undefined position", "42", "4", [undefined])])
|
||||
add("test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T1.js", "charAt", ["A", "B", "C", "A", "B", "C"].map((expected, position) => assertion(`position ${position}`, "ABCABC", expected, [position])))
|
||||
add("test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T2.js", "charAt", [-2, -1].map((position) => assertion(`position ${position}`, "ABCABC", "", [position])))
|
||||
add("test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T3.js", "charAt", [6, 7].map((position) => assertion(`position ${position}`, "ABCABC", "", [position])))
|
||||
add("test/built-ins/String/prototype/charAt/S9.4_A1.js", "charAt", [assertion("NaN position", "abc", "a", [NaN])])
|
||||
add("test/built-ins/String/prototype/charAt/S9.4_A2.js", "charAt", [
|
||||
assertion("positive zero", "abc", "a", [0]),
|
||||
assertion("negative zero", "abc", "a", [-0]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/charAt/pos-rounding.js", "charAt", [
|
||||
assertion("-0.99999", "abc", "a", [-0.99999]),
|
||||
assertion("-0.00001", "abc", "a", [-0.00001]),
|
||||
assertion("0.00001", "abc", "a", [0.00001]),
|
||||
assertion("0.99999", "abc", "a", [0.99999]),
|
||||
assertion("1.00001", "abc", "b", [1.00001]),
|
||||
assertion("1.99999", "abc", "b", [1.99999]),
|
||||
])
|
||||
|
||||
add("test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T4.js", "charCodeAt", [assertion("omitted position", "smart", 0x73)])
|
||||
add("test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T7.js", "charCodeAt", [assertion("undefined position", "lego", 0x6c, [undefined])])
|
||||
add("test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T8.js", "charCodeAt", [assertion("undefined position", "42", 0x34, [undefined])])
|
||||
add("test/built-ins/String/prototype/charCodeAt/pos-rounding.js", "charCodeAt", [
|
||||
assertion("-0.99999", "abc", 0x61, [-0.99999]),
|
||||
assertion("-0.00001", "abc", 0x61, [-0.00001]),
|
||||
assertion("0.00001", "abc", 0x61, [0.00001]),
|
||||
assertion("0.99999", "abc", 0x61, [0.99999]),
|
||||
assertion("1.00001", "abc", 0x62, [1.00001]),
|
||||
assertion("1.99999", "abc", 0x62, [1.99999]),
|
||||
])
|
||||
|
||||
add("test/built-ins/String/prototype/codePointAt/return-single-code-unit.js", "codePointAt", [
|
||||
assertion("a", "abc", 97, [0]), assertion("b", "abc", 98, [1]), assertion("c", "abc", 99, [2]),
|
||||
assertion("ordinary BMP", "\uAAAA\uBBBB", 0xaaaa, [0]), assertion("before high-surrogate range", "\uD7FF\uAAAA", 0xd7ff, [0]),
|
||||
assertion("low surrogate", "\uDC00\uAAAA", 0xdc00, [0]), assertion("trailing D800", "123\uD800", 0xd800, [3]),
|
||||
assertion("trailing DAAA", "123\uDAAA", 0xdaaa, [3]), assertion("trailing DBFF", "123\uDBFF", 0xdbff, [3]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/codePointAt/return-first-code-unit.js", "codePointAt", [
|
||||
assertion("D800 before DBFF", "\uD800\uDBFF", 0xd800, [0]), assertion("D800 before E000", "\uD800\uE000", 0xd800, [0]),
|
||||
assertion("DAAA before DBFF", "\uDAAA\uDBFF", 0xdaaa, [0]), assertion("DAAA before E000", "\uDAAA\uE000", 0xdaaa, [0]),
|
||||
assertion("DBFF before DBFF", "\uDBFF\uDBFF", 0xdbff, [0]), assertion("DBFF before E000", "\uDBFF\uE000", 0xdbff, [0]),
|
||||
assertion("D800 before NUL", "\uD800\u0000", 0xd800, [0]), assertion("D800 before FFFF", "\uD800\uFFFF", 0xd800, [0]),
|
||||
assertion("DAAA before NUL", "\uDAAA\u0000", 0xdaaa, [0]), assertion("DAAA before FFFF", "\uDAAA\uFFFF", 0xdaaa, [0]),
|
||||
assertion("DBFF before FFFF", "\uDBFF\uFFFF", 0xdbff, [0]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/codePointAt/return-utf16-decode.js", "codePointAt", [
|
||||
assertion("U+10000", "\uD800\uDC00", 65536, [0]), assertion("U+101D0", "\uD800\uDDD0", 66000, [0]),
|
||||
assertion("U+103FF", "\uD800\uDFFF", 66559, [0]), assertion("U+BA800", "\uDAAA\uDC00", 763904, [0]),
|
||||
assertion("U+BA9D0", "\uDAAA\uDDD0", 764368, [0]), assertion("U+BABFF", "\uDAAA\uDFFF", 764927, [0]),
|
||||
assertion("U+10FC00", "\uDBFF\uDC00", 1113088, [0]), assertion("U+10FDD0", "\uDBFF\uDDD0", 1113552, [0]),
|
||||
assertion("U+10FFFF", "\uDBFF\uDFFF", 1114111, [0]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/codePointAt/return-code-unit-coerced-position.js", "codePointAt", [
|
||||
assertion("NaN", "\uD800\uDC00", 65536, [NaN]), assertion("undefined", "\uD800\uDC00", 65536, [undefined]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/codePointAt/returns-undefined-on-position-less-than-zero.js", "codePointAt", [
|
||||
{ label: "negative one", input: "abc", args: [-1], outcome: "undefined" },
|
||||
{ label: "negative infinity", input: "abc", args: [-Infinity], outcome: "undefined" },
|
||||
])
|
||||
add("test/built-ins/String/prototype/codePointAt/returns-undefined-on-position-equal-or-more-than-size.js", "codePointAt", [
|
||||
{ label: "equal to size", input: "abc", args: [3], outcome: "undefined" },
|
||||
{ label: "greater than size", input: "abc", args: [4], outcome: "undefined" },
|
||||
{ label: "positive infinity", input: "abc", args: [Infinity], outcome: "undefined" },
|
||||
])
|
||||
|
||||
add("test/built-ins/String/prototype/at/returns-code-unit.js", "at", [
|
||||
assertion("position 0", "12\uD80034", "1", [0]), assertion("position 1", "12\uD80034", "2", [1]),
|
||||
assertion("unpaired surrogate", "12\uD80034", "\uD800", [2]), assertion("position 3", "12\uD80034", "3", [3]),
|
||||
assertion("position 4", "12\uD80034", "4", [4]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/at/returns-item.js", "at", ["1", "2", "3", "4", "5"].map((expected, position) => assertion(`position ${position}`, "12345", expected, [position])))
|
||||
add("test/built-ins/String/prototype/at/returns-item-relative-index.js", "at", [
|
||||
assertion("zero", "12345", "1", [0]), assertion("negative one", "12345", "5", [-1]),
|
||||
assertion("negative three", "12345", "3", [-3]), assertion("negative four", "12345", "2", [-4]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/at/returns-undefined-for-out-of-range-index.js", "at", [-2, 0, 1].map((position) => ({ label: `position ${position}`, input: "", args: [position], outcome: "undefined" })))
|
||||
add("test/built-ins/String/prototype/at/index-non-numeric-argument-tointeger.js", "at", [assertion("undefined", "01", "0", [undefined])])
|
||||
|
||||
add("test/built-ins/String/prototype/concat/S15.5.4.6_A1_T4.js", "concat", [assertion("no arguments", "lego", "lego")])
|
||||
add("test/built-ins/String/prototype/toString/string-primitive.js", "toString", [
|
||||
assertion("empty string", "", ""), assertion("non-empty string", "str", "str"),
|
||||
])
|
||||
|
||||
add("test/built-ins/String/prototype/normalize/return-normalized-string.js", "normalize", [
|
||||
assertion("NFC short", "\u1E9B\u0323", "\u1E9B\u0323", ["NFC"]),
|
||||
assertion("NFD short", "\u1E9B\u0323", "\u017F\u0323\u0307", ["NFD"]),
|
||||
assertion("NFKC short", "\u1E9B\u0323", "\u1E69", ["NFKC"]),
|
||||
assertion("NFKD short", "\u1E9B\u0323", "\u0073\u0323\u0307", ["NFKD"]),
|
||||
assertion("NFC long", "\u00C5\u2ADC\u0958\u2126\u0344", "\xC5\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", ["NFC"]),
|
||||
assertion("NFD long", "\u00C5\u2ADC\u0958\u2126\u0344", "A\u030A\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", ["NFD"]),
|
||||
assertion("NFKC long", "\u00C5\u2ADC\u0958\u2126\u0344", "\xC5\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", ["NFKC"]),
|
||||
assertion("NFKD long", "\u00C5\u2ADC\u0958\u2126\u0344", "A\u030A\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", ["NFKD"]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/normalize/return-normalized-string-using-default-parameter.js", "normalize", [
|
||||
assertion("omitted", "\u00C5\u2ADC\u0958\u2126\u0344", "\xC5\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301"),
|
||||
assertion("undefined", "\u00C5\u2ADC\u0958\u2126\u0344", "\xC5\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", [undefined]),
|
||||
])
|
||||
add("test/built-ins/String/prototype/normalize/form-is-not-valid-throws.js", "normalize", [
|
||||
{ label: "bar", input: "foo", args: ["bar"], outcome: "RangeError" },
|
||||
{ label: "NFC1", input: "foo", args: ["NFC1"], outcome: "RangeError" },
|
||||
])
|
||||
|
||||
add("test/built-ins/String/prototype/localeCompare/15.5.4.9_CE.js", "localeCompare", [
|
||||
assertion("D70", "o\u0308", 0, ["ö"]), assertion("reordered diaeresis", "ä\u0323", 0, ["a\u0323\u0308"]),
|
||||
assertion("reordered marks", "a\u0308\u0323", 0, ["a\u0323\u0308"]), assertion("precomposed dot below", "ạ\u0308", 0, ["a\u0323\u0308"]),
|
||||
assertion("breve after diaeresis", "ä\u0306", 0, ["a\u0308\u0306"]), assertion("diaeresis after breve", "ă\u0308", 0, ["a\u0306\u0308"]),
|
||||
assertion("Hangul", "\u1111\u1171\u11B6", 0, ["퓛"]), assertion("angstrom compatibility", "Å", 0, ["Å"]),
|
||||
assertion("angstrom decomposed", "Å", 0, ["A\u030A"]), assertion("reordered horn and dot", "x\u031B\u0323", 0, ["x\u0323\u031B"]),
|
||||
assertion("Vietnamese precomposed 1", "ự", 0, ["ụ\u031B"]), assertion("Vietnamese decomposed", "ự", 0, ["u\u031B\u0323"]),
|
||||
assertion("Vietnamese precomposed 2", "ự", 0, ["ư\u0323"]), assertion("Vietnamese reordered", "ự", 0, ["u\u0323\u031B"]),
|
||||
assertion("cedilla", "Ç", 0, ["C\u0327"]), assertion("q reordered", "q\u0307\u0323", 0, ["q\u0323\u0307"]),
|
||||
assertion("Hangul syllable", "가", 0, ["\u1100\u1161"]), assertion("ohm", "Ω", 0, ["Ω"]),
|
||||
assertion("angstrom", "Å", 0, ["A\u030A"]), assertion("circumflex", "ô", 0, ["o\u0302"]),
|
||||
assertion("s with marks", "ṩ", 0, ["s\u0323\u0307"]), assertion("d composed plus dot", "ḋ\u0323", 0, ["d\u0323\u0307"]),
|
||||
assertion("d two precompositions", "ḋ\u0323", 0, ["ḍ\u0307"]),
|
||||
])
|
||||
|
||||
add("test/built-ins/String/fromCharCode/S15.5.3.2_A2.js", "fromCharCode", [{ label: "no arguments", expected: "" }], true)
|
||||
add("test/built-ins/String/fromCharCode/S15.5.3.2_A3_T1.js", "fromCharCode", [{ label: "ABBA", args: [65, 66, 66, 65], expected: "ABBA" }], true)
|
||||
add("test/built-ins/String/fromCharCode/S9.7_A1.js", "fromCharCode", [
|
||||
{ label: "NaN", args: [NaN], expected: 0 }, { label: "zero", args: [0], expected: 0 }, { label: "negative zero", args: [-0], expected: 0 },
|
||||
{ label: "positive infinity", args: [Infinity], expected: 0 }, { label: "negative infinity", args: [-Infinity], expected: 0 },
|
||||
], true)
|
||||
add("test/built-ins/String/fromCharCode/S9.7_A2.1.js", "fromCharCode", [
|
||||
[0, 0], [1, 1], [-1, 65535], [65535, 65535], [65534, 65534], [65536, 0], [4294967295, 65535], [4294967294, 65534], [4294967296, 0],
|
||||
].map(([input, expected]) => ({ label: String(input), args: [input!], expected })), true)
|
||||
add("test/built-ins/String/fromCharCode/S9.7_A2.2.js", "fromCharCode", [
|
||||
[-32767, 32769], [-32768, 32768], [-32769, 32767], [-65535, 1], [-65536, 0], [-65537, 65535], [65535, 65535], [65536, 0], [65537, 1], [131071, 65535], [131072, 0], [131073, 1],
|
||||
].map(([input, expected]) => ({ label: String(input), args: [input!], expected })), true)
|
||||
add("test/built-ins/String/fromCharCode/S9.7_A3.2_T1.js", "fromCharCode", [
|
||||
{ label: "positive fraction", args: [1.2345], expected: 1 }, { label: "negative fraction", args: [-5.4321], expected: 65531 },
|
||||
], true)
|
||||
|
||||
add("test/built-ins/String/fromCodePoint/arguments-is-empty.js", "fromCodePoint", [{ label: "no arguments", expected: "" }], true)
|
||||
add("test/built-ins/String/fromCodePoint/return-string-value.js", "fromCodePoint", [
|
||||
{ label: "NUL", args: [0], expected: "\x00" }, { label: "asterisk", args: [42], expected: "*" },
|
||||
{ label: "AZ", args: [65, 90], expected: "AZ" }, { label: "Cyrillic", args: [0x404], expected: "\u0404" },
|
||||
{ label: "hex supplementary", args: [0x2f804], expected: "\uD87E\uDC04" }, { label: "decimal supplementary", args: [194564], expected: "\uD87E\uDC04" },
|
||||
{ label: "mixed supplementary", args: [0x1d306, 0x61, 0x1d307], expected: "\uD834\uDF06a\uD834\uDF07" },
|
||||
{ label: "maximum code point", args: [1114111], expected: "\uDBFF\uDFFF" },
|
||||
], true)
|
||||
add("test/built-ins/String/fromCodePoint/argument-is-not-integer.js", "fromCodePoint", [
|
||||
{ label: "fraction", args: [3.14], outcome: "RangeError" }, { label: "fraction after valid", args: [42, 3.14], outcome: "RangeError" },
|
||||
], true)
|
||||
add("test/built-ins/String/fromCodePoint/number-is-out-of-range.js", "fromCodePoint", [
|
||||
{ label: "negative one", args: [-1], outcome: "RangeError" }, { label: "negative after valid", args: [1, -1], outcome: "RangeError" },
|
||||
{ label: "above maximum", args: [1114112], outcome: "RangeError" }, { label: "infinity", args: [Infinity], outcome: "RangeError" },
|
||||
], true)
|
||||
|
||||
describe("Test262-adapted core String behavior", () => {
|
||||
for (const vector of vectors) {
|
||||
test(vector.path, async () => {
|
||||
const results = vector.assertions.map((item) => {
|
||||
const args = (item.args ?? []).map(literal).join(", ")
|
||||
const expression = vector.static
|
||||
? `String.${vector.method}(${args})`
|
||||
: `${JSON.stringify(item.input)}.${vector.method}(${args})`
|
||||
const observed = vector.static && vector.method === "fromCharCode" && typeof item.expected === "number"
|
||||
? `${expression}.charCodeAt(0)`
|
||||
: expression
|
||||
const checked = item.outcome === "undefined"
|
||||
? `${observed} === undefined`
|
||||
: item.outcome === "length"
|
||||
? `${observed}.length`
|
||||
: item.outcome === "RangeError"
|
||||
? `(() => { try { ${observed}; return false } catch (error) { return error instanceof RangeError } })()`
|
||||
: observed
|
||||
return `{ label: ${JSON.stringify(item.label)}, value: ${checked} }`
|
||||
})
|
||||
const expected = vector.assertions.map((item) => ({
|
||||
label: item.label,
|
||||
value: item.outcome === undefined || item.outcome === "length" ? item.expected! : true,
|
||||
}))
|
||||
expect(await value(`return [${results.join(",")}]`)).toEqual(expected)
|
||||
})
|
||||
}
|
||||
})
|
||||
625
packages/codemode/test/string-regexp-test262.test.ts
Normal file
625
packages/codemode/test/string-regexp-test262.test.ts
Normal file
|
|
@ -0,0 +1,625 @@
|
|||
/*
|
||||
* Portions adapted from Test262 at revision 250f204f23a9249ff204be2baec29600faae7b75:
|
||||
* - test/built-ins/String/prototype/split/separator-regexp.js
|
||||
* - test/built-ins/String/prototype/split/arguments-are-regexp-s-and-3-and-instance-is-string-a-b-c-de-f.js
|
||||
* - test/built-ins/String/prototype/split/argument-is-regexp-s-and-instance-is-string-a-b-c-de-f.js
|
||||
* - test/built-ins/String/prototype/split/argument-is-regexp-d-and-instance-is-string-dfe23iu-34-65.js
|
||||
* - test/built-ins/String/prototype/split/argument-is-regexp-reg-exp-d-and-instance-is-string-dfe23iu-34-65.js
|
||||
* - test/built-ins/String/prototype/split/argument-is-regexp-a-z-and-instance-is-string-abc.js
|
||||
* - test/built-ins/String/prototype/split/argument-is-reg-exp-a-z-and-instance-is-string-abc.js
|
||||
* - test/built-ins/String/prototype/split/arguments-are-regexp-l-and-undefined-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/arguments-are-regexp-l-and-0-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/arguments-are-regexp-l-and-1-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/arguments-are-regexp-l-and-2-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/arguments-are-regexp-l-and-3-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/arguments-are-regexp-l-and-4-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/argument-is-regexp-l-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/argument-is-new-reg-exp-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/arguments-are-new-reg-exp-and-0-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/arguments-are-new-reg-exp-and-1-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/arguments-are-new-reg-exp-and-2-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/arguments-are-new-reg-exp-and-3-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/arguments-are-new-reg-exp-and-4-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/arguments-are-new-reg-exp-and-undefined-and-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-2-instance-is-string-one-two-three-four-five.js
|
||||
* - test/built-ins/String/prototype/split/separator-regexp-comma-instance-is-string-one-1-two-2-four-4.js
|
||||
* - test/built-ins/String/prototype/split/argument-is-regexp-x-and-instance-is-string-a-b-c-de-f.js
|
||||
* - test/built-ins/String/prototype/replace/regexp-capture-by-index.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A1_T17.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A2_T1.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A2_T2.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A2_T3.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A2_T4.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A2_T5.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A2_T6.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A2_T7.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A2_T8.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A2_T9.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A2_T10.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A3_T1.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A3_T2.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A3_T3.js
|
||||
* - test/built-ins/String/prototype/replace/S15.5.4.11_A5_T1.js
|
||||
* - test/built-ins/String/prototype/replaceAll/searchValue-replacer-RegExp-call.js
|
||||
* - test/built-ins/String/prototype/replaceAll/searchValue-empty-string.js
|
||||
* - test/built-ins/String/prototype/replaceAll/searchValue-empty-string-this-empty-string.js
|
||||
* - test/built-ins/String/prototype/replaceAll/replaceValue-value-replaces-string.js
|
||||
* - test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024.js
|
||||
* - test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0024.js
|
||||
* - test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0026.js
|
||||
* - test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0060.js
|
||||
* - test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0027.js
|
||||
* - test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024N.js
|
||||
* - test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024NN.js
|
||||
* - test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x003C.js
|
||||
* - test/built-ins/String/prototype/match/S15.5.4.10_A1_T14.js
|
||||
* - test/built-ins/String/prototype/match/S15.5.4.10_A2_T2.js
|
||||
* - test/built-ins/String/prototype/match/S15.5.4.10_A2_T3.js
|
||||
* - test/built-ins/String/prototype/match/S15.5.4.10_A2_T4.js
|
||||
* - test/built-ins/String/prototype/match/S15.5.4.10_A2_T5.js
|
||||
* - test/built-ins/String/prototype/match/S15.5.4.10_A2_T6.js
|
||||
* - test/built-ins/String/prototype/match/S15.5.4.10_A2_T7.js
|
||||
* - test/built-ins/String/prototype/match/S15.5.4.10_A2_T8.js
|
||||
* - test/built-ins/String/prototype/match/S15.5.4.10_A2_T12.js
|
||||
* - test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-v-u-flag.js
|
||||
* - test/built-ins/String/prototype/search/S15.5.4.12_A1_T14.js
|
||||
* - test/built-ins/String/prototype/search/S15.5.4.12_A2_T1.js
|
||||
* - test/built-ins/String/prototype/search/S15.5.4.12_A2_T2.js
|
||||
* - test/built-ins/String/prototype/search/S15.5.4.12_A2_T3.js
|
||||
* - test/built-ins/String/prototype/search/S15.5.4.12_A2_T4.js
|
||||
* - test/built-ins/String/prototype/search/S15.5.4.12_A2_T5.js
|
||||
* - test/built-ins/String/prototype/search/S15.5.4.12_A2_T6.js
|
||||
* - test/built-ins/String/prototype/search/S15.5.4.12_A2_T7.js
|
||||
* - test/built-ins/String/prototype/search/S15.5.4.12_A3_T1.js
|
||||
* - test/built-ins/String/prototype/search/S15.5.4.12_A3_T2.js
|
||||
*
|
||||
* Copyright 2009 the Sputnik authors. All rights reserved.
|
||||
* Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||
* Copyright (C) 2020 Rick Waldron. All rights reserved.
|
||||
* Copyright (C) 2023 Richard Gibson. All rights reserved.
|
||||
* Copyright (C) 2024 Tan Meng. All rights reserved.
|
||||
* Test262 portions are governed by the BSD license in LICENSE.test262.
|
||||
*/
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { CodeMode } from "../src/index.js"
|
||||
|
||||
type Vector = {
|
||||
readonly path: string
|
||||
readonly code: string
|
||||
readonly expected: CodeMode.DataValue
|
||||
}
|
||||
|
||||
const value = async (code: string) => {
|
||||
const result = await Effect.runPromise(CodeMode.execute({ code, tools: {} }))
|
||||
if (!result.ok) throw new Error(`expected success, got ${result.error.kind}: ${result.error.message}`)
|
||||
return result.value
|
||||
}
|
||||
|
||||
const run = (name: string, vectors: ReadonlyArray<Vector>) => {
|
||||
describe(name, () => {
|
||||
for (const vector of vectors) {
|
||||
test(vector.path, async () => {
|
||||
expect(await value(vector.code)).toEqual(vector.expected)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
run("Test262-adapted regexp split behavior", [
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/separator-regexp.js",
|
||||
code: `
|
||||
return [
|
||||
"x".split(/^/), "x".split(/$/), "x".split(/.?/), "x".split(/.*/), "x".split(/.+/),
|
||||
"x".split(/.*?/), "x".split(/.{1}/), "x".split(/.{1,}/), "x".split(/.{1,2}/),
|
||||
"x".split(/()/), "x".split(/./), "x".split(/(?:)/), "x".split(/(...)/),
|
||||
"x".split(/(|)/), "x".split(/[]/), "x".split(/[^]/), "x".split(/[.-.]/),
|
||||
"x".split(/\\0/), "x".split(/\\b/), "x".split(/\\B/), "x".split(/\\d/),
|
||||
"x".split(/\\D/), "x".split(/\\n/), "x".split(/\\r/), "x".split(/\\s/),
|
||||
"x".split(/\\S/), "x".split(/\\v/), "x".split(/\\w/), "x".split(/\\W/),
|
||||
]
|
||||
`,
|
||||
expected: [
|
||||
["x"], ["x"], ["", ""], ["", ""], ["", ""], ["x"], ["", ""], ["", ""], ["", ""],
|
||||
["x"], ["", ""], ["x"], ["x"], ["x"], ["x"], ["", ""], ["x"], ["x"], ["x"],
|
||||
["x"], ["x"], ["", ""], ["x"], ["x"], ["x"], ["", ""], ["x"], ["", ""], ["x"],
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/arguments-are-regexp-s-and-3-and-instance-is-string-a-b-c-de-f.js",
|
||||
code: `return "a b c de f".split(/\\s/, 3)`,
|
||||
expected: ["a", "b", "c"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/argument-is-regexp-s-and-instance-is-string-a-b-c-de-f.js",
|
||||
code: `return "a b c de f".split(/\\s/)`,
|
||||
expected: ["a", "b", "c", "de", "f"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/argument-is-regexp-d-and-instance-is-string-dfe23iu-34-65.js",
|
||||
code: `return "dfe23iu 34 =+65--".split(/\\d+/)`,
|
||||
expected: ["dfe", "iu ", " =+", "--"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/argument-is-regexp-reg-exp-d-and-instance-is-string-dfe23iu-34-65.js",
|
||||
code: `return "dfe23iu 34 =+65--".split(new RegExp("\\\\d+"))`,
|
||||
expected: ["dfe", "iu ", " =+", "--"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/argument-is-regexp-a-z-and-instance-is-string-abc.js",
|
||||
code: `return "abc".split(/[a-z]/)`,
|
||||
expected: ["", "", "", ""],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/argument-is-reg-exp-a-z-and-instance-is-string-abc.js",
|
||||
code: `return "abc".split(new RegExp("[a-z]"))`,
|
||||
expected: ["", "", "", ""],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/arguments-are-regexp-l-and-undefined-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(/l/, undefined)`,
|
||||
expected: ["he", "", "o"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/arguments-are-regexp-l-and-0-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(/l/, 0)`,
|
||||
expected: [],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/arguments-are-regexp-l-and-1-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(/l/, 1)`,
|
||||
expected: ["he"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/arguments-are-regexp-l-and-2-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(/l/, 2)`,
|
||||
expected: ["he", ""],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/arguments-are-regexp-l-and-3-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(/l/, 3)`,
|
||||
expected: ["he", "", "o"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/arguments-are-regexp-l-and-4-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(/l/, 4)`,
|
||||
expected: ["he", "", "o"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/argument-is-regexp-l-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(/l/)`,
|
||||
expected: ["he", "", "o"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/argument-is-new-reg-exp-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(new RegExp())`,
|
||||
expected: ["h", "e", "l", "l", "o"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/arguments-are-new-reg-exp-and-0-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(new RegExp(), 0)`,
|
||||
expected: [],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/arguments-are-new-reg-exp-and-1-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(new RegExp(), 1)`,
|
||||
expected: ["h"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/arguments-are-new-reg-exp-and-2-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(new RegExp(), 2)`,
|
||||
expected: ["h", "e"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/arguments-are-new-reg-exp-and-3-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(new RegExp(), 3)`,
|
||||
expected: ["h", "e", "l"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/arguments-are-new-reg-exp-and-4-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(new RegExp(), 4)`,
|
||||
expected: ["h", "e", "l", "l"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/arguments-are-new-reg-exp-and-undefined-and-instance-is-string-hello.js",
|
||||
code: `return "hello".split(new RegExp(), undefined)`,
|
||||
expected: ["h", "e", "l", "l", "o"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-2-instance-is-string-one-two-three-four-five.js",
|
||||
code: `return "one two three four five".split(/ /, 2)`,
|
||||
expected: ["one", "two"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/separator-regexp-comma-instance-is-string-one-1-two-2-four-4.js",
|
||||
code: `return "one-1,two-2,four-4".split(/,/)`,
|
||||
expected: ["one-1", "two-2", "four-4"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/argument-is-regexp-x-and-instance-is-string-a-b-c-de-f.js",
|
||||
code: `return "a b c de f".split(/X/)`,
|
||||
expected: ["a b c de f"],
|
||||
},
|
||||
])
|
||||
|
||||
run("Test262-adapted replace behavior", [
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/regexp-capture-by-index.js",
|
||||
code: `
|
||||
const str = "foo-x-bar"
|
||||
const patterns = ["x", /x/, /(x)/, /(x)($^)?/, /((((((((((x))))))))))/]
|
||||
const replacements = ["|$0|", "|$00|", "|$000|", "|$1|", "|$01|", "|$010|", "|$2|", "|$02|", "|$020|", "|$10|", "|$100|", "|$20|", "|$200|"]
|
||||
return replacements.flatMap((replacement) => patterns.map((pattern) => str.replace(pattern, replacement)))
|
||||
`,
|
||||
expected: [
|
||||
"foo-|$0|-bar", "foo-|$0|-bar", "foo-|$0|-bar", "foo-|$0|-bar", "foo-|$0|-bar",
|
||||
"foo-|$00|-bar", "foo-|$00|-bar", "foo-|$00|-bar", "foo-|$00|-bar", "foo-|$00|-bar",
|
||||
"foo-|$000|-bar", "foo-|$000|-bar", "foo-|$000|-bar", "foo-|$000|-bar", "foo-|$000|-bar",
|
||||
"foo-|$1|-bar", "foo-|$1|-bar", "foo-|x|-bar", "foo-|x|-bar", "foo-|x|-bar",
|
||||
"foo-|$01|-bar", "foo-|$01|-bar", "foo-|x|-bar", "foo-|x|-bar", "foo-|x|-bar",
|
||||
"foo-|$010|-bar", "foo-|$010|-bar", "foo-|x0|-bar", "foo-|x0|-bar", "foo-|x0|-bar",
|
||||
"foo-|$2|-bar", "foo-|$2|-bar", "foo-|$2|-bar", "foo-||-bar", "foo-|x|-bar",
|
||||
"foo-|$02|-bar", "foo-|$02|-bar", "foo-|$02|-bar", "foo-||-bar", "foo-|x|-bar",
|
||||
"foo-|$020|-bar", "foo-|$020|-bar", "foo-|$020|-bar", "foo-|0|-bar", "foo-|x0|-bar",
|
||||
"foo-|$10|-bar", "foo-|$10|-bar", "foo-|x0|-bar", "foo-|x0|-bar", "foo-|x|-bar",
|
||||
"foo-|$100|-bar", "foo-|$100|-bar", "foo-|x00|-bar", "foo-|x00|-bar", "foo-|x0|-bar",
|
||||
"foo-|$20|-bar", "foo-|$20|-bar", "foo-|$20|-bar", "foo-|0|-bar", "foo-|x0|-bar",
|
||||
"foo-|$200|-bar", "foo-|$200|-bar", "foo-|$200|-bar", "foo-|00|-bar", "foo-|x00|-bar",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A1_T17.js",
|
||||
code: `return "asdf".replace(new RegExp(undefined, "g"), "1")`,
|
||||
expected: "1a1s1d1f1",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A2_T1.js",
|
||||
code: `return "She sells seashells by the seashore.".replace(/sh/g, "sch")`,
|
||||
expected: "She sells seaschells by the seaschore.",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A2_T2.js",
|
||||
code: `return "She sells seashells by the seashore.".replace(/sh/g, "$$sch")`,
|
||||
expected: "She sells sea$schells by the sea$schore.",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A2_T3.js",
|
||||
code: `return "She sells seashells by the seashore.".replace(/sh/g, "$&sch")`,
|
||||
expected: "She sells seashschells by the seashschore.",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A2_T4.js",
|
||||
code: `return "She sells seashells by the seashore.".replace(/sh/g, "$\`sch")`,
|
||||
expected: "She sells seaShe sells seaschells by the seaShe sells seashells by the seaschore.",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A2_T5.js",
|
||||
code: `return "She sells seashells by the seashore.".replace(/sh/g, "$'sch")`,
|
||||
expected: "She sells seaells by the seashore.schells by the seaore.schore.",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A2_T6.js",
|
||||
code: `return "She sells seashells by the seashore.".replace(/sh/, "sch")`,
|
||||
expected: "She sells seaschells by the seashore.",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A2_T7.js",
|
||||
code: `return "She sells seashells by the seashore.".replace(/sh/, "$$sch")`,
|
||||
expected: "She sells sea$schells by the seashore.",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A2_T8.js",
|
||||
code: `return "She sells seashells by the seashore.".replace(/sh/, "$&sch")`,
|
||||
expected: "She sells seashschells by the seashore.",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A2_T9.js",
|
||||
code: `return "She sells seashells by the seashore.".replace(/sh/, "$\`sch")`,
|
||||
expected: "She sells seaShe sells seaschells by the seashore.",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A2_T10.js",
|
||||
code: `return "She sells seashells by the seashore.".replace(/sh/, "$'sch")`,
|
||||
expected: "She sells seaells by the seashore.schells by the seashore.",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A3_T1.js",
|
||||
code: `return "uid=31".replace(/(uid=)(\\d+)/, "$1115")`,
|
||||
expected: "uid=115",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A3_T2.js",
|
||||
code: `return "uid=31".replace(/(uid=)(\\d+)/, "$1115")`,
|
||||
expected: "uid=115",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A3_T3.js",
|
||||
code: `return "uid=31".replace(/(uid=)(\\d+)/, "$11A15")`,
|
||||
expected: "uid=1A15",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replace/S15.5.4.11_A5_T1.js",
|
||||
code: `return "aaaaaaaaaa,aaaaaaaaaaaaaaa".replace(/^(a+)\\1*,\\1+$/, "$1")`,
|
||||
expected: "aaaaa",
|
||||
},
|
||||
])
|
||||
|
||||
run("Test262-adapted replaceAll behavior", [
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replaceAll/searchValue-replacer-RegExp-call.js",
|
||||
code: `
|
||||
return [
|
||||
"abc abc abc".replaceAll(new RegExp("b", "g"), "z"),
|
||||
"abc abc abc".replaceAll(new RegExp("b", "gy"), "z"),
|
||||
"abc abc abc".replaceAll(new RegExp("b", "giy"), "z"),
|
||||
"No Uppercase!".replaceAll(new RegExp("[A-Z]", "g"), ""),
|
||||
"No Uppercase?".replaceAll(new RegExp("[A-Z]", "gy"), ""),
|
||||
"NO UPPERCASE!".replaceAll(new RegExp("[A-Z]", "gy"), ""),
|
||||
"abcabcabcabc".replaceAll(new RegExp("a(b)(ca)", "g"), "$2-$1"),
|
||||
"abcabcabcabc".replaceAll(new RegExp("(a(.))", "g"), "$1$2$3"),
|
||||
"aabacadaeafagahaiajakalamano a azaya".replaceAll(new RegExp("(((((((((((((a(.).).).).).).).).))))))", "g"), "($10)-($12)-($1)"),
|
||||
"abcba".replaceAll(new RegExp("b", "g"), "$'"),
|
||||
"abcba".replaceAll(new RegExp("b", "g"), "$\`"),
|
||||
"abcba".replaceAll(new RegExp("(?<named>b)", "g"), "($<named>)"),
|
||||
"abcba".replaceAll(new RegExp("(?<named>b)", "g"), "($<named)"),
|
||||
"abcba".replaceAll(new RegExp("(?<named>b)", "g"), "($<unnamed>)"),
|
||||
"abcabcabcabc".replaceAll(new RegExp("a(b)(ca)", "g"), "($$)"),
|
||||
"abcabcabcabc".replaceAll(new RegExp("a(b)(ca)", "g"), "($)"),
|
||||
"abcabcabcabc".replaceAll(new RegExp("a(b)(ca)", "g"), "($$$$)"),
|
||||
"abcabcabcabc".replaceAll(new RegExp("a(b)(ca)", "g"), "($$$)"),
|
||||
"abcabcabcabc".replaceAll(new RegExp("a(b)(ca)", "g"), "($$&)"),
|
||||
"abcabcabcabc".replaceAll(new RegExp("a(b)(ca)", "g"), "($$1)"),
|
||||
"abcabcabcabc".replaceAll(new RegExp("a(b)(ca)", "g"), "($$\`)"),
|
||||
"abcabcabcabc".replaceAll(new RegExp("a(b)(ca)", "g"), "($$')"),
|
||||
"abcabcabcabc".replaceAll(new RegExp("a(?<z>b)(ca)", "g"), "($$<z>)"),
|
||||
"abcabcabcabc".replaceAll(new RegExp("a(b)(ca)", "g"), "($&)"),
|
||||
]
|
||||
`,
|
||||
expected: [
|
||||
"azc azc azc", "abc abc abc", "abc abc abc", "o ppercase!", "o Uppercase?", " UPPERCASE!",
|
||||
"ca-bbcca-bbc", "abb$3cabb$3cabb$3cabb$3c",
|
||||
"(aabaca)-(aaba)-(aabacadaea)f(agahai)-(agah)-(agahaiajak)(alaman)-(alam)-(alamano a )azaya",
|
||||
"acbacaa", "aacabca", "a(b)c(b)a", "a($<named)c($<named)a", "a()c()a", "($)bc($)bc",
|
||||
"($)bc($)bc", "($$)bc($$)bc", "($$)bc($$)bc", "($&)bc($&)bc", "($1)bc($1)bc",
|
||||
"($`)bc($`)bc", "($')bc($')bc", "($<z>)bc($<z>)bc", "(abca)bc(abca)bc",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replaceAll/searchValue-empty-string.js",
|
||||
code: `return ["aab c \\nx".replaceAll("", "_"), "a".replaceAll("", "_")]`,
|
||||
expected: ["_a_a_b_ _c_ _ _\n_x_", "_a_"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replaceAll/searchValue-empty-string-this-empty-string.js",
|
||||
code: `return "".replaceAll("", "abc")`,
|
||||
expected: "abc",
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replaceAll/replaceValue-value-replaces-string.js",
|
||||
code: `return ["aaab a a aac".replaceAll("aa", "z"), "aaab a a aac".replaceAll("aa", "a"), "aaab a a aac".replaceAll("a", "a"), "aaab a a aac".replaceAll("a", "z")]`,
|
||||
expected: ["zab a a zc", "aab a a ac", "aaab a a aac", "zzzb z z zzc"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024.js",
|
||||
code: `
|
||||
const str = "Ninguém é igual a ninguém. Todo o ser humano é um estranho ímpar."
|
||||
return [str.replaceAll("ninguém", "$"), str.replaceAll("é", "$"), str.replaceAll("é", "$ -"), str.replaceAll("é", "$$$")]
|
||||
`,
|
||||
expected: [
|
||||
"Ninguém é igual a $. Todo o ser humano é um estranho ímpar.",
|
||||
"Ningu$m $ igual a ningu$m. Todo o ser humano $ um estranho ímpar.",
|
||||
"Ningu$ -m $ - igual a ningu$ -m. Todo o ser humano $ - um estranho ímpar.",
|
||||
"Ningu$$m $$ igual a ningu$$m. Todo o ser humano $$ um estranho ímpar.",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0024.js",
|
||||
code: `
|
||||
const str = "Ninguém é igual a ninguém. Todo o ser humano é um estranho ímpar."
|
||||
return [str.replaceAll("ninguém", "$$"), str.replaceAll("é", "$$"), str.replaceAll("é", "$$ -"), str.replaceAll("é", "$$&"), str.replaceAll("é", "$$$"), str.replaceAll("é", "$$$$")]
|
||||
`,
|
||||
expected: [
|
||||
"Ninguém é igual a $. Todo o ser humano é um estranho ímpar.",
|
||||
"Ningu$m $ igual a ningu$m. Todo o ser humano $ um estranho ímpar.",
|
||||
"Ningu$ -m $ - igual a ningu$ -m. Todo o ser humano $ - um estranho ímpar.",
|
||||
"Ningu$&m $& igual a ningu$&m. Todo o ser humano $& um estranho ímpar.",
|
||||
"Ningu$$m $$ igual a ningu$$m. Todo o ser humano $$ um estranho ímpar.",
|
||||
"Ningu$$m $$ igual a ningu$$m. Todo o ser humano $$ um estranho ímpar.",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0026.js",
|
||||
code: `
|
||||
const str = "Ninguém é igual a ninguém. Todo o ser humano é um estranho ímpar."
|
||||
return [str.replaceAll("ninguém", "$&"), str.replaceAll("ninguém", "($&)"), str.replaceAll("é", "($&)"), str.replaceAll("é", "($&) $&")]
|
||||
`,
|
||||
expected: [
|
||||
"Ninguém é igual a ninguém. Todo o ser humano é um estranho ímpar.",
|
||||
"Ninguém é igual a (ninguém). Todo o ser humano é um estranho ímpar.",
|
||||
"Ningu(é)m (é) igual a ningu(é)m. Todo o ser humano (é) um estranho ímpar.",
|
||||
"Ningu(é) ém (é) é igual a ningu(é) ém. Todo o ser humano (é) é um estranho ímpar.",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0060.js",
|
||||
code: `
|
||||
const str = "Ninguém é igual a ninguém. Todo o ser humano é um estranho ímpar."
|
||||
return [str.replaceAll("ninguém", "$\`"), str.replaceAll("Ninguém", "$\`"), str.replaceAll("ninguém", "($\`)"), str.replaceAll("é", "($\`)")]
|
||||
`,
|
||||
expected: [
|
||||
"Ninguém é igual a Ninguém é igual a . Todo o ser humano é um estranho ímpar.",
|
||||
" é igual a ninguém. Todo o ser humano é um estranho ímpar.",
|
||||
"Ninguém é igual a (Ninguém é igual a ). Todo o ser humano é um estranho ímpar.",
|
||||
"Ningu(Ningu)m (Ninguém ) igual a ningu(Ninguém é igual a ningu)m. Todo o ser humano (Ninguém é igual a ninguém. Todo o ser humano ) um estranho ímpar.",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0027.js",
|
||||
code: `
|
||||
const str = "Ninguém é igual a ninguém. Todo o ser humano é um estranho ímpar."
|
||||
return [str.replaceAll("ninguém", "$'"), str.replaceAll(".", "--- $'"), str.replaceAll("é", "($')")]
|
||||
`,
|
||||
expected: [
|
||||
"Ninguém é igual a . Todo o ser humano é um estranho ímpar.. Todo o ser humano é um estranho ímpar.",
|
||||
"Ninguém é igual a ninguém--- Todo o ser humano é um estranho ímpar. Todo o ser humano é um estranho ímpar--- ",
|
||||
"Ningu(m é igual a ninguém. Todo o ser humano é um estranho ímpar.)m ( igual a ninguém. Todo o ser humano é um estranho ímpar.) igual a ningu(m. Todo o ser humano é um estranho ímpar.)m. Todo o ser humano ( um estranho ímpar.) um estranho ímpar.",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024N.js",
|
||||
code: `
|
||||
const str = "ABC AAA ABC AAA"
|
||||
return ["$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9"].map((replacement) => str.replaceAll("ABC", replacement))
|
||||
`,
|
||||
expected: ["$1 AAA $1 AAA", "$2 AAA $2 AAA", "$3 AAA $3 AAA", "$4 AAA $4 AAA", "$5 AAA $5 AAA", "$6 AAA $6 AAA", "$7 AAA $7 AAA", "$8 AAA $8 AAA", "$9 AAA $9 AAA"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024NN.js",
|
||||
code: `
|
||||
const str = "aaaaaaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaa"
|
||||
return [str.replaceAll("a", "$11"), str.replaceAll("a", "$29")]
|
||||
`,
|
||||
expected: [
|
||||
"$11$11$11$11$11$11$11$11$11$11$11$11$11$11$11$11 $11$11$11$11$11$11$11$11 $11$11$11$11$11$11$11$11$11$11$11$11$11$11$11$11",
|
||||
"$29$29$29$29$29$29$29$29$29$29$29$29$29$29$29$29 $29$29$29$29$29$29$29$29 $29$29$29$29$29$29$29$29$29$29$29$29$29$29$29$29",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x003C.js",
|
||||
code: `return "aaaaaaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaa".replaceAll("a", "$<")`,
|
||||
expected: "$<$<$<$<$<$<$<$<$<$<$<$<$<$<$<$< $<$<$<$<$<$<$<$< $<$<$<$<$<$<$<$<$<$<$<$<$<$<$<$<",
|
||||
},
|
||||
])
|
||||
|
||||
run("Test262-adapted match behavior", [
|
||||
{
|
||||
path: "test/built-ins/String/prototype/match/S15.5.4.10_A1_T14.js",
|
||||
code: `const match = "ABBABABAB77BBAA".match(new RegExp("77")); return [match[0], match.index]`,
|
||||
expected: ["77", 9],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/match/S15.5.4.10_A2_T2.js",
|
||||
code: `return "343443444".match(/34/g)`,
|
||||
expected: ["34", "34", "34"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/match/S15.5.4.10_A2_T3.js",
|
||||
code: `return "123456abcde7890".match(/\\d{1}/g)`,
|
||||
expected: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/match/S15.5.4.10_A2_T4.js",
|
||||
code: `return "123456abcde7890".match(/\\d{2}/g)`,
|
||||
expected: ["12", "34", "56", "78", "90"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/match/S15.5.4.10_A2_T5.js",
|
||||
code: `return "123456abcde7890".match(/\\D{2}/g)`,
|
||||
expected: ["ab", "cd"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/match/S15.5.4.10_A2_T6.js",
|
||||
code: `const match = "Boston, Mass. 02134".match(/([\\d]{5})([- ]?[\\d]{4})?$/); return [match[0], match[1], match[2] === undefined, match.length, match.index]`,
|
||||
expected: ["02134", "02134", true, 3, 14],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/match/S15.5.4.10_A2_T7.js",
|
||||
code: `return "Boston, Mass. 02134".match(/([\\d]{5})([- ]?[\\d]{4})?$/g)`,
|
||||
expected: ["02134"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/match/S15.5.4.10_A2_T8.js",
|
||||
code: `const match = "Boston, MA 02134".match(/([\\d]{5})([- ]?[\\d]{4})?$/); return [match[0], match[1], match[2] === undefined, match.length, match.index]`,
|
||||
expected: ["02134", "02134", true, 3, 11],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/match/S15.5.4.10_A2_T12.js",
|
||||
code: `return "Boston, MA 02134".match(/([\\d]{5})([- ]?[\\d]{4})?$/g)`,
|
||||
expected: ["02134"],
|
||||
},
|
||||
])
|
||||
|
||||
run("Test262-adapted matchAll behavior", [
|
||||
{
|
||||
path: "test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-v-u-flag.js",
|
||||
code: `
|
||||
const text = "𠮷a𠮷b𠮷"
|
||||
const collect = (regex) => {
|
||||
const matches = text.matchAll(regex)
|
||||
return matches.map((match) => match[0]).concat(matches.map((match) => match.index))
|
||||
}
|
||||
const empty = text.matchAll(/(?:)/gu)
|
||||
const complex = "a𠮷bc".matchAll(/\\P{ASCII}/gu)
|
||||
return [
|
||||
collect(/𠮷/g),
|
||||
collect(/𠮷/gu),
|
||||
collect(/\\p{Script=Han}/gu),
|
||||
collect(/./gu),
|
||||
empty.map((match) => match[0]).concat(empty.map((match) => match.index)).length,
|
||||
complex.map((match) => match[0]),
|
||||
]
|
||||
`,
|
||||
expected: [
|
||||
["𠮷", "𠮷", "𠮷", 0, 3, 6],
|
||||
["𠮷", "𠮷", "𠮷", 0, 3, 6],
|
||||
["𠮷", "𠮷", "𠮷", 0, 3, 6],
|
||||
["𠮷", "a", "𠮷", "b", "𠮷", 0, 2, 3, 5, 6],
|
||||
12,
|
||||
["𠮷", ""],
|
||||
],
|
||||
},
|
||||
])
|
||||
|
||||
run("Test262-adapted search behavior", [
|
||||
{
|
||||
path: "test/built-ins/String/prototype/search/S15.5.4.12_A1_T14.js",
|
||||
code: `return "ABBABABAB77BBAA".search(new RegExp("77"))`,
|
||||
expected: 9,
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/search/S15.5.4.12_A2_T1.js",
|
||||
code: `return "test string".search("string")`,
|
||||
expected: 5,
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/search/S15.5.4.12_A2_T2.js",
|
||||
code: `return "test string".search("String")`,
|
||||
expected: -1,
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/search/S15.5.4.12_A2_T3.js",
|
||||
code: `return "test string".search(/String/i)`,
|
||||
expected: 5,
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/search/S15.5.4.12_A2_T4.js",
|
||||
code: `return "one two three four five".search(/Four/)`,
|
||||
expected: -1,
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/search/S15.5.4.12_A2_T5.js",
|
||||
code: `return "one two three four five".search(/four/)`,
|
||||
expected: 14,
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/search/S15.5.4.12_A2_T6.js",
|
||||
code: `return "test string".search("notexist")`,
|
||||
expected: -1,
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/search/S15.5.4.12_A2_T7.js",
|
||||
code: `return "test string probe".search("string pro")`,
|
||||
expected: 5,
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/search/S15.5.4.12_A3_T1.js",
|
||||
code: `const text = "power of the power of the power of the great sword"; return [text.search(/the/), text.search(/the/g)]`,
|
||||
expected: [9, 9],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/search/S15.5.4.12_A3_T2.js",
|
||||
code: `const text = "power of the power of the power of the great sword"; return [text.search(/of/), text.search(/of/g)]`,
|
||||
expected: [6, 6],
|
||||
},
|
||||
])
|
||||
794
packages/codemode/test/string-search-test262.test.ts
Normal file
794
packages/codemode/test/string-search-test262.test.ts
Normal file
|
|
@ -0,0 +1,794 @@
|
|||
/*
|
||||
* Portions adapted from Test262 at revision 250f204f23a9249ff204be2baec29600faae7b75:
|
||||
* - test/built-ins/String/prototype/split/call-split-l-0-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-l-1-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-l-2-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-l-3-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-l-4-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-l-na-n-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-l-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-ll-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-h-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-hello-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-hellothere-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-o-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-x-instance-is-string-hello.js
|
||||
* - test/built-ins/String/prototype/split/call-split-x-instance-is-empty-string.js
|
||||
* - test/built-ins/String/prototype/split/call-split-4-instance-is-string-one-1-two-2-four-4.js
|
||||
* - test/built-ins/String/prototype/split/call-split-on-instance-is-string-one-1-two-2-four-4.js
|
||||
* - test/built-ins/String/prototype/split/call-split-instance-is-string-one-two-three-four-five.js
|
||||
* - test/built-ins/String/prototype/split/call-split-instance-is-string-one-two-three.js
|
||||
* - test/built-ins/String/prototype/split/call-split-instance-is-string.js
|
||||
* - test/built-ins/String/prototype/split/instance-is-string-one-two-three-four-five.js
|
||||
* - test/built-ins/String/prototype/split/instance-is-string.js
|
||||
* - test/built-ins/String/prototype/split/separator-colon-instance-is-string-one-1-two-2-four-4.js
|
||||
* - test/built-ins/String/prototype/split/separator-comma-instance-is-string-one-two-three-four-five.js
|
||||
* - test/built-ins/String/prototype/split/separator-empty-string-instance-is-string.js
|
||||
* - test/built-ins/String/prototype/split/call-split-without-arguments-and-instance-is-empty-string.js
|
||||
* - test/built-ins/String/prototype/split/separator-undef.js
|
||||
* - test/built-ins/String/prototype/slice/S15.5.4.13_A1_T6.js
|
||||
* - test/built-ins/String/prototype/slice/S15.5.4.13_A1_T14.js
|
||||
* - test/built-ins/String/prototype/slice/S15.5.4.13_A2_T1.js
|
||||
* - test/built-ins/String/prototype/slice/S15.5.4.13_A2_T2.js
|
||||
* - test/built-ins/String/prototype/slice/S15.5.4.13_A2_T3.js
|
||||
* - test/built-ins/String/prototype/slice/S15.5.4.13_A2_T4.js
|
||||
* - test/built-ins/String/prototype/slice/S15.5.4.13_A2_T5.js
|
||||
* - test/built-ins/String/prototype/slice/S15.5.4.13_A2_T6.js
|
||||
* - test/built-ins/String/prototype/slice/S15.5.4.13_A2_T7.js
|
||||
* - test/built-ins/String/prototype/slice/S15.5.4.13_A2_T8.js
|
||||
* - test/built-ins/String/prototype/slice/S15.5.4.13_A2_T9.js
|
||||
* - test/built-ins/String/prototype/substring/S15.5.4.15_A1_T6.js
|
||||
* - test/built-ins/String/prototype/substring/S15.5.4.15_A1_T14.js
|
||||
* - test/built-ins/String/prototype/substring/S15.5.4.15_A2_T1.js
|
||||
* - test/built-ins/String/prototype/substring/S15.5.4.15_A2_T2.js
|
||||
* - test/built-ins/String/prototype/substring/S15.5.4.15_A2_T3.js
|
||||
* - test/built-ins/String/prototype/substring/S15.5.4.15_A2_T4.js
|
||||
* - test/built-ins/String/prototype/substring/S15.5.4.15_A2_T5.js
|
||||
* - test/built-ins/String/prototype/substring/S15.5.4.15_A2_T6.js
|
||||
* - test/built-ins/String/prototype/substring/S15.5.4.15_A2_T7.js
|
||||
* - test/built-ins/String/prototype/substring/S15.5.4.15_A2_T8.js
|
||||
* - test/built-ins/String/prototype/substring/S15.5.4.15_A2_T9.js
|
||||
* - test/built-ins/String/prototype/substring/S15.5.4.15_A2_T10.js
|
||||
* - test/annexB/built-ins/String/prototype/substr/start-negative.js
|
||||
* - test/annexB/built-ins/String/prototype/substr/length-negative.js
|
||||
* - test/annexB/built-ins/String/prototype/substr/length-positive.js
|
||||
* - test/annexB/built-ins/String/prototype/substr/length-falsey.js
|
||||
* - test/annexB/built-ins/String/prototype/substr/length-undef.js
|
||||
* - test/annexB/built-ins/String/prototype/substr/surrogate-pairs.js
|
||||
* - test/built-ins/String/prototype/includes/String.prototype.includes_FailMissingLetter.js
|
||||
* - test/built-ins/String/prototype/includes/String.prototype.includes_SuccessNoLocation.js
|
||||
* - test/built-ins/String/prototype/includes/String.prototype.includes_FailBadLocation.js
|
||||
* - test/built-ins/String/prototype/includes/String.prototype.includes_FailLocation.js
|
||||
* - test/built-ins/String/prototype/includes/String.prototype.includes_Success.js
|
||||
* - test/built-ins/String/prototype/includes/searchstring-found-with-position.js
|
||||
* - test/built-ins/String/prototype/includes/searchstring-found-without-position.js
|
||||
* - test/built-ins/String/prototype/includes/searchstring-not-found-with-position.js
|
||||
* - test/built-ins/String/prototype/includes/searchstring-not-found-without-position.js
|
||||
* - test/built-ins/String/prototype/includes/return-false-with-out-of-bounds-position.js
|
||||
* - test/built-ins/String/prototype/includes/return-true-if-searchstring-is-empty.js
|
||||
* - test/built-ins/String/prototype/includes/coerced-values-of-position.js
|
||||
* - test/built-ins/String/prototype/startsWith/searchstring-found-with-position.js
|
||||
* - test/built-ins/String/prototype/startsWith/searchstring-found-without-position.js
|
||||
* - test/built-ins/String/prototype/startsWith/searchstring-not-found-with-position.js
|
||||
* - test/built-ins/String/prototype/startsWith/searchstring-not-found-without-position.js
|
||||
* - test/built-ins/String/prototype/startsWith/out-of-bounds-position.js
|
||||
* - test/built-ins/String/prototype/startsWith/return-true-if-searchstring-is-empty.js
|
||||
* - test/built-ins/String/prototype/startsWith/coerced-values-of-position.js
|
||||
* - test/built-ins/String/prototype/endsWith/String.prototype.endsWith_Success.js
|
||||
* - test/built-ins/String/prototype/endsWith/String.prototype.endsWith_Success_2.js
|
||||
* - test/built-ins/String/prototype/endsWith/String.prototype.endsWith_Success_3.js
|
||||
* - test/built-ins/String/prototype/endsWith/String.prototype.endsWith_Success_4.js
|
||||
* - test/built-ins/String/prototype/endsWith/String.prototype.endsWith_Fail.js
|
||||
* - test/built-ins/String/prototype/endsWith/String.prototype.endsWith_Fail_2.js
|
||||
* - test/built-ins/String/prototype/endsWith/searchstring-found-with-position.js
|
||||
* - test/built-ins/String/prototype/endsWith/searchstring-found-without-position.js
|
||||
* - test/built-ins/String/prototype/endsWith/searchstring-not-found-with-position.js
|
||||
* - test/built-ins/String/prototype/endsWith/searchstring-not-found-without-position.js
|
||||
* - test/built-ins/String/prototype/endsWith/return-false-if-search-start-is-less-than-zero.js
|
||||
* - test/built-ins/String/prototype/endsWith/return-true-if-searchstring-is-empty.js
|
||||
* - test/built-ins/String/prototype/endsWith/coerced-values-of-position.js
|
||||
* - test/built-ins/String/prototype/indexOf/S15.5.4.7_A2_T1.js
|
||||
* - test/built-ins/String/prototype/indexOf/S15.5.4.7_A2_T2.js
|
||||
* - test/built-ins/String/prototype/indexOf/S15.5.4.7_A2_T3.js
|
||||
* - test/built-ins/String/prototype/indexOf/S15.5.4.7_A2_T4.js
|
||||
* - test/built-ins/String/prototype/indexOf/S15.5.4.7_A3_T1.js
|
||||
* - test/built-ins/String/prototype/indexOf/S15.5.4.7_A3_T3.js
|
||||
* - test/built-ins/String/prototype/indexOf/position-tointeger.js
|
||||
* - test/built-ins/String/prototype/indexOf/searchstring-tostring.js
|
||||
* - test/built-ins/String/prototype/lastIndexOf/not-a-substring.js
|
||||
*
|
||||
* Copyright 2009 the Sputnik authors. All rights reserved.
|
||||
* Copyright (c) 2014 Ryan Lewis. All rights reserved.
|
||||
* Copyright (C) 2015 the V8 project authors. All rights reserved.
|
||||
* Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||
* Copyright (C) 2017 Josh Wolfe. All rights reserved.
|
||||
* Copyright (C) 2020 Leo Balter. All rights reserved.
|
||||
* Copyright (C) 2026 Garham Lee. All rights reserved.
|
||||
* Test262 portions are governed by the BSD license in LICENSE.test262.
|
||||
*/
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { CodeMode } from "../src/index.js"
|
||||
|
||||
const value = async (code: string) => {
|
||||
const result = await Effect.runPromise(CodeMode.execute({ code, tools: {} }))
|
||||
if (!result.ok) throw new Error(`expected success, got ${result.error.kind}: ${result.error.message}`)
|
||||
return result.value
|
||||
}
|
||||
|
||||
const cases = [
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-l-0-instance-is-string-hello.js",
|
||||
code: `const result = "hello".split("l", 0); return [result.length, result[0] === undefined]`,
|
||||
expected: [0, true],
|
||||
labels: [
|
||||
"The value of __split.length is expected to equal the value of __expected.length",
|
||||
"The value of __split[0] is expected to equal the value of __expected[0]",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-l-1-instance-is-string-hello.js",
|
||||
code: `const result = "hello".split("l", 1); return [result.length, result[0]]`,
|
||||
expected: [1, "he"],
|
||||
labels: [
|
||||
"The value of __split.length is expected to equal the value of __expected.length",
|
||||
"The value of __split[0] is expected to equal the value of __expected[0]",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-l-2-instance-is-string-hello.js",
|
||||
code: `const result = "hello".split("l", 2); return [result.length, result[0], result[1]]`,
|
||||
expected: [2, "he", ""],
|
||||
labels: [
|
||||
"The value of __split.length is expected to equal the value of __expected.length",
|
||||
"The value of __split[index] is expected to equal the value of __expected[index]",
|
||||
"The value of __split[index] is expected to equal the value of __expected[index]",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-l-3-instance-is-string-hello.js",
|
||||
code: `const result = "hello".split("l", 3); return [result.length, result[0], result[1], result[2]]`,
|
||||
expected: [3, "he", "", "o"],
|
||||
labels: [
|
||||
"The value of __split.length is expected to equal the value of __expected.length",
|
||||
"The value of __split[index] is expected to equal the value of __expected[index]",
|
||||
"The value of __split[index] is expected to equal the value of __expected[index]",
|
||||
"The value of __split[index] is expected to equal the value of __expected[index]",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-l-4-instance-is-string-hello.js",
|
||||
code: `const result = "hello".split("l", 4); return [result.length, result[0], result[1], result[2]]`,
|
||||
expected: [3, "he", "", "o"],
|
||||
labels: [
|
||||
"The value of __split.length is expected to equal the value of __expected.length",
|
||||
"The value of __split[index] is expected to equal the value of __expected[index]",
|
||||
"The value of __split[index] is expected to equal the value of __expected[index]",
|
||||
"The value of __split[index] is expected to equal the value of __expected[index]",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-l-na-n-instance-is-string-hello.js",
|
||||
code: `const result = "hello".split("l", NaN); return [result.length, result[0] === undefined]`,
|
||||
expected: [0, true],
|
||||
labels: [
|
||||
"The value of __split.length is expected to equal the value of __expected.length",
|
||||
"The value of __split[0] is expected to equal the value of __expected[0]",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-l-instance-is-string-hello.js",
|
||||
code: `const result = "hello".split("l"); return [result.length, result[0], result[1], result[2]]`,
|
||||
expected: [3, "he", "", "o"],
|
||||
labels: [
|
||||
"The value of __split.length is 3",
|
||||
'The value of __split[0] is "he"',
|
||||
'The value of __split[1] is ""',
|
||||
'The value of __split[2] is "o"',
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-ll-instance-is-string-hello.js",
|
||||
code: `const result = "hello".split("ll"); return [result.length, result[0], result[1]]`,
|
||||
expected: [2, "he", "o"],
|
||||
labels: ["The value of __split.length is 2", 'The value of __split[0] is "he"', 'The value of __split[1] is "o"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-h-instance-is-string-hello.js",
|
||||
code: `const result = "hello".split("h"); return [result.length, result[0], result[1]]`,
|
||||
expected: [2, "", "ello"],
|
||||
labels: ["The value of __split.length is 2", 'The value of __split[0] is ""', 'The value of __split[1] is "ello"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-hello-instance-is-string-hello.js",
|
||||
code: `const result = "hello".split("hello"); return [result.length, result[0], result[1]]`,
|
||||
expected: [2, "", ""],
|
||||
labels: ["The value of __split.length is 2", 'The value of __split[0] is ""', 'The value of __split[1] is ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-hellothere-instance-is-string-hello.js",
|
||||
code: `const result = "hello".split("hellothere"); return [result.length, result[0]]`,
|
||||
expected: [1, "hello"],
|
||||
labels: ["The value of __split.length is 1", 'The value of __split[0] is "hello"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-o-instance-is-string-hello.js",
|
||||
code: `const result = "hello".split("o"); return [result.length, result[0], result[1]]`,
|
||||
expected: [2, "hell", ""],
|
||||
labels: ["The value of __split.length is 2", 'The value of __split[0] is "hell"', 'The value of __split[1] is ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-x-instance-is-string-hello.js",
|
||||
code: `const result = "hello".split("x"); return [result.length, result[0]]`,
|
||||
expected: [1, "hello"],
|
||||
labels: ["The value of __split.length is 1", 'The value of __split[0] is "hello"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-x-instance-is-empty-string.js",
|
||||
code: `const result = "".split("x"); return [result.length, result[0]]`,
|
||||
expected: [1, ""],
|
||||
labels: ["The value of __split.length is 1", 'The value of __split[0] is ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-4-instance-is-string-one-1-two-2-four-4.js",
|
||||
code: `const result = "one-1 two-2 four-4".split("-4"); return [result.length, result[0], result[1]]`,
|
||||
expected: [2, "one-1 two-2 four", ""],
|
||||
labels: [
|
||||
"The value of __split.length is 2",
|
||||
'The value of __split[0] is "one-1 two-2 four"',
|
||||
'The value of __split[1] is ""',
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-on-instance-is-string-one-1-two-2-four-4.js",
|
||||
code: `const result = "one-1 two-2 four-4".split("on"); return [result.length, result[0], result[1]]`,
|
||||
expected: [2, "", "e-1 two-2 four-4"],
|
||||
labels: [
|
||||
"The value of __split.length is 2",
|
||||
'The value of __split[0] is ""',
|
||||
'The value of __split[1] is "e-1 two-2 four-4"',
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-instance-is-string-one-two-three-four-five.js",
|
||||
code: `const result = "one two three four five".split(" "); return [result.length, ...result]`,
|
||||
expected: [5, "one", "two", "three", "four", "five"],
|
||||
labels: [
|
||||
"The value of __split.length is 5", 'The value of __split[0] is "one"', 'The value of __split[1] is "two"',
|
||||
'The value of __split[2] is "three"', 'The value of __split[3] is "four"', 'The value of __split[4] is "five"',
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-instance-is-string-one-two-three.js",
|
||||
code: `const result = "one two three".split(""); return [result[0], result[1], result[11], result[12]]`,
|
||||
expected: ["o", "n", "e", "e"],
|
||||
labels: [
|
||||
'The value of __split[0] is "o"', 'The value of __split[1] is "n"',
|
||||
'The value of __split[11] is "e"', 'The value of __split[12] is "e"',
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-instance-is-string.js",
|
||||
code: `const result = " ".split(" "); return [result.length, result[0], result[1]]`,
|
||||
expected: [2, "", ""],
|
||||
labels: ["The value of __split.length is 2", 'The value of __split[0] is ""', 'The value of __split[1] is ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/instance-is-string-one-two-three-four-five.js",
|
||||
code: `const result = "one,two,three,four,five".split(); return [result.length, result[0]]`,
|
||||
expected: [1, "one,two,three,four,five"],
|
||||
labels: ["The value of __split.length is 1", 'The value of __split[0] is "one,two,three,four,five"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/instance-is-string.js",
|
||||
code: `const result = " ".split(); return [result.length, result[0]]`,
|
||||
expected: [1, " "],
|
||||
labels: ["The value of __split.length is 1", 'The value of __split[0] is " "'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/separator-colon-instance-is-string-one-1-two-2-four-4.js",
|
||||
code: `const result = "one-1,two-2,four-4".split(":"); return [result.length, result[0]]`,
|
||||
expected: [1, "one-1,two-2,four-4"],
|
||||
labels: ["The value of __split.length is 1", 'The value of __split[0] is "one-1,two-2,four-4"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/separator-comma-instance-is-string-one-two-three-four-five.js",
|
||||
code: `const result = "one,two,three,four,five".split(","); return [result.length, ...result]`,
|
||||
expected: [5, "one", "two", "three", "four", "five"],
|
||||
labels: [
|
||||
"The value of __split.length is 5",
|
||||
'The value of __split[0] is "one"',
|
||||
'The value of __split[1] is "two"',
|
||||
'The value of __split[2] is "three"',
|
||||
'The value of __split[3] is "four"',
|
||||
'The value of __split[4] is "five"',
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/separator-empty-string-instance-is-string.js",
|
||||
code: `const result = " ".split(""); return [result.length, result[0]]`,
|
||||
expected: [1, " "],
|
||||
labels: ["The value of __split.length is 1", 'The value of __split[0] is " "'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/call-split-without-arguments-and-instance-is-empty-string.js",
|
||||
code: `const result = "".split(); return [result.length, result[0]]`,
|
||||
expected: [1, ""],
|
||||
labels: ["The value of __split.length is 1", 'The value of __split[0] is ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/split/separator-undef.js",
|
||||
code: `const result = "undefined is not a function".split(); return [Array.isArray(result), result.length, result[0]]`,
|
||||
expected: [true, 1, "undefined is not a function"],
|
||||
labels: ["implicit separator, result is array", "implicit separator, result.length", "implicit separator, [0] is the same string"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/slice/S15.5.4.13_A1_T6.js",
|
||||
code: `return ["undefined".slice(undefined, 3)]`,
|
||||
expected: ["und"],
|
||||
labels: ['#1: new String("undefined").slice(x,3) === "und"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/slice/S15.5.4.13_A1_T14.js",
|
||||
code: `return ["report".slice(undefined)]`,
|
||||
expected: ["report"],
|
||||
labels: ['#1: "report".slice(function(){}()) === "report"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/slice/S15.5.4.13_A2_T1.js",
|
||||
code: `return [typeof "this is a string object".slice()]`,
|
||||
expected: ["string"],
|
||||
labels: ['#1: typeof __string.slice() === "string"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/slice/S15.5.4.13_A2_T2.js",
|
||||
code: `return ["this is a string object".slice(NaN, Infinity)]`,
|
||||
expected: ["this is a string object"],
|
||||
labels: ['#1: __string.slice(NaN, Infinity) === "this is a string object"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/slice/S15.5.4.13_A2_T3.js",
|
||||
code: `return ["".slice(1, 0)]`,
|
||||
expected: [""],
|
||||
labels: ['#1: __string.slice(1,0) === ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/slice/S15.5.4.13_A2_T4.js",
|
||||
code: `return ["this is a string object".slice(Infinity, NaN)]`,
|
||||
expected: [""],
|
||||
labels: ['#1: __string.slice(Infinity, NaN) === ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/slice/S15.5.4.13_A2_T5.js",
|
||||
code: `return ["this is a string object".slice(Infinity, Infinity)]`,
|
||||
expected: [""],
|
||||
labels: ['#1: __string.slice(Infinity, Infinity) === ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/slice/S15.5.4.13_A2_T6.js",
|
||||
code: `return ["this is a string object".slice(-0.01, 0)]`,
|
||||
expected: [""],
|
||||
labels: ['#1: __string.slice(-0.01,0) === ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/slice/S15.5.4.13_A2_T7.js",
|
||||
code: `const text = "this is a string object"; return [text.slice(text.length, text.length)]`,
|
||||
expected: [""],
|
||||
labels: ['#1: __string.slice(__string.length, __string.length) === ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/slice/S15.5.4.13_A2_T8.js",
|
||||
code: `const text = "this is a string object"; return [text.slice(text.length + 1, 0)]`,
|
||||
expected: [""],
|
||||
labels: ['#1: __string.slice(__string.length+1, 0) === ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/slice/S15.5.4.13_A2_T9.js",
|
||||
code: `return ["this is a string object".slice(-Infinity, -Infinity)]`,
|
||||
expected: [""],
|
||||
labels: ['#1: __string.slice(-Infinity, -Infinity) === ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/substring/S15.5.4.15_A1_T6.js",
|
||||
code: `return ["undefined".substring(undefined, 3)]`,
|
||||
expected: ["und"],
|
||||
labels: ['#1: new String("undefined").substring(x,3) === "und"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/substring/S15.5.4.15_A1_T14.js",
|
||||
code: `return ["report".substring(undefined)]`,
|
||||
expected: ["report"],
|
||||
labels: ['#1: "report".substring(function(){}()) === "report"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/substring/S15.5.4.15_A2_T1.js",
|
||||
code: `return [typeof "this is a string object".substring()]`,
|
||||
expected: ["string"],
|
||||
labels: ['#1: typeof __string.substring() === "string"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/substring/S15.5.4.15_A2_T2.js",
|
||||
code: `return ["this is a string object".substring(NaN, Infinity)]`,
|
||||
expected: ["this is a string object"],
|
||||
labels: ['#1: __string.substring(NaN, Infinity) === "this is a string object"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/substring/S15.5.4.15_A2_T3.js",
|
||||
code: `return ["".substring(1, 0)]`,
|
||||
expected: [""],
|
||||
labels: ['#1: __string.substring(1,0) === ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/substring/S15.5.4.15_A2_T4.js",
|
||||
code: `return ["this is a string object".substring(Infinity, NaN)]`,
|
||||
expected: ["this is a string object"],
|
||||
labels: ['#1: __string.substring(Infinity, NaN) === "this is a string object"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/substring/S15.5.4.15_A2_T5.js",
|
||||
code: `return ["this is a string object".substring(Infinity, Infinity)]`,
|
||||
expected: [""],
|
||||
labels: ['#1: __string.substring(Infinity, Infinity) === ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/substring/S15.5.4.15_A2_T6.js",
|
||||
code: `return ["this is a string object".substring(-0.01, 0)]`,
|
||||
expected: [""],
|
||||
labels: ['#1: __string.substring(-0.01,0) === ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/substring/S15.5.4.15_A2_T7.js",
|
||||
code: `const text = "this is a string object"; return [text.substring(text.length, text.length)]`,
|
||||
expected: [""],
|
||||
labels: ['#1: __string.substring(__string.length, __string.length) === ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/substring/S15.5.4.15_A2_T8.js",
|
||||
code: `const text = "this is a string object"; return [text.substring(text.length + 1, 0)]`,
|
||||
expected: ["this is a string object"],
|
||||
labels: ['#1: __string.substring(__string.length+1, 0) === "this is a string object"'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/substring/S15.5.4.15_A2_T9.js",
|
||||
code: `return ["this is a string object".substring(-Infinity, -Infinity)]`,
|
||||
expected: [""],
|
||||
labels: ['#1: __string.substring(-Infinity, -Infinity) === ""'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/substring/S15.5.4.15_A2_T10.js",
|
||||
code: `return ["this_is_a_string object".substring(0, 8)]`,
|
||||
expected: ["this_is_"],
|
||||
labels: ['#1: __string.substring(0,8) === "this_is_"'],
|
||||
},
|
||||
{
|
||||
path: "test/annexB/built-ins/String/prototype/substr/start-negative.js",
|
||||
code: `return ["abc".substr(-1), "abc".substr(-2), "abc".substr(-3), "abc".substr(-4), "abc".substr(-1.1)]`,
|
||||
expected: ["c", "bc", "abc", "abc", "c"],
|
||||
labels: ["-1", "-2", "-3", "size + intStart < 0", "floating point rounding semantics"],
|
||||
},
|
||||
{
|
||||
path: "test/annexB/built-ins/String/prototype/substr/length-negative.js",
|
||||
code: `return [
|
||||
"abc".substr(0, -1), "abc".substr(0, -2), "abc".substr(0, -3), "abc".substr(0, -4),
|
||||
"abc".substr(1, -1), "abc".substr(1, -2), "abc".substr(1, -3), "abc".substr(1, -4),
|
||||
"abc".substr(2, -1), "abc".substr(2, -2), "abc".substr(2, -3), "abc".substr(2, -4),
|
||||
"abc".substr(3, -1), "abc".substr(3, -2), "abc".substr(3, -3), "abc".substr(3, -4),
|
||||
]`,
|
||||
expected: ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
|
||||
labels: [
|
||||
"0, -1", "0, -2", "0, -3", "0, -4", "1, -1", "1, -2", "1, -3", "1, -4",
|
||||
"2, -1", "2, -2", "2, -3", "2, -4", "3, -1", "3, -2", "3, -3", "3, -4",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/annexB/built-ins/String/prototype/substr/length-positive.js",
|
||||
code: `return [
|
||||
"abc".substr(0, 1), "abc".substr(0, 2), "abc".substr(0, 3), "abc".substr(0, 4),
|
||||
"abc".substr(1, 1), "abc".substr(1, 2), "abc".substr(1, 3), "abc".substr(1, 4),
|
||||
"abc".substr(2, 1), "abc".substr(2, 2), "abc".substr(2, 3), "abc".substr(2, 4),
|
||||
"abc".substr(3, 1), "abc".substr(3, 2), "abc".substr(3, 3), "abc".substr(3, 4),
|
||||
]`,
|
||||
expected: ["a", "ab", "abc", "abc", "b", "bc", "bc", "bc", "c", "c", "c", "c", "", "", "", ""],
|
||||
labels: [
|
||||
"0, 1", "0, 1", "0, 1", "0, 1", "1, 1", "1, 1", "1, 1", "1, 1",
|
||||
"2, 1", "2, 1", "2, 1", "2, 1", "3, 1", "3, 1", "3, 1", "3, 1",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/annexB/built-ins/String/prototype/substr/length-falsey.js",
|
||||
code: `return ["abc".substr(0, NaN), "abc".substr(1, NaN), "abc".substr(2, NaN), "abc".substr(3, NaN)]`,
|
||||
expected: ["", "", "", ""],
|
||||
labels: ["start: 0, length: NaN", "start: 1, length: NaN", "start: 2, length: NaN", "start: 3, length: NaN"],
|
||||
},
|
||||
{
|
||||
path: "test/annexB/built-ins/String/prototype/substr/length-undef.js",
|
||||
code: `return [
|
||||
"abc".substr(0), "abc".substr(1), "abc".substr(2), "abc".substr(3),
|
||||
"abc".substr(0, undefined), "abc".substr(1, undefined), "abc".substr(2, undefined), "abc".substr(3, undefined),
|
||||
]`,
|
||||
expected: ["abc", "bc", "c", "", "abc", "bc", "c", ""],
|
||||
labels: [
|
||||
"start: 0, length: unspecified", "start: 1, length: unspecified", "start: 2, length: unspecified", "start: 3, length: unspecified",
|
||||
"start: 0, length: undefined", "start: 1, length: undefined", "start: 2, length: undefined", "start: 3, length: undefined",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/annexB/built-ins/String/prototype/substr/surrogate-pairs.js",
|
||||
code: `return [
|
||||
"\uD834\uDF06".substr(0), "\uD834\uDF06".substr(1), "\uD834\uDF06".substr(2),
|
||||
"\uD834\uDF06".substr(0, 0), "\uD834\uDF06".substr(0, 1), "\uD834\uDF06".substr(0, 2),
|
||||
]`,
|
||||
expected: ["\uD834\uDF06", "\uDF06", "", "", "\uD834", "\uD834\uDF06"],
|
||||
labels: ["start: 0", "start: 1", "start: 2", "end: 0", "end: 1", "end: 2"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/includes/String.prototype.includes_FailMissingLetter.js",
|
||||
code: `return ["word".includes("a", 0)]`, expected: [false], labels: ['"word".includes("a", 0)'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/includes/String.prototype.includes_SuccessNoLocation.js",
|
||||
code: `return ["word".includes("w")]`, expected: [true], labels: ['"word".includes("w")'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/includes/String.prototype.includes_FailBadLocation.js",
|
||||
code: `return ["word".includes("w", 5)]`, expected: [false], labels: ['"word".includes("w", 5)'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/includes/String.prototype.includes_FailLocation.js",
|
||||
code: `return ["word".includes("o", 3)]`, expected: [false], labels: ['"word".includes("o", 3)'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/includes/String.prototype.includes_Success.js",
|
||||
code: `return ["word".includes("w", 0)]`, expected: [true], labels: ['"word".includes("w", 0)'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/includes/searchstring-found-with-position.js",
|
||||
code: `const text = "The future is cool!"; return [text.includes("The future", 0), text.includes(" is ", 1), text.includes("cool!", 10)]`,
|
||||
expected: [true, true, true],
|
||||
labels: [
|
||||
'Returns true for str.includes("The future", 0)',
|
||||
'Returns true for str.includes(" is ", 1)',
|
||||
'Returns true for str.includes("cool!", 10)',
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/includes/searchstring-found-without-position.js",
|
||||
code: `const text = "The future is cool!"; return [text.includes("The future"), text.includes("is cool!"), text.includes(text)]`,
|
||||
expected: [true, true, true],
|
||||
labels: [
|
||||
'Returns true for str.includes("The future")',
|
||||
'Returns true for str.includes("is cool!")',
|
||||
"Returns true for str.includes(str)",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/includes/searchstring-not-found-with-position.js",
|
||||
code: `const text = "The future is cool!"; return [text.includes("The future", 1), text.includes(text, 1)]`,
|
||||
expected: [false, false],
|
||||
labels: ['Returns false on str.includes("The future", 1)', "Returns false on str.includes(str, 1)"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/includes/searchstring-not-found-without-position.js",
|
||||
code: `const text = "The future is cool!"; return [text.includes("Flash"), text.includes("FUTURE")]`,
|
||||
expected: [false, false], labels: ["Flash if not included", "includes is case sensitive"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/includes/return-false-with-out-of-bounds-position.js",
|
||||
code: `const text = "The future is cool!"; return [
|
||||
text.includes("!", text.length + 1), text.includes("!", 100), text.includes("!", Infinity), text.includes("!", text.length),
|
||||
]`,
|
||||
expected: [false, false, false, false],
|
||||
labels: [
|
||||
'str.includes("!", str.length + 1) returns false', 'str.includes("!", 100) returns false',
|
||||
'str.includes("!", Infinity) returns false', 'str.includes("!", str.length) returns false',
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/includes/return-true-if-searchstring-is-empty.js",
|
||||
code: `const text = "The future is cool!"; return [text.includes("", text.length), text.includes(""), text.includes("", Infinity)]`,
|
||||
expected: [true, true, true],
|
||||
labels: ['str.includes("", str.length) returns true', 'str.includes("") returns true', 'str.includes("", Infinity) returns true'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/includes/coerced-values-of-position.js",
|
||||
code: `const text = "The future is cool!"; return [
|
||||
text.includes("The future", NaN), text.includes("The future", undefined), text.includes("The future", 0.4),
|
||||
text.includes("The future", -1), text.includes("The future", 1.4),
|
||||
]`,
|
||||
expected: [true, true, true, true, false],
|
||||
labels: ["NaN coerced to 0", "undefined coerced to 0", "0.4 coerced to 0", "negative position", "1.4 coerced to 1"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/startsWith/searchstring-found-with-position.js",
|
||||
code: `const text = "The future is cool!"; return [text.startsWith("The future", 0), text.startsWith("future", 4), text.startsWith(" is cool!", 10)]`,
|
||||
expected: [true, true, true],
|
||||
labels: [
|
||||
'str.startsWith("The future", 0) === true', 'str.startsWith("future", 4) === true',
|
||||
'str.startsWith(" is cool!", 10) === true',
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/startsWith/searchstring-found-without-position.js",
|
||||
code: `const text = "The future is cool!"; return [text.startsWith("The "), text.startsWith("The future"), text.startsWith(text)]`,
|
||||
expected: [true, true, true],
|
||||
labels: ['str.startsWith("The ") === true', 'str.startsWith("The future") === true', "str.startsWith(str) === true"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/startsWith/searchstring-not-found-with-position.js",
|
||||
code: `const text = "The future is cool!"; return [text.startsWith("The future", 1), text.startsWith(text, 1)]`,
|
||||
expected: [false, false],
|
||||
labels: ['str.startsWith("The future", 1) === false', "str.startsWith(str, 1) === false"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/startsWith/searchstring-not-found-without-position.js",
|
||||
code: `const text = "The future is cool!"; return [text.startsWith("Flash"), text.startsWith("THE FUTURE"), text.startsWith("future is cool!")]`,
|
||||
expected: [false, false, false],
|
||||
labels: ['str.startsWith("Flash") === false', "startsWith is case sensitive", 'str.startsWith("future is cool!") === false'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/startsWith/out-of-bounds-position.js",
|
||||
code: `const text = "The future is cool!"; return [
|
||||
text.startsWith("!", text.length), text.startsWith("!", 100), text.startsWith("!", Infinity),
|
||||
text.startsWith("The future", -1), text.startsWith("The future", -Infinity),
|
||||
]`,
|
||||
expected: [false, false, false, true, true],
|
||||
labels: [
|
||||
'str.startsWith("!", str.length) returns false', 'str.startsWith("!", 100) returns false',
|
||||
'str.startsWith("!", Infinity) returns false', "position argument < 0 will search from the start of the string (-1)",
|
||||
"position argument < 0 will search from the start of the string (-Infinity)",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/startsWith/return-true-if-searchstring-is-empty.js",
|
||||
code: `const text = "The future is cool!"; return [text.startsWith(""), text.startsWith("", text.length), text.startsWith("", Infinity)]`,
|
||||
expected: [true, true, true],
|
||||
labels: ['str.startsWith("") returns true', 'str.startsWith("", str.length) returns true', 'str.startsWith("", Infinity) returns true'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/startsWith/coerced-values-of-position.js",
|
||||
code: `const text = "The future is cool!"; return [
|
||||
text.startsWith("The future", NaN), text.startsWith("The future", undefined),
|
||||
text.startsWith("The future", 0.4), text.startsWith("The future", 1.4),
|
||||
]`,
|
||||
expected: [true, true, true, false],
|
||||
labels: ["NaN coerced to 0", "undefined coerced to 0", "0.4 coerced to 0", "1.4 coerced to 1"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/endsWith/String.prototype.endsWith_Success.js",
|
||||
code: `return ["word".endsWith("d")]`, expected: [true], labels: ['"word".endsWith("d")'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/endsWith/String.prototype.endsWith_Success_2.js",
|
||||
code: `return ["word".endsWith("d", 4)]`, expected: [true], labels: ['"word".endsWith("d", 4)'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/endsWith/String.prototype.endsWith_Success_3.js",
|
||||
code: `return ["word".endsWith("d", 25)]`, expected: [true], labels: ['"word".endsWith("d", 25)'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/endsWith/String.prototype.endsWith_Success_4.js",
|
||||
code: `return ["word".endsWith("r", 3)]`, expected: [true], labels: ['"word".endsWith("r", 3)'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/endsWith/String.prototype.endsWith_Fail.js",
|
||||
code: `return ["word".endsWith("r")]`, expected: [false], labels: ['"word".endsWith("r")'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/endsWith/String.prototype.endsWith_Fail_2.js",
|
||||
code: `return ["word".endsWith("d", 3)]`, expected: [false], labels: ['"word".endsWith("d", 3)'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/endsWith/searchstring-found-with-position.js",
|
||||
code: `const text = "The future is cool!"; return [text.endsWith("The future", 10), text.endsWith("future", 10), text.endsWith(" is cool!", text.length)]`,
|
||||
expected: [true, true, true],
|
||||
labels: [
|
||||
'str.endsWith("The future", 10) === true', 'str.endsWith("future", 10) === true',
|
||||
'str.endsWith(" is cool!", str.length) === true',
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/endsWith/searchstring-found-without-position.js",
|
||||
code: `const text = "The future is cool!"; return [text.endsWith("cool!"), text.endsWith("!"), text.endsWith(text)]`,
|
||||
expected: [true, true, true],
|
||||
labels: ['str.endsWith("cool!") === true', 'str.endsWith("!") === true', "str.endsWith(str) === true"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/endsWith/searchstring-not-found-with-position.js",
|
||||
code: `const text = "The future is cool!"; return [text.endsWith("is cool!", text.length - 1), text.endsWith("!", 1)]`,
|
||||
expected: [false, false],
|
||||
labels: ['str.endsWith("is cool!", str.length - 1) === false', 'str.endsWith("!", 1) === false'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/endsWith/searchstring-not-found-without-position.js",
|
||||
code: `const text = "The future is cool!"; return [text.endsWith("is Flash!"), text.endsWith("IS COOL!"), text.endsWith("The future")]`,
|
||||
expected: [false, false, false],
|
||||
labels: ['str.endsWith("is Flash!") === false', "endsWith is case sensitive", 'str.endsWith("The future") === false'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/endsWith/return-false-if-search-start-is-less-than-zero.js",
|
||||
code: `return ["web".endsWith("w", 0), "Bob".endsWith(" Bob")]`,
|
||||
expected: [false, false],
|
||||
labels: ['"web".endsWith("w", 0) returns false', '"Bob".endsWith(" Bob") returns false'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/endsWith/return-true-if-searchstring-is-empty.js",
|
||||
code: `const text = "The future is cool!"; return [
|
||||
text.endsWith(""), text.endsWith("", text.length), text.endsWith("", Infinity),
|
||||
text.endsWith("", -1), text.endsWith("", -Infinity),
|
||||
]`,
|
||||
expected: [true, true, true, true, true],
|
||||
labels: [
|
||||
'str.endsWith("") returns true', 'str.endsWith("", str.length) returns true', 'str.endsWith("", Infinity) returns true',
|
||||
'str.endsWith("", -1) returns true', 'str.endsWith("", -Infinity) returns true',
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/endsWith/coerced-values-of-position.js",
|
||||
code: `const text = "The future is cool!"; return [
|
||||
text.endsWith("", NaN), text.endsWith("", undefined), text.endsWith("The future", 10.4),
|
||||
]`,
|
||||
expected: [true, true, true],
|
||||
labels: ["NaN coerced to 0", "undefined coerced to 0", "10.4 coerced to 10"],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/indexOf/S15.5.4.7_A2_T1.js",
|
||||
code: `return ["abcd".indexOf("abcdab")]`, expected: [-1], labels: ['#1: "abcd".indexOf("abcdab")===-1'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/indexOf/S15.5.4.7_A2_T2.js",
|
||||
code: `return ["abcd".indexOf("abcdab", 0)]`, expected: [-1], labels: ['#1: "abcd".indexOf("abcdab",0)===-1'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/indexOf/S15.5.4.7_A2_T3.js",
|
||||
code: `return ["abcd".indexOf("abcdab", 99)]`, expected: [-1], labels: ['#1: "abcd".indexOf("abcdab",99)===-1'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/indexOf/S15.5.4.7_A2_T4.js",
|
||||
code: `return ["abcd".indexOf("abcdab", NaN)]`, expected: [-1], labels: ['#1: "abcd".indexOf("abcdab",NaN)===-1'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/indexOf/S15.5.4.7_A3_T1.js",
|
||||
code: `return ["$$abcdabcd".indexOf("ab", NaN)]`, expected: [2], labels: ['#1: "$$abcdabcd".indexOf("ab",NaN)===2'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/indexOf/S15.5.4.7_A3_T3.js",
|
||||
code: `return ["$$abcdabcd".indexOf("ab", -Infinity)]`, expected: [2], labels: ['#1: "$$abcdabcd".indexOf("ab", function(){return -Infinity;}())===2'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/indexOf/position-tointeger.js",
|
||||
code: `return [
|
||||
"aaaa".indexOf("aa", 0), "aaaa".indexOf("aa", 1), "aaaa".indexOf("aa", -0.9),
|
||||
"aaaa".indexOf("aa", 0.9), "aaaa".indexOf("aa", 1.9), "aaaa".indexOf("aa", NaN),
|
||||
"aaaa".indexOf("aa", Infinity), "aaaa".indexOf("aa", undefined),
|
||||
"aaaa".indexOf("aa", 2), "aaaa".indexOf("aa", 2.9),
|
||||
]`,
|
||||
expected: [0, 1, 0, 0, 1, 0, -1, 0, 2, 2],
|
||||
labels: [
|
||||
"position 0", "position 1", "ToInteger: truncate towards 0 (-0.9)", "ToInteger: truncate towards 0 (0.9)",
|
||||
"ToInteger: truncate towards 0 (1.9)", "ToInteger: NaN => 0", "position Infinity",
|
||||
"ToInteger: undefined => NaN => 0", "position 2", "ToInteger: truncate towards 0 (2.9)",
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/indexOf/searchstring-tostring.js",
|
||||
code: `return ["foo".indexOf(""), "__foo__".indexOf("foo")]`,
|
||||
expected: [0, 2], labels: ['"foo".indexOf("")', '"__foo__".indexOf("foo")'],
|
||||
},
|
||||
{
|
||||
path: "test/built-ins/String/prototype/lastIndexOf/not-a-substring.js",
|
||||
code: `return ["abc".lastIndexOf("d")]`,
|
||||
expected: [-1],
|
||||
labels: ["String.prototype.lastIndexOf returns -1 when searchString is shorter than this and searchString is not a substring of this."],
|
||||
},
|
||||
] as const
|
||||
|
||||
describe("Test262-adapted String search and extraction behavior", () => {
|
||||
for (const item of cases) {
|
||||
test(item.path, async () => {
|
||||
const actual = await value(item.code)
|
||||
if (!Array.isArray(actual)) throw new Error(`expected assertion values for ${item.path}`)
|
||||
expect(actual.length, "adapted assertion count").toBe(item.expected.length)
|
||||
item.expected.forEach((expected, index) => expect(actual[index], item.labels[index]!).toEqual(expected))
|
||||
})
|
||||
}
|
||||
})
|
||||
69
packages/codemode/test/test262-string.md
Normal file
69
packages/codemode/test/test262-string.md
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
# Test262 String Coverage
|
||||
|
||||
The String tests adapt Test262 at revision `250f204f23a9249ff204be2baec29600faae7b75`. They cover CodeMode's 32
|
||||
exposed instance methods and two static methods using primitive receivers, accepted argument types, and deterministic
|
||||
behavior. Each executable case names its exact upstream source path. `LICENSE.test262` contains the upstream BSD terms.
|
||||
|
||||
This is coverage of CodeMode's bounded String surface, not a claim of ECMAScript or Test262 conformance. One upstream
|
||||
file may contain both adapted and inapplicable assertions, so a cited source means only that the represented assertions
|
||||
were adapted.
|
||||
|
||||
## Inventory
|
||||
|
||||
The relevant upstream directories contain 1,048 files: 1,009 core built-in files, 29 Annex B files for exposed methods,
|
||||
and 10 Intl `localeCompare` files. The executable suite adapts assertions from 298 distinct sources.
|
||||
|
||||
| API | Upstream files | Adapted sources |
|
||||
| --- | ---: | ---: |
|
||||
| `String.fromCharCode` | 17 | 6 |
|
||||
| `String.fromCodePoint` | 11 | 4 |
|
||||
| `String.prototype.at` | 11 | 5 |
|
||||
| `String.prototype.charAt` | 30 | 9 |
|
||||
| `String.prototype.charCodeAt` | 25 | 4 |
|
||||
| `String.prototype.codePointAt` | 16 | 6 |
|
||||
| `String.prototype.concat` | 22 | 1 |
|
||||
| `String.prototype.endsWith` | 27 | 13 |
|
||||
| `String.prototype.includes` | 27 | 12 |
|
||||
| `String.prototype.indexOf` | 47 | 8 |
|
||||
| `String.prototype.lastIndexOf` | 25 | 1 |
|
||||
| `String.prototype.localeCompare` | 23 | 1 |
|
||||
| `String.prototype.match` | 52 | 9 |
|
||||
| `String.prototype.matchAll` | 26 | 1 |
|
||||
| `String.prototype.normalize` | 14 | 3 |
|
||||
| `String.prototype.padEnd` | 13 | 4 |
|
||||
| `String.prototype.padStart` | 13 | 4 |
|
||||
| `String.prototype.repeat` | 16 | 4 |
|
||||
| `String.prototype.replace` | 56 | 16 |
|
||||
| `String.prototype.replaceAll` | 46 | 12 |
|
||||
| `String.prototype.search` | 44 | 10 |
|
||||
| `String.prototype.slice` | 38 | 11 |
|
||||
| `String.prototype.split` | 121 | 50 |
|
||||
| `String.prototype.startsWith` | 21 | 7 |
|
||||
| `String.prototype.substr` | 15 | 6 |
|
||||
| `String.prototype.substring` | 46 | 12 |
|
||||
| `String.prototype.toLowerCase` | 30 | 5 |
|
||||
| `String.prototype.toString` | 7 | 1 |
|
||||
| `String.prototype.toUpperCase` | 26 | 3 |
|
||||
| `String.prototype.trim` | 129 | 66 |
|
||||
| `String.prototype.trimEnd` | 23 | 2 |
|
||||
| `String.prototype.trimLeft` | 4 | 0 |
|
||||
| `String.prototype.trimRight` | 4 | 0 |
|
||||
| `String.prototype.trimStart` | 23 | 2 |
|
||||
|
||||
## Exclusions
|
||||
|
||||
Assertions are not adapted when they test behavior outside CodeMode's documented String surface:
|
||||
|
||||
- Function metadata, property descriptors, constructibility, prototype mutation, or cross-realm identity.
|
||||
- The `trimLeft`/`trimRight` Test262 files assert prototype function identity, which CodeMode does not expose. Their
|
||||
supported call behavior remains covered by CodeMode-specific tests.
|
||||
- Boxed strings, generic receivers, custom coercion objects, Symbols, BigInts, or argument types CodeMode rejects.
|
||||
- Symbol-based RegExp dispatch, custom matchers, species constructors, or iterator protocol details. CodeMode materializes
|
||||
`matchAll` results instead of exposing iterators.
|
||||
- Locale selection and options. CodeMode deliberately uses the host default locale and ignores those arguments.
|
||||
- Test262 harness behavior or setup syntax unavailable in the confined interpreter.
|
||||
- Function-replacer behavior that is covered by CodeMode-specific tests for sequential callbacks, async tool calls,
|
||||
result coercion, diagnostics, and sandbox boundaries.
|
||||
- Assertions requiring an exact native error type when CodeMode deliberately exposes only its safe runtime error.
|
||||
|
||||
Handwritten tests remain where they specify CodeMode behavior rather than ordinary ECMAScript String semantics.
|
||||
Loading…
Add table
Add a link
Reference in a new issue