Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit tests for common/array files #23006

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ src/cast/dev_const.ts

# Jetbrains
/.idea/

# test coverage
test/coverage/
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"postinstall": "husky",
"prepack": "pinst --disable",
"postpack": "pinst --enable",
"test": "vitest run --config test/vitest.config.ts"
"test": "vitest run --config test/vitest.config.ts",
"test:coverage": "vitest run --config test/vitest.config.ts --coverage"
},
"author": "Paulus Schoutsen <[email protected]> (http://paulusschoutsen.nl)",
"license": "Apache-2.0",
Expand Down Expand Up @@ -189,6 +190,7 @@
"@types/webspeechapi": "0.0.29",
"@typescript-eslint/eslint-plugin": "7.18.0",
"@typescript-eslint/parser": "7.18.0",
"@vitest/coverage-v8": "2.1.5",
"@web/dev-server": "0.1.38",
"babel-loader": "9.2.1",
"babel-plugin-template-html-minifier": "4.1.0",
Expand Down
5 changes: 5 additions & 0 deletions src/common/array/combinations.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* Get all possible combinations of an array
* @param arr - The array to get combinations of
* @returns A multidimensional array of all possible combinations
*/
export function getAllCombinations<T>(arr: T[]) {
return arr.reduce<T[][]>(
(combinations, element) =>
Expand Down
4 changes: 4 additions & 0 deletions src/common/array/ensure-array.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
type NonUndefined<T> = T extends undefined ? never : T;

/**
* Ensure that the input is an array or wrap it in an array
* @param value - The value to ensure is an array
*/
export function ensureArray(value: undefined): undefined;
export function ensureArray<T>(value: T | T[]): NonUndefined<T>[];
export function ensureArray<T>(value: T | readonly T[]): NonUndefined<T>[];
Expand Down
6 changes: 5 additions & 1 deletion src/common/array/literal-includes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
// Creates a type predicate function for determining if an array literal includes a given value
/**
* Creates a type predicate function for determining if an array literal includes a given value
* @param array - The array to check
* @returns A type predicate function
*/
export const arrayLiteralIncludes =
<T extends readonly unknown[]>(array: T) =>
(searchElement: unknown, fromIndex?: number): searchElement is T[number] =>
Expand Down
33 changes: 33 additions & 0 deletions test/common/array/combination.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { describe, expect, it } from "vitest";
import { getAllCombinations } from "../../../src/common/array/combinations";

describe("getAllCombinations", () => {
it("should return all combinations of an array", () => {
const result = getAllCombinations([1, 2, 3]);
expect(result).toEqual([
[],
[1],
[2],
[1, 2],
[3],
[1, 3],
[2, 3],
[1, 2, 3],
]);
});

it("should return an empty array for an empty input", () => {
const result = getAllCombinations([]);
expect(result).toEqual([[]]);
});

it("should handle an array with one element", () => {
const result = getAllCombinations([1]);
expect(result).toEqual([[], [1]]);
});

it("should handle an array with duplicate elements", () => {
const result = getAllCombinations([1, 1]);
expect(result).toEqual([[], [1], [1], [1, 1]]);
});
});
28 changes: 28 additions & 0 deletions test/common/array/ensure-array.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { describe, expect, it } from "vitest";
import { ensureArray } from "../../../src/common/array/ensure-array";

describe("ensureArray", () => {
it("should return undefined when input is undefined", () => {
expect(ensureArray(undefined)).toBeUndefined();
});

it("should return the same array when input is an array", () => {
const arr = [1, 2, 3];
expect(ensureArray(arr)).toBe(arr);
});

it("should wrap non-array value in an array", () => {
const value = 5;
expect(ensureArray(value)).toEqual([value]);
});

it("should wrap non-array object in an array", () => {
const value = { key: "value" };
expect(ensureArray(value)).toEqual([value]);
});

it("should return the same readonly array when input is a readonly array", () => {
const arr = [1, 2, 3] as const;
expect(ensureArray(arr)).toBe(arr);
});
});
30 changes: 30 additions & 0 deletions test/common/array/literal-includes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { describe, it, expect } from "vitest";
import { arrayLiteralIncludes } from "../../../src/common/array/literal-includes";

describe("arrayLiteralIncludes", () => {
const array = ["a", "b", "c"] as const;
const includes = arrayLiteralIncludes(array);

it("should return true if the element is in the array", () => {
expect(includes("a")).toBe(true);
expect(includes("b")).toBe(true);
expect(includes("c")).toBe(true);
});

it("should return false if the element is not in the array", () => {
expect(includes("d")).toBe(false);
expect(includes(1)).toBe(false);
});

it("should respect the fromIndex parameter", () => {
expect(includes("a", 1)).toBe(false);
expect(includes("b", 1)).toBe(true);
});

it("should handle empty arrays", () => {
const emptyArray = [] as const;
const includesEmpty = arrayLiteralIncludes(emptyArray);

expect(includesEmpty("a")).toBe(false);
});
});
6 changes: 6 additions & 0 deletions test/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,11 @@ export default defineConfig({
IS_TEST: "true",
},
setupFiles: ["./test/setup.ts"],
coverage: {
include: ["src/data/**/*", "src/common/**/*"],
reporter: ["text", "html"],
provider: "v8",
reportsDirectory: "test/coverage",
},
},
});
127 changes: 119 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ __metadata:
version: 8
cacheKey: 10

"@ampproject/remapping@npm:^2.2.0":
"@ampproject/remapping@npm:^2.2.0, @ampproject/remapping@npm:^2.3.0":
version: 2.3.0
resolution: "@ampproject/remapping@npm:2.3.0"
dependencies:
Expand Down Expand Up @@ -318,7 +318,7 @@ __metadata:
languageName: node
linkType: hard

"@babel/parser@npm:^7.23.5, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.0":
"@babel/parser@npm:^7.23.5, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.0":
version: 7.26.2
resolution: "@babel/parser@npm:7.26.2"
dependencies:
Expand Down Expand Up @@ -1261,7 +1261,7 @@ __metadata:
languageName: node
linkType: hard

"@babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.4.4":
"@babel/types@npm:^7.25.4, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.4.4":
version: 7.26.0
resolution: "@babel/types@npm:7.26.0"
dependencies:
Expand All @@ -1271,6 +1271,13 @@ __metadata:
languageName: node
linkType: hard

"@bcoe/v8-coverage@npm:^0.2.3":
version: 0.2.3
resolution: "@bcoe/v8-coverage@npm:0.2.3"
checksum: 10/1a1f0e356a3bb30b5f1ced6f79c413e6ebacf130421f15fac5fcd8be5ddf98aedb4404d7f5624e3285b700e041f9ef938321f3ca4d359d5b716f96afa120d88d
languageName: node
linkType: hard

"@braintree/sanitize-url@npm:7.1.0":
version: 7.1.0
resolution: "@braintree/sanitize-url@npm:7.1.0"
Expand Down Expand Up @@ -1911,6 +1918,13 @@ __metadata:
languageName: node
linkType: hard

"@istanbuljs/schema@npm:^0.1.2":
version: 0.1.3
resolution: "@istanbuljs/schema@npm:0.1.3"
checksum: 10/a9b1e49acdf5efc2f5b2359f2df7f90c5c725f2656f16099e8b2cd3a000619ecca9fc48cf693ba789cf0fd989f6e0df6a22bc05574be4223ecdbb7997d04384b
languageName: node
linkType: hard

"@jimp/bmp@npm:^0.16.13":
version: 0.16.13
resolution: "@jimp/bmp@npm:0.16.13"
Expand Down Expand Up @@ -2086,7 +2100,7 @@ __metadata:
languageName: node
linkType: hard

"@jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25":
"@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":
version: 0.3.25
resolution: "@jridgewell/trace-mapping@npm:0.3.25"
dependencies:
Expand Down Expand Up @@ -5473,6 +5487,32 @@ __metadata:
languageName: node
linkType: hard

"@vitest/coverage-v8@npm:2.1.5":
version: 2.1.5
resolution: "@vitest/coverage-v8@npm:2.1.5"
dependencies:
"@ampproject/remapping": "npm:^2.3.0"
"@bcoe/v8-coverage": "npm:^0.2.3"
debug: "npm:^4.3.7"
istanbul-lib-coverage: "npm:^3.2.2"
istanbul-lib-report: "npm:^3.0.1"
istanbul-lib-source-maps: "npm:^5.0.6"
istanbul-reports: "npm:^3.1.7"
magic-string: "npm:^0.30.12"
magicast: "npm:^0.3.5"
std-env: "npm:^3.8.0"
test-exclude: "npm:^7.0.1"
tinyrainbow: "npm:^1.2.0"
peerDependencies:
"@vitest/browser": 2.1.5
vitest: 2.1.5
peerDependenciesMeta:
"@vitest/browser":
optional: true
checksum: 10/14c90c9201f480b7a028086f05063a89e55897bce005f8bef322089775473384ece3acf63e2b819f50eb650bac68b3e6b30f7bd07e13e7772f4d12e739116191
languageName: node
linkType: hard

"@vitest/expect@npm:2.1.5":
version: 2.1.5
resolution: "@vitest/expect@npm:2.1.5"
Expand Down Expand Up @@ -9085,7 +9125,7 @@ __metadata:
languageName: node
linkType: hard

"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7":
"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7, glob@npm:^10.4.1":
version: 10.4.5
resolution: "glob@npm:10.4.5"
dependencies:
Expand Down Expand Up @@ -9533,6 +9573,7 @@ __metadata:
"@vibrant/color": "npm:3.2.1-alpha.1"
"@vibrant/core": "npm:3.2.1-alpha.1"
"@vibrant/quantizer-mmcq": "npm:3.2.1-alpha.1"
"@vitest/coverage-v8": "npm:2.1.5"
"@vue/web-component-wrapper": "npm:1.3.0"
"@web/dev-server": "npm:0.1.38"
"@webcomponents/scoped-custom-element-registry": "npm:0.0.9"
Expand Down Expand Up @@ -9677,7 +9718,7 @@ __metadata:
languageName: node
linkType: hard

"html-escaper@npm:^2.0.2":
"html-escaper@npm:^2.0.0, html-escaper@npm:^2.0.2":
version: 2.0.2
resolution: "html-escaper@npm:2.0.2"
checksum: 10/034d74029dcca544a34fb6135e98d427acd73019796ffc17383eaa3ec2fe1c0471dcbbc8f8ed39e46e86d43ccd753a160631615e4048285e313569609b66d5b7
Expand Down Expand Up @@ -10514,6 +10555,45 @@ __metadata:
languageName: node
linkType: hard

"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.2":
version: 3.2.2
resolution: "istanbul-lib-coverage@npm:3.2.2"
checksum: 10/40bbdd1e937dfd8c830fa286d0f665e81b7a78bdabcd4565f6d5667c99828bda3db7fb7ac6b96a3e2e8a2461ddbc5452d9f8bc7d00cb00075fa6a3e99f5b6a81
languageName: node
linkType: hard

"istanbul-lib-report@npm:^3.0.0, istanbul-lib-report@npm:^3.0.1":
version: 3.0.1
resolution: "istanbul-lib-report@npm:3.0.1"
dependencies:
istanbul-lib-coverage: "npm:^3.0.0"
make-dir: "npm:^4.0.0"
supports-color: "npm:^7.1.0"
checksum: 10/86a83421ca1cf2109a9f6d193c06c31ef04a45e72a74579b11060b1e7bb9b6337a4e6f04abfb8857e2d569c271273c65e855ee429376a0d7c91ad91db42accd1
languageName: node
linkType: hard

"istanbul-lib-source-maps@npm:^5.0.6":
version: 5.0.6
resolution: "istanbul-lib-source-maps@npm:5.0.6"
dependencies:
"@jridgewell/trace-mapping": "npm:^0.3.23"
debug: "npm:^4.1.1"
istanbul-lib-coverage: "npm:^3.0.0"
checksum: 10/569dd0a392ee3464b1fe1accbaef5cc26de3479eacb5b91d8c67ebb7b425d39fd02247d85649c3a0e9c29b600809fa60b5af5a281a75a89c01f385b1e24823a2
languageName: node
linkType: hard

"istanbul-reports@npm:^3.1.7":
version: 3.1.7
resolution: "istanbul-reports@npm:3.1.7"
dependencies:
html-escaper: "npm:^2.0.0"
istanbul-lib-report: "npm:^3.0.0"
checksum: 10/f1faaa4684efaf57d64087776018d7426312a59aa6eeb4e0e3a777347d23cd286ad18f427e98f0e3dee666103d7404c9d7abc5f240406a912fa16bd6695437fa
languageName: node
linkType: hard

"jackspeak@npm:^3.1.2":
version: 3.4.3
resolution: "jackspeak@npm:3.4.3"
Expand Down Expand Up @@ -11225,6 +11305,26 @@ __metadata:
languageName: node
linkType: hard

"magicast@npm:^0.3.5":
version: 0.3.5
resolution: "magicast@npm:0.3.5"
dependencies:
"@babel/parser": "npm:^7.25.4"
"@babel/types": "npm:^7.25.4"
source-map-js: "npm:^1.2.0"
checksum: 10/3a2dba6b0bdde957797361d09c7931ebdc1b30231705360eeb40ed458d28e1c3112841c3ed4e1b87ceb28f741e333c7673cd961193aa9fdb4f4946b202e6205a
languageName: node
linkType: hard

"make-dir@npm:^4.0.0":
version: 4.0.0
resolution: "make-dir@npm:4.0.0"
dependencies:
semver: "npm:^7.5.3"
checksum: 10/bf0731a2dd3aab4db6f3de1585cea0b746bb73eb5a02e3d8d72757e376e64e6ada190b1eddcde5b2f24a81b688a9897efd5018737d05e02e2a671dda9cff8a8a
languageName: node
linkType: hard

"make-fetch-happen@npm:^13.0.0":
version: 13.0.1
resolution: "make-fetch-happen@npm:13.0.1"
Expand Down Expand Up @@ -13388,7 +13488,7 @@ __metadata:
languageName: node
linkType: hard

"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":
"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":
version: 7.6.3
resolution: "semver@npm:7.6.3"
bin:
Expand Down Expand Up @@ -13744,7 +13844,7 @@ __metadata:
languageName: node
linkType: hard

"source-map-js@npm:^1.2.1":
"source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1":
version: 1.2.1
resolution: "source-map-js@npm:1.2.1"
checksum: 10/ff9d8c8bf096d534a5b7707e0382ef827b4dd360a577d3f34d2b9f48e12c9d230b5747974ee7c607f0df65113732711bb701fe9ece3c7edbd43cb2294d707df3
Expand Down Expand Up @@ -14335,6 +14435,17 @@ __metadata:
languageName: node
linkType: hard

"test-exclude@npm:^7.0.1":
version: 7.0.1
resolution: "test-exclude@npm:7.0.1"
dependencies:
"@istanbuljs/schema": "npm:^0.1.2"
glob: "npm:^10.4.1"
minimatch: "npm:^9.0.4"
checksum: 10/e6f6f4e1df2e7810e082e8d7dfc53be51a931e6e87925f5e1c2ef92cc1165246ba3bf2dae6b5d86251c16925683dba906bd41e40169ebc77120a2d1b5a0dbbe0
languageName: node
linkType: hard

"text-decoder@npm:^1.1.0":
version: 1.2.0
resolution: "text-decoder@npm:1.2.0"
Expand Down
Loading