mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-03 02:15:45 +00:00
214 lines
8.3 KiB
TypeScript
214 lines
8.3 KiB
TypeScript
/**
|
|
* Portions adapted from Test262 at revision 250f204f23a9249ff204be2baec29600faae7b75:
|
|
* - test/built-ins/Object/keys/15.2.3.14-1-1.js
|
|
* - test/built-ins/Object/keys/15.2.3.14-1-2.js
|
|
* - test/built-ins/Object/keys/15.2.3.14-1-3.js
|
|
* - test/built-ins/Object/keys/15.2.3.14-1-4.js
|
|
* - test/built-ins/Object/keys/15.2.3.14-1-5.js
|
|
* - test/built-ins/Object/entries/primitive-strings.js
|
|
* - test/built-ins/Object/entries/primitive-numbers.js
|
|
* - test/built-ins/Object/entries/primitive-booleans.js
|
|
* - test/built-ins/Object/values/primitive-strings.js
|
|
* - test/built-ins/Object/values/primitive-numbers.js
|
|
* - test/built-ins/Object/values/primitive-booleans.js
|
|
* - test/built-ins/Object/hasOwn/toobject_null.js
|
|
* - test/built-ins/Object/hasOwn/toobject_undefined.js
|
|
* - test/built-ins/Object/hasOwn/hasown_nonexistent.js
|
|
* - test/built-ins/Object/assign/Source-String.js
|
|
* - test/built-ins/Object/assign/Source-Null-Undefined.js
|
|
* - test/built-ins/Object/assign/target-Array.js
|
|
* - test/built-ins/Object/assign/Target-Null.js
|
|
* - test/built-ins/Object/assign/Target-Undefined.js
|
|
* - test/built-ins/Object/assign/Target-Object.js
|
|
* - test/built-ins/Object/assign/Override.js
|
|
* - test/built-ins/Object/assign/ObjectOverride-sameproperty.js
|
|
*
|
|
* Copyright (c) 2012 Ecma International. All rights reserved.
|
|
* Copyright (C) 2015 Jordan Harband. All rights reserved.
|
|
* Copyright 2015 Microsoft Corporation. All rights reserved.
|
|
* Copyright 2021 Jamie Kyle. All rights reserved.
|
|
* Test262 portions are governed by the BSD license in LICENSE.test262.
|
|
*
|
|
* Boxed-primitive cases (`Object.assign("a")`, `Object.assign(1, …)`) are omitted: CodeMode has no
|
|
* wrapper objects, so a primitive target is a TypeError rather than a boxed result. `Override.js`
|
|
* checks `Object.keys(result).length` instead of `Object.getOwnPropertyNames`. `target-Array.js`
|
|
* omits its named-key (`-0`, `1.5`, `4294967295`), `length`, and Proxy assertions: arrays here hold
|
|
* only indexed elements, so those keys are a TypeError (pinned below) rather than array properties.
|
|
*/
|
|
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 throwsTypeError = (expression: string) =>
|
|
value(`try { ${expression}; return "no throw" } catch (error) { return error.name }`)
|
|
|
|
describe("Object.keys Test262 parity", () => {
|
|
test("test/built-ins/Object/keys/15.2.3.14-1-{1,2,3}.js: primitives are coerced", async () => {
|
|
expect(await value(`return [Object.keys(0), Object.keys(true), Object.keys("abc")]`)).toEqual([
|
|
[],
|
|
[],
|
|
["0", "1", "2"],
|
|
])
|
|
})
|
|
|
|
test("test/built-ins/Object/keys/15.2.3.14-1-{4,5}.js: null and undefined throw TypeError", async () => {
|
|
expect(await throwsTypeError(`Object.keys(null)`)).toBe("TypeError")
|
|
expect(await throwsTypeError(`Object.keys(undefined)`)).toBe("TypeError")
|
|
})
|
|
})
|
|
|
|
describe("Object.entries and Object.values Test262 parity", () => {
|
|
test("test/built-ins/Object/entries/primitive-strings.js", async () => {
|
|
expect(
|
|
await value(`
|
|
const result = Object.entries('abc')
|
|
return [Array.isArray(result), result.length, result[0][0], result[0][1], result[1][0], result[1][1], result[2][0], result[2][1]]
|
|
`),
|
|
).toEqual([true, 3, "0", "a", "1", "b", "2", "c"])
|
|
})
|
|
|
|
test("test/built-ins/Object/entries/primitive-numbers.js", async () => {
|
|
expect(
|
|
await value(`
|
|
return [0, -0, Infinity, -Infinity, NaN, Math.PI].map((number) => Object.entries(number).length)
|
|
`),
|
|
).toEqual([0, 0, 0, 0, 0, 0])
|
|
})
|
|
|
|
test("test/built-ins/Object/entries/primitive-booleans.js", async () => {
|
|
expect(
|
|
await value(`
|
|
const trueResult = Object.entries(true)
|
|
const falseResult = Object.entries(false)
|
|
return [Array.isArray(trueResult), trueResult.length, Array.isArray(falseResult), falseResult.length]
|
|
`),
|
|
).toEqual([true, 0, true, 0])
|
|
})
|
|
|
|
test("test/built-ins/Object/values/primitive-strings.js", async () => {
|
|
expect(
|
|
await value(`
|
|
const result = Object.values('abc')
|
|
return [Array.isArray(result), result.length, result[0], result[1], result[2]]
|
|
`),
|
|
).toEqual([true, 3, "a", "b", "c"])
|
|
})
|
|
|
|
test("test/built-ins/Object/values/primitive-numbers.js", async () => {
|
|
expect(
|
|
await value(`
|
|
return [0, -0, Infinity, -Infinity, NaN, Math.PI].map((number) => Object.values(number).length)
|
|
`),
|
|
).toEqual([0, 0, 0, 0, 0, 0])
|
|
})
|
|
|
|
test("test/built-ins/Object/values/primitive-booleans.js", async () => {
|
|
expect(
|
|
await value(`
|
|
const trueResult = Object.values(true)
|
|
const falseResult = Object.values(false)
|
|
return [Array.isArray(trueResult), trueResult.length, Array.isArray(falseResult), falseResult.length]
|
|
`),
|
|
).toEqual([true, 0, true, 0])
|
|
})
|
|
})
|
|
|
|
describe("Object.hasOwn Test262 parity", () => {
|
|
test("test/built-ins/Object/hasOwn/toobject_{null,undefined}.js", async () => {
|
|
expect(await throwsTypeError(`Object.hasOwn(null, 'foo')`)).toBe("TypeError")
|
|
expect(await throwsTypeError(`Object.hasOwn(undefined, 'foo')`)).toBe("TypeError")
|
|
})
|
|
|
|
test("test/built-ins/Object/hasOwn/hasown_nonexistent.js", async () => {
|
|
expect(await value(`const o = {}; return Object.hasOwn(o, "foo")`)).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe("Object.assign Test262 parity", () => {
|
|
test("test/built-ins/Object/assign/Source-String.js", async () => {
|
|
expect(
|
|
await value(`
|
|
const target = new Object()
|
|
const result = Object.assign(target, "123")
|
|
return [result[0], result[1], result[2]]
|
|
`),
|
|
).toEqual(["1", "2", "3"])
|
|
})
|
|
|
|
test("test/built-ins/Object/assign/Source-Null-Undefined.js", async () => {
|
|
expect(
|
|
await value(`
|
|
const target = new Object()
|
|
const result = Object.assign(target, undefined, null)
|
|
return result === target
|
|
`),
|
|
).toBe(true)
|
|
})
|
|
|
|
test("test/built-ins/Object/assign/target-Array.js", async () => {
|
|
expect(
|
|
await value(`
|
|
const target = [7, 8, 9]
|
|
let result = Object.assign(target, [1])
|
|
const first = [result === target, [...result]]
|
|
const sparseArraySource = []
|
|
sparseArraySource[2] = 3
|
|
result = Object.assign(target, sparseArraySource)
|
|
const second = [result === target, [...result]]
|
|
result = Object.assign(target, { 4: 0 })
|
|
return [...first, ...second, result === target, result.length, result[3] === undefined, result[4]]
|
|
`),
|
|
).toEqual([true, [1, 8, 9], true, [1, 8, 3], true, 5, true, 0])
|
|
})
|
|
|
|
test("test/built-ins/Object/assign/target-Array.js", async () => {
|
|
expect(
|
|
await value(`
|
|
const target = [7]
|
|
for (const source of [{ x: 1 }, { "1.5": 1 }, { "-0": 1 }, { 1: 8 }, { length: 1 }]) Object.assign(target, source)
|
|
return [[...target], target.length, Object.keys(target), target.x]
|
|
`),
|
|
).toEqual([[7], 1, ["0", "x", "1.5", "-0"], 1])
|
|
})
|
|
|
|
test("test/built-ins/Object/assign/Target-{Null,Undefined}.js", async () => {
|
|
expect(await throwsTypeError(`Object.assign(null, { a: 1 })`)).toBe("TypeError")
|
|
expect(await throwsTypeError(`Object.assign(undefined, { a: 1 })`)).toBe("TypeError")
|
|
})
|
|
|
|
test("test/built-ins/Object/assign/Target-Object.js", async () => {
|
|
expect(
|
|
await value(`
|
|
const target = { foo: 1 }
|
|
const result = Object.assign(target, { a: 2 })
|
|
return [result.foo, result.a]
|
|
`),
|
|
).toEqual([1, 2])
|
|
})
|
|
|
|
test("test/built-ins/Object/assign/Override.js", async () => {
|
|
expect(
|
|
await value(`
|
|
const target = { a: 1 }
|
|
const result = Object.assign(target, "1a2c3", { a: "c" }, undefined, { b: 6 }, null, 125, { a: 5 })
|
|
return [Object.keys(result).length, result.a, result[0], result[1], result[2], result[3], result[4], result.b]
|
|
`),
|
|
).toEqual([7, 5, "1", "a", "2", "c", "3", 6])
|
|
})
|
|
|
|
test("test/built-ins/Object/assign/ObjectOverride-sameproperty.js", async () => {
|
|
expect(
|
|
await value(`
|
|
const target = { a: 1 }
|
|
const result = Object.assign(target, { a: 2 }, { a: "c" })
|
|
return result.a
|
|
`),
|
|
).toBe("c")
|
|
})
|
|
})
|