Skip to content
Merged
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
13 changes: 13 additions & 0 deletions packages/core/tests/enum.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,17 @@ describe("createEnum", () => {
["B", symB],
]);
});

it("should allow direct property access on the enum values", () => {
const Status = createEnum(/**@type {const}*/ ({ ACTIVE: "active", INACTIVE: "inactive" }));
expect(Status.ACTIVE).toBe("active");
expect(Status.INACTIVE).toBe("inactive");
});

it("should return empty arrays for keys, values, and entries when given an empty object", () => {
const Empty = createEnum({});
expect(Empty.keys()).toEqual([]);
expect(Empty.values()).toEqual([]);
expect(Empty.entries()).toEqual([]);
});
});
27 changes: 27 additions & 0 deletions packages/core/tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,20 @@ describe("debounce", () => {
expect(fn).toHaveBeenCalledTimes(1);
expect(fn).toHaveBeenCalledWith("test");
});

it("should allow multiple independent calls after each previous one resolves", async () => {
const fn = vi.fn();
const debounced = debounce(fn, 50);
debounced.run("first");
await wait(60);
expect(fn).toHaveBeenCalledTimes(1);
expect(fn).toHaveBeenCalledWith("first");

debounced.run("second");
await wait(60);
expect(fn).toHaveBeenCalledTimes(2);
expect(fn).toHaveBeenCalledWith("second");
});
});

describe("wait", () => {
Expand Down Expand Up @@ -235,4 +249,17 @@ describe("getInitials", () => {
expect(getInitials("John", null)).toBe("Jo");
expect(getInitials("John", undefined)).toBe("Jo");
});

it("should use default none fallback when options object provides only separator", () => {

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test name says it "should use default none fallback" when only { separator } is provided, but the expectation is undefined (i.e., no fallback applied). Rename the test to reflect the actual behavior being asserted, or (if the default is intended to be "N/A" per the function docs) adjust the expectation and implementation accordingly.

Suggested change
it("should use default none fallback when options object provides only separator", () => {
it("should not apply none fallback when options object provides only separator", () => {

Copilot uses AI. Check for mistakes.
expect(getInitials("", "", { separator: "-" })).toBeUndefined();
});

it("should apply both separator and none options together", () => {
expect(getInitials("", "", { none: "??", separator: "_" })).toBe("??");
expect(getInitials("John", "Doe", { none: "??", separator: "." })).toBe("J.D");
});

it("should uppercase initials even when separator is provided", () => {
expect(getInitials("alice", "bob", { separator: "-" })).toBe("A-B");
});
});
44 changes: 44 additions & 0 deletions packages/form-data/tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,48 @@ describe("parseFormData", () => {
expect(result.items[1]).toBeUndefined();
expect(result.items[2]).toBe("third");
});

it("should handle three-level deep nesting", () => {
const formData = new FormData();
formData.set("a.b.c", "deep");

const result = parseFormData(formData);
expect(result).toEqual({ a: { b: { c: "deep" } } });
});

it("should convert a single existing value to an array when a second value is appended", () => {
const formData = new FormData();
formData.set("color", "red");
formData.append("color", "blue");

const result = parseFormData(formData);
expect(result).toEqual({ color: ["red", "blue"] });
});

it("should grow an existing array when additional values are appended", () => {
const formData = new FormData();
formData.set("tags", "a");
formData.append("tags", "b");
formData.append("tags", "c");

const result = parseFormData(formData);
expect(result).toEqual({ tags: ["a", "b", "c"] });
});

it("should handle indexed arrays with objects inside nested paths", () => {
const formData = new FormData();
formData.set("order.items[0].sku", "ABC");
formData.set("order.items[0].qty", "2");
formData.set("order.items[1].sku", "XYZ");

const result = parseFormData(formData);
expect(result).toEqual({
order: {
items: [
{ sku: "ABC", qty: "2" },
{ sku: "XYZ" },
],
},
});
});
});
52 changes: 51 additions & 1 deletion packages/query/tests/index.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";

import { createSearchParams, createURL, parseSearchParams } from "../src/index.js";
import { createSearchParams, createURL, getLiteralValue, parseSearchParams } from "../src/index.js";

describe("createSearchParams", () => {
it("should create basic search params", () => {
Expand Down Expand Up @@ -72,6 +72,27 @@ describe("createSearchParams", () => {
"limit=10&search=term&offset=undefined&tagIds%5B%5D=123&tagIds%5B%5D=null&tagIds%5B%5D=321&active=Yes&skip=null",
);
});

it("should treat an empty array value as no params", () => {
const params = createSearchParams({ a: [], b: "test" });
expect(params.toString()).toBe("b=test");
});

it("should treat a two-element array whose first element is not an object as a regular array", () => {
const params = createSearchParams({ key: ["a", "b"] });
expect(params.toString()).toBe("key=a&key=b");
});

it("should treat a two-element array whose second element is not a string as a regular array", () => {
const params = createSearchParams({ key: [{ val: "x" }, 42] });
expect(params.toString()).toBe("key=%5Bobject+Object%5D&key=42");
});

it("should serialize as 'undefined' for an Option tuple key that does not exist in the record", () => {
const options = { eager: "EagerValue" };
const params = createSearchParams({ mode: [options, "missing"] });
expect(params.get("mode")).toBe("undefined");
});
});

describe("createURL", () => {
Expand Down Expand Up @@ -241,4 +262,33 @@ describe("parseSearchParams", () => {
const result = parseSearchParams(searchParams);
expect(result).toEqual({ key: ["value1", "value2"] });
});

it("should skip null/undefined array entries by default", () => {
const searchParams = new URLSearchParams("ids[]=1&ids[]=null&ids[]=2");
const result = parseSearchParams(searchParams);
expect(result).toEqual({ "ids[]": ["1", null, "2"] });
});
Comment on lines +266 to +270

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test description says it "should skip null/undefined array entries by default", but the assertion expects the literal "null" entry to be preserved in the resulting array. This reads as contradictory and will mislead future readers; either update the test name to match the current behavior (arrays include null/undefined literals even when allowFalsy=false) or change the expectation/input to actually verify skipping behavior.

Copilot uses AI. Check for mistakes.

it("should accumulate more than two values for the same non-[] key into an array", () => {
const searchParams = new URLSearchParams("tag=a&tag=b&tag=c");
const result = parseSearchParams(searchParams);
expect(result).toEqual({ tag: ["a", "b", "c"] });
});
});

describe("getLiteralValue", () => {
it("should convert the string 'null' to null", () => {
expect(getLiteralValue("null")).toBeNull();
});

it("should convert the string 'undefined' to undefined", () => {
expect(getLiteralValue("undefined")).toBeUndefined();
});

it("should return any other string unchanged", () => {
expect(getLiteralValue("hello")).toBe("hello");
expect(getLiteralValue("")).toBe("");
expect(getLiteralValue("0")).toBe("0");
expect(getLiteralValue("false")).toBe("false");
});
});
Loading