]> Lady’s Gitweb - Pisces/blob - collection.test.js
acd90d2eaa73046c744cdf3cd6668683582fe8f0
[Pisces] / collection.test.js
1 // ♓🌟 Piscēs ∷ collection.test.js
2 // ====================================================================
3 //
4 // Copyright © 2022 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 assertEquals,
12 assertSpyCall,
13 assertSpyCalls,
14 assertStrictEquals,
15 describe,
16 it,
17 spy,
18 } from "./dev-deps.js";
19 import {
20 findIndexedEntry,
21 isArraylikeObject,
22 isCollection,
23 isConcatSpreadable,
24 } from "./collection.js";
25
26 describe("findIndexedEntry", () => {
27 it("[[Call]] returns undefined if no matching entry exists", () => {
28 assertStrictEquals(findIndexedEntry([], () => true), void {});
29 assertStrictEquals(findIndexedEntry([1], () => false), void {});
30 });
31
32 it("[[Call]] returns an entry for the first match", () => {
33 assertEquals(
34 findIndexedEntry([, true, false], ($) => $ ?? true),
35 [0, void {}],
36 );
37 assertEquals(
38 findIndexedEntry(["failure", "success"], ($) => $ == "success"),
39 [1, "success"],
40 );
41 });
42
43 it("[[Call]] works on arraylike objects", () => {
44 assertEquals(
45 findIndexedEntry({ 1: "success", length: 2 }, ($) => $),
46 [1, "success"],
47 );
48 assertEquals(
49 findIndexedEntry({ 1: "failure", length: 1 }, ($) => $),
50 void {},
51 );
52 });
53
54 it("[[Call]] only gets the value once", () => {
55 const get1 = spy(() => true);
56 findIndexedEntry({
57 get 1() {
58 return get1();
59 },
60 length: 2,
61 }, ($) => $);
62 assertSpyCalls(get1, 1);
63 });
64
65 it("[[Call]] passes the value, index, and this value to the callback", () => {
66 const arr = ["failure", "success", "success"];
67 const callback = spy(($) => $ === "success");
68 const thisArg = {};
69 findIndexedEntry(arr, callback, thisArg);
70 assertSpyCalls(callback, 2);
71 assertSpyCall(callback, 0, {
72 args: ["failure", 0, arr],
73 self: thisArg,
74 });
75 assertSpyCall(callback, 1, {
76 args: ["success", 1, arr],
77 self: thisArg,
78 });
79 });
80 });
81
82 describe("isArraylikeObject", () => {
83 it("[[Call]] returns false for primitives", () => {
84 assertStrictEquals(isArraylikeObject("failure"), false);
85 });
86
87 it("[[Call]] returns false if length throws", () => {
88 assertStrictEquals(
89 isArraylikeObject({
90 get length() {
91 throw void {};
92 },
93 }),
94 false,
95 );
96 });
97
98 it("[[Call]] returns false if length is not a number and cannot be converted to one", () => {
99 assertStrictEquals(isArraylikeObject({ length: 1n }), false);
100 });
101
102 it("[[Call]] returns true if length is convertable to a number", () => {
103 assertStrictEquals(isArraylikeObject({ length: -0 }), true);
104 assertStrictEquals(isArraylikeObject({ length: 1 }), true);
105 assertStrictEquals(isArraylikeObject({ length: -1.25 }), true);
106 assertStrictEquals(
107 isArraylikeObject({ length: 9007199254740992 }),
108 true,
109 );
110 assertStrictEquals(isArraylikeObject({ length: Infinity }), true);
111 assertStrictEquals(isArraylikeObject({ length: "success" }), true);
112 });
113 });
114
115 describe("isCollection", () => {
116 it("[[Call]] returns false for primitives", () => {
117 assertStrictEquals(isCollection("failure"), false);
118 });
119
120 it("[[Call]] returns false if length throws", () => {
121 assertStrictEquals(
122 isCollection({
123 get length() {
124 throw void {};
125 },
126 }),
127 false,
128 );
129 });
130
131 it("[[Call]] returns false if length is not an integer index and cannot be converted to one", () => {
132 assertStrictEquals(
133 isCollection({ length: -1, [Symbol.isConcatSpreadable]: true }),
134 false,
135 );
136 assertStrictEquals(
137 isCollection({
138 length: Infinity,
139 [Symbol.isConcatSpreadable]: true,
140 }),
141 false,
142 );
143 assertStrictEquals(
144 isCollection({
145 length: 9007199254740992,
146 [Symbol.isConcatSpreadable]: true,
147 }),
148 false,
149 );
150 });
151
152 it("[[Call]] returns true if length is an integer index and the object is concat spreadable", () => {
153 assertStrictEquals(
154 isCollection({ length: 1, [Symbol.isConcatSpreadable]: true }),
155 true,
156 );
157 assertStrictEquals(
158 isCollection({ length: 0, [Symbol.isConcatSpreadable]: true }),
159 true,
160 );
161 assertStrictEquals(
162 isCollection({
163 length: 9007199254740991,
164 [Symbol.isConcatSpreadable]: true,
165 }),
166 true,
167 );
168 });
169
170 it("[[Call]] returns true if length can be converted to an index without throwing an error and the object is concat spreadable", () => {
171 assertStrictEquals(
172 isCollection({ length: -0, [Symbol.isConcatSpreadable]: true }),
173 true,
174 );
175 assertStrictEquals(
176 isCollection({ length: NaN, [Symbol.isConcatSpreadable]: true }),
177 true,
178 );
179 });
180 });
181
182 describe("isConcatSpreadable", () => {
183 it("[[Call]] returns false for primitives", () => {
184 assertStrictEquals(isConcatSpreadable("failure"), false);
185 });
186
187 it("[[Call]] returns false if [Symbol.isConcatSpreadable] is null or false", () => {
188 assertStrictEquals(
189 isConcatSpreadable(
190 Object.assign([], { [Symbol.isConcatSpreadable]: null }),
191 ),
192 false,
193 );
194 assertStrictEquals(
195 isConcatSpreadable(
196 Object.assign([], { [Symbol.isConcatSpreadable]: false }),
197 ),
198 false,
199 );
200 });
201
202 it("[[Call]] returns true if [Symbol.isConcatSpreadable] is undefined and the object is an array", () => {
203 assertStrictEquals(
204 isConcatSpreadable(
205 Object.assign([], { [Symbol.isConcatSpreadable]: undefined }),
206 ),
207 true,
208 );
209 });
210
211 it("[[Call]] returns true if [Symbol.isConcatSpreadable] is true", () => {
212 assertStrictEquals(
213 isConcatSpreadable({ [Symbol.isConcatSpreadable]: true }),
214 true,
215 );
216 });
217 });
This page took 0.110444 seconds and 3 git commands to generate.