]> Lady’s Gitweb - Pisces/blob - value.test.js
df8677801934ecb7a09b878e36fe3fe6c2a155be
[Pisces] / value.test.js
1 // ♓🌟 Piscēs ∷ value.test.js
2 // ====================================================================
3 //
4 // Copyright © 2022–2023 Lady [@ Lady’s Computer].
5 //
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/>.
9
10 import {
11 assert,
12 assertStrictEquals,
13 assertThrows,
14 describe,
15 it,
16 } from "./dev-deps.js";
17 import {
18 ASYNC_ITERATOR,
19 HAS_INSTANCE,
20 IS_CONCAT_SPREADABLE,
21 ITERATOR,
22 MATCH,
23 MATCH_ALL,
24 NULL,
25 ordinaryToPrimitive,
26 REPLACE,
27 sameValue,
28 sameValueZero,
29 SPECIES,
30 SPLIT,
31 TO_PRIMITIVE,
32 TO_STRING_TAG,
33 toPrimitive,
34 type,
35 UNDEFINED,
36 UNSCOPABLES,
37 } from "./value.js";
38
39 describe("ASYNC_ITERATOR", () => {
40 it("[[Get]] is @@asyncIterator", () => {
41 assertStrictEquals(ASYNC_ITERATOR, Symbol.asyncIterator);
42 });
43 });
44
45 describe("HAS_INSTANCE", () => {
46 it("[[Get]] is @@hasInstance", () => {
47 assertStrictEquals(HAS_INSTANCE, Symbol.hasInstance);
48 });
49 });
50
51 describe("IS_CONCAT_SPREADABLE", () => {
52 it("[[Get]] is @@isConcatSpreadable", () => {
53 assertStrictEquals(
54 IS_CONCAT_SPREADABLE,
55 Symbol.isConcatSpreadable,
56 );
57 });
58 });
59
60 describe("ITERATOR", () => {
61 it("[[Get]] is @@iterator", () => {
62 assertStrictEquals(ITERATOR, Symbol.iterator);
63 });
64 });
65
66 describe("MATCH", () => {
67 it("[[Get]] is @@match", () => {
68 assertStrictEquals(MATCH, Symbol.match);
69 });
70 });
71
72 describe("MATCH_ALL", () => {
73 it("[[Get]] is @@matchAll", () => {
74 assertStrictEquals(MATCH_ALL, Symbol.matchAll);
75 });
76 });
77
78 describe("NULL", () => {
79 it("[[Get]] is null", () => {
80 assertStrictEquals(NULL, null);
81 });
82 });
83
84 describe("REPLACE", () => {
85 it("[[Get]] is @@replace", () => {
86 assertStrictEquals(REPLACE, Symbol.replace);
87 });
88 });
89
90 describe("SPECIES", () => {
91 it("[[Get]] is @@species", () => {
92 assertStrictEquals(SPECIES, Symbol.species);
93 });
94 });
95
96 describe("SPLIT", () => {
97 it("[[Get]] is @@split", () => {
98 assertStrictEquals(SPLIT, Symbol.split);
99 });
100 });
101
102 describe("TO_PRIMITIVE", () => {
103 it("[[Get]] is @@toPrimitive", () => {
104 assertStrictEquals(TO_PRIMITIVE, Symbol.toPrimitive);
105 });
106 });
107
108 describe("TO_STRING_TAG", () => {
109 it("[[Get]] is @@toStringTag", () => {
110 assertStrictEquals(TO_STRING_TAG, Symbol.toStringTag);
111 });
112 });
113
114 describe("UNDEFINED", () => {
115 it("[[Get]] is undefined", () => {
116 assertStrictEquals(UNDEFINED, void {});
117 });
118 });
119
120 describe("UNSCOPABLES", () => {
121 it("[[Get]] is @@unscopables", () => {
122 assertStrictEquals(UNSCOPABLES, Symbol.unscopables);
123 });
124 });
125
126 describe("ordinaryToPrimitive", () => {
127 it("[[Call]] prefers `valueOf` by default", () => {
128 const obj = {
129 toString() {
130 return "failure";
131 },
132 valueOf() {
133 return "success";
134 },
135 };
136 assertStrictEquals(ordinaryToPrimitive(obj), "success");
137 assertStrictEquals(ordinaryToPrimitive(obj, "default"), "success");
138 });
139
140 it('[[Call]] prefers `valueOf` for a "number" hint', () => {
141 const obj = {
142 toString() {
143 return "failure";
144 },
145 valueOf() {
146 return "success";
147 },
148 };
149 assertStrictEquals(ordinaryToPrimitive(obj, "number"), "success");
150 });
151
152 it('[[Call]] prefers `toString` for a "string" hint', () => {
153 const obj = {
154 toString() {
155 return "success";
156 },
157 valueOf() {
158 return "failure";
159 },
160 };
161 assertStrictEquals(ordinaryToPrimitive(obj, "string"), "success");
162 });
163
164 it("[[Call]] falls back to the other method if the first isn’t callable", () => {
165 const obj = {
166 toString() {
167 return "success";
168 },
169 valueOf: "failure",
170 };
171 assertStrictEquals(ordinaryToPrimitive(obj), "success");
172 });
173
174 it("[[Call]] falls back to the other method if the first returns an object", () => {
175 const obj = {
176 toString() {
177 return "success";
178 },
179 valueOf() {
180 return new String("failure");
181 },
182 };
183 assertStrictEquals(ordinaryToPrimitive(obj), "success");
184 });
185
186 it("[[Call]] throws an error if neither method is callable", () => {
187 const obj = {
188 toString: "failure",
189 valueOf: "failure",
190 };
191 assertThrows(() => ordinaryToPrimitive(obj));
192 });
193
194 it("[[Call]] throws an error if neither method returns an object", () => {
195 const obj = {
196 toString() {
197 return new String("failure");
198 },
199 valueOf() {
200 return new String("failure");
201 },
202 };
203 assertThrows(() => ordinaryToPrimitive(obj));
204 });
205 });
206
207 describe("sameValue", () => {
208 it("[[Call]] returns false for null 🆚 undefined", () => {
209 assert(!sameValue(null, void {}));
210 });
211
212 it("[[Call]] returns false for null 🆚 an object", () => {
213 assert(!sameValue(null, {}));
214 });
215
216 it("[[Call]] returns true for null 🆚 null", () => {
217 assert(sameValue(null, null));
218 });
219
220 it("[[Call]] returns false for two different objects", () => {
221 assert(!sameValue({}, {}));
222 });
223
224 it("[[Call]] returns true for the same object", () => {
225 const obj = {};
226 assert(sameValue(obj, obj));
227 });
228
229 it("[[Call]] returns false for ±0", () => {
230 assert(!sameValue(0, -0));
231 });
232
233 it("[[Call]] returns true for -0", () => {
234 assert(sameValue(-0, -0));
235 });
236
237 it("[[Call]] returns true for nan", () => {
238 assert(sameValue(0 / 0, 0 / 0));
239 });
240
241 it("[[Call]] returns false for a primitive and its wrapped object", () => {
242 assert(!sameValue(false, new Boolean(false)));
243 });
244 });
245
246 describe("sameValueZero", () => {
247 it("[[Call]] returns false for null 🆚 undefined", () => {
248 assert(!sameValueZero(null, void {}));
249 });
250
251 it("[[Call]] returns false for null 🆚 an object", () => {
252 assert(!sameValueZero(null, {}));
253 });
254
255 it("[[Call]] returns true for null 🆚 null", () => {
256 assert(sameValueZero(null, null));
257 });
258
259 it("[[Call]] returns false for two different objects", () => {
260 assert(!sameValueZero({}, {}));
261 });
262
263 it("[[Call]] returns true for the same object", () => {
264 const obj = {};
265 assert(sameValueZero(obj, obj));
266 });
267
268 it("[[Call]] returns true for ±0", () => {
269 assert(sameValueZero(0, -0));
270 });
271
272 it("[[Call]] returns true for -0", () => {
273 assert(sameValueZero(-0, -0));
274 });
275
276 it("[[Call]] returns true for nan", () => {
277 assert(sameValueZero(0 / 0, 0 / 0));
278 });
279
280 it("[[Call]] returns false for a primitive and its wrapped object", () => {
281 assert(!sameValueZero(false, new Boolean(false)));
282 });
283 });
284
285 describe("toPrimitive", () => {
286 it("[[Call]] returns the argument when passed a primitive", () => {
287 const value = Symbol();
288 assertStrictEquals(toPrimitive(value), value);
289 });
290
291 it("[[Call]] works with nullish values", () => {
292 assertStrictEquals(toPrimitive(null), null);
293 assertStrictEquals(toPrimitive(), void {});
294 });
295
296 it("[[Call]] calls ordinaryToPrimitive by default", () => {
297 const value = Object.assign(
298 Object.create(null),
299 {
300 valueOf() {
301 return "success";
302 },
303 },
304 );
305 assertStrictEquals(toPrimitive(value), "success");
306 });
307
308 it("[[Call]] accepts a hint", () => {
309 const value = Object.assign(
310 Object.create(null),
311 {
312 toString() {
313 return "success";
314 },
315 valueOf() {
316 return "failure";
317 },
318 },
319 );
320 assertStrictEquals(toPrimitive(value, "string"), "success");
321 });
322
323 it("[[Call]] uses the exotic toPrimitive method if available", () => {
324 const value = Object.assign(
325 Object.create(null),
326 {
327 [Symbol.toPrimitive]() {
328 return "success";
329 },
330 },
331 );
332 assertStrictEquals(toPrimitive(value), "success");
333 });
334
335 it("[[Call]] passes the hint to the exotic toPrimitive", () => {
336 const value = Object.assign(
337 Object.create(null),
338 {
339 [Symbol.toPrimitive](hint) {
340 return hint === "string" ? "success" : "failure";
341 },
342 },
343 );
344 assertStrictEquals(toPrimitive(value, "string"), "success");
345 });
346
347 it('[[Call]] passes a "default" hint by default', () => {
348 const value = Object.assign(
349 Object.create(null),
350 {
351 [Symbol.toPrimitive](hint) {
352 return hint === "default" ? "success" : "failure";
353 },
354 },
355 );
356 assertStrictEquals(toPrimitive(value, "default"), "success");
357 });
358
359 it("[[Call]] throws for an invalid hint", () => {
360 const value1 = Object.assign(
361 Object.create(null),
362 {
363 [Symbol.toPrimitive]() {
364 return "success";
365 },
366 },
367 );
368 const value2 = Object.assign(
369 Object.create(null),
370 {
371 valueOf() {
372 return true;
373 },
374 },
375 );
376 assertThrows(() => toPrimitive(value1, "badhint"));
377 assertThrows(() => toPrimitive(value2, "badhint"));
378 assertThrows(() => toPrimitive(true, "badhint"));
379 });
380 });
381
382 describe("type", () => {
383 it('[[Call]] returns "null" for null', () => {
384 assertStrictEquals(type(null), "null");
385 });
386
387 it('[[Call]] returns "undefined" for undefined', () => {
388 assertStrictEquals(type(void {}), "undefined");
389 });
390
391 it('[[Call]] returns "object" for non‐callable objects', () => {
392 assertStrictEquals(type(Object.create(null)), "object");
393 });
394
395 it('[[Call]] returns "object" for callable objects', () => {
396 assertStrictEquals(type(() => {}), "object");
397 });
398
399 it('[[Call]] returns "object" for constructable objects', () => {
400 assertStrictEquals(type(class {}), "object");
401 });
402 });
This page took 0.095964 seconds and 3 git commands to generate.