Skip to content
Source
Sign inSign up
Open History to see the last commit

usagePriceForm.test.ts

84 lines2.9 KB

1import { describe, expect, it } from "vite-plus/test";
2​
3import { isUsagePriceEdit, parseUsagePriceForm, usagePriceForm } from "./usagePriceForm.ts";
4​
5describe("model price entry", () => {
6 it("keeps free cache tokens distinct from blank cache prices", () => {
7 const parsed = parseUsagePriceForm({
8 ...usagePriceForm(),
9 model: "example-model",
10 inputCostPerMillionTokens: "2",
11 outputCostPerMillionTokens: "8",
12 cacheReadCostPerMillionTokens: "0",
13 cacheWriteCostPerMillionTokens: " ",
14 });
15 expect(parsed?.price).toEqual({
16 inputCostPerMillionTokens: 2,
17 outputCostPerMillionTokens: 8,
18 cacheReadCostPerMillionTokens: 0,
19 });
20 });
21​
22 it("preserves all prices when editing, including small fractional prices", () => {
23 const price = {
24 inputCostPerMillionTokens: 0,
25 outputCostPerMillionTokens: 8,
26 cacheReadCostPerMillionTokens: 0.0000001,
27 cacheWriteCostPerMillionTokens: 3.5,
28 };
29 expect(parseUsagePriceForm(usagePriceForm("example-model", price))).toEqual({
30 model: "example-model",
31 price,
32 });
33 });
34​
35 it.each(["", " ", "-1", "Infinity", "NaN", "1e999", "$2", "0x10", "1,2,3", "1.2,3", "1,2.3"])(
36 "rejects invalid required prices: %j",
37 (inputCostPerMillionTokens) => {
38 expect(
39 parseUsagePriceForm({
40 ...usagePriceForm("example-model", {
41 inputCostPerMillionTokens: 2,
42 outputCostPerMillionTokens: 8,
43 }),
44 inputCostPerMillionTokens,
45 }),
46 ).toBeNull();
47 },
48 );
49​
50 it("reads a comma as the decimal point", () => {
51 const form = usagePriceForm("example-model", {
52 inputCostPerMillionTokens: 2,
53 outputCostPerMillionTokens: 8,
54 });
55 expect(
56 parseUsagePriceForm({
57 ...form,
58 inputCostPerMillionTokens: "2,5",
59 outputCostPerMillionTokens: "0,075",
60 }),
61 ).toEqual({
62 model: "example-model",
63 price: { inputCostPerMillionTokens: 2.5, outputCostPerMillionTokens: 0.075 },
64 });
65 expect(parseUsagePriceForm({ ...form, inputCostPerMillionTokens: "1,2,3" })).toBeNull();
66 expect(isUsagePriceEdit("", "2,5")).toBe(true);
67 expect(isUsagePriceEdit("", ",5")).toBe(true);
68 expect(isUsagePriceEdit("", "1,2,3")).toBe(false);
69 expect(isUsagePriceEdit("1,2", "1,2.3")).toBe(false);
70 for (const value of ["2,5", ",5", "0,075", "1,5e-7"]) {
71 for (let end = 1; end <= value.length; end++) {
72 expect(isUsagePriceEdit(value.slice(0, end - 1), value.slice(0, end))).toBe(true);
73 }
74 }
75 });
76​
77 it("never blocks deleting part of a price, but blocks replacing it with a non-number", () => {
78 expect(isUsagePriceEdit("1e-7", "e-7")).toBe(true);
79 expect(isUsagePriceEdit("1e-7", "1-7")).toBe(true);
80 expect(isUsagePriceEdit("1e-7", "a7")).toBe(false);
81 expect(isUsagePriceEdit("2.5", "x")).toBe(false);
82 expect(isUsagePriceEdit("123456", "1.2.3")).toBe(false);
83 });
84});