SPB Git forge

spb/polyllm

Public
15commits 1branches 0releases
2.2 MBsize
maindefault branch
13 days agolast push
TypeScript 97.4% SQL 1% JavaScript 0.9% CSS 0.6%
2.8 KB · 66 lines typescript
Raw Blame History
1import { describe, expect, it } from "vitest";2import { curatePublicModels, formatContext, formatPricePair, type CurationInput } from "@/lib/marketing/public-models";34const NOW = new Date("2026-09-11T12:00:00Z");5const days = (n: number) => new Date(NOW.getTime() - n * 86_400_000);67function row(partial: Partial<CurationInput> & Pick<CurationInput, "key" | "provider">): CurationInput {8  return {9    displayName: partial.key,10    status: "active",11    sortWeight: 0,12    firstSeenAt: days(120),13    contextTokens: 128_000,14    inputPerMillion: 1,15    outputPerMillion: 4,16    ...partial,17  };18}1920describe("curatePublicModels", () => {21  it("drops hidden and deprecated/unknown models", () => {22    const out = curatePublicModels(23      [row({ key: "openai/a", provider: "openai" }), row({ key: "openai/b", provider: "openai", hidden: true }), row({ key: "openai/c", provider: "openai", status: "deprecated" }), row({ key: "openai/d", provider: "openai", status: "unknown" })],24      NOW,25    );26    expect(out.map((m) => m.key)).toEqual(["openai/a"]);27  });2829  it("puts new releases first, then flagships by sortWeight, interleaved per provider", () => {30    const out = curatePublicModels(31      [32        row({ key: "openai/old-flagship", provider: "openai", sortWeight: 100 }),33        row({ key: "openai/new", provider: "openai", sortWeight: 10, firstSeenAt: days(3) }),34        row({ key: "anthropic/flagship", provider: "anthropic", sortWeight: 90 }),35        row({ key: "anthropic/small", provider: "anthropic", sortWeight: 5 }),36        row({ key: "gemini/only", provider: "gemini", sortWeight: 1 }),37      ],38      NOW,39    );40    expect(out.map((m) => m.key)).toEqual(["openai/new", "anthropic/flagship", "gemini/only", "openai/old-flagship", "anthropic/small"]);41  });4243  it("caps the list and never leaks extra fields", () => {44    const rows = Array.from({ length: 60 }, (_, i) => row({ key: `openai/m${i}`, provider: "openai", sortWeight: i }));45    const out = curatePublicModels(rows, NOW, 40);46    expect(out).toHaveLength(40);47    expect(out[0].key).toBe("openai/m59");48    expect(Object.keys(out[0]).sort()).toEqual(["contextTokens", "displayName", "firstSeenAt", "inputPerMillion", "outputPerMillion", "provider", "status"].concat(["key"]).sort());49  });50});5152describe("formatters", () => {53  it("formats context windows", () => {54    expect(formatContext(1_000_000)).toBe("1M");55    expect(formatContext(2_000_000)).toBe("2M");56    expect(formatContext(400_000)).toBe("400K");57    expect(formatContext(null)).toBe("—");58  });59  it("formats price pairs", () => {60    expect(formatPricePair(1.25, 10)).toBe("$1.25 / $10");61    expect(formatPricePair(0.3, 2.5)).toBe("$0.30 / $2.50");62    expect(formatPricePair(0, 0)).toBe("free / free");63    expect(formatPricePair(null, null)).toBeNull();64  });65});66