MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1import { test, testDeep, summary } from './helpers.js';
2
3console.log('Array Tests\n');
4
5let arr = [1, 2, 3];
6test('array literal creates array', arr instanceof Array, true);
7test('array index 0', arr[0], 1);
8test('array index 1', arr[1], 2);
9test('array index 2', arr[2], 3);
10test('array length', arr.length, 3);
11
12let empty = [];
13test('empty array is array', empty instanceof Array, true);
14test('empty array length', empty.length, 0);
15
16let mixed = [1, 'hello', true, null];
17test('mixed array length', mixed.length, 4);
18test('mixed array string', mixed[1], 'hello');
19test('mixed array bool', mixed[2], true);
20test('mixed array null', mixed[3], null);
21
22arr[0] = 10;
23test('array assignment', arr[0], 10);
24
25arr.push(4);
26test('push adds element', arr[arr.length - 1], 4);
27test('push increases length', arr.length, 4);
28
29arr.push(5, 6);
30test('push multiple', arr.length, 6);
31
32let popped = arr.pop();
33test('pop returns last', popped, 6);
34test('pop decreases length', arr.length, 5);
35
36let nested = [
37 [1, 2],
38 [3, 4]
39];
40test('nested array access', nested[0][0], 1);
41test('nested array access deep', nested[1][1], 4);
42
43let arr2 = Array(3);
44test('Array(n) creates sparse', arr2.length, 3);
45
46let arr3 = Array(10, 20, 30);
47test('Array with elements', arr3.length, 3);
48test('Array with elements value', arr3[1], 20);
49
50test('instanceof Array true', [1, 2] instanceof Array, true);
51test('instanceof Array false for object', {} instanceof Array, false);
52
53let obj = [1, 2, 3];
54obj['foo'] = 'bar';
55test('array string key', obj.foo, 'bar');
56
57let sumArr = [1, 2, 3, 4];
58let sum = 0;
59for (let i = 0; i < sumArr.length; i++) sum += sumArr[i];
60test('array iteration sum', sum, 10);
61
62let a = [1, 2, 3];
63testDeep('concat arrays', a.concat([4, 5]), [1, 2, 3, 4, 5]);
64test('join with comma', a.join(','), '1,2,3');
65test('indexOf found', a.indexOf(2), 1);
66test('indexOf not found', a.indexOf(5), -1);
67test('includes true', a.includes(2), true);
68test('includes false', a.includes(5), false);
69testDeep('slice', a.slice(1, 3), [2, 3]);
70testDeep('reverse', [1, 2, 3].reverse(), [3, 2, 1]);
71
72let shifted = [1, 2, 3];
73test('shift returns first', shifted.shift(), 1);
74test('shift decreases length', shifted.length, 2);
75
76let unshifted = [2, 3];
77unshifted.unshift(1);
78test('unshift adds to front', unshifted[0], 1);
79test('unshift increases length', unshifted.length, 3);
80
81testDeep(
82 'map',
83 [1, 2, 3].map(x => x * 2),
84 [2, 4, 6]
85);
86testDeep(
87 'filter',
88 [1, 2, 3, 4].filter(x => x % 2 === 0),
89 [2, 4]
90);
91test(
92 'reduce sum',
93 [1, 2, 3].reduce((a, b) => a + b, 0),
94 6
95);
96test(
97 'find',
98 [1, 2, 3].find(x => x > 1),
99 2
100);
101test(
102 'findIndex',
103 [1, 2, 3].findIndex(x => x > 1),
104 1
105);
106test(
107 'every true',
108 [2, 4, 6].every(x => x % 2 === 0),
109 true
110);
111test(
112 'every false',
113 [2, 3, 6].every(x => x % 2 === 0),
114 false
115);
116test(
117 'some true',
118 [1, 2, 3].some(x => x > 2),
119 true
120);
121test(
122 'some false',
123 [1, 2, 3].some(x => x > 5),
124 false
125);
126
127testDeep('Array.from string', Array.from('abc'), ['a', 'b', 'c']);
128testDeep('Array.of', Array.of(1, 2, 3), [1, 2, 3]);
129test('instanceof Array true', [] instanceof Array, true);
130test('instanceof Array false', {} instanceof Array, false);
131
132testDeep('flat', [1, [2, 3]].flat(), [1, 2, 3]);
133testDeep(
134 'flatMap',
135 [1, 2].flatMap(x => [x, x * 2]),
136 [1, 2, 2, 4]
137);
138
139let filled = new Array(3).fill(0);
140testDeep('fill', filled, [0, 0, 0]);
141
142let sorted = [3, 1, 2].sort();
143testDeep('sort default', sorted, [1, 2, 3]);
144
145let sortedDesc = [1, 2, 3].sort((a, b) => b - a);
146testDeep('sort descending', sortedDesc, [3, 2, 1]);
147
148let orig = [3, 1, 4, 1, 5];
149testDeep('toSorted returns sorted copy', orig.toSorted(), [1, 1, 3, 4, 5]);
150testDeep('toSorted does not mutate', orig, [3, 1, 4, 1, 5]);
151testDeep(
152 'toSorted with compareFn',
153 [3, 1, 2].toSorted((a, b) => b - a),
154 [3, 2, 1]
155);
156
157testDeep('toReversed returns reversed copy', [1, 2, 3].toReversed(), [3, 2, 1]);
158let orig2 = [1, 2, 3];
159orig2.toReversed();
160testDeep('toReversed does not mutate', orig2, [1, 2, 3]);
161
162testDeep('toSpliced removes elements', [1, 2, 3, 4, 5].toSpliced(1, 2), [1, 4, 5]);
163testDeep('toSpliced inserts elements', [1, 2, 3].toSpliced(1, 0, 99), [1, 99, 2, 3]);
164testDeep('toSpliced replaces elements', [1, 2, 3, 4, 5].toSpliced(1, 2, 99), [1, 99, 4, 5]);
165let orig3 = [1, 2, 3];
166orig3.toSpliced(1, 1);
167testDeep('toSpliced does not mutate', orig3, [1, 2, 3]);
168
169testDeep('with replaces element', [1, 2, 3].with(1, 99), [1, 99, 3]);
170testDeep('with negative index', [1, 2, 3].with(-1, 99), [1, 2, 99]);
171let orig4 = [1, 2, 3];
172orig4.with(0, 99);
173testDeep('with does not mutate', orig4, [1, 2, 3]);
174
175test(
176 'findLast',
177 [1, 2, 3, 2, 1].findLast(x => x === 2),
178 2
179);
180test(
181 'findLast returns last match',
182 [1, 2, 3, 4, 5].findLast(x => x > 2),
183 5
184);
185test(
186 'findLast not found',
187 [1, 2, 3].findLast(x => x > 5),
188 undefined
189);
190test(
191 'findLastIndex',
192 [1, 2, 3, 2, 1].findLastIndex(x => x === 2),
193 3
194);
195test(
196 'findLastIndex not found',
197 [1, 2, 3].findLastIndex(x => x > 5),
198 -1
199);
200
201test('at positive', [1, 2, 3].at(1), 2);
202test('at negative', [1, 2, 3].at(-1), 3);
203test('at out of bounds', [1, 2, 3].at(5), undefined);
204
205let forEachResult = [];
206[1, 2, 3].forEach(x => forEachResult.push(x * 2));
207testDeep('forEach', forEachResult, [2, 4, 6]);
208
209test(
210 'reduceRight',
211 [1, 2, 3].reduceRight((acc, x) => acc + x, 0),
212 6
213);
214test(
215 'reduceRight order',
216 ['a', 'b', 'c'].reduceRight((acc, x) => acc + x, ''),
217 'cba'
218);
219
220test('lastIndexOf found', [1, 2, 3, 2, 1].lastIndexOf(2), 3);
221test('lastIndexOf not found', [1, 2, 3].lastIndexOf(5), -1);
222
223testDeep('copyWithin', [1, 2, 3, 4, 5].copyWithin(0, 3), [4, 5, 3, 4, 5]);
224testDeep('copyWithin with end', [1, 2, 3, 4, 5].copyWithin(1, 3, 4), [1, 4, 3, 4, 5]);
225
226let spliceArr = [1, 2, 3, 4, 5];
227let removed = spliceArr.splice(1, 2);
228testDeep('splice returns removed', removed, [2, 3]);
229testDeep('splice mutates array', spliceArr, [1, 4, 5]);
230
231let spliceArr2 = [1, 2, 3];
232spliceArr2.splice(1, 0, 99, 100);
233testDeep('splice insert', spliceArr2, [1, 99, 100, 2, 3]);
234
235let spliceNoArgs = [1, 2];
236let spliceNoArgsRemoved = spliceNoArgs.splice();
237testDeep('splice no args leaves array', spliceNoArgs, [1, 2]);
238testDeep('splice no args removes nothing', spliceNoArgsRemoved, []);
239
240let entriesArr = ['a', 'b', 'c'];
241let entriesResult = [];
242for (let [i, v] of entriesArr.entries()) entriesResult.push([i, v]);
243testDeep('entries', entriesResult, [
244 [0, 'a'],
245 [1, 'b'],
246 [2, 'c']
247]);
248
249let keysResult = [];
250for (let k of ['a', 'b', 'c'].keys()) keysResult.push(k);
251testDeep('keys', keysResult, [0, 1, 2]);
252
253let valuesResult = [];
254for (let v of ['a', 'b', 'c'].values()) valuesResult.push(v);
255testDeep('values', valuesResult, ['a', 'b', 'c']);
256
257test('Array.isArray true', Array.isArray([1, 2, 3]), true);
258test('Array.isArray false object', Array.isArray({}), false);
259test('Array.isArray false string', Array.isArray('abc'), false);
260
261summary();