1 // โ๐ Piscฤs โท string.test.js
2 // ====================================================================
4 // Copyright ยฉ 2022 Lady [@ Ladyโs Computer].
6 // This Source Code Form is subject to the terms of the Mozilla Public
7 // License, v. 2.0. If a copy of the MPL was not distributed with this
8 // file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
15 } from "./dev-deps.js";
25 splitOnASCIIWhitespace
,
27 stripAndCollapseASCIIWhitespace
,
28 stripLeadingAndTrailingASCIIWhitespace
,
31 describe("asciiLowercase", () => {
32 it("[[Call]] lowercases (just) AยทSยทCยทIยทI letters", () => {
33 assertStrictEquals(asciiLowercase("aBลฟรss Ftษษร"), "abลฟรss ftษษร");
37 describe("asciiUppercase", () => {
38 it("[[Call]] uppercases (just) AยทSยทCยทIยทI letters", () => {
39 assertStrictEquals(asciiUppercase("aBลฟรss Ftษษร"), "ABลฟรSS FTษษร");
43 describe("codeUnits", () => {
44 it("[[Call]] returns an iterable", () => {
46 typeof codeUnits("")[Symbol
.iterator
],
51 it("[[Call]] returns an iterator", () => {
52 assertStrictEquals(typeof codeUnits("").next
, "function");
55 it("[[Call]] returns a string code value iterator", () => {
57 codeUnits("")[Symbol
.toStringTag
],
58 "String Code Value Iterator",
62 it("[[Call]] iterates over the code units", () => {
64 ...codeUnits("Ii๐\uDFFF\uDD96\uD83C\uD800๐โบ"),
81 describe("codepoints", () => {
82 it("[[Call]] returns an iterable", () => {
84 typeof codepoints("")[Symbol
.iterator
],
89 it("[[Call]] returns an iterator", () => {
90 assertStrictEquals(typeof codepoints("").next
, "function");
93 it("[[Call]] returns a string code value iterator", () => {
95 codepoints("")[Symbol
.toStringTag
],
96 "String Code Value Iterator",
100 it("[[Call]] iterates over the codepoints", () => {
102 ...codepoints("Ii๐\uDFFF\uDD96\uD83C\uD800๐โบ"),
117 describe("getCharacter", () => {
118 it("[[Call]] returns the character at the provided position", () => {
119 assertStrictEquals(getCharacter("Ii๐๐โบ", 4), "๐");
122 it("[[Call]] returns a low surrogate if the provided position splits a character", () => {
123 assertStrictEquals(getCharacter("Ii๐๐โบ", 5), "\uDD97");
126 it("[[Call]] returns undefined for an outโofโbounds index", () => {
127 assertStrictEquals(getCharacter("Ii๐๐โบ", -1), void {});
128 assertStrictEquals(getCharacter("Ii๐๐โบ", 7), void {});
132 describe("join", () => {
133 it("[[Call]] joins the provided iterator with the provided separartor", () => {
134 assertStrictEquals(join([1, 2, 3, 4].values(), "โ"), "1โ2โ3โ4");
137 it('[[Call]] uses "," if no separator is provided', () => {
138 assertStrictEquals(join([1, 2, 3, 4].values()), "1,2,3,4");
141 it("[[Call]] uses the empty sting for nullish values", () => {
143 join([null, , null, undefined].values(), "โ"),
149 describe("scalarValueString", () => {
150 it("[[Call]] replaces invalid values", () => {
152 scalarValueString("Ii๐\uDFFF\uDD96\uD83C\uD800๐โบ"),
153 "Ii๐\uFFFD\uFFFD\uFFFD\uFFFD๐โบ",
158 describe("scalarValues", () => {
159 it("[[Call]] returns an iterable", () => {
161 typeof scalarValues("")[Symbol
.iterator
],
166 it("[[Call]] returns an iterator", () => {
167 assertStrictEquals(typeof scalarValues("").next
, "function");
170 it("[[Call]] returns a string code value iterator", () => {
172 scalarValues("")[Symbol
.toStringTag
],
173 "String Code Value Iterator",
177 it("[[Call]] iterates over the scalar values", () => {
179 ...scalarValues("Ii๐\uDFFF\uDD96\uD83C\uD800๐โบ"),
194 describe("splitOnASCIIWhitespace", () => {
195 it("[[Call]] splits on sequences of spaces", () => {
197 splitOnASCIIWhitespace("๐
ฐ๏ธ ๐
ฑ๏ธ ๐ ๐
พ๏ธ"),
198 ["๐
ฐ๏ธ", "๐
ฑ๏ธ", "๐", "๐
พ๏ธ"],
202 it("[[Call]] splits on sequences of tabs", () => {
204 splitOnASCIIWhitespace("๐
ฐ๏ธ\t\t\t๐
ฑ๏ธ\t๐\t\t๐
พ๏ธ"),
205 ["๐
ฐ๏ธ", "๐
ฑ๏ธ", "๐", "๐
พ๏ธ"],
209 it("[[Call]] splits on sequences of carriage returns", () => {
211 splitOnASCIIWhitespace("๐
ฐ๏ธ\r\r\r๐
ฑ๏ธ\r๐\r\r๐
พ๏ธ"),
212 ["๐
ฐ๏ธ", "๐
ฑ๏ธ", "๐", "๐
พ๏ธ"],
216 it("[[Call]] splits on sequences of newlines", () => {
218 splitOnASCIIWhitespace("๐
ฐ๏ธ\r\r\r๐
ฑ๏ธ\r๐\r\r๐
พ๏ธ"),
219 ["๐
ฐ๏ธ", "๐
ฑ๏ธ", "๐", "๐
พ๏ธ"],
223 it("[[Call]] splits on sequences of form feeds", () => {
225 splitOnASCIIWhitespace("๐
ฐ๏ธ\f\f\f๐
ฑ๏ธ\f๐\f\f๐
พ๏ธ"),
226 ["๐
ฐ๏ธ", "๐
ฑ๏ธ", "๐", "๐
พ๏ธ"],
230 it("[[Call]] splits on mixed whitespace", () => {
232 splitOnASCIIWhitespace("๐
ฐ๏ธ\f \t\n๐
ฑ๏ธ\r\n\r๐\n\f๐
พ๏ธ"),
233 ["๐
ฐ๏ธ", "๐
ฑ๏ธ", "๐", "๐
พ๏ธ"],
237 it("[[Call]] returns an array of just the empty string for the empty string", () => {
238 assertEquals(splitOnASCIIWhitespace(""), [""]);
241 it("[[Call]] returns a single token if there are no spaces", () => {
242 assertEquals(splitOnASCIIWhitespace("abcd"), ["abcd"]);
245 it("[[Call]] does not split on other kinds of whitespace", () => {
247 splitOnASCIIWhitespace("a\u202F\u205F\xa0\v\0\bb"),
248 ["a\u202F\u205F\xa0\v\0\bb"],
252 it("[[Call]] trims leading and trailing whitespace", () => {
254 splitOnASCIIWhitespace(
255 "\f\r\n\r\n \n\t๐
ฐ๏ธ\f \t\n๐
ฑ๏ธ\r๐\n\f๐
พ๏ธ\n\f",
257 ["๐
ฐ๏ธ", "๐
ฑ๏ธ", "๐", "๐
พ๏ธ"],
262 describe("splitOnCommas", () => {
263 it("[[Call]] splits on commas", () => {
265 splitOnCommas("๐
ฐ๏ธ,๐
ฑ๏ธ,๐,๐
พ๏ธ"),
266 ["๐
ฐ๏ธ", "๐
ฑ๏ธ", "๐", "๐
พ๏ธ"],
270 it("[[Call]] returns an array of just the empty string for the empty string", () => {
271 assertEquals(splitOnCommas(""), [""]);
274 it("[[Call]] returns a single token if there are no commas", () => {
275 assertEquals(splitOnCommas("abcd"), ["abcd"]);
278 it("[[Call]] splits into empty strings if there are only commas", () => {
279 assertEquals(splitOnCommas(",,,"), ["", "", "", ""]);
282 it("[[Call]] trims leading and trailing whitespace", () => {
284 splitOnCommas("\f\r\n\r\n \n\t๐
ฐ๏ธ,๐
ฑ๏ธ,๐,๐
พ๏ธ\n\f"),
285 ["๐
ฐ๏ธ", "๐
ฑ๏ธ", "๐", "๐
พ๏ธ"],
288 splitOnCommas("\f\r\n\r\n \n\t,,,\n\f"),
293 it("[[Call]] removes whitespace from the split tokens", () => {
296 "\f\r\n\r\n \n\t๐
ฐ๏ธ\f , \t\n๐
ฑ๏ธ,\r\n\r๐\n\f,๐
พ๏ธ\n\f",
298 ["๐
ฐ๏ธ", "๐
ฑ๏ธ", "๐", "๐
พ๏ธ"],
301 splitOnCommas("\f\r\n\r\n \n\t\f , \t\n,\r\n\r\n\f,\n\f"),
307 describe("stripAndCollapseASCIIWhitespace", () => {
308 it("[[Call]] collapses mixed inner whitespace", () => {
310 stripAndCollapseASCIIWhitespace("๐
ฐ๏ธ\f \t\n๐
ฑ๏ธ\r\n\r๐\n\f๐
พ๏ธ"),
311 "๐
ฐ๏ธ ๐
ฑ๏ธ ๐ ๐
พ๏ธ",
315 it("[[Call]] trims leading and trailing whitespace", () => {
317 stripAndCollapseASCIIWhitespace(
318 "\f\r\n\r\n \n\t\f ๐
ฐ๏ธ\f \t\n๐
ฑ๏ธ\r\n\r๐\n\f๐
พ๏ธ\n\f",
320 "๐
ฐ๏ธ ๐
ฑ๏ธ ๐ ๐
พ๏ธ",
324 it("[[Call]] returns the empty string for strings of whitespace", () => {
326 stripAndCollapseASCIIWhitespace("\f\r\n\r\n \n\t\f \n\f"),
331 it("[[Call]] does not collapse other kinds of whitespace", () => {
333 stripAndCollapseASCIIWhitespace("a\u202F\u205F\xa0\v\0\bb"),
334 "a\u202F\u205F\xa0\v\0\bb",
339 describe("stripLeadingAndTrailingASCIIWhitespace", () => {
340 it("[[Call]] trims leading and trailing whitespace", () => {
342 stripLeadingAndTrailingASCIIWhitespace(
343 "\f\r\n\r\n \n\t\f ๐
ฐ๏ธ๐
ฑ๏ธ๐๐
พ๏ธ\n\f",
345 "๐
ฐ๏ธ๐
ฑ๏ธ๐๐
พ๏ธ",
349 it("[[Call]] returns the empty string for strings of whitespace", () => {
351 stripLeadingAndTrailingASCIIWhitespace("\f\r\n\r\n \n\t\f \n\f"),
356 it("[[Call]] does not trim other kinds of whitespace", () => {
358 stripLeadingAndTrailingASCIIWhitespace(
359 "\v\u202F\u205Fx\0\b\xa0",
361 "\v\u202F\u205Fx\0\b\xa0",
365 it("[[Call]] does not adjust inner whitespace", () => {
367 stripLeadingAndTrailingASCIIWhitespace("a b"),