string-core-test262.test.ts 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. /*
  2. * Portions adapted from Test262 at revision 250f204f23a9249ff204be2baec29600faae7b75:
  3. * - test/built-ins/String/prototype/toLowerCase/S15.5.4.16_A2_T1.js
  4. * - test/built-ins/String/prototype/toLowerCase/special_casing.js
  5. * - test/built-ins/String/prototype/toLowerCase/special_casing_conditional.js
  6. * - test/built-ins/String/prototype/toLowerCase/Final_Sigma_U180E.js
  7. * - test/built-ins/String/prototype/toLowerCase/supplementary_plane.js
  8. * - test/built-ins/String/prototype/toUpperCase/S15.5.4.18_A2_T1.js
  9. * - test/built-ins/String/prototype/toUpperCase/special_casing.js
  10. * - test/built-ins/String/prototype/toUpperCase/supplementary_plane.js
  11. * - test/built-ins/String/prototype/trim/15.5.4.20-3-1.js
  12. * - test/built-ins/String/prototype/trim/15.5.4.20-3-2.js
  13. * - test/built-ins/String/prototype/trim/15.5.4.20-3-3.js
  14. * - test/built-ins/String/prototype/trim/15.5.4.20-3-4.js
  15. * - test/built-ins/String/prototype/trim/15.5.4.20-3-5.js
  16. * - test/built-ins/String/prototype/trim/15.5.4.20-3-6.js
  17. * - test/built-ins/String/prototype/trim/15.5.4.20-3-7.js
  18. * - test/built-ins/String/prototype/trim/15.5.4.20-3-8.js
  19. * - test/built-ins/String/prototype/trim/15.5.4.20-3-9.js
  20. * - test/built-ins/String/prototype/trim/15.5.4.20-3-10.js
  21. * - test/built-ins/String/prototype/trim/15.5.4.20-3-11.js
  22. * - test/built-ins/String/prototype/trim/15.5.4.20-3-12.js
  23. * - test/built-ins/String/prototype/trim/15.5.4.20-3-13.js
  24. * - test/built-ins/String/prototype/trim/15.5.4.20-3-14.js
  25. * - test/built-ins/String/prototype/trim/15.5.4.20-4-1.js
  26. * - test/built-ins/String/prototype/trim/15.5.4.20-4-2.js
  27. * - test/built-ins/String/prototype/trim/15.5.4.20-4-3.js
  28. * - test/built-ins/String/prototype/trim/15.5.4.20-4-4.js
  29. * - test/built-ins/String/prototype/trim/15.5.4.20-4-5.js
  30. * - test/built-ins/String/prototype/trim/15.5.4.20-4-6.js
  31. * - test/built-ins/String/prototype/trim/15.5.4.20-4-8.js
  32. * - test/built-ins/String/prototype/trim/15.5.4.20-4-10.js
  33. * - test/built-ins/String/prototype/trim/15.5.4.20-4-11.js
  34. * - test/built-ins/String/prototype/trim/15.5.4.20-4-12.js
  35. * - test/built-ins/String/prototype/trim/15.5.4.20-4-13.js
  36. * - test/built-ins/String/prototype/trim/15.5.4.20-4-14.js
  37. * - test/built-ins/String/prototype/trim/15.5.4.20-4-16.js
  38. * - test/built-ins/String/prototype/trim/15.5.4.20-4-18.js
  39. * - test/built-ins/String/prototype/trim/15.5.4.20-4-19.js
  40. * - test/built-ins/String/prototype/trim/15.5.4.20-4-20.js
  41. * - test/built-ins/String/prototype/trim/15.5.4.20-4-21.js
  42. * - test/built-ins/String/prototype/trim/15.5.4.20-4-22.js
  43. * - test/built-ins/String/prototype/trim/15.5.4.20-4-24.js
  44. * - test/built-ins/String/prototype/trim/15.5.4.20-4-27.js
  45. * - test/built-ins/String/prototype/trim/15.5.4.20-4-28.js
  46. * - test/built-ins/String/prototype/trim/15.5.4.20-4-29.js
  47. * - test/built-ins/String/prototype/trim/15.5.4.20-4-30.js
  48. * - test/built-ins/String/prototype/trim/15.5.4.20-4-32.js
  49. * - test/built-ins/String/prototype/trim/15.5.4.20-4-34.js
  50. * - test/built-ins/String/prototype/trim/15.5.4.20-4-35.js
  51. * - test/built-ins/String/prototype/trim/15.5.4.20-4-36.js
  52. * - test/built-ins/String/prototype/trim/15.5.4.20-4-37.js
  53. * - test/built-ins/String/prototype/trim/15.5.4.20-4-38.js
  54. * - test/built-ins/String/prototype/trim/15.5.4.20-4-39.js
  55. * - test/built-ins/String/prototype/trim/15.5.4.20-4-40.js
  56. * - test/built-ins/String/prototype/trim/15.5.4.20-4-41.js
  57. * - test/built-ins/String/prototype/trim/15.5.4.20-4-42.js
  58. * - test/built-ins/String/prototype/trim/15.5.4.20-4-43.js
  59. * - test/built-ins/String/prototype/trim/15.5.4.20-4-44.js
  60. * - test/built-ins/String/prototype/trim/15.5.4.20-4-45.js
  61. * - test/built-ins/String/prototype/trim/15.5.4.20-4-46.js
  62. * - test/built-ins/String/prototype/trim/15.5.4.20-4-47.js
  63. * - test/built-ins/String/prototype/trim/15.5.4.20-4-48.js
  64. * - test/built-ins/String/prototype/trim/15.5.4.20-4-49.js
  65. * - test/built-ins/String/prototype/trim/15.5.4.20-4-50.js
  66. * - test/built-ins/String/prototype/trim/15.5.4.20-4-51.js
  67. * - test/built-ins/String/prototype/trim/15.5.4.20-4-52.js
  68. * - test/built-ins/String/prototype/trim/15.5.4.20-4-53.js
  69. * - test/built-ins/String/prototype/trim/15.5.4.20-4-54.js
  70. * - test/built-ins/String/prototype/trim/15.5.4.20-4-55.js
  71. * - test/built-ins/String/prototype/trim/15.5.4.20-4-56.js
  72. * - test/built-ins/String/prototype/trim/15.5.4.20-4-57.js
  73. * - test/built-ins/String/prototype/trim/15.5.4.20-4-58.js
  74. * - test/built-ins/String/prototype/trim/15.5.4.20-4-59.js
  75. * - test/built-ins/String/prototype/trim/15.5.4.20-4-60.js
  76. * - test/built-ins/String/prototype/trim/u180e.js
  77. * - test/built-ins/String/prototype/trimStart/this-value-whitespace.js
  78. * - test/built-ins/String/prototype/trimStart/this-value-line-terminator.js
  79. * - test/built-ins/String/prototype/trimEnd/this-value-whitespace.js
  80. * - test/built-ins/String/prototype/trimEnd/this-value-line-terminator.js
  81. * - test/built-ins/String/prototype/repeat/repeat-string-n-times.js
  82. * - test/built-ins/String/prototype/repeat/empty-string-returns-empty.js
  83. * - test/built-ins/String/prototype/repeat/count-is-zero-returns-empty-string.js
  84. * - test/built-ins/String/prototype/repeat/count-coerced-to-zero-returns-empty-string.js
  85. * - test/built-ins/String/prototype/padStart/fill-string-empty.js
  86. * - test/built-ins/String/prototype/padStart/normal-operation.js
  87. * - test/built-ins/String/prototype/padStart/fill-string-omitted.js
  88. * - test/built-ins/String/prototype/padStart/max-length-not-greater-than-string.js
  89. * - test/built-ins/String/prototype/padEnd/fill-string-empty.js
  90. * - test/built-ins/String/prototype/padEnd/normal-operation.js
  91. * - test/built-ins/String/prototype/padEnd/fill-string-omitted.js
  92. * - test/built-ins/String/prototype/padEnd/max-length-not-greater-than-string.js
  93. * - test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T4.js
  94. * - test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T7.js
  95. * - test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T8.js
  96. * - test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T1.js
  97. * - test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T2.js
  98. * - test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T3.js
  99. * - test/built-ins/String/prototype/charAt/S9.4_A1.js
  100. * - test/built-ins/String/prototype/charAt/S9.4_A2.js
  101. * - test/built-ins/String/prototype/charAt/pos-rounding.js
  102. * - test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T4.js
  103. * - test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T7.js
  104. * - test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T8.js
  105. * - test/built-ins/String/prototype/charCodeAt/pos-rounding.js
  106. * - test/built-ins/String/prototype/codePointAt/return-single-code-unit.js
  107. * - test/built-ins/String/prototype/codePointAt/return-first-code-unit.js
  108. * - test/built-ins/String/prototype/codePointAt/return-utf16-decode.js
  109. * - test/built-ins/String/prototype/codePointAt/return-code-unit-coerced-position.js
  110. * - test/built-ins/String/prototype/codePointAt/returns-undefined-on-position-less-than-zero.js
  111. * - test/built-ins/String/prototype/codePointAt/returns-undefined-on-position-equal-or-more-than-size.js
  112. * - test/built-ins/String/prototype/at/returns-code-unit.js
  113. * - test/built-ins/String/prototype/at/returns-item.js
  114. * - test/built-ins/String/prototype/at/returns-item-relative-index.js
  115. * - test/built-ins/String/prototype/at/returns-undefined-for-out-of-range-index.js
  116. * - test/built-ins/String/prototype/at/index-non-numeric-argument-tointeger.js
  117. * - test/built-ins/String/prototype/concat/S15.5.4.6_A1_T4.js
  118. * - test/built-ins/String/prototype/toString/string-primitive.js
  119. * - test/built-ins/String/prototype/normalize/return-normalized-string.js
  120. * - test/built-ins/String/prototype/normalize/return-normalized-string-using-default-parameter.js
  121. * - test/built-ins/String/prototype/normalize/form-is-not-valid-throws.js
  122. * - test/built-ins/String/prototype/localeCompare/15.5.4.9_CE.js
  123. * - test/built-ins/String/fromCharCode/S15.5.3.2_A2.js
  124. * - test/built-ins/String/fromCharCode/S15.5.3.2_A3_T1.js
  125. * - test/built-ins/String/fromCharCode/S9.7_A1.js
  126. * - test/built-ins/String/fromCharCode/S9.7_A2.1.js
  127. * - test/built-ins/String/fromCharCode/S9.7_A2.2.js
  128. * - test/built-ins/String/fromCharCode/S9.7_A3.2_T1.js
  129. * - test/built-ins/String/fromCodePoint/arguments-is-empty.js
  130. * - test/built-ins/String/fromCodePoint/return-string-value.js
  131. * - test/built-ins/String/fromCodePoint/argument-is-not-integer.js
  132. * - test/built-ins/String/fromCodePoint/number-is-out-of-range.js
  133. *
  134. * Copyright 2009 the Sputnik authors. All rights reserved.
  135. * Copyright (C) 2009 the Sputnik authors. All rights reserved.
  136. * Copyright (c) 2012 Ecma International. All rights reserved.
  137. * Copyright 2012 Norbert Lindenberg. All rights reserved.
  138. * Copyright 2012 Mozilla Corporation. All rights reserved.
  139. * Copyright 2013 Microsoft Corporation. All rights reserved.
  140. * Copyright (C) 2015 the V8 project authors. All rights reserved.
  141. * Copyright (C) 2015 André Bargull. All rights reserved.
  142. * Copyright (C) 2016 the V8 project authors. All rights reserved.
  143. * Copyright (C) 2016 André Bargull. All rights reserved.
  144. * Copyright (C) 2016 Jordan Harband. All rights reserved.
  145. * Copyright (C) 2016 Mathias Bynens. All rights reserved.
  146. * Copyright (c) 2017 Valerie Young. All rights reserved.
  147. * Copyright (C) 2017 Valerie Young. All rights reserved.
  148. * Copyright (C) 2020 Rick Waldron. All rights reserved.
  149. * Copyright (C) 2022 Richard Gibson. All rights reserved.
  150. * Test262 portions are governed by the BSD license in LICENSE.test262.
  151. */
  152. import { describe, expect, test } from "bun:test"
  153. import { Effect } from "effect"
  154. import { CodeMode } from "../src/index.js"
  155. type Argument = string | number | undefined
  156. type Outcome = "undefined" | "length" | "RangeError"
  157. type Assertion = {
  158. label: string
  159. input?: string
  160. args?: ReadonlyArray<Argument>
  161. expected?: string | number
  162. outcome?: Outcome
  163. }
  164. type Vector = {
  165. path: string
  166. method: string
  167. static?: boolean
  168. assertions: ReadonlyArray<Assertion>
  169. }
  170. const value = async (code: string) => {
  171. const result = await Effect.runPromise(CodeMode.execute({ code, tools: {} }))
  172. if (!result.ok) throw new Error(`expected success, got ${result.error.kind}: ${result.error.message}`)
  173. return result.value
  174. }
  175. const literal = (input: Argument) => {
  176. if (input === undefined) return "undefined"
  177. if (typeof input === "string") return JSON.stringify(input)
  178. if (Number.isNaN(input)) return "NaN"
  179. if (input === Infinity) return "Infinity"
  180. if (input === -Infinity) return "-Infinity"
  181. if (Object.is(input, -0)) return "-0"
  182. return JSON.stringify(input)
  183. }
  184. const vectors: Array<Vector> = []
  185. const add = (path: string, method: string, assertions: ReadonlyArray<Assertion>, staticMethod = false) => {
  186. vectors.push({ path, method, assertions, static: staticMethod })
  187. }
  188. const assertion = (label: string, input: string, expected: string | number, args: ReadonlyArray<Argument> = []) => ({
  189. label,
  190. input,
  191. args,
  192. expected,
  193. })
  194. add("test/built-ins/String/prototype/toLowerCase/S15.5.4.16_A2_T1.js", "toLowerCase", [
  195. assertion("#1 direct value", "Hello, WoRlD!", "hello, world!"),
  196. assertion("#2 String value", "Hello, WoRlD!", "hello, world!"),
  197. ])
  198. add("test/built-ins/String/prototype/toLowerCase/special_casing.js", "toLowerCase", [
  199. assertion(
  200. "103 SpecialCasing mappings",
  201. "\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",
  202. "\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",
  203. ),
  204. ])
  205. add("test/built-ins/String/prototype/toLowerCase/special_casing_conditional.js", "toLowerCase", [
  206. assertion("single sigma", "\u03A3", "\u03C3"),
  207. assertion("preceded by cased", "A\u03A3", "a\u03C2"),
  208. assertion("preceded by supplementary cased", "\uD835\uDCA2\u03A3", "\uD835\uDCA2\u03C2"),
  209. assertion("preceded by full stop", "A.\u03A3", "a.\u03C2"),
  210. assertion("preceded by soft hyphen", "A\u00AD\u03A3", "a\u00AD\u03C2"),
  211. assertion("preceded by combining mark", "A\uD834\uDE42\u03A3", "a\uD834\uDE42\u03C2"),
  212. assertion("preceded by uncased combining mark", "\u0345\u03A3", "\u0345\u03C3"),
  213. assertion("preceded by cased and combining mark", "\u0391\u0345\u03A3", "\u03B1\u0345\u03C2"),
  214. assertion("followed by cased", "A\u03A3B", "a\u03C3b"),
  215. assertion("followed by supplementary cased", "A\u03A3\uD835\uDCA2", "a\u03C3\uD835\uDCA2"),
  216. assertion("followed by full stop and cased", "A\u03A3.b", "a\u03C3.b"),
  217. assertion("followed by soft hyphen and cased", "A\u03A3\u00ADB", "a\u03C3\u00ADb"),
  218. assertion("followed by combining mark and cased", "A\u03A3\uD834\uDE42B", "a\u03C3\uD834\uDE42b"),
  219. assertion("followed by uncased combining mark", "A\u03A3\u0345", "a\u03C2\u0345"),
  220. assertion("followed by combining mark and cased Greek", "A\u03A3\u0345\u0391", "a\u03C3\u0345\u03B1"),
  221. ])
  222. add("test/built-ins/String/prototype/toLowerCase/Final_Sigma_U180E.js", "toLowerCase", [
  223. assertion("preceded by U+180E", "A\u180E\u03A3", "a\u180E\u03C2"),
  224. assertion("preceded by U+180E and followed by cased", "A\u180E\u03A3B", "a\u180E\u03C3b"),
  225. assertion("followed by U+180E", "A\u03A3\u180E", "a\u03C2\u180E"),
  226. assertion("followed by U+180E and cased", "A\u03A3\u180EB", "a\u03C3\u180Eb"),
  227. assertion("surrounded by U+180E", "A\u180E\u03A3\u180E", "a\u180E\u03C2\u180E"),
  228. assertion("surrounded by U+180E and followed by cased", "A\u180E\u03A3\u180EB", "a\u180E\u03C3\u180Eb"),
  229. ])
  230. add("test/built-ins/String/prototype/toLowerCase/supplementary_plane.js", "toLowerCase", [
  231. assertion(
  232. "40 Deseret mappings",
  233. "\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",
  234. "\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",
  235. ),
  236. ])
  237. add("test/built-ins/String/prototype/toUpperCase/S15.5.4.18_A2_T1.js", "toUpperCase", [
  238. assertion("#1 direct value", "Hello, WoRlD!", "HELLO, WORLD!"),
  239. assertion("#2 String value", "Hello, WoRlD!", "HELLO, WORLD!"),
  240. ])
  241. add("test/built-ins/String/prototype/toUpperCase/special_casing.js", "toUpperCase", [
  242. assertion(
  243. "103 SpecialCasing mappings",
  244. "\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",
  245. "\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",
  246. ),
  247. ])
  248. add("test/built-ins/String/prototype/toUpperCase/supplementary_plane.js", "toUpperCase", [
  249. assertion(
  250. "40 Deseret mappings",
  251. "\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",
  252. "\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",
  253. ),
  254. ])
  255. 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"
  256. const lineTerminators = "\u000A\u000D\u2028\u2029"
  257. const trim = (file: string, input: string, expected: string) =>
  258. add(`test/built-ins/String/prototype/trim/${file}`, "trim", [assertion("upstream assertion", input, expected)])
  259. trim("15.5.4.20-3-1.js", lineTerminators, "")
  260. trim("15.5.4.20-3-2.js", whitespace, "")
  261. trim("15.5.4.20-3-3.js", whitespace + lineTerminators, "")
  262. trim("15.5.4.20-3-4.js", whitespace + lineTerminators + "abc", "abc")
  263. trim("15.5.4.20-3-5.js", "abc" + whitespace + lineTerminators, "abc")
  264. trim("15.5.4.20-3-6.js", whitespace + lineTerminators + "abc" + whitespace + lineTerminators, "abc")
  265. trim("15.5.4.20-3-7.js", "ab" + whitespace + lineTerminators + "cd", "ab" + whitespace + lineTerminators + "cd")
  266. trim("15.5.4.20-3-8.js", "\0\u0000", "\0\u0000")
  267. trim("15.5.4.20-3-9.js", "\0", "\0")
  268. trim("15.5.4.20-3-10.js", "\u0000", "\u0000")
  269. trim("15.5.4.20-3-11.js", "\0\u0000abc", "\0\u0000abc")
  270. trim("15.5.4.20-3-12.js", "abc\0\u0000", "abc\0\u0000")
  271. trim("15.5.4.20-3-13.js", "\0\u0000abc\0\u0000", "\0\u0000abc\0\u0000")
  272. trim("15.5.4.20-3-14.js", "a\0\u0000bc", "a\0\u0000bc")
  273. trim("15.5.4.20-4-1.js", "\u0009a bc \u0009", "a bc")
  274. trim("15.5.4.20-4-2.js", " \u0009abc \u0009", "abc")
  275. trim("15.5.4.20-4-3.js", "\u0009abc", "abc")
  276. trim("15.5.4.20-4-4.js", "\u000Babc", "abc")
  277. trim("15.5.4.20-4-5.js", "\u000Cabc", "abc")
  278. trim("15.5.4.20-4-6.js", "\u0020abc", "abc")
  279. trim("15.5.4.20-4-8.js", "\u00A0abc", "abc")
  280. trim("15.5.4.20-4-10.js", "\uFEFFabc", "abc")
  281. trim("15.5.4.20-4-11.js", "abc\u0009", "abc")
  282. trim("15.5.4.20-4-12.js", "abc\u000B", "abc")
  283. trim("15.5.4.20-4-13.js", "abc\u000C", "abc")
  284. trim("15.5.4.20-4-14.js", "abc\u0020", "abc")
  285. trim("15.5.4.20-4-16.js", "abc\u00A0", "abc")
  286. trim("15.5.4.20-4-18.js", "abc\uFEFF", "abc")
  287. trim("15.5.4.20-4-19.js", "\u0009abc\u0009", "abc")
  288. trim("15.5.4.20-4-20.js", "\u000Babc\u000B", "abc")
  289. trim("15.5.4.20-4-21.js", "\u000Cabc\u000C", "abc")
  290. trim("15.5.4.20-4-22.js", "\u0020abc\u0020", "abc")
  291. trim("15.5.4.20-4-24.js", "\u00A0abc\u00A0", "abc")
  292. trim("15.5.4.20-4-27.js", "\u0009\u0009", "")
  293. trim("15.5.4.20-4-28.js", "\u000B\u000B", "")
  294. trim("15.5.4.20-4-29.js", "\u000C\u000C", "")
  295. trim("15.5.4.20-4-30.js", "\u0020\u0020", "")
  296. trim("15.5.4.20-4-32.js", "\u00A0\u00A0", "")
  297. trim("15.5.4.20-4-34.js", "\uFEFF\uFEFF", "")
  298. trim("15.5.4.20-4-35.js", "ab\u0009c", "ab\u0009c")
  299. trim("15.5.4.20-4-36.js", "ab\u000Bc", "ab\u000Bc")
  300. trim("15.5.4.20-4-37.js", "ab\u000Cc", "ab\u000Cc")
  301. trim("15.5.4.20-4-38.js", "ab\u0020c", "ab\u0020c")
  302. trim("15.5.4.20-4-39.js", "ab\u0085c", "ab\u0085c")
  303. trim("15.5.4.20-4-40.js", "ab\u00A0c", "ab\u00A0c")
  304. trim("15.5.4.20-4-41.js", "ab\u200Bc", "ab\u200Bc")
  305. trim("15.5.4.20-4-42.js", "ab\uFEFFc", "ab\uFEFFc")
  306. trim("15.5.4.20-4-43.js", "\u000Aabc", "abc")
  307. trim("15.5.4.20-4-44.js", "\u000Dabc", "abc")
  308. trim("15.5.4.20-4-45.js", "\u2028abc", "abc")
  309. trim("15.5.4.20-4-46.js", "\u2029abc", "abc")
  310. trim("15.5.4.20-4-47.js", "abc\u000A", "abc")
  311. trim("15.5.4.20-4-48.js", "abc\u000D", "abc")
  312. trim("15.5.4.20-4-49.js", "abc\u2028", "abc")
  313. trim("15.5.4.20-4-50.js", "abc\u2029", "abc")
  314. trim("15.5.4.20-4-51.js", "\u000Aabc\u000A", "abc")
  315. trim("15.5.4.20-4-52.js", "\u000Dabc\u000D", "abc")
  316. trim("15.5.4.20-4-53.js", "\u2028abc\u2028", "abc")
  317. trim("15.5.4.20-4-54.js", "\u2029abc\u2029", "abc")
  318. trim("15.5.4.20-4-55.js", "\u000A\u000A", "")
  319. trim("15.5.4.20-4-56.js", "\u000D\u000D", "")
  320. trim("15.5.4.20-4-57.js", "\u2028\u2028", "")
  321. trim("15.5.4.20-4-58.js", "\u2029\u2029", "")
  322. trim("15.5.4.20-4-59.js", "\u2029 abc", "abc")
  323. trim("15.5.4.20-4-60.js", " ", "")
  324. add("test/built-ins/String/prototype/trim/u180e.js", "trim", [
  325. assertion("trailing U+180E", "_\u180E", "_\u180E"),
  326. assertion("only U+180E", "\u180E", "\u180E"),
  327. assertion("leading U+180E", "\u180E_", "\u180E_"),
  328. ])
  329. 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"
  330. add("test/built-ins/String/prototype/trimStart/this-value-whitespace.js", "trimStart", [
  331. assertion("all whitespace", directionalWhitespace + "a" + directionalWhitespace + "b" + directionalWhitespace, "a" + directionalWhitespace + "b" + directionalWhitespace),
  332. ])
  333. add("test/built-ins/String/prototype/trimStart/this-value-line-terminator.js", "trimStart", [
  334. assertion("all line terminators", lineTerminators + "a" + lineTerminators + "b" + lineTerminators, "a" + lineTerminators + "b" + lineTerminators),
  335. ])
  336. add("test/built-ins/String/prototype/trimEnd/this-value-whitespace.js", "trimEnd", [
  337. assertion("all whitespace", directionalWhitespace + "a" + directionalWhitespace + "b" + directionalWhitespace, directionalWhitespace + "a" + directionalWhitespace + "b"),
  338. ])
  339. add("test/built-ins/String/prototype/trimEnd/this-value-line-terminator.js", "trimEnd", [
  340. assertion("all line terminators", lineTerminators + "a" + lineTerminators + "b" + lineTerminators, lineTerminators + "a" + lineTerminators + "b"),
  341. ])
  342. add("test/built-ins/String/prototype/repeat/repeat-string-n-times.js", "repeat", [
  343. assertion("repeat once", "abc", "abc", [1]),
  344. assertion("repeat three times", "abc", "abcabcabc", [3]),
  345. { label: "repeat 10000 times length", input: ".", args: [10000], expected: 10000, outcome: "length" },
  346. ])
  347. add("test/built-ins/String/prototype/repeat/empty-string-returns-empty.js", "repeat", [
  348. assertion("count 1", "", "", [1]),
  349. assertion("count 3", "", "", [3]),
  350. assertion("maximum 32-bit count", "", "", [0xffffffff]),
  351. ])
  352. add("test/built-ins/String/prototype/repeat/count-is-zero-returns-empty-string.js", "repeat", [
  353. assertion("zero", "foo", "", [0]),
  354. ])
  355. add("test/built-ins/String/prototype/repeat/count-coerced-to-zero-returns-empty-string.js", "repeat", [
  356. assertion("fraction truncates to zero", "abc", "", [0.9]),
  357. ])
  358. add("test/built-ins/String/prototype/padStart/fill-string-empty.js", "padStart", [assertion("empty fill", "abc", "abc", [5, ""])])
  359. add("test/built-ins/String/prototype/padStart/normal-operation.js", "padStart", [
  360. assertion("truncated multi-character fill", "abc", "defdabc", [7, "def"]),
  361. assertion("single-character fill", "abc", "**abc", [5, "*"]),
  362. assertion("truncated surrogate pair", "abc", "\uD83D\uDCA9\uD83Dabc", [6, "\uD83D\uDCA9"]),
  363. ])
  364. add("test/built-ins/String/prototype/padStart/fill-string-omitted.js", "padStart", [
  365. assertion("omitted fill", "abc", " abc", [5]),
  366. assertion("undefined fill", "abc", " abc", [5, undefined]),
  367. ])
  368. add("test/built-ins/String/prototype/padStart/max-length-not-greater-than-string.js", "padStart", [
  369. assertion("NaN", "abc", "abc", [NaN, "def"]),
  370. assertion("negative infinity", "abc", "abc", [-Infinity, "def"]),
  371. assertion("zero", "abc", "abc", [0, "def"]),
  372. assertion("negative one", "abc", "abc", [-1, "def"]),
  373. assertion("equal length", "abc", "abc", [3, "def"]),
  374. assertion("fraction truncates", "abc", "abc", [3.9999, "def"]),
  375. ])
  376. add("test/built-ins/String/prototype/padEnd/fill-string-empty.js", "padEnd", [assertion("empty fill", "abc", "abc", [5, ""])])
  377. add("test/built-ins/String/prototype/padEnd/normal-operation.js", "padEnd", [
  378. assertion("truncated multi-character fill", "abc", "abcdefd", [7, "def"]),
  379. assertion("single-character fill", "abc", "abc**", [5, "*"]),
  380. assertion("truncated surrogate pair", "abc", "abc\uD83D\uDCA9\uD83D", [6, "\uD83D\uDCA9"]),
  381. ])
  382. add("test/built-ins/String/prototype/padEnd/fill-string-omitted.js", "padEnd", [
  383. assertion("omitted fill", "abc", "abc ", [5]),
  384. assertion("undefined fill", "abc", "abc ", [5, undefined]),
  385. ])
  386. add("test/built-ins/String/prototype/padEnd/max-length-not-greater-than-string.js", "padEnd", [
  387. assertion("NaN", "abc", "abc", [NaN, "def"]),
  388. assertion("negative infinity", "abc", "abc", [-Infinity, "def"]),
  389. assertion("zero", "abc", "abc", [0, "def"]),
  390. assertion("negative one", "abc", "abc", [-1, "def"]),
  391. assertion("equal length", "abc", "abc", [3, "def"]),
  392. assertion("fraction truncates", "abc", "abc", [3.9999, "def"]),
  393. ])
  394. add("test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T4.js", "charAt", [assertion("omitted position", "lego", "l")])
  395. add("test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T7.js", "charAt", [assertion("undefined position", "lego", "l", [undefined])])
  396. add("test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T8.js", "charAt", [assertion("undefined position", "42", "4", [undefined])])
  397. 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])))
  398. add("test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T2.js", "charAt", [-2, -1].map((position) => assertion(`position ${position}`, "ABCABC", "", [position])))
  399. add("test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T3.js", "charAt", [6, 7].map((position) => assertion(`position ${position}`, "ABCABC", "", [position])))
  400. add("test/built-ins/String/prototype/charAt/S9.4_A1.js", "charAt", [assertion("NaN position", "abc", "a", [NaN])])
  401. add("test/built-ins/String/prototype/charAt/S9.4_A2.js", "charAt", [
  402. assertion("positive zero", "abc", "a", [0]),
  403. assertion("negative zero", "abc", "a", [-0]),
  404. ])
  405. add("test/built-ins/String/prototype/charAt/pos-rounding.js", "charAt", [
  406. assertion("-0.99999", "abc", "a", [-0.99999]),
  407. assertion("-0.00001", "abc", "a", [-0.00001]),
  408. assertion("0.00001", "abc", "a", [0.00001]),
  409. assertion("0.99999", "abc", "a", [0.99999]),
  410. assertion("1.00001", "abc", "b", [1.00001]),
  411. assertion("1.99999", "abc", "b", [1.99999]),
  412. ])
  413. add("test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T4.js", "charCodeAt", [assertion("omitted position", "smart", 0x73)])
  414. add("test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T7.js", "charCodeAt", [assertion("undefined position", "lego", 0x6c, [undefined])])
  415. add("test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T8.js", "charCodeAt", [assertion("undefined position", "42", 0x34, [undefined])])
  416. add("test/built-ins/String/prototype/charCodeAt/pos-rounding.js", "charCodeAt", [
  417. assertion("-0.99999", "abc", 0x61, [-0.99999]),
  418. assertion("-0.00001", "abc", 0x61, [-0.00001]),
  419. assertion("0.00001", "abc", 0x61, [0.00001]),
  420. assertion("0.99999", "abc", 0x61, [0.99999]),
  421. assertion("1.00001", "abc", 0x62, [1.00001]),
  422. assertion("1.99999", "abc", 0x62, [1.99999]),
  423. ])
  424. add("test/built-ins/String/prototype/codePointAt/return-single-code-unit.js", "codePointAt", [
  425. assertion("a", "abc", 97, [0]), assertion("b", "abc", 98, [1]), assertion("c", "abc", 99, [2]),
  426. assertion("ordinary BMP", "\uAAAA\uBBBB", 0xaaaa, [0]), assertion("before high-surrogate range", "\uD7FF\uAAAA", 0xd7ff, [0]),
  427. assertion("low surrogate", "\uDC00\uAAAA", 0xdc00, [0]), assertion("trailing D800", "123\uD800", 0xd800, [3]),
  428. assertion("trailing DAAA", "123\uDAAA", 0xdaaa, [3]), assertion("trailing DBFF", "123\uDBFF", 0xdbff, [3]),
  429. ])
  430. add("test/built-ins/String/prototype/codePointAt/return-first-code-unit.js", "codePointAt", [
  431. assertion("D800 before DBFF", "\uD800\uDBFF", 0xd800, [0]), assertion("D800 before E000", "\uD800\uE000", 0xd800, [0]),
  432. assertion("DAAA before DBFF", "\uDAAA\uDBFF", 0xdaaa, [0]), assertion("DAAA before E000", "\uDAAA\uE000", 0xdaaa, [0]),
  433. assertion("DBFF before DBFF", "\uDBFF\uDBFF", 0xdbff, [0]), assertion("DBFF before E000", "\uDBFF\uE000", 0xdbff, [0]),
  434. assertion("D800 before NUL", "\uD800\u0000", 0xd800, [0]), assertion("D800 before FFFF", "\uD800\uFFFF", 0xd800, [0]),
  435. assertion("DAAA before NUL", "\uDAAA\u0000", 0xdaaa, [0]), assertion("DAAA before FFFF", "\uDAAA\uFFFF", 0xdaaa, [0]),
  436. assertion("DBFF before FFFF", "\uDBFF\uFFFF", 0xdbff, [0]),
  437. ])
  438. add("test/built-ins/String/prototype/codePointAt/return-utf16-decode.js", "codePointAt", [
  439. assertion("U+10000", "\uD800\uDC00", 65536, [0]), assertion("U+101D0", "\uD800\uDDD0", 66000, [0]),
  440. assertion("U+103FF", "\uD800\uDFFF", 66559, [0]), assertion("U+BA800", "\uDAAA\uDC00", 763904, [0]),
  441. assertion("U+BA9D0", "\uDAAA\uDDD0", 764368, [0]), assertion("U+BABFF", "\uDAAA\uDFFF", 764927, [0]),
  442. assertion("U+10FC00", "\uDBFF\uDC00", 1113088, [0]), assertion("U+10FDD0", "\uDBFF\uDDD0", 1113552, [0]),
  443. assertion("U+10FFFF", "\uDBFF\uDFFF", 1114111, [0]),
  444. ])
  445. add("test/built-ins/String/prototype/codePointAt/return-code-unit-coerced-position.js", "codePointAt", [
  446. assertion("NaN", "\uD800\uDC00", 65536, [NaN]), assertion("undefined", "\uD800\uDC00", 65536, [undefined]),
  447. ])
  448. add("test/built-ins/String/prototype/codePointAt/returns-undefined-on-position-less-than-zero.js", "codePointAt", [
  449. { label: "negative one", input: "abc", args: [-1], outcome: "undefined" },
  450. { label: "negative infinity", input: "abc", args: [-Infinity], outcome: "undefined" },
  451. ])
  452. add("test/built-ins/String/prototype/codePointAt/returns-undefined-on-position-equal-or-more-than-size.js", "codePointAt", [
  453. { label: "equal to size", input: "abc", args: [3], outcome: "undefined" },
  454. { label: "greater than size", input: "abc", args: [4], outcome: "undefined" },
  455. { label: "positive infinity", input: "abc", args: [Infinity], outcome: "undefined" },
  456. ])
  457. add("test/built-ins/String/prototype/at/returns-code-unit.js", "at", [
  458. assertion("position 0", "12\uD80034", "1", [0]), assertion("position 1", "12\uD80034", "2", [1]),
  459. assertion("unpaired surrogate", "12\uD80034", "\uD800", [2]), assertion("position 3", "12\uD80034", "3", [3]),
  460. assertion("position 4", "12\uD80034", "4", [4]),
  461. ])
  462. 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])))
  463. add("test/built-ins/String/prototype/at/returns-item-relative-index.js", "at", [
  464. assertion("zero", "12345", "1", [0]), assertion("negative one", "12345", "5", [-1]),
  465. assertion("negative three", "12345", "3", [-3]), assertion("negative four", "12345", "2", [-4]),
  466. ])
  467. 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" })))
  468. add("test/built-ins/String/prototype/at/index-non-numeric-argument-tointeger.js", "at", [assertion("undefined", "01", "0", [undefined])])
  469. add("test/built-ins/String/prototype/concat/S15.5.4.6_A1_T4.js", "concat", [assertion("no arguments", "lego", "lego")])
  470. add("test/built-ins/String/prototype/toString/string-primitive.js", "toString", [
  471. assertion("empty string", "", ""), assertion("non-empty string", "str", "str"),
  472. ])
  473. add("test/built-ins/String/prototype/normalize/return-normalized-string.js", "normalize", [
  474. assertion("NFC short", "\u1E9B\u0323", "\u1E9B\u0323", ["NFC"]),
  475. assertion("NFD short", "\u1E9B\u0323", "\u017F\u0323\u0307", ["NFD"]),
  476. assertion("NFKC short", "\u1E9B\u0323", "\u1E69", ["NFKC"]),
  477. assertion("NFKD short", "\u1E9B\u0323", "\u0073\u0323\u0307", ["NFKD"]),
  478. assertion("NFC long", "\u00C5\u2ADC\u0958\u2126\u0344", "\xC5\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", ["NFC"]),
  479. assertion("NFD long", "\u00C5\u2ADC\u0958\u2126\u0344", "A\u030A\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", ["NFD"]),
  480. assertion("NFKC long", "\u00C5\u2ADC\u0958\u2126\u0344", "\xC5\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", ["NFKC"]),
  481. assertion("NFKD long", "\u00C5\u2ADC\u0958\u2126\u0344", "A\u030A\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", ["NFKD"]),
  482. ])
  483. add("test/built-ins/String/prototype/normalize/return-normalized-string-using-default-parameter.js", "normalize", [
  484. assertion("omitted", "\u00C5\u2ADC\u0958\u2126\u0344", "\xC5\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301"),
  485. assertion("undefined", "\u00C5\u2ADC\u0958\u2126\u0344", "\xC5\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", [undefined]),
  486. ])
  487. add("test/built-ins/String/prototype/normalize/form-is-not-valid-throws.js", "normalize", [
  488. { label: "bar", input: "foo", args: ["bar"], outcome: "RangeError" },
  489. { label: "NFC1", input: "foo", args: ["NFC1"], outcome: "RangeError" },
  490. ])
  491. add("test/built-ins/String/prototype/localeCompare/15.5.4.9_CE.js", "localeCompare", [
  492. assertion("D70", "o\u0308", 0, ["ö"]), assertion("reordered diaeresis", "ä\u0323", 0, ["a\u0323\u0308"]),
  493. assertion("reordered marks", "a\u0308\u0323", 0, ["a\u0323\u0308"]), assertion("precomposed dot below", "ạ\u0308", 0, ["a\u0323\u0308"]),
  494. assertion("breve after diaeresis", "ä\u0306", 0, ["a\u0308\u0306"]), assertion("diaeresis after breve", "ă\u0308", 0, ["a\u0306\u0308"]),
  495. assertion("Hangul", "\u1111\u1171\u11B6", 0, ["퓛"]), assertion("angstrom compatibility", "Å", 0, ["Å"]),
  496. assertion("angstrom decomposed", "Å", 0, ["A\u030A"]), assertion("reordered horn and dot", "x\u031B\u0323", 0, ["x\u0323\u031B"]),
  497. assertion("Vietnamese precomposed 1", "ự", 0, ["ụ\u031B"]), assertion("Vietnamese decomposed", "ự", 0, ["u\u031B\u0323"]),
  498. assertion("Vietnamese precomposed 2", "ự", 0, ["ư\u0323"]), assertion("Vietnamese reordered", "ự", 0, ["u\u0323\u031B"]),
  499. assertion("cedilla", "Ç", 0, ["C\u0327"]), assertion("q reordered", "q\u0307\u0323", 0, ["q\u0323\u0307"]),
  500. assertion("Hangul syllable", "가", 0, ["\u1100\u1161"]), assertion("ohm", "Ω", 0, ["Ω"]),
  501. assertion("angstrom", "Å", 0, ["A\u030A"]), assertion("circumflex", "ô", 0, ["o\u0302"]),
  502. assertion("s with marks", "ṩ", 0, ["s\u0323\u0307"]), assertion("d composed plus dot", "ḋ\u0323", 0, ["d\u0323\u0307"]),
  503. assertion("d two precompositions", "ḋ\u0323", 0, ["ḍ\u0307"]),
  504. ])
  505. add("test/built-ins/String/fromCharCode/S15.5.3.2_A2.js", "fromCharCode", [{ label: "no arguments", expected: "" }], true)
  506. add("test/built-ins/String/fromCharCode/S15.5.3.2_A3_T1.js", "fromCharCode", [{ label: "ABBA", args: [65, 66, 66, 65], expected: "ABBA" }], true)
  507. add("test/built-ins/String/fromCharCode/S9.7_A1.js", "fromCharCode", [
  508. { label: "NaN", args: [NaN], expected: 0 }, { label: "zero", args: [0], expected: 0 }, { label: "negative zero", args: [-0], expected: 0 },
  509. { label: "positive infinity", args: [Infinity], expected: 0 }, { label: "negative infinity", args: [-Infinity], expected: 0 },
  510. ], true)
  511. add("test/built-ins/String/fromCharCode/S9.7_A2.1.js", "fromCharCode", [
  512. [0, 0], [1, 1], [-1, 65535], [65535, 65535], [65534, 65534], [65536, 0], [4294967295, 65535], [4294967294, 65534], [4294967296, 0],
  513. ].map(([input, expected]) => ({ label: String(input), args: [input!], expected })), true)
  514. add("test/built-ins/String/fromCharCode/S9.7_A2.2.js", "fromCharCode", [
  515. [-32767, 32769], [-32768, 32768], [-32769, 32767], [-65535, 1], [-65536, 0], [-65537, 65535], [65535, 65535], [65536, 0], [65537, 1], [131071, 65535], [131072, 0], [131073, 1],
  516. ].map(([input, expected]) => ({ label: String(input), args: [input!], expected })), true)
  517. add("test/built-ins/String/fromCharCode/S9.7_A3.2_T1.js", "fromCharCode", [
  518. { label: "positive fraction", args: [1.2345], expected: 1 }, { label: "negative fraction", args: [-5.4321], expected: 65531 },
  519. ], true)
  520. add("test/built-ins/String/fromCodePoint/arguments-is-empty.js", "fromCodePoint", [{ label: "no arguments", expected: "" }], true)
  521. add("test/built-ins/String/fromCodePoint/return-string-value.js", "fromCodePoint", [
  522. { label: "NUL", args: [0], expected: "\x00" }, { label: "asterisk", args: [42], expected: "*" },
  523. { label: "AZ", args: [65, 90], expected: "AZ" }, { label: "Cyrillic", args: [0x404], expected: "\u0404" },
  524. { label: "hex supplementary", args: [0x2f804], expected: "\uD87E\uDC04" }, { label: "decimal supplementary", args: [194564], expected: "\uD87E\uDC04" },
  525. { label: "mixed supplementary", args: [0x1d306, 0x61, 0x1d307], expected: "\uD834\uDF06a\uD834\uDF07" },
  526. { label: "maximum code point", args: [1114111], expected: "\uDBFF\uDFFF" },
  527. ], true)
  528. add("test/built-ins/String/fromCodePoint/argument-is-not-integer.js", "fromCodePoint", [
  529. { label: "fraction", args: [3.14], outcome: "RangeError" }, { label: "fraction after valid", args: [42, 3.14], outcome: "RangeError" },
  530. ], true)
  531. add("test/built-ins/String/fromCodePoint/number-is-out-of-range.js", "fromCodePoint", [
  532. { label: "negative one", args: [-1], outcome: "RangeError" }, { label: "negative after valid", args: [1, -1], outcome: "RangeError" },
  533. { label: "above maximum", args: [1114112], outcome: "RangeError" }, { label: "infinity", args: [Infinity], outcome: "RangeError" },
  534. ], true)
  535. describe("Test262-adapted core String behavior", () => {
  536. for (const vector of vectors) {
  537. test(vector.path, async () => {
  538. const results = vector.assertions.map((item) => {
  539. const args = (item.args ?? []).map(literal).join(", ")
  540. const expression = vector.static
  541. ? `String.${vector.method}(${args})`
  542. : `${JSON.stringify(item.input)}.${vector.method}(${args})`
  543. const observed = vector.static && vector.method === "fromCharCode" && typeof item.expected === "number"
  544. ? `${expression}.charCodeAt(0)`
  545. : expression
  546. const checked = item.outcome === "undefined"
  547. ? `${observed} === undefined`
  548. : item.outcome === "length"
  549. ? `${observed}.length`
  550. : item.outcome === "RangeError"
  551. ? `(() => { try { ${observed}; return false } catch (error) { return error instanceof RangeError } })()`
  552. : observed
  553. return `{ label: ${JSON.stringify(item.label)}, value: ${checked} }`
  554. })
  555. const expected = vector.assertions.map((item) => ({
  556. label: item.label,
  557. value: item.outcome === undefined || item.outcome === "length" ? item.expected! : true,
  558. }))
  559. expect(await value(`return [${results.join(",")}]`)).toEqual(expected)
  560. })
  561. }
  562. })