@inglorious/utils 3.6.3 → 3.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,198 +0,0 @@
1
- import { expect, test } from "vitest"
2
-
3
- import {
4
- abs,
5
- clamp,
6
- isBetween,
7
- isClose,
8
- mod,
9
- sign,
10
- snap,
11
- sqrt,
12
- } from "./numbers.js"
13
-
14
- test("it should return the same number if already positive", () => {
15
- const num = 42
16
- const expectedResult = 42
17
-
18
- expect(abs(num)).toBe(expectedResult)
19
- })
20
-
21
- test("it should return the absolute value of a number", () => {
22
- const num = -42
23
- const expectedResult = 42
24
-
25
- expect(abs(num)).toBe(expectedResult)
26
- })
27
-
28
- test("it should not clamp a number in the range", () => {
29
- const num = 42
30
- const min = 0
31
- const max = 100
32
- const expectedResult = 42
33
-
34
- expect(clamp(num, min, max)).toBe(expectedResult)
35
- })
36
-
37
- test("it should clamp a number too small", () => {
38
- const num = -42
39
- const min = 0
40
- const max = 100
41
- const expectedResult = 0
42
-
43
- expect(clamp(num, min, max)).toBe(expectedResult)
44
- })
45
-
46
- test("it should clamp a number too big", () => {
47
- const num = 142
48
- const min = 0
49
- const max = 100
50
- const expectedResult = 100
51
-
52
- expect(clamp(num, min, max)).toBe(expectedResult)
53
- })
54
-
55
- test("it should return true if a number is between min and max", () => {
56
- const num = 50
57
- const min = 0
58
- const max = 100
59
- const expectedResult = true
60
-
61
- expect(isBetween(num, min, max)).toBe(expectedResult)
62
- })
63
-
64
- test("it should return true if a number is equal to min", () => {
65
- const num = 0
66
- const min = 0
67
- const max = 100
68
- const expectedResult = true
69
-
70
- expect(isBetween(num, min, max)).toBe(expectedResult)
71
- })
72
-
73
- test("it should return true if a number is equal to max", () => {
74
- const num = 100
75
- const min = 0
76
- const max = 100
77
- const expectedResult = true
78
-
79
- expect(isBetween(num, min, max)).toBe(expectedResult)
80
- })
81
-
82
- test("it should return false if a number is lower than min", () => {
83
- const num = -1
84
- const min = 0
85
- const max = 100
86
- const expectedResult = false
87
-
88
- expect(isBetween(num, min, max)).toBe(expectedResult)
89
- })
90
-
91
- test("it should return false if a number is greater than max", () => {
92
- const num = 101
93
- const min = 0
94
- const max = 100
95
- const expectedResult = false
96
-
97
- expect(isBetween(num, min, max)).toBe(expectedResult)
98
- })
99
-
100
- test("it should check if two numbers are close given some tolerance", () => {
101
- const num1 = 42
102
- const num2 = 42.1
103
- const tolerance = 0.2
104
- const expectedResult = true
105
-
106
- expect(isClose(num1, num2, tolerance)).toBe(expectedResult)
107
- })
108
-
109
- test("it should return zero if dividend equals divisor", () => {
110
- const num = 2
111
- const divisor = 2
112
- const expectedResult = 0
113
-
114
- expect(mod(num, divisor)).toBe(expectedResult)
115
- })
116
-
117
- test("it should return one if number is odd", () => {
118
- const num = 3
119
- const divisor = 2
120
- const expectedResult = 1
121
-
122
- expect(mod(num, divisor)).toBe(expectedResult)
123
- })
124
-
125
- test("it should return one if negative number turns to positive one", () => {
126
- const num = -3
127
- const divisor = 2
128
- const expectedResult = 1
129
-
130
- expect(mod(num, divisor)).toBe(expectedResult)
131
- })
132
-
133
- test("it should convert a float number greater than 1 to a range between -1 and 1", () => {
134
- const num = 5 / 4
135
- const divisor = 1
136
- const expectedResult = 1 / 4
137
-
138
- expect(mod(num, divisor)).toBe(expectedResult)
139
- })
140
-
141
- test("it should convert a float number greater than 2 to a range between -1 and 1", () => {
142
- const num = 13 / 4
143
- const divisor = 1
144
- const expectedResult = 1 / 4
145
-
146
- expect(mod(num, divisor)).toBe(expectedResult)
147
- })
148
-
149
- test("it should convert a negative float number to a range between -1 and 1", () => {
150
- const num = -5 / 4
151
- const divisor = 1
152
- const expectedResult = 3 / 4
153
-
154
- expect(mod(num, divisor)).toBe(expectedResult)
155
- })
156
-
157
- test("it should return the dividend if the divisor is zero", () => {
158
- const num = 42
159
- const divisor = 0
160
-
161
- expect(mod(num, divisor)).toBe(num)
162
- })
163
-
164
- test("it should return one if number is positive", () => {
165
- const num = 42
166
- const expectedResult = 1
167
-
168
- expect(sign(num)).toBe(expectedResult)
169
- })
170
-
171
- test("it should return minus one if number is negative", () => {
172
- const num = -42
173
- const expectedResult = -1
174
-
175
- expect(sign(num)).toBe(expectedResult)
176
- })
177
-
178
- test("it should return the number itself if the sign is zero", () => {
179
- const num = 0
180
- const expectedResult = 0
181
-
182
- expect(sign(num)).toBe(expectedResult)
183
- })
184
-
185
- test("it should snap the number to the given precision", () => {
186
- const num = 42
187
- const precision = 10
188
- const expectedResult = 40
189
-
190
- expect(snap(num, precision)).toBe(expectedResult)
191
- })
192
-
193
- test("it should compute the square root of the number", () => {
194
- const num = 9
195
- const expectedResult = 3
196
-
197
- expect(sqrt(num)).toBe(expectedResult)
198
- })
@@ -1,94 +0,0 @@
1
- import { expect, test } from "vitest"
2
-
3
- import { v } from "../v.js"
4
- import {
5
- intersectsCircle,
6
- intersectsPoint,
7
- intersectsRectangle,
8
- } from "./point.js"
9
-
10
- test("it should prove that two equal points intersect", () => {
11
- const point1 = v(1.5, 1.5, 0)
12
- const point2 = v(1.5, 1.5, 0)
13
-
14
- expect(intersectsPoint(point1, point2)).toBe(true)
15
- })
16
-
17
- test("it should prove that two different points do not intersect", () => {
18
- const point1 = v(1.5, 1.5, 0)
19
- const point2 = v(2, 1, 0)
20
-
21
- expect(intersectsPoint(point1, point2)).toBe(false)
22
- })
23
-
24
- test("it should prove that a point inside of a circle intersects with it", () => {
25
- const point = v(1.5, 1.5, 0)
26
- const circle = {
27
- position: v(1, 1, 0),
28
- radius: 1,
29
- }
30
-
31
- expect(intersectsCircle(point, circle)).toBe(true)
32
- })
33
-
34
- test("it should prove that a point on the border of a circle intersects with it", () => {
35
- const point = v(2, 1, 0)
36
- const circle = {
37
- position: v(1, 1, 0),
38
- radius: 1,
39
- }
40
-
41
- expect(intersectsCircle(point, circle)).toBe(true)
42
- })
43
-
44
- test("it should prove that a point outside of a circle does not intersect with it", () => {
45
- const point = v(2, 2, 0)
46
- const circle = {
47
- position: v(1, 1, 0),
48
- radius: 1,
49
- }
50
-
51
- expect(intersectsCircle(point, circle)).toBe(false)
52
- })
53
-
54
- test("it should prove that a point inside of a rectangle intersects with it", () => {
55
- const point = v(1.5, 1.5, 0)
56
- const rectangle = {
57
- position: v(1, 1, 0),
58
- size: v(2, 2, 0),
59
- }
60
-
61
- expect(intersectsRectangle(point, rectangle)).toBe(true)
62
- })
63
-
64
- test("it should prove that a point on the border of a rectangle intersects with it", () => {
65
- const point = v(2, 1, 0)
66
- const rectangle = {
67
- position: v(1, 1, 0),
68
- size: v(2, 2, 0),
69
- }
70
-
71
- expect(intersectsRectangle(point, rectangle)).toBe(true)
72
- })
73
-
74
- test("it should prove that a point outside of a rectangle does not intersect with it", () => {
75
- const point = v(2.5, 2.5, 0)
76
- const rectangle = {
77
- position: v(1, 1, 0),
78
- size: v(2, 2, 0),
79
- }
80
-
81
- expect(intersectsRectangle(point, rectangle)).toBe(false)
82
- })
83
-
84
- test("it should work even if the point is an object with a position", () => {
85
- const point = {
86
- position: v(1.5, 1.5, 0),
87
- }
88
- const rectangle = {
89
- position: v(1, 1, 0),
90
- size: v(2, 2, 0),
91
- }
92
-
93
- expect(intersectsRectangle(point, rectangle)).toBe(true)
94
- })
@@ -1,25 +0,0 @@
1
- import { expect, test } from "vitest"
2
-
3
- import { quaternion } from "./quaternion.js"
4
- import { cos, pi, sin } from "./trigonometry.js"
5
-
6
- test("it should return the quaternion for no rotation", () => {
7
- const angle = 0
8
- const expectedResult = [1, 0, 0, 0]
9
-
10
- expect(quaternion(angle)).toStrictEqual(expectedResult)
11
- })
12
-
13
- test("it should return the quaternion for a rotation of pi/2", () => {
14
- const angle = pi() / 2
15
- const expectedResult = [cos(pi() / 4), 0, sin(pi() / 4), 0]
16
-
17
- expect(quaternion(angle)).toStrictEqual(expectedResult)
18
- })
19
-
20
- test("it should return the quaternion for a rotation of negative pi/2", () => {
21
- const angle = -pi() / 2
22
- const expectedResult = [cos(-pi() / 4), -0, sin(-pi() / 4), -0]
23
-
24
- expect(quaternion(angle)).toStrictEqual(expectedResult)
25
- })
@@ -1,29 +0,0 @@
1
- import { expect, test } from "vitest"
2
-
3
- import { quaternion } from "./quaternion.js"
4
- import { combine } from "./quaternions.js"
5
- import { cos, pi, sin } from "./trigonometry.js"
6
-
7
- test("it should combine two zero-angle quaternions by giving the same 0-angle quaternion", () => {
8
- const q1 = quaternion(0)
9
- const q2 = quaternion(0)
10
- const expectedResult = [1, 0, 0, 0]
11
-
12
- expect(combine(q1, q2)).toStrictEqual(expectedResult)
13
- })
14
-
15
- test("it should combine a zero-angle quaternion with a nonzero-angle quaternion", () => {
16
- const q1 = quaternion(0)
17
- const q2 = quaternion(pi() / 2)
18
- const expectedResult = [cos(pi() / 4), 0, sin(pi() / 4), 0]
19
-
20
- expect(combine(q1, q2)).toStrictEqual(expectedResult)
21
- })
22
-
23
- test("it should combine two nonzero-angle quaternions", () => {
24
- const q1 = quaternion(pi() / 2)
25
- const q2 = quaternion(pi() / 2)
26
- const expectedResult = [2.220446049250313e-16, 0, 1, 0] // close to [0, 0, 1, 0]
27
-
28
- expect(combine(q1, q2)).toStrictEqual(expectedResult)
29
- })
@@ -1,43 +0,0 @@
1
- import { expect, test } from "vitest"
2
-
3
- import { v } from "../v.js"
4
- import { intersectsRectangle } from "./rectangle.js"
5
-
6
- test("it should prove that a rectangle crossing another one intersects with it", () => {
7
- const rectangle1 = {
8
- position: v(0, 0, 0),
9
- size: v(2, 2, 2),
10
- }
11
- const rectangle2 = {
12
- position: v(1, 1, 1),
13
- size: v(2, 2, 2),
14
- }
15
-
16
- expect(intersectsRectangle(rectangle1, rectangle2)).toBe(true)
17
- })
18
-
19
- test("it should prove that a rectangle right on top of another intersects with it", () => {
20
- const rectangle1 = {
21
- position: v(0, 0, 0),
22
- size: v(2, 2, 2),
23
- }
24
- const rectangle2 = {
25
- position: v(0, 0, 0),
26
- size: v(2, 0, 2),
27
- }
28
-
29
- expect(intersectsRectangle(rectangle1, rectangle2)).toBe(true)
30
- })
31
-
32
- test("it should prove that a rectangle not crossing another one does not intersect with it", () => {
33
- const rectangle1 = {
34
- position: v(0, 0, 0),
35
- size: v(2, 2, 2),
36
- }
37
- const rectangle2 = {
38
- position: v(3, 3, 3),
39
- size: v(2, 2, 2),
40
- }
41
-
42
- expect(intersectsRectangle(rectangle1, rectangle2)).toBe(false)
43
- })
@@ -1,55 +0,0 @@
1
- import { expect, test } from "vitest"
2
-
3
- import { choose, random, randomBinomial } from "./rng.js"
4
-
5
- test("it should choose a random value from the given arguments", () => {
6
- const values = ["a", "b", "c"]
7
- const chosenValue = choose(...values)
8
-
9
- expect(values).toContain(chosenValue)
10
- })
11
-
12
- test("it should create a random number in the range [0, 1)", () => {
13
- const randomNumber = random()
14
-
15
- expect(randomNumber).toBeGreaterThanOrEqual(0)
16
- expect(randomNumber).toBeLessThan(1)
17
- })
18
-
19
- test("it should create a random integer in the range [0, 6]", () => {
20
- const randomNumber = random(6)
21
-
22
- expect(randomNumber).toBeGreaterThanOrEqual(0)
23
- expect(randomNumber).toBeLessThanOrEqual(6)
24
- })
25
-
26
- test("it should create a random integer in the range [1, 6]", () => {
27
- const randomNumber = random(1, 6)
28
-
29
- expect(randomNumber).toBeGreaterThanOrEqual(1)
30
- expect(randomNumber).toBeLessThanOrEqual(6)
31
- })
32
-
33
- test("it should create a random even number in the range [2, 6]", () => {
34
- const randomNumber = random(2, 6, 2)
35
-
36
- expect(randomNumber).toBeGreaterThanOrEqual(1)
37
- expect(randomNumber).toBeLessThanOrEqual(6)
38
- expect(randomNumber % 2).toBe(0)
39
- })
40
-
41
- test("it should create a random float in the range [1.5, 6.5)", () => {
42
- const from = 1.5
43
- const to = 6.5
44
- const randomNumber = random(from, to)
45
-
46
- expect(randomNumber).toBeGreaterThanOrEqual(from)
47
- expect(randomNumber).toBeLessThan(to)
48
- })
49
-
50
- test("it should create a random number in the range (-1, 1)", () => {
51
- const randomNumber = randomBinomial()
52
-
53
- expect(randomNumber).toBeGreaterThan(-1)
54
- expect(randomNumber).toBeLessThan(1)
55
- })
@@ -1,184 +0,0 @@
1
- import { expect, test } from "vitest"
2
-
3
- import { v } from "../v.js"
4
- import { isClose } from "./numbers.js"
5
- import {
6
- closestPoint,
7
- coefficients,
8
- distanceFromPoint,
9
- intersectsCircle,
10
- } from "./segment.js"
11
-
12
- expect.extend({
13
- toStrictEqualVector(received, expected) {
14
- const { isNot } = this
15
- return {
16
- pass: received.every((coord, index) => isClose(coord, expected[index])),
17
- message: () =>
18
- `${received} is ${isNot ? "" : "not"} close to ${expected}`,
19
- }
20
- },
21
- })
22
-
23
- test("it should retrieve values of *a*, *b*, and *c* from a segment, so it looks like a line in the form *ax + by + c = 0*", () => {
24
- const segment = {
25
- from: v(0, 0, 0),
26
- to: v(1, 0, 2),
27
- }
28
- const expectedResult = v(-2, 1, 0)
29
-
30
- expect(coefficients(segment)).toStrictEqual(expectedResult)
31
- })
32
-
33
- test("it should find the closest point in a segment to a point projectable on it", () => {
34
- const segment = {
35
- from: v(0, 0, 0),
36
- to: v(2, 0, 2),
37
- }
38
- const point = v(2, 0, 0)
39
- const expectedResult = v(1, 0, 1)
40
-
41
- expect(closestPoint(segment, point)).toStrictEqualVector(expectedResult)
42
- })
43
-
44
- test("it should find the closest point as the point itself when resting on the segment", () => {
45
- const segment = {
46
- from: v(0, 0, 0),
47
- to: v(2, 0, 2),
48
- }
49
- const point = v(1, 0, 1)
50
- const expectedResult = v(1, 0, 1)
51
-
52
- expect(closestPoint(segment, point)).toStrictEqualVector(expectedResult)
53
- })
54
-
55
- test("it return the start of a segment when the point is close to its start", () => {
56
- const segment = {
57
- from: v(0, 0, 0),
58
- to: v(3, 0, 4),
59
- }
60
- const point = v(-2, 0, 0)
61
- const expectedResult = v(0, 0, 0)
62
-
63
- expect(closestPoint(segment, point)).toStrictEqualVector(expectedResult)
64
- })
65
-
66
- test("it should return the end of a segment when the point is close to its end", () => {
67
- const segment = {
68
- from: v(0, 0, 0),
69
- to: v(3, 0, 4),
70
- }
71
- const point = v(5, 0, 4)
72
- const expectedResult = v(3, 0, 4)
73
-
74
- expect(closestPoint(segment, point)).toStrictEqualVector(expectedResult)
75
- })
76
-
77
- test("it should compute the distance between a segment and a point projectable on it", () => {
78
- const segment = {
79
- from: v(0, 0, 0),
80
- to: v(3, 0, 4),
81
- }
82
- const point = v(5, 0, 0)
83
- const expectedResult = 4
84
-
85
- expect(distanceFromPoint(segment, point)).toBe(expectedResult)
86
- })
87
-
88
- test("it should compute the distance between a segment and a point resting on it", () => {
89
- const segment = {
90
- from: v(0, 0, 0),
91
- to: v(2, 0, 2),
92
- }
93
- const point = v(1, 0, 1)
94
- const expectedResult = 0
95
-
96
- expect(distanceFromPoint(segment, point)).toBeCloseTo(expectedResult)
97
- })
98
-
99
- test("it should compute the distance between a segment and a point close to the start", () => {
100
- const segment = {
101
- from: v(0, 0, 0),
102
- to: v(3, 0, 4),
103
- }
104
- const point = v(-2, 0, 0)
105
- const expectedResult = 2
106
-
107
- expect(distanceFromPoint(segment, point)).toBe(expectedResult)
108
- })
109
-
110
- test("it should compute the distance between a segment and a point close to the end", () => {
111
- const segment = {
112
- from: v(0, 0, 0),
113
- to: v(3, 0, 4),
114
- }
115
- const point = v(5, 0, 4)
116
- const expectedResult = 2
117
-
118
- expect(distanceFromPoint(segment, point)).toBeCloseTo(expectedResult)
119
- })
120
-
121
- test("it should prove that a segment that crosses a circle intersects with it", () => {
122
- const segment = {
123
- from: v(0, 0, 0),
124
- to: v(2, 0, 2),
125
- }
126
- const circle = {
127
- position: v(1, 0, 1),
128
- radius: 1,
129
- }
130
-
131
- expect(intersectsCircle(segment, circle)).toBe(true)
132
- })
133
-
134
- test("it should prove that a segment tangent to a circle intersects with it", () => {
135
- const segment = {
136
- from: v(0, 0, 0),
137
- to: v(0, 0, 2),
138
- }
139
- const circle = {
140
- position: v(1, 0, 1),
141
- radius: 1,
142
- }
143
-
144
- expect(intersectsCircle(segment, circle)).toBe(true)
145
- })
146
-
147
- test("it should prove that a segment inside of a circle intersects with it", () => {
148
- const segment = {
149
- from: v(0.5, 0, 0.5),
150
- to: v(1.5, 0, 1.5),
151
- }
152
- const circle = {
153
- position: v(1, 0, 1),
154
- radius: 1,
155
- }
156
-
157
- expect(intersectsCircle(segment, circle)).toBe(true)
158
- })
159
-
160
- test("it should prove that a segment that does not cross a circle does not intersect with it", () => {
161
- const segment = {
162
- from: v(0, 0, 0),
163
- to: v(-2, 0, 2),
164
- }
165
- const circle = {
166
- position: v(1, 0, 1),
167
- radius: 1,
168
- }
169
-
170
- expect(intersectsCircle(segment, circle)).toBe(false)
171
- })
172
-
173
- test("it should prove that a segment that reaches outside of a circle does not intersect with it", () => {
174
- const segment = {
175
- from: v(0, 0, 0),
176
- to: v(-1, 0, -2),
177
- }
178
- const circle = {
179
- position: v(1, 0, 1),
180
- radius: 1,
181
- }
182
-
183
- expect(intersectsCircle(segment, circle)).toBe(false)
184
- })
@@ -1,47 +0,0 @@
1
- import { expect, test } from "vitest"
2
-
3
- import { mean, median, mode } from "./statistics.js"
4
-
5
- test("it should return the average of the given numbers", () => {
6
- const numbers = [1, 3, 2]
7
- const expectedResult = 2
8
-
9
- expect(mean(...numbers)).toBeCloseTo(expectedResult)
10
- })
11
-
12
- test("it should return the median value from an odd list of numbers", () => {
13
- const numbers = [1, 3, 2]
14
- const expectedResult = 2
15
-
16
- expect(median(...numbers)).toBe(expectedResult)
17
- })
18
-
19
- test("it should return the median value from an even list of numbers", () => {
20
- const numbers = [1, 3, 2, 4]
21
- const expectedResult = 2.5
22
-
23
- expect(median(...numbers)).toBe(expectedResult)
24
- })
25
-
26
- test("it should find the mode of a list of values", () => {
27
- const values = [
28
- "rarely",
29
- "seldom",
30
- "seldom",
31
- "sometimes",
32
- "sometimes",
33
- "sometimes",
34
- "often",
35
- "often",
36
- "often",
37
- "often",
38
- "always",
39
- "always",
40
- "always",
41
- "always",
42
- "always",
43
- ]
44
- const expectedResult = "always"
45
-
46
- expect(mode(...values)).toBe(expectedResult)
47
- })
@@ -1,11 +0,0 @@
1
- import { expect, test } from "vitest"
2
-
3
- import { hypothenuse } from "./triangle.js"
4
-
5
- test("it should compute the hypothenuse of two catheti (aka pythagoras)", () => {
6
- const cat1 = 3
7
- const cat2 = 4
8
- const expectedResult = 5
9
-
10
- expect(hypothenuse(cat1, cat2)).toBe(expectedResult)
11
- })