Ctrl K
ComunidadGuías…

packages/codemode/test/string-date-methods-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/annexB/built-ins/String/prototype/substr/length-falsey.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-undef.js
 * - test/annexB/built-ins/String/prototype/substr/start-negative.js
 * - test/annexB/built-ins/String/prototype/substr/surrogate-pairs.js
 * - test/built-ins/String/prototype/isWellFormed/returns-boolean.js
 * - test/built-ins/String/prototype/toWellFormed/returns-well-formed-string.js
 * - test/built-ins/Date/prototype/toDateString/format.js
 * - test/built-ins/Date/prototype/toDateString/invalid-date.js
 * - test/built-ins/Date/prototype/toDateString/negative-year.js
 * - test/built-ins/Date/prototype/toTimeString/format.js
 * - test/built-ins/Date/prototype/toTimeString/invalid-date.js
 *
 * Copyright (C) 2016, 2017 the V8 project authors. All rights reserved.
 * Copyright (C) 2018 Richard Gibson. All rights reserved.
 * Copyright (C) 2022 Jordan Harband. All rights reserved.
 * Test262 portions are governed by the BSD license in LICENSE.test262.
 *
 * The `typeof String.prototype.method` checks are replaced with `typeof "".method` because
 * CodeMode has no prototype objects.
 */
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
}

describe("String.prototype.substr Test262 parity", () => {
  test("test/annexB/built-ins/String/prototype/substr/length-falsey.js", async () => {
    expect(
      await value(`
        return [false, NaN, "", null].flatMap((length) => [0, 1, 2, 3].map((start) => "abc".substr(start, length)))
      `),
    ).toEqual(Array(16).fill(""))
  })

  test("test/annexB/built-ins/String/prototype/substr/length-negative.js", async () => {
    expect(
      await value(`
        return [0, 1, 2, 3].flatMap((start) => [-1, -2, -3, -4].map((length) => "abc".substr(start, length)))
      `),
    ).toEqual(Array(16).fill(""))
  })

  test("test/annexB/built-ins/String/prototype/substr/length-positive.js", async () => {
    expect(
      await value(`
        return [0, 1, 2, 3].map((start) => [1, 2, 3, 4].map((length) => "abc".substr(start, length)))
      `),
    ).toEqual([
      ["a", "ab", "abc", "abc"],
      ["b", "bc", "bc", "bc"],
      ["c", "c", "c", "c"],
      ["", "", "", ""],
    ])
  })

  test("test/annexB/built-ins/String/prototype/substr/length-undef.js", async () => {
    expect(
      await value(`
        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),
        ]
      `),
    ).toEqual(["abc", "bc", "c", "", "abc", "bc", "c", ""])
  })

  test("test/annexB/built-ins/String/prototype/substr/start-negative.js", async () => {
    expect(
      await value(`
        return ["abc".substr(-1), "abc".substr(-2), "abc".substr(-3), "abc".substr(-4), "abc".substr(-1.1)]
      `),
    ).toEqual(["c", "bc", "abc", "abc", "c"])
  })

  test("test/annexB/built-ins/String/prototype/substr/surrogate-pairs.js", async () => {
    expect(
      await value(`
        const pair = "\\ud834\\udf06"
        return [pair.substr(0), pair.substr(1), pair.substr(2), pair.substr(0, 0), pair.substr(0, 1), pair.substr(0, 2)]
      `),
    ).toEqual(["\ud834\udf06", "\udf06", "", "", "\ud834", "\ud834\udf06"])
  })
})

describe("String well-formedness Test262 parity", () => {
  test("test/built-ins/String/prototype/isWellFormed/returns-boolean.js", async () => {
    expect(
      await value(`
        const leadingPoo = "\\uD83D"
        const trailingPoo = "\\uDCA9"
        const wholePoo = leadingPoo + trailingPoo
        return [
          typeof "".isWellFormed,
          ("a" + leadingPoo + "c" + leadingPoo + "e").isWellFormed(),
          ("a" + trailingPoo + "c" + trailingPoo + "e").isWellFormed(),
          ("a" + trailingPoo + leadingPoo + "d").isWellFormed(),
          "a💩c".isWellFormed(),
          "a\\uD83D\\uDCA9c".isWellFormed(),
          ("a" + leadingPoo + trailingPoo + "d").isWellFormed(),
          wholePoo.slice(0, 1).isWellFormed(),
          wholePoo.slice(1).isWellFormed(),
          "abc".isWellFormed(),
          "a\\u25A8c".isWellFormed(),
        ]
      `),
    ).toEqual(["function", false, false, false, true, true, true, false, false, true, true])
  })

  test("test/built-ins/String/prototype/toWellFormed/returns-well-formed-string.js", async () => {
    expect(
      await value(`
        const replacementChar = "\\uFFFD"
        const leadingPoo = "\\uD83D"
        const trailingPoo = "\\uDCA9"
        const wholePoo = leadingPoo + trailingPoo
        return [
          typeof "".toWellFormed,
          ("a" + leadingPoo + "c" + leadingPoo + "e").toWellFormed() === "a" + replacementChar + "c" + replacementChar + "e",
          ("a" + trailingPoo + "c" + trailingPoo + "e").toWellFormed() === "a" + replacementChar + "c" + replacementChar + "e",
          ("a" + trailingPoo + leadingPoo + "d").toWellFormed() === "a" + replacementChar + replacementChar + "d",
          "a💩c".toWellFormed() === "a💩c",
          "a\\uD83D\\uDCA9c".toWellFormed() === "a\\uD83D\\uDCA9c",
          ("a" + leadingPoo + trailingPoo + "d").toWellFormed() === "a" + wholePoo + "d",
          wholePoo.slice(0, 1).toWellFormed() === replacementChar,
          wholePoo.slice(1).toWellFormed() === replacementChar,
          "abc".toWellFormed() === "abc",
          "a\\u25A8c".toWellFormed() === "a\\u25A8c",
        ]
      `),
    ).toEqual(["function", true, true, true, true, true, true, true, true, true, true])
  })
})

describe("Date string formatting Test262 parity", () => {
  test("test/built-ins/Date/prototype/toDateString/format.js", async () => {
    expect(
      await value(`
        const dateRegExp = /^(Sun|Mon|Tue|Wed|Thu|Fri|Sat) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9]{2} [0-9]{4}$/
        return [dateRegExp.test(new Date(0).toDateString()), dateRegExp.test(new Date("0020-01-01T00:00:00Z").toDateString())]
      `),
    ).toEqual([true, true])
  })

  test("test/built-ins/Date/prototype/toDateString/invalid-date.js", async () => {
    expect(await value(`return new Date(NaN).toDateString()`)).toBe("Invalid Date")
  })

  test("test/built-ins/Date/prototype/toDateString/negative-year.js", async () => {
    expect(
      await value(`
        return ["-000001", "-000012", "-000123", "-001234", "-012345", "-123456"].map(
          (year) => new Date(year + "-07-01T00:00Z").toDateString().split(" ")[3],
        )
      `),
    ).toEqual(["-0001", "-0012", "-0123", "-1234", "-12345", "-123456"])
  })

  test("test/built-ins/Date/prototype/toTimeString/format.js", async () => {
    expect(
      await value(`
        const timeRegExp = /^[0-9]{2}:[0-9]{2}:[0-9]{2} GMT[+-][0-9]{4}( \\(.+\\))?$/
        return timeRegExp.test(new Date(0).toTimeString())
      `),
    ).toBe(true)
  })

  test("test/built-ins/Date/prototype/toTimeString/invalid-date.js", async () => {
    expect(await value(`return new Date(NaN).toTimeString()`)).toBe("Invalid Date")
  })
})