string-core-test262.test.ts 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  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 =
  256. "\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"
  257. const lineTerminators = "\u000A\u000D\u2028\u2029"
  258. const trim = (file: string, input: string, expected: string) =>
  259. add(`test/built-ins/String/prototype/trim/${file}`, "trim", [assertion("upstream assertion", input, expected)])
  260. trim("15.5.4.20-3-1.js", lineTerminators, "")
  261. trim("15.5.4.20-3-2.js", whitespace, "")
  262. trim("15.5.4.20-3-3.js", whitespace + lineTerminators, "")
  263. trim("15.5.4.20-3-4.js", whitespace + lineTerminators + "abc", "abc")
  264. trim("15.5.4.20-3-5.js", "abc" + whitespace + lineTerminators, "abc")
  265. trim("15.5.4.20-3-6.js", whitespace + lineTerminators + "abc" + whitespace + lineTerminators, "abc")
  266. trim("15.5.4.20-3-7.js", "ab" + whitespace + lineTerminators + "cd", "ab" + whitespace + lineTerminators + "cd")
  267. trim("15.5.4.20-3-8.js", "\0\u0000", "\0\u0000")
  268. trim("15.5.4.20-3-9.js", "\0", "\0")
  269. trim("15.5.4.20-3-10.js", "\u0000", "\u0000")
  270. trim("15.5.4.20-3-11.js", "\0\u0000abc", "\0\u0000abc")
  271. trim("15.5.4.20-3-12.js", "abc\0\u0000", "abc\0\u0000")
  272. trim("15.5.4.20-3-13.js", "\0\u0000abc\0\u0000", "\0\u0000abc\0\u0000")
  273. trim("15.5.4.20-3-14.js", "a\0\u0000bc", "a\0\u0000bc")
  274. trim("15.5.4.20-4-1.js", "\u0009a bc \u0009", "a bc")
  275. trim("15.5.4.20-4-2.js", " \u0009abc \u0009", "abc")
  276. trim("15.5.4.20-4-3.js", "\u0009abc", "abc")
  277. trim("15.5.4.20-4-4.js", "\u000Babc", "abc")
  278. trim("15.5.4.20-4-5.js", "\u000Cabc", "abc")
  279. trim("15.5.4.20-4-6.js", "\u0020abc", "abc")
  280. trim("15.5.4.20-4-8.js", "\u00A0abc", "abc")
  281. trim("15.5.4.20-4-10.js", "\uFEFFabc", "abc")
  282. trim("15.5.4.20-4-11.js", "abc\u0009", "abc")
  283. trim("15.5.4.20-4-12.js", "abc\u000B", "abc")
  284. trim("15.5.4.20-4-13.js", "abc\u000C", "abc")
  285. trim("15.5.4.20-4-14.js", "abc\u0020", "abc")
  286. trim("15.5.4.20-4-16.js", "abc\u00A0", "abc")
  287. trim("15.5.4.20-4-18.js", "abc\uFEFF", "abc")
  288. trim("15.5.4.20-4-19.js", "\u0009abc\u0009", "abc")
  289. trim("15.5.4.20-4-20.js", "\u000Babc\u000B", "abc")
  290. trim("15.5.4.20-4-21.js", "\u000Cabc\u000C", "abc")
  291. trim("15.5.4.20-4-22.js", "\u0020abc\u0020", "abc")
  292. trim("15.5.4.20-4-24.js", "\u00A0abc\u00A0", "abc")
  293. trim("15.5.4.20-4-27.js", "\u0009\u0009", "")
  294. trim("15.5.4.20-4-28.js", "\u000B\u000B", "")
  295. trim("15.5.4.20-4-29.js", "\u000C\u000C", "")
  296. trim("15.5.4.20-4-30.js", "\u0020\u0020", "")
  297. trim("15.5.4.20-4-32.js", "\u00A0\u00A0", "")
  298. trim("15.5.4.20-4-34.js", "\uFEFF\uFEFF", "")
  299. trim("15.5.4.20-4-35.js", "ab\u0009c", "ab\u0009c")
  300. trim("15.5.4.20-4-36.js", "ab\u000Bc", "ab\u000Bc")
  301. trim("15.5.4.20-4-37.js", "ab\u000Cc", "ab\u000Cc")
  302. trim("15.5.4.20-4-38.js", "ab\u0020c", "ab\u0020c")
  303. trim("15.5.4.20-4-39.js", "ab\u0085c", "ab\u0085c")
  304. trim("15.5.4.20-4-40.js", "ab\u00A0c", "ab\u00A0c")
  305. trim("15.5.4.20-4-41.js", "ab\u200Bc", "ab\u200Bc")
  306. trim("15.5.4.20-4-42.js", "ab\uFEFFc", "ab\uFEFFc")
  307. trim("15.5.4.20-4-43.js", "\u000Aabc", "abc")
  308. trim("15.5.4.20-4-44.js", "\u000Dabc", "abc")
  309. trim("15.5.4.20-4-45.js", "\u2028abc", "abc")
  310. trim("15.5.4.20-4-46.js", "\u2029abc", "abc")
  311. trim("15.5.4.20-4-47.js", "abc\u000A", "abc")
  312. trim("15.5.4.20-4-48.js", "abc\u000D", "abc")
  313. trim("15.5.4.20-4-49.js", "abc\u2028", "abc")
  314. trim("15.5.4.20-4-50.js", "abc\u2029", "abc")
  315. trim("15.5.4.20-4-51.js", "\u000Aabc\u000A", "abc")
  316. trim("15.5.4.20-4-52.js", "\u000Dabc\u000D", "abc")
  317. trim("15.5.4.20-4-53.js", "\u2028abc\u2028", "abc")
  318. trim("15.5.4.20-4-54.js", "\u2029abc\u2029", "abc")
  319. trim("15.5.4.20-4-55.js", "\u000A\u000A", "")
  320. trim("15.5.4.20-4-56.js", "\u000D\u000D", "")
  321. trim("15.5.4.20-4-57.js", "\u2028\u2028", "")
  322. trim("15.5.4.20-4-58.js", "\u2029\u2029", "")
  323. trim("15.5.4.20-4-59.js", "\u2029 abc", "abc")
  324. trim("15.5.4.20-4-60.js", " ", "")
  325. add("test/built-ins/String/prototype/trim/u180e.js", "trim", [
  326. assertion("trailing U+180E", "_\u180E", "_\u180E"),
  327. assertion("only U+180E", "\u180E", "\u180E"),
  328. assertion("leading U+180E", "\u180E_", "\u180E_"),
  329. ])
  330. const directionalWhitespace =
  331. "\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"
  332. add("test/built-ins/String/prototype/trimStart/this-value-whitespace.js", "trimStart", [
  333. assertion(
  334. "all whitespace",
  335. directionalWhitespace + "a" + directionalWhitespace + "b" + directionalWhitespace,
  336. "a" + directionalWhitespace + "b" + directionalWhitespace,
  337. ),
  338. ])
  339. add("test/built-ins/String/prototype/trimStart/this-value-line-terminator.js", "trimStart", [
  340. assertion(
  341. "all line terminators",
  342. lineTerminators + "a" + lineTerminators + "b" + lineTerminators,
  343. "a" + lineTerminators + "b" + lineTerminators,
  344. ),
  345. ])
  346. add("test/built-ins/String/prototype/trimEnd/this-value-whitespace.js", "trimEnd", [
  347. assertion(
  348. "all whitespace",
  349. directionalWhitespace + "a" + directionalWhitespace + "b" + directionalWhitespace,
  350. directionalWhitespace + "a" + directionalWhitespace + "b",
  351. ),
  352. ])
  353. add("test/built-ins/String/prototype/trimEnd/this-value-line-terminator.js", "trimEnd", [
  354. assertion(
  355. "all line terminators",
  356. lineTerminators + "a" + lineTerminators + "b" + lineTerminators,
  357. lineTerminators + "a" + lineTerminators + "b",
  358. ),
  359. ])
  360. add("test/built-ins/String/prototype/repeat/repeat-string-n-times.js", "repeat", [
  361. assertion("repeat once", "abc", "abc", [1]),
  362. assertion("repeat three times", "abc", "abcabcabc", [3]),
  363. { label: "repeat 10000 times length", input: ".", args: [10000], expected: 10000, outcome: "length" },
  364. ])
  365. add("test/built-ins/String/prototype/repeat/empty-string-returns-empty.js", "repeat", [
  366. assertion("count 1", "", "", [1]),
  367. assertion("count 3", "", "", [3]),
  368. assertion("maximum 32-bit count", "", "", [0xffffffff]),
  369. ])
  370. add("test/built-ins/String/prototype/repeat/count-is-zero-returns-empty-string.js", "repeat", [
  371. assertion("zero", "foo", "", [0]),
  372. ])
  373. add("test/built-ins/String/prototype/repeat/count-coerced-to-zero-returns-empty-string.js", "repeat", [
  374. assertion("fraction truncates to zero", "abc", "", [0.9]),
  375. ])
  376. add("test/built-ins/String/prototype/padStart/fill-string-empty.js", "padStart", [
  377. assertion("empty fill", "abc", "abc", [5, ""]),
  378. ])
  379. add("test/built-ins/String/prototype/padStart/normal-operation.js", "padStart", [
  380. assertion("truncated multi-character fill", "abc", "defdabc", [7, "def"]),
  381. assertion("single-character fill", "abc", "**abc", [5, "*"]),
  382. assertion("truncated surrogate pair", "abc", "\uD83D\uDCA9\uD83Dabc", [6, "\uD83D\uDCA9"]),
  383. ])
  384. add("test/built-ins/String/prototype/padStart/fill-string-omitted.js", "padStart", [
  385. assertion("omitted fill", "abc", " abc", [5]),
  386. assertion("undefined fill", "abc", " abc", [5, undefined]),
  387. ])
  388. add("test/built-ins/String/prototype/padStart/max-length-not-greater-than-string.js", "padStart", [
  389. assertion("NaN", "abc", "abc", [NaN, "def"]),
  390. assertion("negative infinity", "abc", "abc", [-Infinity, "def"]),
  391. assertion("zero", "abc", "abc", [0, "def"]),
  392. assertion("negative one", "abc", "abc", [-1, "def"]),
  393. assertion("equal length", "abc", "abc", [3, "def"]),
  394. assertion("fraction truncates", "abc", "abc", [3.9999, "def"]),
  395. ])
  396. add("test/built-ins/String/prototype/padEnd/fill-string-empty.js", "padEnd", [
  397. assertion("empty fill", "abc", "abc", [5, ""]),
  398. ])
  399. add("test/built-ins/String/prototype/padEnd/normal-operation.js", "padEnd", [
  400. assertion("truncated multi-character fill", "abc", "abcdefd", [7, "def"]),
  401. assertion("single-character fill", "abc", "abc**", [5, "*"]),
  402. assertion("truncated surrogate pair", "abc", "abc\uD83D\uDCA9\uD83D", [6, "\uD83D\uDCA9"]),
  403. ])
  404. add("test/built-ins/String/prototype/padEnd/fill-string-omitted.js", "padEnd", [
  405. assertion("omitted fill", "abc", "abc ", [5]),
  406. assertion("undefined fill", "abc", "abc ", [5, undefined]),
  407. ])
  408. add("test/built-ins/String/prototype/padEnd/max-length-not-greater-than-string.js", "padEnd", [
  409. assertion("NaN", "abc", "abc", [NaN, "def"]),
  410. assertion("negative infinity", "abc", "abc", [-Infinity, "def"]),
  411. assertion("zero", "abc", "abc", [0, "def"]),
  412. assertion("negative one", "abc", "abc", [-1, "def"]),
  413. assertion("equal length", "abc", "abc", [3, "def"]),
  414. assertion("fraction truncates", "abc", "abc", [3.9999, "def"]),
  415. ])
  416. add("test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T4.js", "charAt", [assertion("omitted position", "lego", "l")])
  417. add("test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T7.js", "charAt", [
  418. assertion("undefined position", "lego", "l", [undefined]),
  419. ])
  420. add("test/built-ins/String/prototype/charAt/S15.5.4.4_A1_T8.js", "charAt", [
  421. assertion("undefined position", "42", "4", [undefined]),
  422. ])
  423. add(
  424. "test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T1.js",
  425. "charAt",
  426. ["A", "B", "C", "A", "B", "C"].map((expected, position) =>
  427. assertion(`position ${position}`, "ABCABC", expected, [position]),
  428. ),
  429. )
  430. add(
  431. "test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T2.js",
  432. "charAt",
  433. [-2, -1].map((position) => assertion(`position ${position}`, "ABCABC", "", [position])),
  434. )
  435. add(
  436. "test/built-ins/String/prototype/charAt/S15.5.4.4_A4_T3.js",
  437. "charAt",
  438. [6, 7].map((position) => assertion(`position ${position}`, "ABCABC", "", [position])),
  439. )
  440. add("test/built-ins/String/prototype/charAt/S9.4_A1.js", "charAt", [assertion("NaN position", "abc", "a", [NaN])])
  441. add("test/built-ins/String/prototype/charAt/S9.4_A2.js", "charAt", [
  442. assertion("positive zero", "abc", "a", [0]),
  443. assertion("negative zero", "abc", "a", [-0]),
  444. ])
  445. add("test/built-ins/String/prototype/charAt/pos-rounding.js", "charAt", [
  446. assertion("-0.99999", "abc", "a", [-0.99999]),
  447. assertion("-0.00001", "abc", "a", [-0.00001]),
  448. assertion("0.00001", "abc", "a", [0.00001]),
  449. assertion("0.99999", "abc", "a", [0.99999]),
  450. assertion("1.00001", "abc", "b", [1.00001]),
  451. assertion("1.99999", "abc", "b", [1.99999]),
  452. ])
  453. add("test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T4.js", "charCodeAt", [
  454. assertion("omitted position", "smart", 0x73),
  455. ])
  456. add("test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T7.js", "charCodeAt", [
  457. assertion("undefined position", "lego", 0x6c, [undefined]),
  458. ])
  459. add("test/built-ins/String/prototype/charCodeAt/S15.5.4.5_A1_T8.js", "charCodeAt", [
  460. assertion("undefined position", "42", 0x34, [undefined]),
  461. ])
  462. add("test/built-ins/String/prototype/charCodeAt/pos-rounding.js", "charCodeAt", [
  463. assertion("-0.99999", "abc", 0x61, [-0.99999]),
  464. assertion("-0.00001", "abc", 0x61, [-0.00001]),
  465. assertion("0.00001", "abc", 0x61, [0.00001]),
  466. assertion("0.99999", "abc", 0x61, [0.99999]),
  467. assertion("1.00001", "abc", 0x62, [1.00001]),
  468. assertion("1.99999", "abc", 0x62, [1.99999]),
  469. ])
  470. add("test/built-ins/String/prototype/codePointAt/return-single-code-unit.js", "codePointAt", [
  471. assertion("a", "abc", 97, [0]),
  472. assertion("b", "abc", 98, [1]),
  473. assertion("c", "abc", 99, [2]),
  474. assertion("ordinary BMP", "\uAAAA\uBBBB", 0xaaaa, [0]),
  475. assertion("before high-surrogate range", "\uD7FF\uAAAA", 0xd7ff, [0]),
  476. assertion("low surrogate", "\uDC00\uAAAA", 0xdc00, [0]),
  477. assertion("trailing D800", "123\uD800", 0xd800, [3]),
  478. assertion("trailing DAAA", "123\uDAAA", 0xdaaa, [3]),
  479. assertion("trailing DBFF", "123\uDBFF", 0xdbff, [3]),
  480. ])
  481. add("test/built-ins/String/prototype/codePointAt/return-first-code-unit.js", "codePointAt", [
  482. assertion("D800 before DBFF", "\uD800\uDBFF", 0xd800, [0]),
  483. assertion("D800 before E000", "\uD800\uE000", 0xd800, [0]),
  484. assertion("DAAA before DBFF", "\uDAAA\uDBFF", 0xdaaa, [0]),
  485. assertion("DAAA before E000", "\uDAAA\uE000", 0xdaaa, [0]),
  486. assertion("DBFF before DBFF", "\uDBFF\uDBFF", 0xdbff, [0]),
  487. assertion("DBFF before E000", "\uDBFF\uE000", 0xdbff, [0]),
  488. assertion("D800 before NUL", "\uD800\u0000", 0xd800, [0]),
  489. assertion("D800 before FFFF", "\uD800\uFFFF", 0xd800, [0]),
  490. assertion("DAAA before NUL", "\uDAAA\u0000", 0xdaaa, [0]),
  491. assertion("DAAA before FFFF", "\uDAAA\uFFFF", 0xdaaa, [0]),
  492. assertion("DBFF before FFFF", "\uDBFF\uFFFF", 0xdbff, [0]),
  493. ])
  494. add("test/built-ins/String/prototype/codePointAt/return-utf16-decode.js", "codePointAt", [
  495. assertion("U+10000", "\uD800\uDC00", 65536, [0]),
  496. assertion("U+101D0", "\uD800\uDDD0", 66000, [0]),
  497. assertion("U+103FF", "\uD800\uDFFF", 66559, [0]),
  498. assertion("U+BA800", "\uDAAA\uDC00", 763904, [0]),
  499. assertion("U+BA9D0", "\uDAAA\uDDD0", 764368, [0]),
  500. assertion("U+BABFF", "\uDAAA\uDFFF", 764927, [0]),
  501. assertion("U+10FC00", "\uDBFF\uDC00", 1113088, [0]),
  502. assertion("U+10FDD0", "\uDBFF\uDDD0", 1113552, [0]),
  503. assertion("U+10FFFF", "\uDBFF\uDFFF", 1114111, [0]),
  504. ])
  505. add("test/built-ins/String/prototype/codePointAt/return-code-unit-coerced-position.js", "codePointAt", [
  506. assertion("NaN", "\uD800\uDC00", 65536, [NaN]),
  507. assertion("undefined", "\uD800\uDC00", 65536, [undefined]),
  508. ])
  509. add("test/built-ins/String/prototype/codePointAt/returns-undefined-on-position-less-than-zero.js", "codePointAt", [
  510. { label: "negative one", input: "abc", args: [-1], outcome: "undefined" },
  511. { label: "negative infinity", input: "abc", args: [-Infinity], outcome: "undefined" },
  512. ])
  513. add(
  514. "test/built-ins/String/prototype/codePointAt/returns-undefined-on-position-equal-or-more-than-size.js",
  515. "codePointAt",
  516. [
  517. { label: "equal to size", input: "abc", args: [3], outcome: "undefined" },
  518. { label: "greater than size", input: "abc", args: [4], outcome: "undefined" },
  519. { label: "positive infinity", input: "abc", args: [Infinity], outcome: "undefined" },
  520. ],
  521. )
  522. add("test/built-ins/String/prototype/at/returns-code-unit.js", "at", [
  523. assertion("position 0", "12\uD80034", "1", [0]),
  524. assertion("position 1", "12\uD80034", "2", [1]),
  525. assertion("unpaired surrogate", "12\uD80034", "\uD800", [2]),
  526. assertion("position 3", "12\uD80034", "3", [3]),
  527. assertion("position 4", "12\uD80034", "4", [4]),
  528. ])
  529. add(
  530. "test/built-ins/String/prototype/at/returns-item.js",
  531. "at",
  532. ["1", "2", "3", "4", "5"].map((expected, position) =>
  533. assertion(`position ${position}`, "12345", expected, [position]),
  534. ),
  535. )
  536. add("test/built-ins/String/prototype/at/returns-item-relative-index.js", "at", [
  537. assertion("zero", "12345", "1", [0]),
  538. assertion("negative one", "12345", "5", [-1]),
  539. assertion("negative three", "12345", "3", [-3]),
  540. assertion("negative four", "12345", "2", [-4]),
  541. ])
  542. add(
  543. "test/built-ins/String/prototype/at/returns-undefined-for-out-of-range-index.js",
  544. "at",
  545. [-2, 0, 1].map((position) => ({ label: `position ${position}`, input: "", args: [position], outcome: "undefined" })),
  546. )
  547. add("test/built-ins/String/prototype/at/index-non-numeric-argument-tointeger.js", "at", [
  548. assertion("undefined", "01", "0", [undefined]),
  549. ])
  550. add("test/built-ins/String/prototype/concat/S15.5.4.6_A1_T4.js", "concat", [assertion("no arguments", "lego", "lego")])
  551. add("test/built-ins/String/prototype/toString/string-primitive.js", "toString", [
  552. assertion("empty string", "", ""),
  553. assertion("non-empty string", "str", "str"),
  554. ])
  555. add("test/built-ins/String/prototype/normalize/return-normalized-string.js", "normalize", [
  556. assertion("NFC short", "\u1E9B\u0323", "\u1E9B\u0323", ["NFC"]),
  557. assertion("NFD short", "\u1E9B\u0323", "\u017F\u0323\u0307", ["NFD"]),
  558. assertion("NFKC short", "\u1E9B\u0323", "\u1E69", ["NFKC"]),
  559. assertion("NFKD short", "\u1E9B\u0323", "\u0073\u0323\u0307", ["NFKD"]),
  560. assertion("NFC long", "\u00C5\u2ADC\u0958\u2126\u0344", "\xC5\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", ["NFC"]),
  561. assertion("NFD long", "\u00C5\u2ADC\u0958\u2126\u0344", "A\u030A\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", ["NFD"]),
  562. assertion("NFKC long", "\u00C5\u2ADC\u0958\u2126\u0344", "\xC5\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", ["NFKC"]),
  563. assertion("NFKD long", "\u00C5\u2ADC\u0958\u2126\u0344", "A\u030A\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", [
  564. "NFKD",
  565. ]),
  566. ])
  567. add("test/built-ins/String/prototype/normalize/return-normalized-string-using-default-parameter.js", "normalize", [
  568. assertion("omitted", "\u00C5\u2ADC\u0958\u2126\u0344", "\xC5\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301"),
  569. assertion("undefined", "\u00C5\u2ADC\u0958\u2126\u0344", "\xC5\u2ADD\u0338\u0915\u093C\u03A9\u0308\u0301", [
  570. undefined,
  571. ]),
  572. ])
  573. add("test/built-ins/String/prototype/normalize/form-is-not-valid-throws.js", "normalize", [
  574. { label: "bar", input: "foo", args: ["bar"], outcome: "RangeError" },
  575. { label: "NFC1", input: "foo", args: ["NFC1"], outcome: "RangeError" },
  576. ])
  577. add("test/built-ins/String/prototype/localeCompare/15.5.4.9_CE.js", "localeCompare", [
  578. assertion("D70", "o\u0308", 0, ["ö"]),
  579. assertion("reordered diaeresis", "ä\u0323", 0, ["a\u0323\u0308"]),
  580. assertion("reordered marks", "a\u0308\u0323", 0, ["a\u0323\u0308"]),
  581. assertion("precomposed dot below", "ạ\u0308", 0, ["a\u0323\u0308"]),
  582. assertion("breve after diaeresis", "ä\u0306", 0, ["a\u0308\u0306"]),
  583. assertion("diaeresis after breve", "ă\u0308", 0, ["a\u0306\u0308"]),
  584. assertion("Hangul", "\u1111\u1171\u11B6", 0, ["퓛"]),
  585. assertion("angstrom compatibility", "Å", 0, ["Å"]),
  586. assertion("angstrom decomposed", "Å", 0, ["A\u030A"]),
  587. assertion("reordered horn and dot", "x\u031B\u0323", 0, ["x\u0323\u031B"]),
  588. assertion("Vietnamese precomposed 1", "ự", 0, ["ụ\u031B"]),
  589. assertion("Vietnamese decomposed", "ự", 0, ["u\u031B\u0323"]),
  590. assertion("Vietnamese precomposed 2", "ự", 0, ["ư\u0323"]),
  591. assertion("Vietnamese reordered", "ự", 0, ["u\u0323\u031B"]),
  592. assertion("cedilla", "Ç", 0, ["C\u0327"]),
  593. assertion("q reordered", "q\u0307\u0323", 0, ["q\u0323\u0307"]),
  594. assertion("Hangul syllable", "가", 0, ["\u1100\u1161"]),
  595. assertion("ohm", "Ω", 0, ["Ω"]),
  596. assertion("angstrom", "Å", 0, ["A\u030A"]),
  597. assertion("circumflex", "ô", 0, ["o\u0302"]),
  598. assertion("s with marks", "ṩ", 0, ["s\u0323\u0307"]),
  599. assertion("d composed plus dot", "ḋ\u0323", 0, ["d\u0323\u0307"]),
  600. assertion("d two precompositions", "ḋ\u0323", 0, ["ḍ\u0307"]),
  601. ])
  602. add(
  603. "test/built-ins/String/fromCharCode/S15.5.3.2_A2.js",
  604. "fromCharCode",
  605. [{ label: "no arguments", expected: "" }],
  606. true,
  607. )
  608. add(
  609. "test/built-ins/String/fromCharCode/S15.5.3.2_A3_T1.js",
  610. "fromCharCode",
  611. [{ label: "ABBA", args: [65, 66, 66, 65], expected: "ABBA" }],
  612. true,
  613. )
  614. add(
  615. "test/built-ins/String/fromCharCode/S9.7_A1.js",
  616. "fromCharCode",
  617. [
  618. { label: "NaN", args: [NaN], expected: 0 },
  619. { label: "zero", args: [0], expected: 0 },
  620. { label: "negative zero", args: [-0], expected: 0 },
  621. { label: "positive infinity", args: [Infinity], expected: 0 },
  622. { label: "negative infinity", args: [-Infinity], expected: 0 },
  623. ],
  624. true,
  625. )
  626. add(
  627. "test/built-ins/String/fromCharCode/S9.7_A2.1.js",
  628. "fromCharCode",
  629. [
  630. [0, 0],
  631. [1, 1],
  632. [-1, 65535],
  633. [65535, 65535],
  634. [65534, 65534],
  635. [65536, 0],
  636. [4294967295, 65535],
  637. [4294967294, 65534],
  638. [4294967296, 0],
  639. ].map(([input, expected]) => ({ label: String(input), args: [input!], expected })),
  640. true,
  641. )
  642. add(
  643. "test/built-ins/String/fromCharCode/S9.7_A2.2.js",
  644. "fromCharCode",
  645. [
  646. [-32767, 32769],
  647. [-32768, 32768],
  648. [-32769, 32767],
  649. [-65535, 1],
  650. [-65536, 0],
  651. [-65537, 65535],
  652. [65535, 65535],
  653. [65536, 0],
  654. [65537, 1],
  655. [131071, 65535],
  656. [131072, 0],
  657. [131073, 1],
  658. ].map(([input, expected]) => ({ label: String(input), args: [input!], expected })),
  659. true,
  660. )
  661. add(
  662. "test/built-ins/String/fromCharCode/S9.7_A3.2_T1.js",
  663. "fromCharCode",
  664. [
  665. { label: "positive fraction", args: [1.2345], expected: 1 },
  666. { label: "negative fraction", args: [-5.4321], expected: 65531 },
  667. ],
  668. true,
  669. )
  670. add(
  671. "test/built-ins/String/fromCodePoint/arguments-is-empty.js",
  672. "fromCodePoint",
  673. [{ label: "no arguments", expected: "" }],
  674. true,
  675. )
  676. add(
  677. "test/built-ins/String/fromCodePoint/return-string-value.js",
  678. "fromCodePoint",
  679. [
  680. { label: "NUL", args: [0], expected: "\x00" },
  681. { label: "asterisk", args: [42], expected: "*" },
  682. { label: "AZ", args: [65, 90], expected: "AZ" },
  683. { label: "Cyrillic", args: [0x404], expected: "\u0404" },
  684. { label: "hex supplementary", args: [0x2f804], expected: "\uD87E\uDC04" },
  685. { label: "decimal supplementary", args: [194564], expected: "\uD87E\uDC04" },
  686. { label: "mixed supplementary", args: [0x1d306, 0x61, 0x1d307], expected: "\uD834\uDF06a\uD834\uDF07" },
  687. { label: "maximum code point", args: [1114111], expected: "\uDBFF\uDFFF" },
  688. ],
  689. true,
  690. )
  691. add(
  692. "test/built-ins/String/fromCodePoint/argument-is-not-integer.js",
  693. "fromCodePoint",
  694. [
  695. { label: "fraction", args: [3.14], outcome: "RangeError" },
  696. { label: "fraction after valid", args: [42, 3.14], outcome: "RangeError" },
  697. ],
  698. true,
  699. )
  700. add(
  701. "test/built-ins/String/fromCodePoint/number-is-out-of-range.js",
  702. "fromCodePoint",
  703. [
  704. { label: "negative one", args: [-1], outcome: "RangeError" },
  705. { label: "negative after valid", args: [1, -1], outcome: "RangeError" },
  706. { label: "above maximum", args: [1114112], outcome: "RangeError" },
  707. { label: "infinity", args: [Infinity], outcome: "RangeError" },
  708. ],
  709. true,
  710. )
  711. describe("Test262-adapted core String behavior", () => {
  712. for (const vector of vectors) {
  713. test(vector.path, async () => {
  714. const results = vector.assertions.map((item) => {
  715. const args = (item.args ?? []).map(literal).join(", ")
  716. const expression = vector.static
  717. ? `String.${vector.method}(${args})`
  718. : `${JSON.stringify(item.input)}.${vector.method}(${args})`
  719. const observed =
  720. vector.static && vector.method === "fromCharCode" && typeof item.expected === "number"
  721. ? `${expression}.charCodeAt(0)`
  722. : expression
  723. const checked =
  724. item.outcome === "undefined"
  725. ? `${observed} === undefined`
  726. : item.outcome === "length"
  727. ? `${observed}.length`
  728. : item.outcome === "RangeError"
  729. ? `(() => { try { ${observed}; return false } catch (error) { return error instanceof RangeError } })()`
  730. : observed
  731. return `{ label: ${JSON.stringify(item.label)}, value: ${checked} }`
  732. })
  733. const expected = vector.assertions.map((item) => ({
  734. label: item.label,
  735. value: item.outcome === undefined || item.outcome === "length" ? item.expected! : true,
  736. }))
  737. expect(await value(`return [${results.join(",")}]`)).toEqual(expected)
  738. })
  739. }
  740. })