-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvector.test.js
More file actions
293 lines (247 loc) · 8.87 KB
/
Copy pathvector.test.js
File metadata and controls
293 lines (247 loc) · 8.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
import * as veclib from './vector.js'
describe('Vector class', () => {
const { Vec } = veclib
test('vector should have x, y, and z properties', () => {
let v = new Vec(1, 2, 3)
expect(v).toHaveProperty('x')
expect(v).toHaveProperty('y')
expect(v).toHaveProperty('z')
})
test('x, y, z should proxy array indices 0, 1, 2', () => {
let v = new Vec(4, 5, 6)
expect(v.x === v[0] && v.y === v[1] && v.z === v[2]).toBe(true)
})
test('vectors with more or less than 3 dimensions work exactly the same', () => {
let vLong = new Vec(1, 2, 3, 4, 5, 6)
let vShort = new Vec(1)
expect(vLong).toHaveLength(6)
expect(vShort).toHaveLength(1)
})
test('mutating x, y, or z should update index and vise versa', () => {
let v = new Vec(4, 5, 6)
v.x = 8
v[1] = 9
expect(v[0] === 8 && v.y === 9).toBe(true)
})
describe('map, filter, reduce', () => {
test('map returns a vector instance instead of a vanilla array', () => {
let v = new Vec(5, 6, 7)
let m = v.map((el) => el * 2)
expect(m.x).toEqual(m[0])
expect(m.x).toEqual(10)
})
test('filter sets false test values to zero', () => {
let v = new Vec(5, 6, 7)
let m = v.filter((el) => el > 5)
expect(m.x).toBeDefined()
expect(m.x).toEqual(0)
})
test('reduce should behave exactly like native Array.reduce', () => {
let v = new Vec([4, 5, 6])
expect(v.reduce((acc, d) => acc + d)).toBe(15)
expect(v.reduce((acc, d) => ({ ...acc, [d]: true }), {})).toEqual({
4: true,
5: true,
6: true,
})
})
test('if reduce returns an array, it should be cast to a Vector', () => {
let v = new Vec(2, 3, 4)
let res = v.reduce((acc, d) => [...acc, d * 2], [])
let resLong = v.reduce((acc, d) => [...acc, d, d * 2], [])
expect(res).toHaveProperty('x')
expect(resLong).toHaveProperty('x')
})
})
test('vector is JSON serializable into an array', () => {
let v = new Vec(4, 5, 6)
expect(JSON.stringify(v) === JSON.stringify([4, 5, 6])).toBe(true)
})
test('An existing array can be "vectorized"', () => {
let v = new Vec([3, 4, 5, 6])
expect(v[0] === 3 && v[1] === 4 && v[2] === 5 && v[3] === 6).toBe(true)
})
test('a vector can be cast back into a plain array with toArray()', () => {
let v = new Vec([3, 4, 5])
expect(v.toArray()).not.toHaveProperty('x')
expect(v).toHaveProperty('x')
})
})
describe('static vector methods', () => {
const { Vec, Vector } = veclib
describe('add', () => {
const { add } = veclib
test('if an array is passed in, it is cast to a vector', () => {
let v = [2, 3, 4]
let res = add(v, 5)
expect(res).toBeInstanceOf(Vec)
})
test('can add a vector and a scalar', () => {
let v = [2, 3, 4]
let res = add(v, 5)
expect(res).toHaveProperty('x', 7)
expect(res).toHaveProperty('y', 8)
expect(res).toHaveProperty('z', 9)
let res2 = add(3, v)
expect(res2.toArray()).toEqual([5, 6, 7])
})
test('trying to add a single vector returns the vector', () => {
expect(add([1, 2, 3]).toArray()).toEqual([1, 2, 3])
})
test('can add a scalars together', () => {
expect(add(1, 2)).toBe(3)
expect(add(1, 2, 3)).toBe(6)
})
test('adds two vectors together', () => {
let v1 = [2, 3, 4]
let v2 = [1, 2, 3]
let res = add(v1, v2)
expect(res.toArray()).toEqual([3, 5, 7])
})
test('adds n vectors together', () => {
let v1 = [2, 3, 4]
let v2 = [2, 3, 4]
let v3 = [2, 3, 4]
let v4 = [2, 3, 4]
expect(add(v1, v2, v3, v4).toArray()).toEqual([8, 12, 16])
})
test('can add 2d vecs together', () => {
let vecs = [[3, 3], [3, 3]]
expect(add(vecs).toArray()).toEqual([6, 6])
})
test('trying to add different sized vecs together throws an error', () => {
let vecs = [[3, 3], [3, 3, 3], 3]
expect(() => add(vecs)).toThrow()
})
test('can add n-dimensional vecs together', () => {
let vecs = [3, [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]
expect(add(vecs).toArray()).toEqual([6, 6, 6, 6, 6])
})
test('can pass vectors in either an array or as arguments', () => {
let vecs = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
expect(add(vecs).toArray()).toEqual([12, 15, 18])
})
})
describe('subtract', () => {
const { sub } = veclib
test('if an array is passed in, it is cast to a vector', () => {
let v = [2, 3, 4]
let res = sub(v, 5)
expect(res).toBeInstanceOf(Vec)
})
test('can pass vectors in either an array or as arguments', () => {
let vecs = [[5, 2, 3], [4, 5, 6], [1, 8, 9]]
expect(sub(vecs).toArray()).toEqual([0, -11, -12])
})
test('processes args from left to right', () => {
let v = [1, 1, 1]
expect(sub(v, 1).toArray()).toEqual([0, 0, 0])
})
test('trying to subtract a vector from a scalar should throw an error', () => {
let v = [1, 1, 1]
expect(() => sub(1, v)).toThrow()
})
})
describe('multiply', () => {
const { mult } = veclib
test('if an array is passed in, it is cast to a vector', () => {
let v = [2, 3, 4]
let res = mult(v, 5)
expect(res).toBeInstanceOf(Vec)
})
test('can multiply a vector and a scalar', () => {
let v = [2, 3, 4]
let res = mult(v, 2)
expect(res).toHaveProperty('x', 4)
expect(res).toHaveProperty('y', 6)
expect(res).toHaveProperty('z', 8)
let res2 = mult(0, v)
expect(res2.toArray()).toEqual([0, 0, 0])
})
test('can multiply a scalars together', () => {
expect(mult(1, 2)).toBe(2)
expect(mult(1, 2, 3)).toBe(6)
})
test('multiplies two vectors together', () => {
let v1 = [2, 3, 4]
let v2 = [1, 2, 3]
let res = mult(v1, v2)
expect(res.toArray()).toEqual([2, 6, 12])
})
test('multiply n vectors together', () => {
let v1 = [1, 0, 2]
let v2 = [1, 3, 2]
let v3 = [1, 3, 2]
let v4 = [1, 3, 2]
expect(mult(v1, v2, v3, v4).toArray()).toEqual([1, 0, 16])
})
test('can multiply 2d vecs together', () => {
let vecs = [[3, 3], [3, 3]]
expect(mult(vecs).toArray()).toEqual([9, 9])
})
test('trying to multiply different sized vecs together throws an error', () => {
let vecs = [[3, 3], [3, 3, 3], 3]
expect(() => mult(vecs)).toThrow()
})
test('can mult n-dimensional vecs together', () => {
let vecs = [3, [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]
expect(mult(vecs).toArray()).toEqual([3, 3, 3, 3, 3])
})
test('can pass vectors in either an array or as arguments', () => {
let vecs = [[1, 2, 2], [1, 1, 0], [1, 1, 9]]
expect(mult(vecs).toArray()).toEqual([1, 2, 0])
})
})
describe('divide', () => {
const { div } = veclib
test('if an array is passed in, it is cast to a vector', () => {
let v = [2, 3, 4]
let res = div(v, 5)
expect(res).toBeInstanceOf(Vec)
})
test('can pass vectors in either an array or as arguments', () => {
let vecs = [[5, 2, 3], [4, 5, 6], [1, 8, 9]]
let res = div(vecs).toArray()
let expected = [1.25, 0.05, 0.05555555555555555]
res.forEach((val, i) => expect(val).toBeCloseTo(expected[i]))
})
test('processes args from left to right', () => {
let v1 = [10, 4, 6]
let v2 = [2, 2, 2]
expect(div(v1, 1, v2).toArray()).toEqual([5, 2, 3])
})
test('trying to subtract a vector from a scalar should throw an error', () => {
let v = [1, 1, 1]
expect(() => sub(1, v)).toThrow()
})
})
describe('sum', () => {
const { sum } = veclib
test('if one vector is passed in, returns the sum of its dimensions', () => {
let v = [1, 2]
let result = sum(v)
let expected = 3
expect(result).toEqual(expected)
})
})
describe('clamp', () => {
const { clamp, create, Vec } = veclib
test('should always return a vector', () => {
expect(clamp([1, 2])).toBeInstanceOf(Vec)
expect(clamp(create([1, 2]))).toBeInstanceOf(Vec)
})
test('if only one arg is passed in, should clamp all dimensions to -1, 1', () => {
expect(clamp([-10]).toArray()).toEqual([-1])
expect(clamp([-10, 10]).toArray()).toEqual([-1, 1])
expect(clamp([-10, 10, 10]).toArray()).toEqual([-1, 1, 1])
})
test('if n arguments are passed in, the ith dimension of the first arg should be clamped to the range of the ith+1 argument vector', () => {
expect(clamp([-10], [-11, 1]).toArray()).toEqual([-10])
expect(clamp([-10, 10], [-2, 3], [0, 9]).toArray()).toEqual([-2, 9])
expect(clamp([-10, 10, 10]).toArray()).toEqual([-1, 1, 1])
})
test('if args.length - 1 is less than arg[0].length, unmatched dimensions will be clamped to the last range vector', () => {
expect(clamp([-3, 3], [-2, 2]).toArray()).toEqual([-2, 2])
})
})
})