MiniSearch / client /modules /stringFormatters.test.ts
github-actions[bot]
Sync from https://github.com/felladrin/MiniSearch
9692fe7
import { describe, expect, it } from "vitest";
import {
formatRelativeTime,
getHostname,
getSemanticVersion,
groupSearchResultsByDate,
searchWithFuzzy,
} from "./stringFormatters";
describe("stringFormatters", () => {
describe("getHostname", () => {
it("should extract hostname from valid URL", () => {
expect(getHostname("https://example.com/page")).toBe("example.com");
});
it("should remove www prefix", () => {
expect(getHostname("https://www.example.com/page")).toBe("example.com");
});
it("should handle http URLs", () => {
expect(getHostname("http://test.org/path")).toBe("test.org");
});
it("should return original string for invalid URL", () => {
expect(getHostname("not-a-url")).toBe("not-a-url");
});
it("should handle URL with port (hostname only)", () => {
expect(getHostname("https://localhost:3000")).toBe("localhost");
});
});
describe("getSemanticVersion", () => {
it("should convert number timestamp to YYYY.MM.DD format", () => {
const result = getSemanticVersion(1700000000000);
expect(result).toMatch(/^\d{4}\.\d{1,2}\.\d{1,2}$/);
});
it("should handle Date object", () => {
const result = getSemanticVersion(new Date(2024, 0, 15));
expect(result).toBe("2024.1.15");
});
it("should handle ISO date string", () => {
const result = getSemanticVersion("2024-06-01");
expect(result).toMatch(/^2024\.6\.1$/);
});
});
describe("formatRelativeTime", () => {
it("should return Just now for recent timestamp", () => {
const now = Date.now();
expect(formatRelativeTime(now)).toBe("Just now");
});
it("should return minutes ago", () => {
const fiveMinutesAgo = Date.now() - 5 * 60 * 1000;
expect(formatRelativeTime(fiveMinutesAgo)).toBe("5m ago");
});
it("should return hours ago", () => {
const twoHoursAgo = Date.now() - 2 * 60 * 60 * 1000;
expect(formatRelativeTime(twoHoursAgo)).toBe("2h ago");
});
it("should return days ago", () => {
const threeDaysAgo = Date.now() - 3 * 24 * 60 * 60 * 1000;
expect(formatRelativeTime(threeDaysAgo)).toBe("3d ago");
});
it("should return locale date for older timestamps", () => {
const oldTimestamp = Date.now() - 30 * 24 * 60 * 60 * 1000;
const result = formatRelativeTime(oldTimestamp);
expect(result).not.toContain("ago");
});
});
describe("searchWithFuzzy", () => {
const items = [
{ id: 1, name: "apple" },
{ id: 2, name: "application" },
{ id: 3, name: "banana" },
{ id: 4, name: "blueprint" },
];
it("should return all items with score 0 for empty query", () => {
const results = searchWithFuzzy(items, "", (item) => item.name);
expect(results).toHaveLength(4);
expect(results.every((r) => r.score === 0)).toBe(true);
});
it("should find matches with fuzzy search", () => {
const results = searchWithFuzzy(items, "app", (item) => item.name);
expect(results.length).toBeGreaterThan(0);
expect(results[0].item.name).toContain("app");
});
it("should respect limit parameter", () => {
const results = searchWithFuzzy(items, "a", (item) => item.name, 2);
expect(results).toHaveLength(2);
});
it("should return empty array for no matches", () => {
const results = searchWithFuzzy(items, "xyz", (item) => item.name);
expect(results).toHaveLength(0);
});
it("should return scores between 0 and 1", () => {
const results = searchWithFuzzy(items, "a", (item) => item.name);
results.forEach((r) => {
expect(r.score).toBeGreaterThanOrEqual(0);
expect(r.score).toBeLessThanOrEqual(1);
});
});
});
describe("groupSearchResultsByDate", () => {
it("should group items by Today", () => {
const now = Date.now();
const items = [{ item: { id: 1 }, timestamp: now }];
const groups = groupSearchResultsByDate(items);
expect(groups.Today).toHaveLength(1);
});
it("should group items by Yesterday", () => {
const yesterday = Date.now() - 24 * 60 * 60 * 1000;
const items = [{ item: { id: 1 }, timestamp: yesterday }];
const groups = groupSearchResultsByDate(items);
expect(groups.Yesterday).toHaveLength(1);
});
it("should group items by This Week", () => {
const threeDaysAgo = Date.now() - 3 * 24 * 60 * 60 * 1000;
const items = [{ item: { id: 1 }, timestamp: threeDaysAgo }];
const groups = groupSearchResultsByDate(items);
expect(groups["This Week"]).toHaveLength(1);
});
it("should group older items by month", () => {
const oldTimestamp = Date.now() - 30 * 24 * 60 * 60 * 1000;
const items = [{ item: { id: 1 }, timestamp: oldTimestamp }];
const groups = groupSearchResultsByDate(items);
const keys = Object.keys(groups);
expect(keys.length).toBe(1);
expect(keys[0]).toMatch(/^\w{3} \d{4}$/);
});
it("should handle empty array", () => {
const groups = groupSearchResultsByDate([]);
expect(Object.keys(groups)).toHaveLength(0);
});
it("should group multiple items in same category", () => {
const now = Date.now();
const items = [
{ item: { id: 1 }, timestamp: now },
{ item: { id: 2 }, timestamp: now - 60 * 1000 },
];
const groups = groupSearchResultsByDate(items);
expect(groups.Today).toHaveLength(2);
});
});
});