| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- /*
- * Portions adapted from Test262 at revision 250f204f23a9249ff204be2baec29600faae7b75:
- * - test/built-ins/Array/prototype/map/15.4.4.19-8-1.js
- * - test/built-ins/Array/prototype/map/15.4.4.19-8-2.js
- * - test/built-ins/Array/prototype/map/15.4.4.19-8-b-1.js
- * - test/built-ins/Array/prototype/filter/15.4.4.20-9-1.js
- * - test/built-ins/Array/prototype/filter/15.4.4.20-9-2.js
- * - test/built-ins/Array/prototype/filter/15.4.4.20-9-b-1.js
- * - test/built-ins/Array/prototype/find/predicate-call-parameters.js
- * - test/built-ins/Array/prototype/find/predicate-not-called-on-empty-array.js
- * - test/built-ins/Array/prototype/find/return-found-value-predicate-result-is-true.js
- * - test/built-ins/Array/prototype/find/return-undefined-if-predicate-returns-false-value.js
- * - test/built-ins/Array/prototype/findIndex/predicate-call-parameters.js
- * - test/built-ins/Array/prototype/findIndex/return-index-predicate-result-is-true.js
- * - test/built-ins/Array/prototype/findIndex/return-negative-one-if-predicate-returns-false-value.js
- * - test/built-ins/Array/prototype/findLast/predicate-call-parameters.js
- * - test/built-ins/Array/prototype/findLast/return-found-value-predicate-result-is-true.js
- * - test/built-ins/Array/prototype/findLast/return-undefined-if-predicate-returns-false-value.js
- * - test/built-ins/Array/prototype/findLastIndex/predicate-call-parameters.js
- * - test/built-ins/Array/prototype/findLastIndex/return-index-predicate-result-is-true.js
- * - test/built-ins/Array/prototype/findLastIndex/return-negative-one-if-predicate-returns-false-value.js
- * - test/built-ins/Array/prototype/some/15.4.4.17-7-1.js
- * - test/built-ins/Array/prototype/some/15.4.4.17-8-1.js
- * - test/built-ins/Array/prototype/every/15.4.4.16-7-1.js
- * - test/built-ins/Array/prototype/every/15.4.4.16-8-1.js
- * - test/built-ins/Array/prototype/forEach/15.4.4.18-7-1.js
- * - test/built-ins/Array/prototype/forEach/15.4.4.18-7-2.js
- * - test/built-ins/Array/prototype/reduce/15.4.4.21-9-5.js
- * - test/built-ins/Array/prototype/reduce/15.4.4.21-9-1.js
- * - test/built-ins/Array/prototype/reduce/15.4.4.21-10-1.js
- * - test/built-ins/Array/prototype/reduceRight/15.4.4.22-9-5.js
- * - test/built-ins/Array/prototype/reduceRight/15.4.4.22-9-1.js
- * - test/built-ins/Array/prototype/reduceRight/15.4.4.22-10-1.js
- * - test/built-ins/Array/prototype/flatMap/depth-always-one.js
- * - test/built-ins/Array/prototype/flatMap/mapperfunction-throws.js
- * - test/built-ins/Array/prototype/sort/S15.4.4.11_A1.1_T1.js
- * - test/built-ins/Array/prototype/sort/S15.4.4.11_A2.1_T1.js
- * - test/built-ins/Array/prototype/sort/stability-5-elements.js
- * - test/built-ins/Array/prototype/toSorted/comparefn-controls-sort.js
- * - test/built-ins/Array/prototype/toSorted/comparefn-default.js
- * - test/built-ins/Array/prototype/toSorted/immutable.js
- * - test/built-ins/Array/prototype/toSorted/zero-or-one-element.js
- *
- * Copyright (C) 2015 the V8 project authors. All rights reserved.
- * Copyright (C) 2018 Mathias Bynens. All rights reserved.
- * Copyright (C) 2018 Shilpi Jain and Michael Ficarra. All rights reserved.
- * Copyright (C) 2021 Igalia, S.L. All rights reserved.
- * Copyright (C) 2021 Microsoft. All rights reserved.
- * Copyright (C) 2025 Google. All rights reserved.
- * Copyright (C) 2026 Garham Lee. All rights reserved.
- * Copyright (c) 2012 Ecma International. All rights reserved.
- * Copyright 2009 the Sputnik authors. 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/Array/prototype/map/15.4.4.19-8-1.js",
- code: `const input = [1, 2]; input[3] = 4; input[4] = 5; const result = input.map((value) => { input[2] = 3; input[5] = 6; return 1 }); return [result.length, result[5] === undefined]`,
- expected: [5, true],
- },
- {
- path: "test/built-ins/Array/prototype/map/15.4.4.19-8-2.js",
- code: `const input = [1, 2, 3, 4, 5]; const result = input.map((value) => { input[4] = -1; return value > 0 ? 1 : 0 }); return [result.length, result[4]]`,
- expected: [5, 0],
- },
- {
- path: "test/built-ins/Array/prototype/map/15.4.4.19-8-b-1.js",
- code: `const input = []; input[10] = 0; input.pop(); input[1] = undefined; let calls = 0; const result = input.map(() => { calls += 1; return 1 }); return [result.length, calls, 0 in result, 1 in result]`,
- expected: [10, 1, false, true],
- },
- {
- path: "test/built-ins/Array/prototype/filter/15.4.4.20-9-1.js",
- code: `const input = [1, 2]; input[3] = 4; input[4] = 5; const result = input.filter(() => { input[2] = 3; input[5] = 6; return true }); return result`,
- expected: [1, 2, 3, 4, 5],
- },
- {
- path: "test/built-ins/Array/prototype/filter/15.4.4.20-9-2.js",
- code: `const input = [1, 2, 3, 4, 5]; return input.filter((value) => { input[2] = -1; input[4] = -1; return value > 0 })`,
- expected: [1, 2, 4],
- },
- {
- path: "test/built-ins/Array/prototype/filter/15.4.4.20-9-b-1.js",
- code: `const input = []; input[9] = 0; input.pop(); input[1] = undefined; let calls = 0; const result = input.filter(() => { calls += 1; return false }); return [result, calls]`,
- expected: [[], 1],
- },
- {
- path: "test/built-ins/Array/prototype/find/predicate-call-parameters.js",
- code: `const input = [10, 20]; const seen = []; input.find((value, index, receiver) => { seen.push([value, index, receiver === input]); return false }); return seen`,
- expected: [
- [10, 0, true],
- [20, 1, true],
- ],
- },
- {
- path: "test/built-ins/Array/prototype/find/return-found-value-predicate-result-is-true.js",
- code: `return [1, 2, 3].find((value) => value > 1)`,
- expected: 2,
- },
- {
- path: "test/built-ins/Array/prototype/find/return-undefined-if-predicate-returns-false-value.js",
- code: `return [1, 2, 3].find((value) => value > 4) === undefined`,
- expected: true,
- },
- {
- path: "test/built-ins/Array/prototype/find/predicate-not-called-on-empty-array.js",
- code: `let calls = 0; const result = [].find(() => { calls += 1; return true }); return [result === undefined, calls]`,
- expected: [true, 0],
- },
- {
- path: "test/built-ins/Array/prototype/findIndex/predicate-call-parameters.js",
- code: `const input = [10, 20]; const seen = []; input.findIndex((value, index, receiver) => { seen.push([value, index, receiver === input]); return false }); return seen`,
- expected: [
- [10, 0, true],
- [20, 1, true],
- ],
- },
- {
- path: "test/built-ins/Array/prototype/findIndex/return-index-predicate-result-is-true.js",
- code: `return [1, 2, 3].findIndex((value) => value > 1)`,
- expected: 1,
- },
- {
- path: "test/built-ins/Array/prototype/findIndex/return-negative-one-if-predicate-returns-false-value.js",
- code: `return [1, 2, 3].findIndex((value) => value > 4)`,
- expected: -1,
- },
- {
- path: "test/built-ins/Array/prototype/findLast/predicate-call-parameters.js",
- code: `const input = [10, 20]; const seen = []; input.findLast((value, index, receiver) => { seen.push([value, index, receiver === input]); return false }); return seen`,
- expected: [
- [20, 1, true],
- [10, 0, true],
- ],
- },
- {
- path: "test/built-ins/Array/prototype/findLast/return-found-value-predicate-result-is-true.js",
- code: `return [1, 2, 3].findLast((value) => value < 3)`,
- expected: 2,
- },
- {
- path: "test/built-ins/Array/prototype/findLast/return-undefined-if-predicate-returns-false-value.js",
- code: `return [1, 2, 3].findLast((value) => value > 4) === undefined`,
- expected: true,
- },
- {
- path: "test/built-ins/Array/prototype/findLastIndex/predicate-call-parameters.js",
- code: `const input = [10, 20]; const seen = []; input.findLastIndex((value, index, receiver) => { seen.push([value, index, receiver === input]); return false }); return seen`,
- expected: [
- [20, 1, true],
- [10, 0, true],
- ],
- },
- {
- path: "test/built-ins/Array/prototype/findLastIndex/return-index-predicate-result-is-true.js",
- code: `return [1, 2, 3].findLastIndex((value) => value < 3)`,
- expected: 1,
- },
- {
- path: "test/built-ins/Array/prototype/findLastIndex/return-negative-one-if-predicate-returns-false-value.js",
- code: `return [1, 2, 3].findLastIndex((value) => value > 4)`,
- expected: -1,
- },
- {
- path: "test/built-ins/Array/prototype/some/15.4.4.17-7-1.js",
- code: `const input = [1, 2]; input[3] = 4; input[4] = 5; const seen = []; const result = input.some((value) => { input[2] = 3; seen.push(value); return false }); return [result, seen.includes(3)]`,
- expected: [false, true],
- },
- {
- path: "test/built-ins/Array/prototype/some/15.4.4.17-8-1.js",
- code: `return [].some(() => true)`,
- expected: false,
- },
- {
- path: "test/built-ins/Array/prototype/every/15.4.4.16-7-1.js",
- code: `const input = [1, 2]; input[3] = 4; input[4] = 5; const seen = []; const result = input.every((value) => { input[2] = 3; seen.push(value); return true }); return [result, seen.includes(3)]`,
- expected: [true, true],
- },
- {
- path: "test/built-ins/Array/prototype/every/15.4.4.16-8-1.js",
- code: `return [].every(() => false)`,
- expected: true,
- },
- {
- path: "test/built-ins/Array/prototype/forEach/15.4.4.18-7-1.js",
- code: `const input = [1, 2]; input[3] = 4; input[4] = 5; let calls = 0; input.forEach(() => { calls += 1; input[2] = 3; input[5] = 6 }); return calls`,
- expected: 5,
- },
- {
- path: "test/built-ins/Array/prototype/forEach/15.4.4.18-7-2.js",
- code: `const input = [1, 2, 3]; const seen = []; input.forEach((value, index) => { seen.push(value); if (index === 0) input.pop() }); return seen`,
- expected: [1, 2],
- },
- {
- path: "test/built-ins/Array/prototype/reduce/15.4.4.21-9-1.js",
- code: `const input = [1, 2]; input[3] = 4; input[4] = "5"; return input.reduce((accumulator, value) => { input[2] = 3; input[5] = 6; return accumulator + value })`,
- expected: "105",
- },
- {
- path: "test/built-ins/Array/prototype/reduce/15.4.4.21-9-5.js",
- code: `let calls = 0; const result = [1].reduce(() => { calls += 1; return 2 }); return [result, calls]`,
- expected: [1, 0],
- },
- {
- path: "test/built-ins/Array/prototype/reduce/15.4.4.21-10-1.js",
- code: `const input = [1, 2, 3, 4, 5]; input.reduce(() => 1); return input`,
- expected: [1, 2, 3, 4, 5],
- },
- {
- path: "test/built-ins/Array/prototype/reduceRight/15.4.4.22-9-1.js",
- code: `const input = ["1", 2]; input[3] = 4; input[4] = "5"; return input.reduceRight((accumulator, value) => { input[2] = 3; input[5] = 6; return accumulator + value })`,
- expected: "54321",
- },
- {
- path: "test/built-ins/Array/prototype/reduceRight/15.4.4.22-9-5.js",
- code: `let calls = 0; const result = [1].reduceRight(() => { calls += 1; return 2 }); return [result, calls]`,
- expected: [1, 0],
- },
- {
- path: "test/built-ins/Array/prototype/reduceRight/15.4.4.22-10-1.js",
- code: `const input = [1, 2, 3, 4, 5]; input.reduceRight(() => 1); return input`,
- expected: [1, 2, 3, 4, 5],
- },
- {
- path: "test/built-ins/Array/prototype/flatMap/depth-always-one.js",
- code: `return [1, 2, 3].flatMap((value) => [[value * 2]])`,
- expected: [[2], [4], [6]],
- },
- {
- path: "test/built-ins/Array/prototype/flatMap/mapperfunction-throws.js",
- code: `try { [1, 2].flatMap(() => { throw "stop" }) } catch (error) { return error === "stop" } return false`,
- expected: true,
- },
- {
- path: "test/built-ins/Array/prototype/sort/S15.4.4.11_A1.1_T1.js",
- code: `const input = []; input[2] = 0; input.pop(); input.sort(); return [input.length, input[0] === undefined, input[1] === undefined]`,
- expected: [2, true, true],
- },
- {
- path: "test/built-ins/Array/prototype/sort/S15.4.4.11_A2.1_T1.js",
- code: `return ["z", "y", "x", "w", "v", "u", "t", "s", "r", "q", "p", "o", "n", "M", "L", "K", "J", "I", "H", "G", "F", "E", "D", "C", "B", "A"].sort()`,
- expected: [
- "A",
- "B",
- "C",
- "D",
- "E",
- "F",
- "G",
- "H",
- "I",
- "J",
- "K",
- "L",
- "M",
- "n",
- "o",
- "p",
- "q",
- "r",
- "s",
- "t",
- "u",
- "v",
- "w",
- "x",
- "y",
- "z",
- ],
- },
- {
- path: "test/built-ins/Array/prototype/sort/stability-5-elements.js",
- code: `const input = [{ n: "A", r: 2 }, { n: "B", r: 3 }, { n: "C", r: 2 }, { n: "D", r: 3 }, { n: "E", r: 3 }]; return input.sort((left, right) => right.r - left.r).map((item) => item.n).join("")`,
- expected: "BDEAC",
- },
- {
- path: "test/built-ins/Array/prototype/toSorted/comparefn-controls-sort.js",
- code: `const mixed = [333, 33, 3, 222, 22, 2, 111, 11, 1]; return [[1, 2, 3, 4].toSorted((a, b) => a - b), [4, 3, 2, 1].toSorted((a, b) => a - b), mixed.toSorted((a, b) => a - b), [1, 2, 3, 4].toSorted((a, b) => b - a), [4, 3, 2, 1].toSorted((a, b) => b - a), mixed.toSorted((a, b) => b - a)]`,
- expected: [
- [1, 2, 3, 4],
- [1, 2, 3, 4],
- [1, 2, 3, 11, 22, 33, 111, 222, 333],
- [4, 3, 2, 1],
- [4, 3, 2, 1],
- [333, 222, 111, 33, 22, 11, 3, 2, 1],
- ],
- },
- {
- path: "test/built-ins/Array/prototype/toSorted/comparefn-default.js",
- code: `return [[1, 2, 3, 4].toSorted(), [4, 3, 2, 1].toSorted(), ["a", 2, 1, "z"].toSorted(), [333, 33, 3, 222, 22, 2, 111, 11, 1].toSorted()]`,
- expected: [
- [1, 2, 3, 4],
- [1, 2, 3, 4],
- [1, 2, "a", "z"],
- [1, 11, 111, 2, 22, 222, 3, 33, 333],
- ],
- },
- {
- path: "test/built-ins/Array/prototype/toSorted/immutable.js",
- code: `const input = [2, 0, 1]; const result = input.toSorted(); return [input, result !== input]`,
- expected: [[2, 0, 1], true],
- },
- {
- path: "test/built-ins/Array/prototype/toSorted/zero-or-one-element.js",
- code: `const zero = []; const one = [1]; const zeroResult = zero.toSorted(); const oneResult = one.toSorted(); return [zeroResult, oneResult, zeroResult !== zero, oneResult !== one]`,
- expected: [[], [1], true, true],
- },
- ] as const
- describe("Test262 Array callback adaptations", () => {
- for (const item of cases) {
- test(item.path, async () => {
- expect(await value(item.code)).toEqual(item.expected)
- })
- }
- })
|