mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-18 02:31:56 +10:00
design nosepass template, add tests, add template previews
This commit is contained in:
162
libs/utils/src/namespaces/tests/array.test.ts
Normal file
162
libs/utils/src/namespaces/tests/array.test.ts
Normal file
@ -0,0 +1,162 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { findItemInLayout, moveItemInLayout, removeItemInLayout } from "../array";
|
||||
|
||||
describe("findItemInLayout", () => {
|
||||
it("should find the correct location of an item", () => {
|
||||
const layout = [
|
||||
[["item1"], ["item2"]],
|
||||
[["item3"], ["item4"]],
|
||||
];
|
||||
const item = "item3";
|
||||
const expectedLocation = { page: 1, column: 0, section: 0 };
|
||||
|
||||
const location = findItemInLayout(item, layout);
|
||||
|
||||
expect(location).toEqual(expectedLocation);
|
||||
});
|
||||
|
||||
it("should return null if the item is not found", () => {
|
||||
const layout = [
|
||||
[["item1"], ["item2"]],
|
||||
[["item3"], ["item4"]],
|
||||
];
|
||||
const item = "item5";
|
||||
|
||||
const location = findItemInLayout(item, layout);
|
||||
|
||||
expect(location).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("removeItemInLayout", () => {
|
||||
it("should remove the item and return its location", () => {
|
||||
const layout = [
|
||||
[["item1"], ["item2"]],
|
||||
[["item3"], ["item4"]],
|
||||
];
|
||||
const item = "item3";
|
||||
const expectedLocation = { page: 1, column: 0, section: 0 };
|
||||
|
||||
const location = removeItemInLayout(item, layout);
|
||||
|
||||
expect(location).toEqual(expectedLocation);
|
||||
expect(layout[1][0]).not.toContain(item);
|
||||
});
|
||||
|
||||
it("should return null and not modify layout if the item is not found", () => {
|
||||
const layout = [
|
||||
[["item1"], ["item2"]],
|
||||
[["item3"], ["item4"]],
|
||||
];
|
||||
const item = "item5";
|
||||
|
||||
const location = removeItemInLayout(item, layout);
|
||||
|
||||
expect(location).toBeNull();
|
||||
expect(layout).toEqual([
|
||||
[["item1"], ["item2"]],
|
||||
[["item3"], ["item4"]],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("moveItemInLayout", () => {
|
||||
it("should move an item from the current location to the target location", () => {
|
||||
const layout = [
|
||||
[["item1"], ["item2"]],
|
||||
[["item3"], ["item4"]],
|
||||
];
|
||||
const current = { page: 0, column: 1, section: 0 };
|
||||
const target = { page: 1, column: 0, section: 1 };
|
||||
const expectedLayout = [
|
||||
[["item1"], []],
|
||||
[["item3", "item2"], ["item4"]],
|
||||
];
|
||||
|
||||
const newLayout = moveItemInLayout(current, target, layout);
|
||||
|
||||
expect(newLayout).toEqual(expectedLayout);
|
||||
});
|
||||
|
||||
it("should not mutate the original layout array", () => {
|
||||
const layout = [
|
||||
[["item1"], ["item2"]],
|
||||
[["item3"], ["item4"]],
|
||||
];
|
||||
const layoutCopy = JSON.parse(JSON.stringify(layout));
|
||||
const current = { page: 0, column: 1, section: 0 };
|
||||
const target = { page: 1, column: 0, section: 1 };
|
||||
|
||||
moveItemInLayout(current, target, layout);
|
||||
|
||||
expect(layout).toEqual(layoutCopy);
|
||||
});
|
||||
|
||||
it("should handle the case where the current and target locations are the same", () => {
|
||||
const layout = [
|
||||
[["item1"], ["item2"]],
|
||||
[["item3"], ["item4"]],
|
||||
];
|
||||
const current = { page: 1, column: 0, section: 0 };
|
||||
const target = { page: 1, column: 0, section: 0 };
|
||||
|
||||
const newLayout = moveItemInLayout(current, target, layout);
|
||||
|
||||
expect(newLayout).toEqual(layout);
|
||||
});
|
||||
|
||||
it("moves an item to the specified target location", () => {
|
||||
const layout = [
|
||||
[["A", "B"], ["C"]],
|
||||
[["D"], ["E", "F"]],
|
||||
];
|
||||
const current = { page: 0, column: 0, section: 1 };
|
||||
const target = { page: 1, column: 1, section: 1 };
|
||||
const result = moveItemInLayout(current, target, layout);
|
||||
expect(result).toEqual([
|
||||
[["A"], ["C"]],
|
||||
[["D"], ["E", "B", "F"]],
|
||||
]);
|
||||
});
|
||||
|
||||
it("handles moving an item within the same column", () => {
|
||||
const layout = [[["A", "B"]], [["C", "D"]]];
|
||||
const current = { page: 0, column: 0, section: 0 };
|
||||
const target = { page: 0, column: 0, section: 1 };
|
||||
const result = moveItemInLayout(current, target, layout);
|
||||
expect(result).toEqual([[["B", "A"]], [["C", "D"]]]);
|
||||
});
|
||||
|
||||
it("handles moving an item to the beginning of a column", () => {
|
||||
const layout = [[["A"], ["B", "C"]], [["D"]]];
|
||||
const current = { page: 1, column: 0, section: 0 };
|
||||
const target = { page: 0, column: 1, section: 0 };
|
||||
const result = moveItemInLayout(current, target, layout);
|
||||
expect(result).toEqual([[["A"], ["D", "B", "C"]], [[]]]);
|
||||
});
|
||||
|
||||
it("handles moving an item to an empty column", () => {
|
||||
const layout = [[["A"], []], [["B"]]];
|
||||
const current = { page: 0, column: 0, section: 0 };
|
||||
const target = { page: 0, column: 1, section: 0 };
|
||||
const result = moveItemInLayout(current, target, layout);
|
||||
expect(result).toEqual([[[], ["A"]], [["B"]]]);
|
||||
});
|
||||
|
||||
it("returns the same layout if the current location is invalid", () => {
|
||||
const layout = [[["A"], ["B"]]];
|
||||
const current = { page: 2, column: 0, section: 0 };
|
||||
const target = { page: 0, column: 1, section: 0 };
|
||||
const result = moveItemInLayout(current, target, layout);
|
||||
expect(result).toEqual(layout);
|
||||
});
|
||||
|
||||
it("returns the same layout if the target location is invalid", () => {
|
||||
const layout = [[["A"], ["B"]]];
|
||||
const current = { page: 0, column: 0, section: 0 };
|
||||
const target = { page: 2, column: 0, section: 0 };
|
||||
const result = moveItemInLayout(current, target, layout);
|
||||
expect(result).toEqual(layout);
|
||||
});
|
||||
});
|
||||
107
libs/utils/src/namespaces/tests/date.test.ts
Normal file
107
libs/utils/src/namespaces/tests/date.test.ts
Normal file
@ -0,0 +1,107 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { deepSearchAndParseDates, sortByDate } from "../date";
|
||||
|
||||
type TestType = { date?: Date };
|
||||
|
||||
describe("sortByDate", () => {
|
||||
it("sorts by date in descending order when desc is true", () => {
|
||||
const a: TestType = { date: new Date("2023-01-01") };
|
||||
const b: TestType = { date: new Date("2023-01-02") };
|
||||
expect(sortByDate(a, b, "date")).toBe(1);
|
||||
expect(sortByDate(b, a, "date")).toBe(-1);
|
||||
});
|
||||
|
||||
it("sorts by date in ascending order when desc is false", () => {
|
||||
const a: TestType = { date: new Date("2023-01-01") };
|
||||
const b: TestType = { date: new Date("2023-01-02") };
|
||||
expect(sortByDate(a, b, "date", false)).toBe(-1);
|
||||
expect(sortByDate(b, a, "date", false)).toBe(1);
|
||||
});
|
||||
|
||||
it("returns 0 if one of the dates is missing", () => {
|
||||
const a: TestType = { date: new Date("2023-01-01") };
|
||||
const b: TestType = {};
|
||||
expect(sortByDate(a, b, "date")).toBe(0);
|
||||
});
|
||||
|
||||
it("returns 0 if one of the values is not a date", () => {
|
||||
const a: TestType = { date: new Date("2023-01-01") };
|
||||
const b: TestType = { date: "2023-01-02" as unknown as Date };
|
||||
expect(sortByDate(a, b, "date")).toBe(0);
|
||||
});
|
||||
|
||||
it("handles equal dates", () => {
|
||||
const a: TestType = { date: new Date("2023-01-01") };
|
||||
const b: TestType = { date: new Date("2023-01-01") };
|
||||
expect(sortByDate(a, b, "date")).toBe(0);
|
||||
expect(sortByDate(a, b, "date", false)).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("deepSearchAndParseDates", () => {
|
||||
it("parses dates at various nesting levels", () => {
|
||||
const input = {
|
||||
level1: {
|
||||
date: "2021-08-17T00:00:00Z",
|
||||
nested: {
|
||||
date: "2022-08-17T00:00:00Z",
|
||||
},
|
||||
},
|
||||
otherKey: "value",
|
||||
};
|
||||
const dateKeys = ["date"];
|
||||
const output = deepSearchAndParseDates(input, dateKeys);
|
||||
|
||||
expect(output.level1.date).toBeInstanceOf(Date);
|
||||
expect(output.level1.nested.date).toBeInstanceOf(Date);
|
||||
expect(output.otherKey).toBe("value");
|
||||
});
|
||||
|
||||
it("does not parse invalid date strings", () => {
|
||||
const input = {
|
||||
date: "not a date",
|
||||
};
|
||||
const dateKeys = ["date"];
|
||||
const output = deepSearchAndParseDates(input, dateKeys);
|
||||
|
||||
expect(output.date).toBe("not a date");
|
||||
});
|
||||
|
||||
it("does not modify non-object input", () => {
|
||||
const input = "2021-08-17T00:00:00Z";
|
||||
const dateKeys = ["date"];
|
||||
const output = deepSearchAndParseDates(input, dateKeys);
|
||||
|
||||
expect(output).toBe(input);
|
||||
});
|
||||
|
||||
it("returns null for null input", () => {
|
||||
const input = null;
|
||||
const dateKeys = ["date"];
|
||||
const output = deepSearchAndParseDates(input, dateKeys);
|
||||
|
||||
expect(output).toBeNull();
|
||||
});
|
||||
|
||||
it("handles arrays with date strings", () => {
|
||||
const input = ["2021-08-17T00:00:00Z", "2022-08-17"];
|
||||
const dateKeys = ["0", "1"]; // Assuming the keys are stringified indices
|
||||
const output = deepSearchAndParseDates(input, dateKeys);
|
||||
|
||||
expect(output[0]).toBeInstanceOf(Date);
|
||||
expect(output[1]).toBeInstanceOf(Date);
|
||||
});
|
||||
|
||||
it("ignores keys that are not in the dateKeys", () => {
|
||||
const input = {
|
||||
date: "2021-08-17T00:00:00Z",
|
||||
notADate: "2021-08-17T00:00:00Z",
|
||||
};
|
||||
const dateKeys = ["date"];
|
||||
const output = deepSearchAndParseDates(input, dateKeys);
|
||||
|
||||
expect(output.date).toBeInstanceOf(Date);
|
||||
expect(output.notADate).toBe("2021-08-17T00:00:00Z");
|
||||
});
|
||||
});
|
||||
53
libs/utils/src/namespaces/tests/number.test.ts
Normal file
53
libs/utils/src/namespaces/tests/number.test.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { linearTransform } from "../number";
|
||||
|
||||
describe("linearTransform", () => {
|
||||
it("transforms values from one range to another", () => {
|
||||
const value = 5;
|
||||
const result = linearTransform(value, 0, 10, 0, 100);
|
||||
expect(result).toBe(50);
|
||||
});
|
||||
|
||||
it("handles negative ranges", () => {
|
||||
const value = -5;
|
||||
const result = linearTransform(value, -10, 0, 0, 100);
|
||||
expect(result).toBe(50);
|
||||
});
|
||||
|
||||
it("correctly transforms the minimum input value to the minimum output value", () => {
|
||||
const value = 0;
|
||||
const result = linearTransform(value, 0, 10, 0, 100);
|
||||
expect(result).toBe(0);
|
||||
});
|
||||
|
||||
it("correctly transforms the maximum input value to the maximum output value", () => {
|
||||
const value = 10;
|
||||
const result = linearTransform(value, 0, 10, 0, 100);
|
||||
expect(result).toBe(100);
|
||||
});
|
||||
|
||||
it("transforms values outside the input range", () => {
|
||||
const value = 15;
|
||||
const result = linearTransform(value, 0, 10, 0, 100);
|
||||
expect(result).toBe(150);
|
||||
});
|
||||
|
||||
it("handles inverted output ranges", () => {
|
||||
const value = 5;
|
||||
const result = linearTransform(value, 0, 10, 100, 0);
|
||||
expect(result).toBe(50);
|
||||
});
|
||||
|
||||
it("returns NaN if input maximum equals input minimum", () => {
|
||||
const value = 5;
|
||||
const result = linearTransform(value, 0, 0, 0, 100);
|
||||
expect(result).toBe(NaN);
|
||||
});
|
||||
|
||||
it("returns NaN if input range is zero (avoids division by zero)", () => {
|
||||
const value = 5;
|
||||
const result = linearTransform(value, 10, 10, 0, 100);
|
||||
expect(result).toBeNaN();
|
||||
});
|
||||
});
|
||||
75
libs/utils/src/namespaces/tests/object.test.ts
Normal file
75
libs/utils/src/namespaces/tests/object.test.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { exclude } from "../object";
|
||||
|
||||
describe("exclude", () => {
|
||||
type TestObject = {
|
||||
id: number;
|
||||
name: string;
|
||||
age: number;
|
||||
email: string;
|
||||
};
|
||||
|
||||
it("excludes specified keys from the object", () => {
|
||||
const object: TestObject = {
|
||||
id: 1,
|
||||
name: "Alice",
|
||||
age: 30,
|
||||
email: "alice@example.com",
|
||||
};
|
||||
const result = exclude(object, ["age", "email"]);
|
||||
|
||||
expect(result).toEqual({ id: 1, name: "Alice" });
|
||||
expect(result).not.toHaveProperty("age");
|
||||
expect(result).not.toHaveProperty("email");
|
||||
});
|
||||
|
||||
it("returns the same object if no keys are specified", () => {
|
||||
const object: TestObject = {
|
||||
id: 1,
|
||||
name: "Alice",
|
||||
age: 30,
|
||||
email: "alice@example.com",
|
||||
};
|
||||
const keysToExclude: Array<keyof TestObject> = [];
|
||||
const result = exclude(object, keysToExclude);
|
||||
|
||||
expect(result).toEqual(object);
|
||||
});
|
||||
|
||||
it("does not modify the original object", () => {
|
||||
const object: TestObject = {
|
||||
id: 1,
|
||||
name: "Alice",
|
||||
age: 30,
|
||||
email: "alice@example.com",
|
||||
};
|
||||
exclude(object, ["age", "email"]);
|
||||
|
||||
expect(object).toHaveProperty("age");
|
||||
expect(object).toHaveProperty("email");
|
||||
});
|
||||
|
||||
it("handles cases where keys to exclude are not present in the object", () => {
|
||||
const object: TestObject = {
|
||||
id: 1,
|
||||
name: "Alice",
|
||||
age: 30,
|
||||
email: "alice@example.com",
|
||||
};
|
||||
const keysToExclude = ["nonExistentKey" as keyof TestObject];
|
||||
const result = exclude(object, keysToExclude);
|
||||
|
||||
expect(result).toEqual(object);
|
||||
});
|
||||
|
||||
it("returns the input if it is not an object", () => {
|
||||
const object: unknown = null;
|
||||
const keysToExclude = ["id"];
|
||||
|
||||
// @ts-expect-error passing invalid input type for tests
|
||||
const result = exclude(object, keysToExclude);
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
66
libs/utils/src/namespaces/tests/string.test.ts
Normal file
66
libs/utils/src/namespaces/tests/string.test.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
extractUrl,
|
||||
generateRandomName,
|
||||
getInitials,
|
||||
isEmptyString,
|
||||
isUrl,
|
||||
kebabCase,
|
||||
processUsername,
|
||||
} from "../string";
|
||||
|
||||
describe("getInitials", () => {
|
||||
it("returns the initials of a name", () => {
|
||||
expect(getInitials("John Doe")).toBe("JD");
|
||||
expect(getInitials("Mary Jane Watson")).toBe("MW");
|
||||
});
|
||||
});
|
||||
|
||||
describe("isUrl", () => {
|
||||
it("checks if a string is a URL", () => {
|
||||
expect(isUrl("https://example.com")).toBe(true);
|
||||
expect(isUrl("not a url")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isEmptyString", () => {
|
||||
it("checks if a string is empty or only contains whitespace", () => {
|
||||
expect(isEmptyString("")).toBe(true);
|
||||
expect(isEmptyString(" ")).toBe(true);
|
||||
expect(isEmptyString("<p></p>")).toBe(true);
|
||||
expect(isEmptyString("not empty")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("extractUrl", () => {
|
||||
it("extracts a URL from a string", () => {
|
||||
expect(extractUrl("Visit https://example.com today!")).toBe("https://example.com");
|
||||
expect(extractUrl("No URL here.")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("kebabCase", () => {
|
||||
it("converts a string to kebab-case", () => {
|
||||
expect(kebabCase("fooBar")).toBe("foo-bar");
|
||||
expect(kebabCase("Foo Bar")).toBe("foo-bar");
|
||||
expect(kebabCase("foo_bar")).toBe("foo-bar");
|
||||
expect(kebabCase("")).toBe("");
|
||||
expect(kebabCase(null)).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("generateRandomName", () => {
|
||||
it("generates a random name", () => {
|
||||
const name = generateRandomName();
|
||||
expect(name).toMatch(/^[A-Z][a-z]+ [A-Z][a-z]+ [A-Z][a-z]+$/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("processUsername", () => {
|
||||
it("processes a username by removing non-alphanumeric characters", () => {
|
||||
expect(processUsername("User@Name!")).toBe("username");
|
||||
expect(processUsername("")).toBe("");
|
||||
expect(processUsername(null)).toBe("");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user