Fork of daniellemaywood.uk/gleam — Wasm codegen work
32 kB
1294 lines
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2021 The Gleam contributors
3
4import {
5 BitArray,
6 BitArray$BitArray,
7 BitArray$BitArray$data,
8 BitArray$isBitArray,
9 CustomType,
10 Error,
11 List,
12 Ok,
13 UtfCodepoint,
14 codepointBits,
15 divideFloat,
16 divideInt,
17 isEqual,
18 stringBits,
19 toBitArray,
20 toList,
21 sizedInt,
22 sizedFloat,
23 bitArraySlice,
24 bitArraySliceToInt,
25 bitArraySliceToFloat,
26} from "./prelude.mjs";
27
28let failures = 0;
29let passes = 0;
30
31function pass() {
32 process.stdout.write(`\u001b[${32}m.\u001b[${0}m`);
33 passes++;
34}
35
36function fail(message) {
37 console.log("");
38 console.assert(false, message);
39 failures++;
40}
41
42function inspect(a) {
43 if (typeof a === "object" && a !== null && typeof a.inspect === "function") {
44 return a.inspect();
45 } else {
46 return JSON.stringify(a);
47 }
48}
49
50function assertEqual(a, b) {
51 if (isEqual(a, b)) {
52 pass();
53 } else {
54 fail(`\n\t${inspect(a)}\n\t!=\n\t${inspect(b)}`);
55 }
56}
57
58function assertNotEqual(a, b) {
59 if (isEqual(a, b)) {
60 fail(`\n\t${inspect(a)}\n\t==\n\t${inspect(b)}`);
61 } else {
62 pass();
63 }
64}
65
66function assertThrows(msg, callable) {
67 try {
68 callable();
69 fail(msg);
70 } catch (error) {
71 pass();
72 }
73}
74
75function assert(msg, value) {
76 if (value) {
77 pass();
78 } else {
79 fail(msg);
80 }
81}
82
83class ExampleRecordImpl extends CustomType {
84 constructor(first, detail, boop) {
85 super();
86 this[0] = first;
87 this.detail = detail;
88 this.boop = boop;
89 }
90}
91
92let fmt = new Intl.DateTimeFormat("en-GB", { timeStyle: "medium" });
93console.log(`Running tests at ${fmt.format(new Date())}\n`);
94
95// Equality of Gleam values
96
97assertEqual(true, true);
98assertEqual(false, false);
99assertEqual(undefined, undefined);
100assertNotEqual(true, false);
101assertNotEqual(false, true);
102assertNotEqual(undefined, false);
103assertNotEqual(undefined, true);
104assertNotEqual(true, undefined);
105assertNotEqual(false, undefined);
106
107assertEqual(1, 1);
108assertNotEqual(1, 2);
109assertEqual(1.1, 1.1);
110assertNotEqual(2.1, 1.1);
111assertEqual(-1, -1);
112assertNotEqual(-1, 1);
113assertEqual(-1.1, -1.1);
114assertNotEqual(-1.1, 1.1);
115
116assertEqual("", "");
117assertEqual("123", "123");
118assertEqual("👽", "👽");
119assertNotEqual("👽", "👾");
120
121assertEqual(new Ok(1), new Ok(1));
122assertEqual(new Ok(2), new Ok(2));
123assertEqual(new Ok(new Ok(2)), new Ok(new Ok(2)));
124assertNotEqual(new Ok(1), new Ok(2));
125assertNotEqual(new Ok(new Ok(2)), new Ok(new Ok(3)));
126
127assertEqual(new Error(1), new Error(1));
128assertEqual(new Error(2), new Error(2));
129assertEqual(new Error(new Error(2)), new Error(new Error(2)));
130assertNotEqual(new Error(2), new Error(3));
131assertNotEqual(new Error(new Error(2)), new Error(new Error(3)));
132
133assertEqual(
134 new ExampleRecordImpl(undefined, 1, new Ok(2.1)),
135 new ExampleRecordImpl(undefined, 1, new Ok(2.1)),
136);
137assertNotEqual(
138 new ExampleRecordImpl(undefined, 1, new Ok("2.1")),
139 new ExampleRecordImpl(undefined, 1, new Ok(2.1)),
140);
141
142assertEqual(List.fromArray([]), List.fromArray([]));
143assertEqual(
144 List.fromArray([1, 2, new Ok(1)]),
145 List.fromArray([1, 2, new Ok(1)]),
146);
147assertNotEqual(
148 List.fromArray([1, 2, new Ok(1)]),
149 List.fromArray([1, 2, new Ok(2)]),
150);
151assertNotEqual(List.fromArray([1, 2]), List.fromArray([1, 2, new Ok(2)]));
152assertNotEqual(List.fromArray([1]), List.fromArray([]));
153assertNotEqual(List.fromArray([]), List.fromArray([1]));
154
155assertEqual(new UtfCodepoint(128013), new UtfCodepoint(128013));
156assertNotEqual(new UtfCodepoint(128013), new UtfCodepoint(128014));
157
158// new BitArray()
159
160assertEqual(
161 new BitArray(new Uint8Array([1, 2, 3])),
162 new BitArray(new Uint8Array([1, 2, 3]), 24),
163);
164
165assertThrows("`new BitArray()` throws with an ArrayBuffer", () => {
166 new BitArray(new ArrayBuffer(8));
167});
168
169assertThrows(
170 "`new BitArray()` throws with a raw array",
171 () => new BitArray([1, 2]),
172);
173
174assertThrows(
175 "`new BitArray()` throws with invalid bit size",
176 () => new BitArray(new Uint8Array([2]), -1),
177);
178
179assertThrows(
180 "`new BitArray()` throws with too many bytes for the bit size",
181 () => new BitArray(new Uint8Array([1, 2]), 7),
182);
183
184assertThrows(
185 "`new BitArray()` throws with too few bytes for the bit size",
186 () => new BitArray(new Uint8Array([1, 2]), 17),
187);
188
189assertThrows(
190 "`new BitArray()` throws with an invalid bit offset",
191 () => new BitArray(new Uint8Array([1]), 0, -1),
192);
193
194assertThrows(
195 "`new BitArray()` throws with an invalid bit offset",
196 () => new BitArray(new Uint8Array([1]), 0, 8),
197);
198
199// toBitArray()
200
201assertEqual(
202 new BitArray(new Uint8Array([1, 2])),
203 toBitArray([new BitArray(new Uint8Array([1, 2]))]),
204);
205
206assertEqual(new BitArray(new Uint8Array([])), toBitArray([]));
207
208const testValues = [
209 { input: 0, u8: 0 },
210 { input: 1, u8: 1 },
211 { input: 127, u8: 127 },
212 { input: 128, u8: 128 },
213 { input: 129, u8: 129 },
214 { input: 255, u8: 255 },
215 { input: 256, u8: 0 },
216 { input: 257, u8: 1 },
217 { input: 2000, u8: 208 },
218 { input: 0, u8: 0 },
219 { input: -1, u8: 255 },
220 { input: -127, u8: 129 },
221 { input: -128, u8: 128 },
222 { input: -129, u8: 127 },
223 { input: -255, u8: 1 },
224 { input: -256, u8: 0 },
225 { input: -257, u8: 255 },
226 { input: -2000, u8: 48 },
227];
228
229for (const { input, u8 } of testValues) {
230 assertEqual(new BitArray(new Uint8Array([u8])), toBitArray([input]));
231}
232
233assertEqual(new BitArray(new Uint8Array([])), toBitArray([new Uint8Array([])]));
234assertEqual(
235 new BitArray(new Uint8Array([1, 2, 4, 8])),
236 toBitArray([new Uint8Array([1, 2, 4, 8])]),
237);
238
239assertEqual(
240 new BitArray(new Uint8Array(testValues.map((t) => t.u8))),
241 toBitArray(testValues.map((t) => t.input)),
242);
243
244assertEqual(
245 new BitArray(
246 new Uint8Array([1, 2, 4, 8, ...testValues.map((t) => t.u8), 80, 90, 100]),
247 ),
248 toBitArray([
249 new Uint8Array([]),
250 new Uint8Array([1, 2, 4, 8]),
251 ...testValues.map((t) => t.input),
252 new Uint8Array([80, 90]),
253 new Uint8Array([]),
254 new Uint8Array([100]),
255 ]),
256);
257
258assertEqual(
259 new BitArray(new Uint8Array([97, 98, 99])),
260 toBitArray([stringBits("abc")]),
261);
262
263assertEqual(
264 new BitArray(new Uint8Array([97])),
265 toBitArray([codepointBits(new UtfCodepoint(97))]),
266);
267
268assertEqual(
269 new BitArray(new Uint8Array([240, 159, 144, 141])),
270 toBitArray([codepointBits(new UtfCodepoint(128013))]),
271);
272
273assertEqual(
274 new BitArray(new Uint8Array([240, 159, 144, 141, 0xfe]), 39),
275 toBitArray([
276 new BitArray(new Uint8Array([240, 159, 144])),
277 new BitArray(new Uint8Array([141])),
278 new BitArray(new Uint8Array([0xfe]), 7),
279 ]),
280);
281
282assertEqual(
283 new BitArray(
284 new Uint8Array([240, 159, 144, 0xa9, 0b11101010, 0xf7, 0x39, 0xae]),
285 64,
286 ),
287 toBitArray([
288 new BitArray(new Uint8Array([240, 159, 144])),
289 new BitArray(new Uint8Array([0b10110101]), 4, 3),
290 new BitArray(new Uint8Array([0x9f]), 7),
291 new BitArray(new Uint8Array([0b00010100]), 4, 2),
292 new BitArray(new Uint8Array([0]), 1),
293 new BitArray(new Uint8Array([0xaf, 0x73, 0x9a, 0xee]), 24, 4),
294 ]),
295);
296
297assertEqual(
298 new BitArray(
299 new Uint8Array([
300 129, 145, 57, 255, 255, 255, 255, 255, 191, 157, 243, 182, 246, 62, 104,
301 49, 62, 31, 110, 200, 120, 13, 88,
302 ]),
303 181,
304 ),
305 toBitArray([
306 sizedInt(2, 2, false),
307 sizedInt(0, 2, false),
308 sizedInt(200, 11, true),
309 sizedInt(-100, 49, false),
310 sizedFloat(-1.234, 32, true),
311 sizedFloat(-8.2e40, 64, false),
312 sizedInt(0xf, 5, false),
313 new Uint8Array([1]),
314 0xab,
315 ]),
316);
317
318// BitArray.equals()
319
320assertEqual(new BitArray(new Uint8Array([])), new BitArray(new Uint8Array([])));
321assertEqual(
322 new BitArray(new Uint8Array([1, 2, 3])),
323 new BitArray(new Uint8Array([1, 2, 3])),
324);
325assertNotEqual(
326 new BitArray(new Uint8Array([1, 2])),
327 new BitArray(new Uint8Array([1, 2, 3])),
328);
329assertNotEqual(
330 new BitArray(new Uint8Array([1, 0xf0]), 12),
331 new BitArray(new Uint8Array([2, 0xf0]), 12),
332);
333assertNotEqual(
334 new BitArray(new Uint8Array([1, 0xf0]), 12),
335 new BitArray(new Uint8Array([1, 0xf0]), 13),
336);
337assertNotEqual(
338 new BitArray(new Uint8Array([0x12, 0x30]), 12),
339 new BitArray(new Uint8Array([0x12, 0x4f]), 12),
340);
341assertEqual(
342 new BitArray(new Uint8Array([0x12, 0x30]), 12),
343 new BitArray(new Uint8Array([0x12, 0x3f]), 12),
344);
345assertEqual(
346 new BitArray(new Uint8Array([0b10110110, 0b01101001]), 8, 3),
347 new BitArray(new Uint8Array([0b10110011]), 8),
348);
349assertEqual(
350 new BitArray(new Uint8Array([0b10110110, 0b01101001, 0b10011010]), 17, 5),
351 new BitArray(new Uint8Array([0b11001101, 0b00110011, 0b01000001]), 17),
352);
353assertEqual(
354 new BitArray(new Uint8Array([0b11001101, 0b00110011]), 14, 1),
355 new BitArray(new Uint8Array([0b11100110, 0b10011001]), 14, 2),
356);
357assertEqual(
358 new BitArray(new Uint8Array([0b10110110]), 4, 2),
359 new BitArray(new Uint8Array([0b10111011]), 4, 3),
360);
361assertNotEqual(
362 new BitArray(new Uint8Array([0b10110110, 0b10110110]), 9, 2),
363 new BitArray(new Uint8Array([0b10110111, 0b10100110]), 9, 2),
364);
365assertNotEqual(
366 new BitArray(new Uint8Array([0b10110110, 0b10110110]), 9, 2),
367 new BitArray(new Uint8Array([0b10110110, 0b10000110]), 9, 2),
368);
369
370// toList
371
372assertEqual(toList([]), List.fromArray([]));
373assertEqual(toList([1, 2, 3]), List.fromArray([1, 2, 3]));
374assertEqual(toList([1, 2], toList([3, 4])), List.fromArray([1, 2, 3, 4]));
375assertEqual(toList([1, 2, 3], toList([4, 5])), List.fromArray([1, 2, 3, 4, 5]));
376
377// Equality of JavaScript values
378
379assertEqual([], []);
380assertEqual([1, 2], [1, 2]);
381assertEqual([new Ok([1, 2])], [new Ok([1, 2])]);
382assertNotEqual([], [[]]);
383assertNotEqual([], [1, []]);
384assertNotEqual([1, []], []);
385
386assertEqual({}, {});
387assertEqual({ a: 1 }, { a: 1 });
388assertEqual({ a: 1, b: 2 }, { b: 2, a: 1 });
389assertEqual({ a: new Ok(1) }, { a: new Ok(1) });
390assertNotEqual({ a: new Ok(2) }, { a: new Ok(1) });
391
392assertEqual(new Date(0), new Date(0));
393assertNotEqual(new Date(1), new Date(0));
394
395assertEqual(new Uint8Array([1, 2]), new Uint8Array([1, 2]));
396assertEqual(new Uint16Array([1, 2]), new Uint16Array([1, 2]));
397assertEqual(new Uint32Array([1, 2]), new Uint32Array([1, 2]));
398assertNotEqual(new Uint8Array([1, 3]), new Uint8Array([1, 2]));
399assertNotEqual(new Uint16Array([1, 3]), new Uint16Array([1, 2]));
400assertNotEqual(new Uint32Array([1, 3]), new Uint32Array([1, 2]));
401
402// Promises are not equal unless they have reference equality
403let promise = Promise.resolve(1);
404assertEqual(promise, promise);
405assertNotEqual(Promise.resolve(1), Promise.resolve(1));
406
407// Functions are not equal unless they have reference equality
408let fun = () => 1;
409assertEqual(fun, fun);
410assertNotEqual(
411 () => 1,
412 () => 1,
413);
414
415// Maps are compared structurally
416let map = new Map([["a", 1]]);
417assertEqual(map, map);
418assertEqual(new Map([["a", 1]]), new Map([["a", 1]]));
419assertNotEqual(
420 new Map([
421 ["a", 1],
422 ["b", 2],
423 ]),
424 new Map([["a", 1]]),
425);
426assertNotEqual(
427 new Map([["a", 1]]),
428 new Map([
429 ["a", 1],
430 ["b", 2],
431 ]),
432);
433assertNotEqual(new Map([["a", 1]]), new Map([["b", 1]]));
434assertEqual(
435 new Map([["a", new Map([["a", []]])]]),
436 new Map([["a", new Map([["a", []]])]]),
437);
438
439assertNotEqual(new Map([]), new Map([["b", 1]]));
440
441// Sets are compared structurally
442let set = new Set(["a", 1]);
443assertEqual(set, set);
444assertEqual(new Set(["a", 1]), new Set(["a", 1]));
445assertNotEqual(new Set(["a", 1]), new Set(["b", 1]));
446assertNotEqual(new Set(["a", 1, "b"]), new Set(["a", 1]));
447assertNotEqual(new Set(["a", 1]), new Set(["a", 1, "b"]));
448assertNotEqual(
449 new Set(["a", new Map([["a", []]])]),
450 new Set(["a", new Map([["a", []]])]),
451);
452
453// WeakMaps are not equal unless they have reference equality
454let weak_map = new WeakMap([[map, 1]]);
455assertEqual(weak_map, weak_map);
456assertNotEqual(new WeakMap([[map, 1]]), new WeakMap([[map, 1]]));
457
458// WeakSets are not equal unless they have reference equality
459let weak_set = new WeakSet([map, set]);
460assertEqual(weak_set, weak_set);
461assertNotEqual(new WeakSet([map, set]), new WeakSet([map, set]));
462
463// RegExp are compared structurally
464let re = new RegExp("test", "g");
465let re_literal = /test/g;
466assertEqual(re, re);
467assertEqual(re_literal, re_literal);
468assertEqual(re, re_literal);
469assertNotEqual(re, new RegExp("test", "i"));
470assertNotEqual(re, new RegExp("test"));
471assertNotEqual(re_literal, new RegExp("test", "i"));
472assertNotEqual(re_literal, /test/);
473assertNotEqual(re_literal, new RegExp("test", "i"));
474assertNotEqual(re, /test/i);
475
476class ExampleA {
477 constructor(x) {
478 this.x = x;
479 }
480}
481
482class ExampleB {
483 constructor(x) {
484 this.x = x;
485 }
486}
487
488assertEqual(new ExampleA(1), new ExampleA(1));
489assertEqual(new ExampleB(1), new ExampleB(1));
490assertNotEqual(new ExampleA(1), new ExampleA(2));
491assertNotEqual(new ExampleA(1), new ExampleB(1));
492
493// Custom .equals() method
494class NoCustomEquals {
495 constructor(id, notImportant) {
496 this.id = id;
497 this.notImportant = notImportant;
498 }
499}
500class HasCustomEqualsThatThrows {
501 constructor(id, notImportant) {
502 this.id = id;
503 this.notImportant = notImportant;
504 }
505 equals() {
506 throw "not today";
507 }
508}
509class HasCustomEquals {
510 constructor(id, notImportant) {
511 this.id = id;
512 this.notImportant = notImportant;
513 }
514 equals(o) {
515 return this.id === o.id;
516 }
517}
518function testCustomEquals(o) {
519 this.id === o.id;
520}
521const hasEqualsField = {
522 id: 1,
523 notImportant: 2,
524 equals: testCustomEquals,
525};
526const hasEqualsField2 = {
527 id: 1,
528 notImportant: 3,
529 equals: testCustomEquals,
530};
531// no custom equals, use structural equality
532assertEqual(new NoCustomEquals(1, 1), new NoCustomEquals(1, 1));
533assertNotEqual(new NoCustomEquals(1, 1), new NoCustomEquals(1, 2));
534// custom equals throws, fallback to structural equality
535assertEqual(
536 new HasCustomEqualsThatThrows(1, 1),
537 new HasCustomEqualsThatThrows(1, 1),
538);
539assertNotEqual(
540 new HasCustomEqualsThatThrows(1, 1),
541 new HasCustomEqualsThatThrows(1, 2),
542);
543// custom equals works, use it
544assertEqual(new HasCustomEquals(1, 1), new HasCustomEquals(1, 1));
545assertEqual(new HasCustomEquals(1, 1), new HasCustomEquals(1, 2));
546assertNotEqual(new HasCustomEquals(1, 1), new HasCustomEquals(2, 1));
547// custom equals defined on object instead of prototype, don't use it
548assertEqual(hasEqualsField, { ...hasEqualsField });
549assertNotEqual(hasEqualsField, hasEqualsField2);
550
551// Objects
552assertEqual({ a: 1 }, { a: 1 });
553assertEqual({ a: 1, b: 2 }, { b: 2, a: 1 });
554
555assertEqual({ a: {} }, { a: {} });
556assertEqual({ a: 1, b: { c: 3 } }, { a: 1, b: { c: 3 } });
557
558assertNotEqual({ a: 1 }, {});
559assertNotEqual({ a: 1, b: 2 }, { b: 2 });
560assertNotEqual({}, { a: 1 });
561assertNotEqual({ b: 2 }, { a: 1, b: 2 });
562
563// BitArray
564
565assertEqual(new BitArray(new Uint8Array([1, 2, 3])).byteAt(0), 1);
566assertEqual(new BitArray(new Uint8Array([1, 2, 3])).byteAt(2), 3);
567
568// bitArraySlice
569
570assertThrows("`bitArraySlice()` throws if start is less than zero", () =>
571 bitArraySlice(new BitArray(new Uint8Array([1])), -1, 8),
572);
573
574assertThrows(
575 "`bitArraySlice()` throws if start is greater than the bit size",
576 () => bitArraySlice(new BitArray(new Uint8Array([1])), 9, 8),
577);
578
579assertThrows("`bitArraySlice()` throws if end is before start", () =>
580 bitArraySlice(new BitArray(new Uint8Array([1])), 4, 2),
581);
582
583assertThrows(
584 "`bitArraySlice()` throws if end is greater than the bit size",
585 () => bitArraySlice(new Uint8Array([1]), 0, 10),
586);
587
588assertEqual(
589 bitArraySlice(new BitArray(new Uint8Array([1, 2, 3])), 0, 0),
590 new BitArray(new Uint8Array([])),
591);
592
593assertEqual(
594 bitArraySlice(new BitArray(new Uint8Array([0xbe, 0xff])), 0, 2),
595 new BitArray(new Uint8Array([0xbe]), 2),
596);
597
598assertEqual(
599 bitArraySlice(new BitArray(new Uint8Array([0x12, 0b10101101, 0xff])), 10, 14),
600 new BitArray(new Uint8Array([0b10110100]), 4),
601);
602
603assertEqual(
604 bitArraySlice(new BitArray(new Uint8Array([1, 2, 3])), 8, 24),
605 new BitArray(new Uint8Array([2, 3])),
606);
607
608assertEqual(
609 bitArraySlice(new BitArray(new Uint8Array([1, 2, 3, 4, 5])), 8, 32),
610 new BitArray(new Uint8Array([2, 3, 4])),
611);
612
613assertEqual(
614 bitArraySlice(new BitArray(new Uint8Array([1, 0xfe, 0xa1])), 8, 19),
615 new BitArray(new Uint8Array([0xfe, 0xa1]), 11),
616);
617
618assertEqual(
619 bitArraySlice(
620 new BitArray(new Uint8Array([17, 79, 190, 151, 98, 222, 101])),
621 19,
622 51,
623 ),
624 new BitArray(new Uint8Array([244, 187, 22, 243]), 32),
625);
626
627assertEqual(
628 bitArraySlice(new BitArray(new Uint8Array([0, 0, 0, 0, 0xff, 0xe0])), 37, 41),
629 new BitArray(new Uint8Array([0b11111100]), 4),
630);
631
632assertEqual(
633 bitArraySliceToFloat(
634 bitArraySlice(
635 new BitArray(new Uint8Array([0xaa, 0xbb, 0xff, 0, 0, 0])),
636 8,
637 48,
638 ),
639 8,
640 40,
641 false,
642 ),
643 3.5733110840282835e-43,
644);
645
646assertEqual(
647 bitArraySlice(
648 bitArraySlice(new BitArray(new Uint8Array([1, 2, 3, 4, 5])), 8, 32),
649 8,
650 ),
651 new BitArray(new Uint8Array([3, 4])),
652);
653
654assertEqual(
655 bitArraySlice(
656 new BitArray(new Uint8Array([0b00000001, 0b00000010, 0b00000011]), 20, 2),
657 4,
658 10,
659 ),
660 new BitArray(new Uint8Array([0b00000001, 0b00000010]), 6, 6),
661);
662
663assertEqual(
664 bitArraySlice(new BitArray(new Uint8Array([1])), 1),
665 new BitArray(new Uint8Array([0b00000010]), 7),
666);
667
668// sizedFloat()
669
670assertEqual(sizedFloat(0.0, 16, true), new Uint8Array([0x00, 0x00]));
671assertEqual(sizedFloat(1.0, 16, true), new Uint8Array([0x3c, 0x00]));
672assertEqual(sizedFloat(-1.0, 16, false), new Uint8Array([0x00, 0xbc]));
673assertEqual(sizedFloat(1.234375, 16, true), new Uint8Array([0x3c, 0xf0]));
674assertEqual(sizedFloat(-65_504.0, 16, false), new Uint8Array([0xff, 0xfb]));
675assertEqual(
676 sizedFloat(-0.00001519918441772461, 16, true),
677 new Uint8Array([0x80, 0xff]),
678);
679assertEqual(sizedFloat(Infinity, 16, true), new Uint8Array([0x7c, 0x00]));
680assertEqual(sizedFloat(-Infinity, 16, false), new Uint8Array([0x00, 0xfc]));
681assertEqual(sizedFloat(NaN, 16, true), new Uint8Array([0x7e, 0x00]));
682assertEqual(sizedFloat(1_000_000.0, 16, true), new Uint8Array([0x7c, 0x00]));
683assertEqual(sizedFloat(-1_000_000.0, 16, true), new Uint8Array([0xfc, 0x00]));
684
685assertEqual(sizedFloat(16.25, 32, true), new Uint8Array([65, 130, 0, 0]));
686assertEqual(sizedFloat(-16.25, 32, false), new Uint8Array([0, 0, 130, 193]));
687assertEqual(
688 sizedFloat(1000.5, 64, true),
689 new Uint8Array([64, 143, 68, 0, 0, 0, 0, 0]),
690);
691assertEqual(
692 sizedFloat(-1000.5, 64, false),
693 new Uint8Array([0, 0, 0, 0, 0, 68, 143, 192]),
694);
695
696// sizedInt()
697
698assertEqual(sizedInt(100, -8, true), new Uint8Array([]));
699assertEqual(sizedInt(100, 0, true), new Uint8Array([]));
700assertEqual(sizedInt(100, 8, true), new Uint8Array([100]));
701assertEqual(sizedInt(-10, 8, true), new Uint8Array([246]));
702
703assertEqual(sizedInt(1, 1, true), new BitArray(new Uint8Array([0x80]), 1));
704assertEqual(sizedInt(2, 2, true), new BitArray(new Uint8Array([0x80]), 2));
705assertEqual(sizedInt(15, 4, true), new BitArray(new Uint8Array([0xf0]), 4));
706assertEqual(sizedInt(100, 7, true), new BitArray(new Uint8Array([200]), 7));
707assertEqual(sizedInt(-44, 7, true), new BitArray(new Uint8Array([168]), 7));
708assertEqual(sizedInt(-1, 6, true), new BitArray(new Uint8Array([252]), 6));
709assertEqual(sizedInt(-1231, 3, true), new BitArray(new Uint8Array([32]), 3));
710assertEqual(sizedInt(1231, 5, true), new BitArray(new Uint8Array([120]), 5));
711
712assertEqual(
713 sizedInt(773, 10, true),
714 new BitArray(new Uint8Array([193, 64]), 10),
715);
716assertEqual(
717 sizedInt(-276, 10, false),
718 new BitArray(new Uint8Array([236, 128]), 10),
719);
720assertEqual(sizedInt(80000, 16, true), new Uint8Array([56, 128]));
721assertEqual(sizedInt(-80000, 16, true), new Uint8Array([199, 128]));
722assertEqual(sizedInt(1, 24, true), new Uint8Array([0, 0, 1]));
723assertEqual(
724 sizedInt(-100, 31, false),
725 new BitArray(new Uint8Array([156, 255, 255, 254]), 31),
726);
727assertEqual(sizedInt(0, 32, true), new Uint8Array([0, 0, 0, 0]));
728assertEqual(sizedInt(-1, 32, true), new Uint8Array([255, 255, 255, 255]));
729assertEqual(
730 sizedInt(-10, 33, true),
731 new BitArray(new Uint8Array([255, 255, 255, 251, 0]), 33),
732);
733assertEqual(
734 sizedInt(-489_391_639_457_909_760, 56, true),
735 new Uint8Array([53, 84, 229, 150, 16, 180, 0]),
736);
737assertEqual(
738 sizedInt(-1, 64, true),
739 new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]),
740);
741assertEqual(
742 sizedInt(Number.MAX_SAFE_INTEGER, 64, true),
743 new Uint8Array([0, 31, 255, 255, 255, 255, 255, 255]),
744);
745assertEqual(
746 sizedInt(Number.MIN_SAFE_INTEGER, 64, true),
747 new Uint8Array([255, 224, 0, 0, 0, 0, 0, 1]),
748);
749assertEqual(
750 sizedInt(Number.MAX_SAFE_INTEGER, 77, true),
751 new BitArray(
752 new Uint8Array([0, 0, 0, 255, 255, 255, 255, 255, 255, 248]),
753 77,
754 ),
755);
756assertEqual(
757 sizedInt(Number.MIN_SAFE_INTEGER, 75, false),
758 new BitArray(new Uint8Array([1, 0, 0, 0, 0, 0, 224, 255, 255, 224]), 75),
759);
760assertEqual(
761 sizedInt(Number(9444732965739289353650176n), 75, true),
762 new BitArray(new Uint8Array([255, 255, 255, 255, 255, 248, 0, 0, 0, 0]), 75),
763);
764
765// bitArraySliceToFloat()
766
767assertEqual(
768 bitArraySliceToFloat(toBitArray([63, 240, 0, 0, 0, 0, 0, 0]), 0, 64, true),
769 1.0,
770);
771assertEqual(
772 bitArraySliceToFloat(toBitArray([0, 0, 0, 0, 0, 0, 240, 63]), 0, 64, false),
773 1.0,
774);
775assertEqual(
776 bitArraySliceToFloat(toBitArray([0xff, 0xc9, 0x74, 0x24, 0x00]), 8, 40, true),
777 -1000000.0,
778);
779assertEqual(
780 bitArraySliceToFloat(toBitArray([0x00, 0x24, 0x74, 0xc9]), 0, 32, false),
781 -1000000.0,
782);
783assertEqual(
784 bitArraySliceToFloat(
785 new BitArray(new Uint8Array([112, 152, 127, 244, 0, 7, 192]), 50, 0),
786 11,
787 43,
788 true,
789 ),
790 -511.25,
791);
792assertEqual(
793 bitArraySliceToFloat(
794 new BitArray(
795 new Uint8Array([8, 0, 0, 0, 1, 129, 39, 103, 129, 254]),
796 79,
797 0,
798 ),
799 7,
800 71,
801 false,
802 ),
803 -5011.75,
804);
805assertEqual(
806 bitArraySliceToFloat(
807 new BitArray(new Uint8Array([212, 152, 127, 244, 0, 7, 192]), 50, 3),
808 11,
809 43,
810 true,
811 ),
812 1.0714967429001753e-19,
813);
814
815assertEqual(
816 bitArraySliceToFloat(new BitArray(new Uint8Array([0x00, 0x00])), 0, 16, true),
817 0.0,
818);
819assertEqual(
820 bitArraySliceToFloat(new BitArray(new Uint8Array([0x3c, 0x00])), 0, 16, true),
821 1.0,
822);
823assertEqual(
824 bitArraySliceToFloat(
825 new BitArray(new Uint8Array([0x00, 0xbc])),
826 0,
827 16,
828 false,
829 ),
830 -1.0,
831);
832assertEqual(
833 bitArraySliceToFloat(
834 new BitArray(new Uint8Array([0xf0, 0x3c])),
835 0,
836 16,
837 false,
838 ),
839 1.234375,
840);
841assertEqual(
842 bitArraySliceToFloat(new BitArray(new Uint8Array([0xfb, 0xff])), 0, 16, true),
843 -65_504.0,
844);
845assertEqual(
846 bitArraySliceToFloat(
847 new BitArray(new Uint8Array([0xff, 0x80])),
848 0,
849 16,
850 false,
851 ),
852 -0.00001519918441772461,
853);
854assertEqual(
855 bitArraySliceToFloat(new BitArray(new Uint8Array([0x7c, 0x00])), 0, 16, true),
856 Infinity,
857);
858assertEqual(
859 bitArraySliceToFloat(
860 new BitArray(new Uint8Array([0x00, 0xfc])),
861 0,
862 16,
863 false,
864 ),
865 -Infinity,
866);
867assertEqual(
868 isNaN(
869 bitArraySliceToFloat(
870 new BitArray(new Uint8Array([0x7e, 0x00])),
871 0,
872 16,
873 true,
874 ),
875 ),
876 true,
877);
878
879// bitArraySliceToInt()
880
881assertEqual(
882 bitArraySliceToInt(toBitArray([0b10011110]), 0, 4, true, false),
883 0b1001,
884);
885assertEqual(
886 bitArraySliceToInt(
887 new BitArray(new Uint8Array([0b11001110]), 7, 1),
888 0,
889 4,
890 true,
891 false,
892 ),
893 0b1001,
894);
895assertEqual(
896 bitArraySliceToInt(toBitArray([0b10011110]), 4, 8, true, false),
897 0b1110,
898);
899assertEqual(
900 bitArraySliceToInt(toBitArray([0b10011110]), 1, 6, true, true),
901 0b00111,
902);
903assertEqual(bitArraySliceToInt(toBitArray([0b10011010]), 3, 8, true, true), -6);
904assertEqual(
905 bitArraySliceToInt(toBitArray([0b10011010]), 0, 7, true, true),
906 -51,
907);
908assertEqual(
909 bitArraySliceToInt(
910 new BitArray(new Uint8Array([0b11001100, 0b00100000]), 11),
911 1,
912 11,
913 false,
914 false,
915 ),
916 408,
917);
918assertEqual(
919 bitArraySliceToInt(toBitArray([0xb6, 0xe3]), 0, 12, true, false),
920 0xb6e,
921);
922assertEqual(
923 bitArraySliceToInt(toBitArray([0xb6, 0xe3]), 0, 12, false, false),
924 0xeb6,
925);
926assertEqual(
927 bitArraySliceToInt(toBitArray([0xff, 0xb6, 0xe3]), 8, 20, true, false),
928 0xb6e,
929);
930assertEqual(
931 bitArraySliceToInt(toBitArray([0xff, 0xb6, 0xe3]), 20, 24, true, false),
932 0x03,
933);
934assertEqual(
935 bitArraySliceToInt(toBitArray([0xff, 0xb6, 0xe3]), 8, 20, false, false),
936 0xeb6,
937);
938assertEqual(
939 bitArraySliceToInt(toBitArray([0xa5, 0x6c, 0xaa]), 5, 18, true, false),
940 5554,
941);
942assertEqual(
943 bitArraySliceToInt(toBitArray([0xa5, 0x6c, 0xaa]), 5, 18, false, true),
944 -3411,
945);
946assertEqual(bitArraySliceToInt(toBitArray([1, 2, 3]), 0, 8, true, false), 1);
947assertEqual(
948 bitArraySliceToInt(toBitArray([160, 2, 3]), 0, 8, false, true),
949 -96,
950);
951assertEqual(bitArraySliceToInt(toBitArray([1, 2, 3]), 0, 16, true, false), 258);
952assertEqual(
953 bitArraySliceToInt(toBitArray([1, 2, 3]), 0, 16, false, false),
954 513,
955);
956assertEqual(
957 bitArraySliceToInt(toBitArray([1, 160, 3]), 0, 16, false, true),
958 -24575,
959);
960assertEqual(
961 bitArraySliceToInt(toBitArray([160, 2, 3]), 0, 16, true, false),
962 40962,
963);
964assertEqual(
965 bitArraySliceToInt(toBitArray([3, 160, 2]), 8, 24, true, true),
966 -24574,
967);
968assertEqual(
969 bitArraySliceToInt(
970 new BitArray(new Uint8Array([146, 192, 70, 25, 128]), 33),
971 1,
972 24,
973 true,
974 true,
975 ),
976 1_228_870,
977);
978assertEqual(
979 bitArraySliceToInt(toBitArray([255, 255, 255, 255]), 0, 32, false, true),
980 -1,
981);
982assertEqual(
983 bitArraySliceToInt(
984 new BitArray(new Uint8Array([217, 150, 209, 191, 0]), 33),
985 1,
986 33,
987 true,
988 false,
989 ),
990 3_006_112_638,
991);
992assertEqual(
993 bitArraySliceToInt(
994 new BitArray(new Uint8Array([146, 192, 70, 25, 128]), 33),
995 1,
996 33,
997 true,
998 true,
999 ),
1000 629_181_491,
1001);
1002assertEqual(
1003 bitArraySliceToInt(
1004 new BitArray(new Uint8Array([251, 24, 47, 227, 128]), 33),
1005 1,
1006 33,
1007 false,
1008 false,
1009 ),
1010 3_344_904_438,
1011);
1012assertEqual(
1013 bitArraySliceToInt(
1014 new BitArray(new Uint8Array([240, 102, 91, 101, 128]), 33),
1015 0,
1016 33,
1017 false,
1018 false,
1019 ),
1020 5_995_456_240,
1021);
1022assertEqual(
1023 bitArraySliceToInt(
1024 toBitArray([231, 255, 255, 255, 254, 123]),
1025 0,
1026 40,
1027 true,
1028 true,
1029 ),
1030 -103_079_215_106,
1031);
1032assertEqual(
1033 bitArraySliceToInt(
1034 toBitArray([0, 231, 255, 255, 253, 123, 17]),
1035 1,
1036 55,
1037 true,
1038 false,
1039 ),
1040 127_543_348_739_464,
1041);
1042assertEqual(
1043 bitArraySliceToInt(
1044 toBitArray([142, 231, 255, 255, 253, 123, 17, 139]),
1045 8,
1046 62,
1047 false,
1048 true,
1049 ),
1050 -8425025061257241,
1051);
1052assertEqual(
1053 bitArraySliceToInt(
1054 toBitArray([142, 231, 255, 255, 253, 123, 17, 139]),
1055 7,
1056 62,
1057 false,
1058 true,
1059 ),
1060 -8293899692933261,
1061);
1062assertEqual(
1063 bitArraySliceToInt(
1064 toBitArray([142, 231, 255, 255, 253, 123, 17]),
1065 8,
1066 48,
1067 true,
1068 true,
1069 ),
1070 -103_079_215_749,
1071);
1072assertEqual(
1073 bitArraySliceToInt(
1074 toBitArray([255, 255, 255, 255, 255, 255, 255]),
1075 0,
1076 56,
1077 true,
1078 true,
1079 ),
1080 -1,
1081);
1082assertEqual(
1083 bitArraySliceToInt(
1084 toBitArray([0x00, 0xaa, 255, 255, 255, 255, 255]),
1085 0,
1086 56,
1087 true,
1088 false,
1089 ),
1090 0xaaffffffffff,
1091);
1092assertEqual(
1093 bitArraySliceToInt(
1094 toBitArray([255, 255, 255, 255, 255, 0xaa, 0x00]),
1095 0,
1096 56,
1097 false,
1098 false,
1099 ),
1100 0xaaffffffffff,
1101);
1102assertEqual(
1103 bitArraySliceToInt(
1104 toBitArray([255, 255, 255, 255, 255, 255, 255]),
1105 0,
1106 56,
1107 true,
1108 false,
1109 ),
1110 Number(0xfffffffffffffen),
1111);
1112assertEqual(
1113 bitArraySliceToInt(toBitArray([0xfe, 0x3f]), 4, 12, true, false),
1114 0xe3,
1115);
1116assertEqual(bitArraySliceToInt(toBitArray([253, 94]), 3, 11, true, true), -22);
1117assertEqual(
1118 bitArraySliceToInt(toBitArray([233, 164]), 3, 15, true, false),
1119 1234,
1120);
1121assertEqual(
1122 bitArraySliceToInt(toBitArray([250, 72]), 3, 15, false, false),
1123 1234,
1124);
1125assertEqual(
1126 bitArraySliceToInt(toBitArray([250, 72, 223, 189]), 7, 29, true, false),
1127 596983,
1128);
1129assertEqual(
1130 bitArraySliceToInt(
1131 toBitArray([250, 72, 223, 189, 41, 97, 165, 0, 0, 0, 0, 177]),
1132 14,
1133 85,
1134 false,
1135 true,
1136 ),
1137 70821197049655,
1138);
1139assertEqual(
1140 bitArraySliceToInt(
1141 toBitArray([250, 72, 223, 189, 41, 97, 165, 0, 0, 0, 0, 177]),
1142 14,
1143 85,
1144 true,
1145 true,
1146 ),
1147 Number(515_906_807_693_217_628_160n),
1148);
1149
1150// Result.isOk
1151
1152assertEqual(new Ok(1).isOk(), true);
1153assertEqual(new Error(1).isOk(), false);
1154
1155// List.atLeastLength
1156
1157assertEqual(List.fromArray([]).atLeastLength(0), true);
1158assertEqual(List.fromArray([]).atLeastLength(1), false);
1159assertEqual(List.fromArray([]).atLeastLength(-1), true);
1160assertEqual(List.fromArray([1]).atLeastLength(0), true);
1161assertEqual(List.fromArray([1]).atLeastLength(1), true);
1162assertEqual(List.fromArray([1]).atLeastLength(2), false);
1163assertEqual(List.fromArray([1]).atLeastLength(-1), true);
1164
1165// List.hasLength
1166
1167assertEqual(toList([]).hasLength(0), true);
1168assertEqual(toList([]).hasLength(1), false);
1169assertEqual(toList([]).hasLength(-1), false);
1170assertEqual(toList([1]).hasLength(0), false);
1171assertEqual(toList([1]).hasLength(1), true);
1172assertEqual(toList([1]).hasLength(2), false);
1173assertEqual(toList([1, 1]).hasLength(1), false);
1174assertEqual(toList([1, 1]).hasLength(2), true);
1175assertEqual(toList([1, 1]).hasLength(3), false);
1176
1177// List iterable interface
1178
1179assertEqual([...toList([])], []);
1180assertEqual([...toList([1, 2, 3])], [1, 2, 3]);
1181
1182// BitArray.byteSize
1183
1184assertEqual(new BitArray(new Uint8Array([])).byteSize, 0);
1185assertEqual(new BitArray(new Uint8Array([1, 2])).byteSize, 2);
1186assertEqual(new BitArray(new Uint8Array([1, 2, 3, 4])).byteSize, 4);
1187assertEqual(new BitArray(new Uint8Array([1, 2, 3, 4], 28)).byteSize, 4);
1188
1189// BitArray
1190
1191assert("numbers are not bit arrays", !BitArray$isBitArray(123));
1192assert("strings are not bit arrays", !BitArray$isBitArray("!"));
1193assert("results are not bit arrays", new Ok("!"));
1194assert(
1195 "Bit arrays are bit arrays",
1196 BitArray$isBitArray(BitArray$BitArray(new Uint8Array([]))),
1197);
1198
1199// Byte aligned bit array
1200{
1201 const bitArray = BitArray$BitArray(new Uint8Array([1, 2, 3]));
1202 assertEqual(bitArray.bitSize, 3 * 8);
1203 assertEqual(bitArray.byteSize, 3);
1204 assertEqual(bitArray.bitOffset, 0);
1205 assertEqual(bitArray.rawBuffer, new Uint8Array([1, 2, 3]));
1206 assertEqual(
1207 BitArray$BitArray$data(bitArray),
1208 new DataView(new Uint8Array([1, 2, 3]).buffer),
1209 );
1210}
1211
1212// Non-byte aligned bit array
1213{
1214 const bitArray = BitArray$BitArray(new Uint8Array([1, 2, 3]), 23, 1);
1215 assertEqual(bitArray.bitSize, 23);
1216 assertEqual(bitArray.byteSize, 3);
1217 assertEqual(bitArray.bitOffset, 1);
1218 assertEqual(bitArray.rawBuffer, new Uint8Array([1, 2, 3]));
1219 assertThrows("BitArray$BitArray$data of un-aligned bit array", () => {
1220 BitArray$BitArray$data(bitArray);
1221 });
1222}
1223
1224assertEqual(
1225 BitArray$BitArray(new Uint8Array([])),
1226 new BitArray(new Uint8Array([])),
1227);
1228
1229//
1230// Division
1231//
1232
1233assertEqual(divideInt(1, 0), 0);
1234assertEqual(divideInt(1, 1), 1);
1235assertEqual(divideInt(1, 2), 0);
1236assertEqual(divideInt(3, 2), 1);
1237assertEqual(divideInt(11, 3), 3);
1238assertEqual(divideInt(-1, 0), 0);
1239assertEqual(divideInt(-1, 1), -1);
1240assertEqual(divideInt(-1, 2), -0);
1241assertEqual(divideInt(-3, 2), -1);
1242assertEqual(divideInt(-11, 3), -3);
1243assertEqual(divideInt(1, -1), -1);
1244assertEqual(divideInt(1, -2), 0);
1245assertEqual(divideInt(3, -2), -1);
1246assertEqual(divideInt(11, -3), -3);
1247assertEqual(divideInt(-1, -1), 1);
1248assertEqual(divideInt(-1, -2), 0);
1249assertEqual(divideInt(-3, -2), 1);
1250assertEqual(divideInt(-11, -3), 3);
1251
1252assertEqual(divideFloat(1.5, 0.0), 0.0);
1253assertEqual(divideFloat(1.5, 2.0), 0.75);
1254assertEqual(divideFloat(1.5, 2.5), 0.6);
1255assertEqual(divideFloat(-1.5, 0.0), -0.0);
1256assertEqual(divideFloat(-1.5, 2.0), -0.75);
1257assertEqual(divideFloat(-1.5, 2.5), -0.6);
1258assertEqual(divideFloat(1.5, -0.0), -0.0);
1259assertEqual(divideFloat(1.5, -2.0), -0.75);
1260assertEqual(divideFloat(1.5, -2.5), -0.6);
1261assertEqual(divideFloat(-1.5, -0.0), 0.0);
1262assertEqual(divideFloat(-1.5, -2.0), 0.75);
1263assertEqual(divideFloat(-1.5, -2.5), 0.6);
1264
1265// Record updates
1266
1267assertEqual(new Ok(1).withFields({ 0: 2 }), new Ok(2));
1268assertEqual(new Error(1).withFields({ 0: 2 }), new Error(2));
1269
1270assertEqual(
1271 new ExampleRecordImpl(1, 2, 3).withFields({}),
1272 new ExampleRecordImpl(1, 2, 3),
1273);
1274assertEqual(
1275 new ExampleRecordImpl(1, 2, 3).withFields({ boop: 6, 0: 40 }),
1276 new ExampleRecordImpl(40, 2, 6),
1277);
1278assertEqual(
1279 new ExampleRecordImpl(1, 2, 3).withFields({ boop: 4, detail: 5, 0: 6 }),
1280 new ExampleRecordImpl(6, 5, 4),
1281);
1282
1283//
1284// Summary
1285//
1286
1287console.log(`
1288
1289${passes + failures} tests
1290${passes} passes
1291${failures} failures
1292`);
1293
1294if (failures) process.exit(1);