import { Snowflake, InvalidEncodingError, InvalidIDLengthError, ID_BYTE_SIZE, ALPHABET, } from "../src/snowflake"; import { describe, it, expect } from "vitest"; describe("generate", () => { it("New returns non-zero Snowflake", () => { const s = Snowflake.generate(); expect(s.isZero()).toBe(false); }); it("New returns unique IDs", () => { const seen = new Set(); for (let i = 0; i < 1000; i++) { const s = Snowflake.generate(); const str = s.toString(); expect(seen.has(str)).toBe(false); seen.add(str); } }); }); describe("zero", () => { it("zero is zero", () => { const z = Snowflake.zero(); expect(z.isZero()).toBe(true); }); it("generated is not zero", () => { const s = Snowflake.generate(); expect(s.isZero()).toBe(false); }); }); describe("base62 round-trip", () => { it("single round-trip", () => { const original = Snowflake.generate(); const str = original.toString(); const parsed = Snowflake.fromString(str); expect(parsed).toEqual(original); }); it("many round-trips", () => { for (let i = 0; i < 100; i++) { const original = Snowflake.generate(); const str = original.toString(); const parsed = Snowflake.fromString(str); expect(parsed).toEqual(original); } }); }); describe("base62 errors", () => { it("invalid characters", () => { expect(() => Snowflake.fromString("!!invalid!!")).toThrow(InvalidEncodingError); }); it("empty string produces zero", () => { const s = Snowflake.fromString(""); expect(s.isZero()).toBe(true); }); it("too long string throws", () => { const tooLong = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; expect(() => Snowflake.fromString(tooLong)).toThrow(InvalidEncodingError); }); }); describe("zero stringification", () => { it("zero stringifies to '0'", () => { const z = Snowflake.zero(); expect(z.toString()).toBe("0"); }); it("zero round-trips", () => { const z = Snowflake.zero(); const str = z.toString(); const parsed = Snowflake.fromString(str); expect(parsed.isZero()).toBe(true); }); }); describe("hex encoding", () => { it("hex has correct length and characters", () => { const s = Snowflake.generate(); const hex = s.toHex(); expect(hex.length).toBe(ID_BYTE_SIZE * 2); expect(hex).toMatch(/^[0-9a-f]+$/); }); it("hex round-trip", () => { const original = Snowflake.generate(); const hex = original.toHex(); const parsed = Snowflake.fromHex(hex); expect(parsed).toEqual(original); }); it("invalid hex throws", () => { expect(() => Snowflake.fromHex("xyz")).toThrow(InvalidEncodingError); }); it("wrong length hex throws", () => { expect(() => Snowflake.fromHex("01")).toThrow(InvalidIDLengthError); }); }); describe("JSON serialization", () => { it("toJSON returns base62 string", () => { const s = Snowflake.generate(); const json = JSON.stringify(s); const parsed = JSON.parse(json); expect(parsed).toBe(s.toString()); }); it("fromJSON round-trip", () => { const s = Snowflake.generate(); const json = JSON.stringify(s); const parsed = Snowflake.fromJSON(json); expect(parsed).toEqual(s); }); it("fromJSON rejects missing quotes", () => { expect(() => Snowflake.fromJSON("invalid")).toThrow(InvalidEncodingError); }); it("fromJSON empty string produces zero", () => { const s = Snowflake.fromJSON('""'); expect(s.isZero()).toBe(true); }); it("fromJSON invalid inner content throws", () => { expect(() => Snowflake.fromJSON('"!!!"')).toThrow(InvalidEncodingError); }); }); describe("bytes", () => { it("toBytes returns correct length", () => { const s = Snowflake.generate(); const bytes = s.toBytes(); expect(bytes.length).toBe(ID_BYTE_SIZE); }); it("fromBytes round-trip with Uint8Array", () => { const original = Snowflake.generate(); const bytes = original.toBytes(); const parsed = Snowflake.fromBytes(bytes); expect(parsed).toEqual(original); }); it("fromBytes round-trip with string", () => { const original = Snowflake.generate(); const bytes = original.toBytes(); const str = String.fromCharCode(...bytes); const parsed = Snowflake.fromBytes(str); expect(parsed).toEqual(original); }); it("fromBytes nil-like (empty) throws", () => { expect(() => Snowflake.fromBytes(new Uint8Array(0))).toThrow(InvalidIDLengthError); }); it("fromBytes wrong length throws", () => { expect(() => Snowflake.fromBytes(new Uint8Array([1, 2, 3]))).toThrow(InvalidIDLengthError); }); it("fromBytes zero bytes produces zero", () => { const zeroBytes = new Uint8Array(ID_BYTE_SIZE); const s = Snowflake.fromBytes(zeroBytes); expect(s.isZero()).toBe(true); }); }); describe("JSON embedding", () => { it("embedded in struct round-trips", () => { const s = Snowflake.generate(); const wrapper = { name: "test", id: s, ref: s }; const data = JSON.stringify(wrapper); const decoded = JSON.parse(data); expect(decoded.id).toBe(s.toString()); expect(decoded.ref).toBe(s.toString()); }); }); describe("cross-encoding consistency", () => { it("toString and toHex encode the same bytes", () => { const s = Snowflake.generate(); const fromBase62 = Snowflake.fromString(s.toString()); const fromHex = Snowflake.fromHex(s.toHex()); expect(fromBase62.bytes).toEqual(fromHex.bytes); }); });