Skip to content

Commit dd7987e

Browse files
authored
Add unit tests for common/array files (#23006)
* add vitest coverage * Add js doc to functions * Add tests for common/array
1 parent 81cc73e commit dd7987e

10 files changed

+236
-10
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,6 @@ src/cast/dev_const.ts
5050

5151
# Jetbrains
5252
/.idea/
53+
54+
# test coverage
55+
test/coverage/

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
"postinstall": "husky",
2020
"prepack": "pinst --disable",
2121
"postpack": "pinst --enable",
22-
"test": "vitest run --config test/vitest.config.ts"
22+
"test": "vitest run --config test/vitest.config.ts",
23+
"test:coverage": "vitest run --config test/vitest.config.ts --coverage"
2324
},
2425
"author": "Paulus Schoutsen <[email protected]> (http://paulusschoutsen.nl)",
2526
"license": "Apache-2.0",
@@ -189,6 +190,7 @@
189190
"@types/webspeechapi": "0.0.29",
190191
"@typescript-eslint/eslint-plugin": "7.18.0",
191192
"@typescript-eslint/parser": "7.18.0",
193+
"@vitest/coverage-v8": "2.1.5",
192194
"@web/dev-server": "0.1.38",
193195
"babel-loader": "9.2.1",
194196
"babel-plugin-template-html-minifier": "4.1.0",

src/common/array/combinations.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* Get all possible combinations of an array
3+
* @param arr - The array to get combinations of
4+
* @returns A multidimensional array of all possible combinations
5+
*/
16
export function getAllCombinations<T>(arr: T[]) {
27
return arr.reduce<T[][]>(
38
(combinations, element) =>

src/common/array/ensure-array.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
type NonUndefined<T> = T extends undefined ? never : T;
22

3+
/**
4+
* Ensure that the input is an array or wrap it in an array
5+
* @param value - The value to ensure is an array
6+
*/
37
export function ensureArray(value: undefined): undefined;
48
export function ensureArray<T>(value: T | T[]): NonUndefined<T>[];
59
export function ensureArray<T>(value: T | readonly T[]): NonUndefined<T>[];

src/common/array/literal-includes.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
// Creates a type predicate function for determining if an array literal includes a given value
1+
/**
2+
* Creates a type predicate function for determining if an array literal includes a given value
3+
* @param array - The array to check
4+
* @returns A type predicate function
5+
*/
26
export const arrayLiteralIncludes =
37
<T extends readonly unknown[]>(array: T) =>
48
(searchElement: unknown, fromIndex?: number): searchElement is T[number] =>

test/common/array/combination.test.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { describe, expect, it } from "vitest";
2+
import { getAllCombinations } from "../../../src/common/array/combinations";
3+
4+
describe("getAllCombinations", () => {
5+
it("should return all combinations of an array", () => {
6+
const result = getAllCombinations([1, 2, 3]);
7+
expect(result).toEqual([
8+
[],
9+
[1],
10+
[2],
11+
[1, 2],
12+
[3],
13+
[1, 3],
14+
[2, 3],
15+
[1, 2, 3],
16+
]);
17+
});
18+
19+
it("should return an empty array for an empty input", () => {
20+
const result = getAllCombinations([]);
21+
expect(result).toEqual([[]]);
22+
});
23+
24+
it("should handle an array with one element", () => {
25+
const result = getAllCombinations([1]);
26+
expect(result).toEqual([[], [1]]);
27+
});
28+
29+
it("should handle an array with duplicate elements", () => {
30+
const result = getAllCombinations([1, 1]);
31+
expect(result).toEqual([[], [1], [1], [1, 1]]);
32+
});
33+
});
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { describe, expect, it } from "vitest";
2+
import { ensureArray } from "../../../src/common/array/ensure-array";
3+
4+
describe("ensureArray", () => {
5+
it("should return undefined when input is undefined", () => {
6+
expect(ensureArray(undefined)).toBeUndefined();
7+
});
8+
9+
it("should return the same array when input is an array", () => {
10+
const arr = [1, 2, 3];
11+
expect(ensureArray(arr)).toBe(arr);
12+
});
13+
14+
it("should wrap non-array value in an array", () => {
15+
const value = 5;
16+
expect(ensureArray(value)).toEqual([value]);
17+
});
18+
19+
it("should wrap non-array object in an array", () => {
20+
const value = { key: "value" };
21+
expect(ensureArray(value)).toEqual([value]);
22+
});
23+
24+
it("should return the same readonly array when input is a readonly array", () => {
25+
const arr = [1, 2, 3] as const;
26+
expect(ensureArray(arr)).toBe(arr);
27+
});
28+
});
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { describe, it, expect } from "vitest";
2+
import { arrayLiteralIncludes } from "../../../src/common/array/literal-includes";
3+
4+
describe("arrayLiteralIncludes", () => {
5+
const array = ["a", "b", "c"] as const;
6+
const includes = arrayLiteralIncludes(array);
7+
8+
it("should return true if the element is in the array", () => {
9+
expect(includes("a")).toBe(true);
10+
expect(includes("b")).toBe(true);
11+
expect(includes("c")).toBe(true);
12+
});
13+
14+
it("should return false if the element is not in the array", () => {
15+
expect(includes("d")).toBe(false);
16+
expect(includes(1)).toBe(false);
17+
});
18+
19+
it("should respect the fromIndex parameter", () => {
20+
expect(includes("a", 1)).toBe(false);
21+
expect(includes("b", 1)).toBe(true);
22+
});
23+
24+
it("should handle empty arrays", () => {
25+
const emptyArray = [] as const;
26+
const includesEmpty = arrayLiteralIncludes(emptyArray);
27+
28+
expect(includesEmpty("a")).toBe(false);
29+
});
30+
});

test/vitest.config.ts

+6
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,11 @@ export default defineConfig({
77
IS_TEST: "true",
88
},
99
setupFiles: ["./test/setup.ts"],
10+
coverage: {
11+
include: ["src/data/**/*", "src/common/**/*"],
12+
reporter: ["text", "html"],
13+
provider: "v8",
14+
reportsDirectory: "test/coverage",
15+
},
1016
},
1117
});

yarn.lock

+119-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ __metadata:
55
version: 8
66
cacheKey: 10
77

8-
"@ampproject/remapping@npm:^2.2.0":
8+
"@ampproject/remapping@npm:^2.2.0, @ampproject/remapping@npm:^2.3.0":
99
version: 2.3.0
1010
resolution: "@ampproject/remapping@npm:2.3.0"
1111
dependencies:
@@ -318,7 +318,7 @@ __metadata:
318318
languageName: node
319319
linkType: hard
320320

321-
"@babel/parser@npm:^7.23.5, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.0":
321+
"@babel/parser@npm:^7.23.5, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.0":
322322
version: 7.26.2
323323
resolution: "@babel/parser@npm:7.26.2"
324324
dependencies:
@@ -1261,7 +1261,7 @@ __metadata:
12611261
languageName: node
12621262
linkType: hard
12631263

1264-
"@babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.4.4":
1264+
"@babel/types@npm:^7.25.4, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.4.4":
12651265
version: 7.26.0
12661266
resolution: "@babel/types@npm:7.26.0"
12671267
dependencies:
@@ -1271,6 +1271,13 @@ __metadata:
12711271
languageName: node
12721272
linkType: hard
12731273

1274+
"@bcoe/v8-coverage@npm:^0.2.3":
1275+
version: 0.2.3
1276+
resolution: "@bcoe/v8-coverage@npm:0.2.3"
1277+
checksum: 10/1a1f0e356a3bb30b5f1ced6f79c413e6ebacf130421f15fac5fcd8be5ddf98aedb4404d7f5624e3285b700e041f9ef938321f3ca4d359d5b716f96afa120d88d
1278+
languageName: node
1279+
linkType: hard
1280+
12741281
"@braintree/sanitize-url@npm:7.1.0":
12751282
version: 7.1.0
12761283
resolution: "@braintree/sanitize-url@npm:7.1.0"
@@ -1911,6 +1918,13 @@ __metadata:
19111918
languageName: node
19121919
linkType: hard
19131920

1921+
"@istanbuljs/schema@npm:^0.1.2":
1922+
version: 0.1.3
1923+
resolution: "@istanbuljs/schema@npm:0.1.3"
1924+
checksum: 10/a9b1e49acdf5efc2f5b2359f2df7f90c5c725f2656f16099e8b2cd3a000619ecca9fc48cf693ba789cf0fd989f6e0df6a22bc05574be4223ecdbb7997d04384b
1925+
languageName: node
1926+
linkType: hard
1927+
19141928
"@jimp/bmp@npm:^0.16.13":
19151929
version: 0.16.13
19161930
resolution: "@jimp/bmp@npm:0.16.13"
@@ -2086,7 +2100,7 @@ __metadata:
20862100
languageName: node
20872101
linkType: hard
20882102

2089-
"@jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25":
2103+
"@jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25":
20902104
version: 0.3.25
20912105
resolution: "@jridgewell/trace-mapping@npm:0.3.25"
20922106
dependencies:
@@ -5473,6 +5487,32 @@ __metadata:
54735487
languageName: node
54745488
linkType: hard
54755489

5490+
"@vitest/coverage-v8@npm:2.1.5":
5491+
version: 2.1.5
5492+
resolution: "@vitest/coverage-v8@npm:2.1.5"
5493+
dependencies:
5494+
"@ampproject/remapping": "npm:^2.3.0"
5495+
"@bcoe/v8-coverage": "npm:^0.2.3"
5496+
debug: "npm:^4.3.7"
5497+
istanbul-lib-coverage: "npm:^3.2.2"
5498+
istanbul-lib-report: "npm:^3.0.1"
5499+
istanbul-lib-source-maps: "npm:^5.0.6"
5500+
istanbul-reports: "npm:^3.1.7"
5501+
magic-string: "npm:^0.30.12"
5502+
magicast: "npm:^0.3.5"
5503+
std-env: "npm:^3.8.0"
5504+
test-exclude: "npm:^7.0.1"
5505+
tinyrainbow: "npm:^1.2.0"
5506+
peerDependencies:
5507+
"@vitest/browser": 2.1.5
5508+
vitest: 2.1.5
5509+
peerDependenciesMeta:
5510+
"@vitest/browser":
5511+
optional: true
5512+
checksum: 10/14c90c9201f480b7a028086f05063a89e55897bce005f8bef322089775473384ece3acf63e2b819f50eb650bac68b3e6b30f7bd07e13e7772f4d12e739116191
5513+
languageName: node
5514+
linkType: hard
5515+
54765516
"@vitest/expect@npm:2.1.5":
54775517
version: 2.1.5
54785518
resolution: "@vitest/expect@npm:2.1.5"
@@ -9085,7 +9125,7 @@ __metadata:
90859125
languageName: node
90869126
linkType: hard
90879127

9088-
"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7":
9128+
"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7, glob@npm:^10.4.1":
90899129
version: 10.4.5
90909130
resolution: "glob@npm:10.4.5"
90919131
dependencies:
@@ -9533,6 +9573,7 @@ __metadata:
95339573
"@vibrant/color": "npm:3.2.1-alpha.1"
95349574
"@vibrant/core": "npm:3.2.1-alpha.1"
95359575
"@vibrant/quantizer-mmcq": "npm:3.2.1-alpha.1"
9576+
"@vitest/coverage-v8": "npm:2.1.5"
95369577
"@vue/web-component-wrapper": "npm:1.3.0"
95379578
"@web/dev-server": "npm:0.1.38"
95389579
"@webcomponents/scoped-custom-element-registry": "npm:0.0.9"
@@ -9677,7 +9718,7 @@ __metadata:
96779718
languageName: node
96789719
linkType: hard
96799720

9680-
"html-escaper@npm:^2.0.2":
9721+
"html-escaper@npm:^2.0.0, html-escaper@npm:^2.0.2":
96819722
version: 2.0.2
96829723
resolution: "html-escaper@npm:2.0.2"
96839724
checksum: 10/034d74029dcca544a34fb6135e98d427acd73019796ffc17383eaa3ec2fe1c0471dcbbc8f8ed39e46e86d43ccd753a160631615e4048285e313569609b66d5b7
@@ -10514,6 +10555,45 @@ __metadata:
1051410555
languageName: node
1051510556
linkType: hard
1051610557

10558+
"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.2":
10559+
version: 3.2.2
10560+
resolution: "istanbul-lib-coverage@npm:3.2.2"
10561+
checksum: 10/40bbdd1e937dfd8c830fa286d0f665e81b7a78bdabcd4565f6d5667c99828bda3db7fb7ac6b96a3e2e8a2461ddbc5452d9f8bc7d00cb00075fa6a3e99f5b6a81
10562+
languageName: node
10563+
linkType: hard
10564+
10565+
"istanbul-lib-report@npm:^3.0.0, istanbul-lib-report@npm:^3.0.1":
10566+
version: 3.0.1
10567+
resolution: "istanbul-lib-report@npm:3.0.1"
10568+
dependencies:
10569+
istanbul-lib-coverage: "npm:^3.0.0"
10570+
make-dir: "npm:^4.0.0"
10571+
supports-color: "npm:^7.1.0"
10572+
checksum: 10/86a83421ca1cf2109a9f6d193c06c31ef04a45e72a74579b11060b1e7bb9b6337a4e6f04abfb8857e2d569c271273c65e855ee429376a0d7c91ad91db42accd1
10573+
languageName: node
10574+
linkType: hard
10575+
10576+
"istanbul-lib-source-maps@npm:^5.0.6":
10577+
version: 5.0.6
10578+
resolution: "istanbul-lib-source-maps@npm:5.0.6"
10579+
dependencies:
10580+
"@jridgewell/trace-mapping": "npm:^0.3.23"
10581+
debug: "npm:^4.1.1"
10582+
istanbul-lib-coverage: "npm:^3.0.0"
10583+
checksum: 10/569dd0a392ee3464b1fe1accbaef5cc26de3479eacb5b91d8c67ebb7b425d39fd02247d85649c3a0e9c29b600809fa60b5af5a281a75a89c01f385b1e24823a2
10584+
languageName: node
10585+
linkType: hard
10586+
10587+
"istanbul-reports@npm:^3.1.7":
10588+
version: 3.1.7
10589+
resolution: "istanbul-reports@npm:3.1.7"
10590+
dependencies:
10591+
html-escaper: "npm:^2.0.0"
10592+
istanbul-lib-report: "npm:^3.0.0"
10593+
checksum: 10/f1faaa4684efaf57d64087776018d7426312a59aa6eeb4e0e3a777347d23cd286ad18f427e98f0e3dee666103d7404c9d7abc5f240406a912fa16bd6695437fa
10594+
languageName: node
10595+
linkType: hard
10596+
1051710597
"jackspeak@npm:^3.1.2":
1051810598
version: 3.4.3
1051910599
resolution: "jackspeak@npm:3.4.3"
@@ -11225,6 +11305,26 @@ __metadata:
1122511305
languageName: node
1122611306
linkType: hard
1122711307

11308+
"magicast@npm:^0.3.5":
11309+
version: 0.3.5
11310+
resolution: "magicast@npm:0.3.5"
11311+
dependencies:
11312+
"@babel/parser": "npm:^7.25.4"
11313+
"@babel/types": "npm:^7.25.4"
11314+
source-map-js: "npm:^1.2.0"
11315+
checksum: 10/3a2dba6b0bdde957797361d09c7931ebdc1b30231705360eeb40ed458d28e1c3112841c3ed4e1b87ceb28f741e333c7673cd961193aa9fdb4f4946b202e6205a
11316+
languageName: node
11317+
linkType: hard
11318+
11319+
"make-dir@npm:^4.0.0":
11320+
version: 4.0.0
11321+
resolution: "make-dir@npm:4.0.0"
11322+
dependencies:
11323+
semver: "npm:^7.5.3"
11324+
checksum: 10/bf0731a2dd3aab4db6f3de1585cea0b746bb73eb5a02e3d8d72757e376e64e6ada190b1eddcde5b2f24a81b688a9897efd5018737d05e02e2a671dda9cff8a8a
11325+
languageName: node
11326+
linkType: hard
11327+
1122811328
"make-fetch-happen@npm:^13.0.0":
1122911329
version: 13.0.1
1123011330
resolution: "make-fetch-happen@npm:13.0.1"
@@ -13388,7 +13488,7 @@ __metadata:
1338813488
languageName: node
1338913489
linkType: hard
1339013490

13391-
"semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.6.3":
13491+
"semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.6.3":
1339213492
version: 7.6.3
1339313493
resolution: "semver@npm:7.6.3"
1339413494
bin:
@@ -13744,7 +13844,7 @@ __metadata:
1374413844
languageName: node
1374513845
linkType: hard
1374613846

13747-
"source-map-js@npm:^1.2.1":
13847+
"source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1":
1374813848
version: 1.2.1
1374913849
resolution: "source-map-js@npm:1.2.1"
1375013850
checksum: 10/ff9d8c8bf096d534a5b7707e0382ef827b4dd360a577d3f34d2b9f48e12c9d230b5747974ee7c607f0df65113732711bb701fe9ece3c7edbd43cb2294d707df3
@@ -14335,6 +14435,17 @@ __metadata:
1433514435
languageName: node
1433614436
linkType: hard
1433714437

14438+
"test-exclude@npm:^7.0.1":
14439+
version: 7.0.1
14440+
resolution: "test-exclude@npm:7.0.1"
14441+
dependencies:
14442+
"@istanbuljs/schema": "npm:^0.1.2"
14443+
glob: "npm:^10.4.1"
14444+
minimatch: "npm:^9.0.4"
14445+
checksum: 10/e6f6f4e1df2e7810e082e8d7dfc53be51a931e6e87925f5e1c2ef92cc1165246ba3bf2dae6b5d86251c16925683dba906bd41e40169ebc77120a2d1b5a0dbbe0
14446+
languageName: node
14447+
linkType: hard
14448+
1433814449
"text-decoder@npm:^1.1.0":
1433914450
version: 1.2.0
1434014451
resolution: "text-decoder@npm:1.2.0"

0 commit comments

Comments
 (0)