Ctrl K
ComunidadGuías…

packages/codemode/test/object-coercion-test262.test.ts

Rama dev · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
/**
 * 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 "./lib/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")
  })
})