Spaces:
Running
Running
File size: 5,529 Bytes
10d1fd4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | 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);
});
});
});
|