Add new tests for array utilities

This commit is contained in:
Sirz Benjie 2025-09-12 08:49:02 -05:00
parent 59afce9276
commit d93bfab831
No known key found for this signature in database
GPG Key ID: 4A524B4D196C759E
3 changed files with 266 additions and 117 deletions

View File

@ -66,15 +66,7 @@ import type { Localizable } from "#types/locales";
import type { Closed, Exact } from "#types/type-helpers";
import { coerceArray } from "#utils/array";
import type { Constructor } from "#utils/common";
import {
BooleanHolder,
coerceArray,
NumberHolder,
randSeedFloat,
randSeedInt,
randSeedItem,
toDmgValue,
} from "#utils/common";
import { BooleanHolder, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common";
import { toCamelCase } from "#utils/strings";
import i18next from "i18next";

View File

@ -16,7 +16,7 @@ import type { AttackMoveResult } from "#types/attack-move-result";
import type { IllusionData } from "#types/illusion-data";
import type { TurnMove } from "#types/turn-move";
import type { CoerceNullPropertiesToUndefined } from "#types/type-helpers";
import { setTypedArray } from "#utils/common";
import { setTypedArray } from "#utils/array";
import { getPokemonSpeciesForm } from "#utils/pokemon-utils";
/**

View File

@ -1,11 +1,13 @@
import { setTypedArray, subArray } from "#utils/array";
import { describe, expect, it } from "vitest";
import type { ReadonlyUint8Array } from "#types/typed-arrays";
import { coerceArray, isTypedArray, setTypedArray, subArray } from "#utils/array";
import { describe, expect, expectTypeOf, it } from "vitest";
/**
* Unit tests for the utility methods in `src/utils/array-utils.ts`
* Unit tests for the utility methods in `src/utils/array.ts`
* @module
*/
describe("Utils - Array", () => {
describe("subArray", () => {
it("returns the same array if length <= n (plain array)", () => {
const arr = [1, 2, 3];
@ -51,6 +53,33 @@ describe("subArray", () => {
// @ts-expect-error
expect(() => subArray({ length: 4 }, 2)).toThrow(TypeError);
});
describe("output type inference", () => {
it("plain array input", () => {
const arr = [1, 2, 3, 4];
const result = subArray(arr, 2);
expectTypeOf(result).toEqualTypeOf<number[]>();
});
it("typed array input", () => {
const arr = new Uint8Array([1, 2, 3, 4]);
const result = subArray(arr, 2);
// @ts-expect-error We get a questionable error about Uint8Array not being assignable to Uint8Array...
expectTypeOf(result).toEqualTypeOf<Uint8Array>();
});
it("readonly array input", () => {
const arr: readonly number[] = [1, 2, 3, 4];
const result = subArray(arr, 2);
expectTypeOf(result).toEqualTypeOf<readonly number[]>();
});
it("readonly typed array input", () => {
const arr = new Uint8Array([1, 2, 3, 4]) as ReadonlyUint8Array;
const result = subArray(arr, 2);
expectTypeOf(result).toEqualTypeOf<ReadonlyUint8Array>();
});
});
});
describe("setTypedArray", () => {
@ -120,3 +149,131 @@ describe("setTypedArray", () => {
}
});
});
describe("coerceArray", () => {
it("returns the same array if input is already an array", () => {
const arr = [1, 2, 3];
const result = coerceArray(arr);
expect(result).toBe(arr);
expect(result).toEqual([1, 2, 3]);
});
it("wraps a non-array input in an array", () => {
const input = 42;
const result = coerceArray(input);
expect(result).toEqual([42]);
});
it("wraps an object in an array", () => {
const obj = { a: 1 };
const result = coerceArray(obj);
expect(result).toEqual([{ a: 1 }]);
});
it("wraps a string in an array", () => {
const str = "hello";
const result = coerceArray(str);
expect(result).toEqual(["hello"]);
});
it("wraps null in an array", () => {
const result = coerceArray(null);
expect(result).toEqual([null]);
});
it("wraps undefined in an array", () => {
const result = coerceArray(undefined);
expect(result).toEqual([undefined]);
});
it("returns the same array for empty array input", () => {
const arr: number[] = [];
const result = coerceArray(arr);
expect(result).toBe(arr);
expect(result).toEqual([]);
});
describe("typing", () => {
it("infers correct type for array input", () => {
const arr = [1, 2, 3];
const result = coerceArray(arr);
expectTypeOf(result).toEqualTypeOf<number[]>();
});
it("infers correct type for non-array input", () => {
const input = "test";
const result = coerceArray(input);
expectTypeOf(result).toEqualTypeOf<[string]>();
});
it("infers correct type for object input", () => {
const obj = { key: "value" };
const result = coerceArray(obj);
expectTypeOf(result).toEqualTypeOf<[{ key: string }]>();
});
it("infers correct type for null input", () => {
const result = coerceArray(null);
expectTypeOf(result).toEqualTypeOf<[null]>();
});
it("infers correct type for undefined input", () => {
const result = coerceArray(undefined);
expectTypeOf(result).toEqualTypeOf<[undefined]>();
});
it("infers correct type for empty array input", () => {
const arr: number[] = [];
const result = coerceArray(arr);
expectTypeOf(result).toEqualTypeOf<number[]>();
});
});
});
describe("isTypedArray", () => {
it.each([
["Int8Array", Int8Array],
["Uint8ClampedArray", Uint8ClampedArray],
["Uint16Array", Uint16Array],
["Uint32Array", Uint32Array],
["Float64Array", Float64Array],
["Float32Array", Float32Array],
])("returns true for %s", (_, ArrayType) => {
if (typeof ArrayType !== "undefined") {
const arr = new ArrayType([1, 2, 3]);
expect(isTypedArray(arr)).toBe(true);
}
});
it.each([
["BigUint64Array", BigUint64Array],
["BigInt64Array", BigInt64Array],
])("returns true for %s", (_, ArrayType) => {
const arr = new ArrayType([1n, 2n, 3n]);
expect(isTypedArray(arr)).toBe(true);
});
it.each([
["strings", "hello"],
["null", null],
["undefined", undefined],
["a number", 123],
["an object", { a: 1 }],
["a plain array", [1, 2, 3]],
["a DataView", new DataView(new ArrayBuffer(8))],
["an ArrayLike", { length: 2, 0: 1, 1: 2 }],
])("returns false for %s", (_, input) => {
expect(isTypedArray(input)).toBe(false);
});
it("returns true for an object that extends a typed array", () => {
class MyUint8Array extends Uint8Array {
customMethod() {
return "custom";
}
}
const arr = new MyUint8Array([1, 2, 3]);
expect(isTypedArray(arr)).toBe(true);
});
});
});