Skip to content

Commit d1ca234

Browse files
committed
Add more tests to increase test coverage
1 parent b741abe commit d1ca234

6 files changed

Lines changed: 394 additions & 91 deletions

File tree

src/linear-algebra/common.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ export function approachVec<
136136
B extends T = T,
137137
C extends T = T,
138138
>(a: A, b: B, c: C): A {
139-
return a.map((v, i) => approach(v, b[i], c[i])) as typeof a;
139+
return a.map((v, i) => approach(v, b[i] ?? 0, c[i] ?? 0)) as typeof a;
140140
}
141141

142142
export function addPos<
@@ -152,6 +152,7 @@ export function addScalar<T extends Vector>(p: T, s: number): T {
152152
if (isVec2(p)) return new Vec2(...sums) as typeof p;
153153
if (isVec3(p)) return new Vec3(...sums) as typeof p;
154154
if (isVec4(p)) return new Vec4(...sums) as typeof p;
155+
if (isQuat(p)) return new Quat(...sums) as typeof p;
155156
return sums as typeof p;
156157
}
157158

@@ -196,16 +197,13 @@ export function posDistanceSq<T extends Vector = Vector>(a: T, b: T): number {
196197

197198
/**
198199
* Checks whether a point lies on a line.
199-
* @param point The point to test
200+
* @param p The point to test
200201
* @param a The start of the line
201202
* @param b The end of the line
202203
*/
203-
export function isPointOnLine<T extends Vector>(point: T, a: T, b: T): boolean {
204-
return (
205-
Math.abs(
206-
posDistance(a, point) + posDistance(point, b) - posDistance(a, b),
207-
) < Number.EPSILON
208-
);
204+
export function isPointOnLine<T extends Vector>(p: T, a: T, b: T): boolean {
205+
const pp = posDistance(a, p) + posDistance(p, b) - posDistance(a, b);
206+
return Math.abs(pp) < Number.EPSILON;
209207
}
210208

211209
/**

src/linear-algebra/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export * from './mat4.js';
55
export * from './vec2.js';
66
export * from './vec3.js';
77
export * from './vec4.js';
8+
export * from './quat.js';

tests/common.spec.ts

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
import { describe, expect, test } from 'vitest';
2+
import {
3+
addPos,
4+
addScalar,
5+
approachVec,
6+
hashPos,
7+
isPointOnLine,
8+
isWithinBounds,
9+
length,
10+
lengthSq,
11+
posDistance,
12+
posDistanceSq,
13+
posEqual,
14+
scalePos,
15+
subPos,
16+
V2_T,
17+
Vec2,
18+
Vec3,
19+
Vec4,
20+
Quat,
21+
} from '../src';
22+
23+
describe(`${addPos.name}()`, () => {
24+
test('should add vectors together', () => {
25+
expect(addPos([1, 2], [3, 4])).toEqualVec2([4, 6]);
26+
expect(addPos(new Vec2(1, 2), [3, 4])).toEqualVec2([4, 6]);
27+
expect(addPos(new Vec2(1, 2), new Vec2(3, 4))).toEqualVec2([4, 6]);
28+
expect(addPos([1, 2], new Vec2(3, 4))).toEqualVec2([4, 6]);
29+
30+
expect(addPos([1, 2, 3], [3, 4])).toEqualVec3([4, 6, 3]);
31+
});
32+
});
33+
34+
describe(`${addScalar.name}()`, () => {
35+
test('should add a scalar to each element in a vector', () => {
36+
const resultArr = addScalar([1, 2], 3);
37+
expect(resultArr).not.toBeInstanceOf(Vec2);
38+
expect(resultArr).not.toBeInstanceOf(Vec3);
39+
expect(resultArr).not.toBeInstanceOf(Vec4);
40+
expect(resultArr).not.toBeInstanceOf(Quat);
41+
expect(resultArr).toEqualVec2([4, 5]);
42+
43+
const resultVec2 = addScalar(new Vec2(1, 2), 3);
44+
expect(resultVec2).toBeInstanceOf(Vec2);
45+
expect(resultVec2).toEqualVec2([4, 5]);
46+
47+
const resultVec3 = addScalar(new Vec3(1, 2, 3), 3);
48+
expect(resultVec3).toBeInstanceOf(Vec3);
49+
expect(resultVec3).toEqualVec3([4, 5, 6]);
50+
51+
const resultVec4 = addScalar(new Vec4(1, 2, 3, 4), 3);
52+
expect(resultVec4).toBeInstanceOf(Vec4);
53+
expect(resultVec4).toEqualVec4([4, 5, 6, 7]);
54+
55+
const resultQuat = addScalar(new Quat(1, 2, 3, 4), 3);
56+
expect(resultQuat).toBeInstanceOf(Quat);
57+
expect(resultQuat).toEqualQuat([4, 5, 6, 7]);
58+
});
59+
});
60+
61+
describe(`${approachVec.name}()`, () => {
62+
test('should approach a vector', () => {
63+
expect(approachVec([0, 0], [5, 5], [2, 2])).toEqualVec2([2, 2]);
64+
});
65+
66+
test('should approach a vector of a smaller length', () => {
67+
expect(approachVec([0, 0, 0], [5, 5], [2, 2])).toEqualVec3([2, 2, 0]);
68+
});
69+
70+
test('should approach a vector of a larger length', () => {
71+
expect(approachVec([0, 0], [5, 5, 5], [2, 2])).toEqualVec2([2, 2]);
72+
});
73+
});
74+
75+
describe(`${hashPos.name}()`, () => {
76+
test('should hash a vector', () => {
77+
expect(hashPos([5, -5])).toEqual('5,-5');
78+
expect(hashPos(new Vec2(-5, 5))).toEqual('-5,5');
79+
80+
expect(hashPos([-1, 2, -3])).toEqual('-1,2,-3');
81+
expect(hashPos(new Vec3(-1, 2, -3))).toEqual('-1,2,-3');
82+
83+
expect(hashPos([-1, 2, -3, 4])).toEqual('-1,2,-3,4');
84+
expect(hashPos(new Vec4(-1, 2, -3, 4))).toEqual('-1,2,-3,4');
85+
expect(hashPos(new Quat(-1, 2, -3, 4))).toEqual('-1,2,-3,4');
86+
});
87+
});
88+
89+
describe(`${isPointOnLine.name}()`, () => {
90+
test('should return true when a point is on a line', () => {
91+
expect(isPointOnLine([-1, -1], [-1, -1], [1, 1])).toEqual(true);
92+
expect(isPointOnLine([0, 0], [-1, -1], [1, 1])).toEqual(true);
93+
expect(isPointOnLine([1, 1], [-1, -1], [1, 1])).toEqual(true);
94+
});
95+
96+
test('should return false when a point is not on a line', () => {
97+
expect(isPointOnLine([-2, -2], [-1, -1], [1, 1])).toEqual(false);
98+
expect(isPointOnLine([0, 5], [-1, -1], [1, 1])).toEqual(false);
99+
expect(isPointOnLine([2, 2], [-1, -1], [1, 1])).toEqual(false);
100+
});
101+
});
102+
103+
describe(`${isWithinBounds.name}()`, () => {
104+
const start: V2_T = [-10, -10];
105+
const end: V2_T = [10, 10];
106+
test('should return true when a point is within bounds', () => {
107+
expect(isWithinBounds([0, 0], start, end)).toEqual(true);
108+
109+
// inclusive start
110+
expect(isWithinBounds(start, start, end)).toEqual(true);
111+
});
112+
113+
test('should return true when a point is within bounds', () => {
114+
expect(isWithinBounds([0, 100], start, end)).toEqual(false);
115+
expect(isWithinBounds([100, 100], start, end)).toEqual(false);
116+
expect(isWithinBounds([100, 0], start, end)).toEqual(false);
117+
118+
// exclusive end
119+
expect(isWithinBounds(end, start, end)).toEqual(false);
120+
});
121+
});
122+
123+
describe(`${length.name}()`, () => {
124+
test('should compute the length of a vector', () => {
125+
expect(length([3, 4])).toEqual(5);
126+
expect(length(new Vec2(3, 4))).toEqual(5);
127+
expect(length([3, 4, 12])).toEqual(13);
128+
expect(length(new Vec3(3, 4, 12))).toEqual(13);
129+
expect(length([1, 2, 2, 4])).toEqual(5);
130+
expect(length(new Vec4(1, 2, 2, 4))).toEqual(5);
131+
});
132+
});
133+
134+
describe(`${lengthSq.name}()`, () => {
135+
test('should compute the length of a vector, squared', () => {
136+
expect(lengthSq([3, 4])).toEqual(25);
137+
expect(lengthSq(new Vec2(3, 4))).toEqual(25);
138+
expect(lengthSq([3, 4, 12])).toEqual(169);
139+
expect(lengthSq(new Vec3(3, 4, 12))).toEqual(169);
140+
expect(lengthSq([1, 2, 2, 4])).toEqual(25);
141+
expect(lengthSq(new Vec4(1, 2, 2, 4))).toEqual(25);
142+
expect(lengthSq(new Quat(1, 2, 2, 4))).toEqual(25);
143+
});
144+
});
145+
146+
describe(`${posDistance.name}()`, () => {
147+
test('should find the distance between two vectors', () => {
148+
const a: V2_T = [-1, -1];
149+
const b: V2_T = [2, 3];
150+
expect(posDistance(a, b)).toEqual(5);
151+
});
152+
});
153+
154+
describe(`${posDistanceSq.name}()`, () => {
155+
test('should find the distance between two vectors, squared', () => {
156+
const a: V2_T = [-1, -1];
157+
const b: V2_T = [2, 3];
158+
expect(posDistanceSq(a, b)).toEqual(25);
159+
});
160+
});
161+
162+
describe(`${posEqual.name}()`, () => {
163+
test('should match equal vectors', () => {
164+
const a1 = [5, 5];
165+
const a2 = [5, 5];
166+
const b1 = new Vec2(5, 5);
167+
const b2 = new Vec2(5, 5);
168+
expect(posEqual(a1, a2)).toEqual(true);
169+
expect(posEqual(b1, b2)).toEqual(true);
170+
expect(posEqual(a1, b2)).toEqual(true);
171+
});
172+
173+
test('should not match non-equal vectors', () => {
174+
const a1 = [5, 5];
175+
const a2 = [0, 0];
176+
const b1 = new Vec2(5, 5);
177+
const b2 = new Vec2(0, 0);
178+
expect(posEqual(a1, a2)).toEqual(false);
179+
expect(posEqual(b1, b2)).toEqual(false);
180+
expect(posEqual(a1, b2)).toEqual(false);
181+
});
182+
});
183+
184+
describe(`${scalePos.name}()`, () => {
185+
test('should scale a vector', () => {
186+
const resultArr = scalePos([3, 4], 5);
187+
expect(resultArr).not.toBeInstanceOf(Vec2);
188+
expect(resultArr).not.toBeInstanceOf(Vec3);
189+
expect(resultArr).not.toBeInstanceOf(Vec4);
190+
expect(resultArr).not.toBeInstanceOf(Quat);
191+
expect(resultArr).toEqualVec2([15, 20]);
192+
193+
const resultVec2 = scalePos(new Vec2(3, 4), 5);
194+
expect(resultVec2).toBeInstanceOf(Vec2);
195+
expect(resultVec2).toEqualVec2([15, 20]);
196+
197+
const resultVec3 = scalePos(new Vec3(3, 4, 5), 5);
198+
expect(resultVec3).toBeInstanceOf(Vec3);
199+
expect(resultVec3).toEqualVec3([15, 20, 25]);
200+
201+
const resultVec4 = scalePos(new Vec4(3, 4, 5, 6), 5);
202+
expect(resultVec4).toBeInstanceOf(Vec4);
203+
expect(resultVec4).toEqualVec4([15, 20, 25, 30]);
204+
205+
const resultQuat = scalePos(new Quat(3, 4, 5, 6), 5);
206+
expect(resultQuat).toBeInstanceOf(Quat);
207+
expect(resultQuat).toEqualQuat([15, 20, 25, 30]);
208+
});
209+
});
210+
211+
describe(`${subPos.name}()`, () => {
212+
test('should subtract vectors', () => {
213+
expect(subPos([1, 2], [3, 4])).toEqualVec2([-2, -2]);
214+
expect(subPos(new Vec2(1, 2), [3, 4])).toEqualVec2([-2, -2]);
215+
expect(subPos(new Vec2(1, 2), new Vec2(3, 4))).toEqualVec2([-2, -2]);
216+
expect(subPos([1, 2], new Vec2(3, 4))).toEqualVec2([-2, -2]);
217+
218+
expect(subPos([1, 2, 3], [3, 4])).toEqualVec3([-2, -2, 3]);
219+
});
220+
});

0 commit comments

Comments
 (0)