@stackframe/stack-shared 2.7.19 → 2.7.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,3 +6,20 @@
6
6
  export function scrambleDuringCompileTime(t) {
7
7
  return t;
8
8
  }
9
+ import.meta.vitest?.test("scrambleDuringCompileTime", ({ expect }) => {
10
+ // Test with primitive values
11
+ expect(scrambleDuringCompileTime(42)).toBe(42);
12
+ expect(scrambleDuringCompileTime("hello")).toBe("hello");
13
+ expect(scrambleDuringCompileTime(true)).toBe(true);
14
+ expect(scrambleDuringCompileTime(null)).toBe(null);
15
+ expect(scrambleDuringCompileTime(undefined)).toBe(undefined);
16
+ // Test with objects (reference equality)
17
+ const obj = { a: 1 };
18
+ expect(scrambleDuringCompileTime(obj)).toBe(obj);
19
+ // Test with arrays (reference equality)
20
+ const arr = [1, 2, 3];
21
+ expect(scrambleDuringCompileTime(arr)).toBe(arr);
22
+ // Test with functions (reference equality)
23
+ const fn = () => "test";
24
+ expect(scrambleDuringCompileTime(fn)).toBe(fn);
25
+ });
@@ -2,6 +2,16 @@ import { remainder } from "./math";
2
2
  export function isWeekend(date) {
3
3
  return date.getDay() === 0 || date.getDay() === 6;
4
4
  }
5
+ import.meta.vitest?.test("isWeekend", ({ expect }) => {
6
+ // Sunday (day 0)
7
+ expect(isWeekend(new Date(2023, 0, 1))).toBe(true);
8
+ // Saturday (day 6)
9
+ expect(isWeekend(new Date(2023, 0, 7))).toBe(true);
10
+ // Monday (day 1)
11
+ expect(isWeekend(new Date(2023, 0, 2))).toBe(false);
12
+ // Friday (day 5)
13
+ expect(isWeekend(new Date(2023, 0, 6))).toBe(false);
14
+ });
5
15
  const agoUnits = [
6
16
  [60, 'second'],
7
17
  [60, 'minute'],
@@ -12,6 +22,29 @@ const agoUnits = [
12
22
  export function fromNow(date) {
13
23
  return fromNowDetailed(date).result;
14
24
  }
25
+ import.meta.vitest?.test("fromNow", ({ expect }) => {
26
+ // Set a fixed date for testing
27
+ const fixedDate = new Date("2023-01-15T12:00:00.000Z");
28
+ // Use Vitest's fake timers
29
+ import.meta.vitest?.vi.useFakeTimers();
30
+ import.meta.vitest?.vi.setSystemTime(fixedDate);
31
+ // Test past times
32
+ expect(fromNow(new Date("2023-01-15T11:59:50.000Z"))).toBe("just now");
33
+ expect(fromNow(new Date("2023-01-15T11:59:00.000Z"))).toBe("1 minute ago");
34
+ expect(fromNow(new Date("2023-01-15T11:00:00.000Z"))).toBe("1 hour ago");
35
+ expect(fromNow(new Date("2023-01-14T12:00:00.000Z"))).toBe("1 day ago");
36
+ expect(fromNow(new Date("2023-01-08T12:00:00.000Z"))).toBe("1 week ago");
37
+ // Test future times
38
+ expect(fromNow(new Date("2023-01-15T12:00:10.000Z"))).toBe("just now");
39
+ expect(fromNow(new Date("2023-01-15T12:01:00.000Z"))).toBe("in 1 minute");
40
+ expect(fromNow(new Date("2023-01-15T13:00:00.000Z"))).toBe("in 1 hour");
41
+ expect(fromNow(new Date("2023-01-16T12:00:00.000Z"))).toBe("in 1 day");
42
+ expect(fromNow(new Date("2023-01-22T12:00:00.000Z"))).toBe("in 1 week");
43
+ // Test very old dates (should use date format)
44
+ expect(fromNow(new Date("2022-01-15T12:00:00.000Z"))).toMatch(/Jan 15, 2022/);
45
+ // Restore real timers
46
+ import.meta.vitest?.vi.useRealTimers();
47
+ });
15
48
  export function fromNowDetailed(date) {
16
49
  if (!(date instanceof Date)) {
17
50
  throw new Error(`fromNow only accepts Date objects (received: ${date})`);
@@ -58,3 +91,24 @@ export function getInputDatetimeLocalString(date) {
58
91
  date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
59
92
  return date.toISOString().slice(0, 19);
60
93
  }
94
+ import.meta.vitest?.test("getInputDatetimeLocalString", ({ expect }) => {
95
+ // Use Vitest's fake timers to ensure consistent timezone behavior
96
+ import.meta.vitest?.vi.useFakeTimers();
97
+ // Test with a specific date
98
+ const mockDate = new Date("2023-01-15T12:30:45.000Z");
99
+ const result = getInputDatetimeLocalString(mockDate);
100
+ // The result should be in the format YYYY-MM-DDTHH:MM:SS
101
+ expect(result).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/);
102
+ // Test with different dates
103
+ const dates = [
104
+ new Date("2023-01-01T00:00:00.000Z"),
105
+ new Date("2023-06-15T23:59:59.000Z"),
106
+ new Date("2023-12-31T12:34:56.000Z"),
107
+ ];
108
+ for (const date of dates) {
109
+ const result = getInputDatetimeLocalString(date);
110
+ expect(result).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/);
111
+ }
112
+ // Restore real timers
113
+ import.meta.vitest?.vi.useRealTimers();
114
+ });
@@ -1,6 +1,21 @@
1
1
  export function identity(t) {
2
2
  return t;
3
3
  }
4
+ import.meta.vitest?.test("identity", ({ expect }) => {
5
+ expect(identity(1)).toBe(1);
6
+ expect(identity("test")).toBe("test");
7
+ expect(identity(null)).toBe(null);
8
+ expect(identity(undefined)).toBe(undefined);
9
+ const obj = { a: 1 };
10
+ expect(identity(obj)).toBe(obj);
11
+ });
4
12
  export function identityArgs(...args) {
5
13
  return args;
6
14
  }
15
+ import.meta.vitest?.test("identityArgs", ({ expect }) => {
16
+ expect(identityArgs()).toEqual([]);
17
+ expect(identityArgs(1)).toEqual([1]);
18
+ expect(identityArgs(1, 2, 3)).toEqual([1, 2, 3]);
19
+ expect(identityArgs("a", "b", "c")).toEqual(["a", "b", "c"]);
20
+ expect(identityArgs(null, undefined)).toEqual([null, undefined]);
21
+ });
@@ -7,6 +7,34 @@ export function escapeHtml(unsafe) {
7
7
  .replace(/"/g, """)
8
8
  .replace(/'/g, "'");
9
9
  }
10
+ import.meta.vitest?.test("escapeHtml", ({ expect }) => {
11
+ // Test with empty string
12
+ expect(escapeHtml("")).toBe("");
13
+ // Test with string without special characters
14
+ expect(escapeHtml("hello world")).toBe("hello world");
15
+ // Test with special characters
16
+ expect(escapeHtml("<div>")).toBe("&lt;div&gt;");
17
+ expect(escapeHtml("a & b")).toBe("a &amp; b");
18
+ expect(escapeHtml('a "quoted" string')).toBe("a &quot;quoted&quot; string");
19
+ expect(escapeHtml("it's a test")).toBe("it&#039;s a test");
20
+ // Test with multiple special characters
21
+ expect(escapeHtml("<a href=\"test\">It's a link</a>")).toBe("&lt;a href=&quot;test&quot;&gt;It&#039;s a link&lt;/a&gt;");
22
+ });
10
23
  export function html(strings, ...values) {
11
24
  return templateIdentity(strings, ...values.map(v => escapeHtml(`${v}`)));
12
25
  }
26
+ import.meta.vitest?.test("html", ({ expect }) => {
27
+ // Test with no interpolation
28
+ expect(html `simple string`).toBe("simple string");
29
+ // Test with string interpolation
30
+ expect(html `Hello, ${"world"}!`).toBe("Hello, world!");
31
+ // Test with number interpolation
32
+ expect(html `Count: ${42}`).toBe("Count: 42");
33
+ // Test with HTML special characters in interpolated values
34
+ expect(html `<div>${"<script>"}</div>`).toBe("<div>&lt;script&gt;</div>");
35
+ // Test with multiple interpolations
36
+ expect(html `${1} + ${2} = ${"<3"}`).toBe("1 + 2 = &lt;3");
37
+ // Test with object interpolation
38
+ const obj = { toString: () => "<object>" };
39
+ expect(html `Object: ${obj}`).toBe("Object: &lt;object&gt;");
40
+ });
@@ -51,8 +51,37 @@ export function decodeBasicAuthorizationHeader(value) {
51
51
  const split = decoded.split(':');
52
52
  return [split[0], split.slice(1).join(':')];
53
53
  }
54
+ import.meta.vitest?.test("decodeBasicAuthorizationHeader", ({ expect }) => {
55
+ // Test with valid Basic Authorization header
56
+ const username = "user";
57
+ const password = "pass";
58
+ const encoded = encodeBasicAuthorizationHeader(username, password);
59
+ expect(decodeBasicAuthorizationHeader(encoded)).toEqual([username, password]);
60
+ // Test with password containing colons
61
+ const complexPassword = "pass:with:colons";
62
+ const encodedComplex = encodeBasicAuthorizationHeader(username, complexPassword);
63
+ expect(decodeBasicAuthorizationHeader(encodedComplex)).toEqual([username, complexPassword]);
64
+ // Test with invalid headers
65
+ expect(decodeBasicAuthorizationHeader("NotBasic dXNlcjpwYXNz")).toBe(null); // Wrong type
66
+ expect(decodeBasicAuthorizationHeader("Basic")).toBe(null); // Missing encoded part
67
+ expect(decodeBasicAuthorizationHeader("Basic not-base64")).toBe(null); // Not base64
68
+ expect(decodeBasicAuthorizationHeader("Basic dXNlcjpwYXNz extra")).toBe(null); // Extra parts
69
+ });
54
70
  export function encodeBasicAuthorizationHeader(id, password) {
55
71
  if (id.includes(':'))
56
72
  throw new Error("Basic authorization header id cannot contain ':'");
57
73
  return `Basic ${encodeBase64(new TextEncoder().encode(`${id}:${password}`))}`;
58
74
  }
75
+ import.meta.vitest?.test("encodeBasicAuthorizationHeader", ({ expect }) => {
76
+ // Test with simple username and password
77
+ const encoded = encodeBasicAuthorizationHeader("user", "pass");
78
+ expect(encoded).toMatch(/^Basic [A-Za-z0-9+/=]+$/); // Should start with "Basic " followed by base64
79
+ // Test with empty password
80
+ const encodedEmptyPass = encodeBasicAuthorizationHeader("user", "");
81
+ expect(encodedEmptyPass).toMatch(/^Basic [A-Za-z0-9+/=]+$/);
82
+ // Test with password containing special characters
83
+ const encodedSpecialChars = encodeBasicAuthorizationHeader("user", "p@ss!w0rd");
84
+ expect(encodedSpecialChars).toMatch(/^Basic [A-Za-z0-9+/=]+$/);
85
+ // Test with username containing colon should throw
86
+ expect(() => encodeBasicAuthorizationHeader("user:name", "pass")).toThrow();
87
+ });
package/dist/utils/ips.js CHANGED
@@ -2,8 +2,37 @@ import ipRegex from "ip-regex";
2
2
  export function isIpAddress(ip) {
3
3
  return ipRegex({ exact: true }).test(ip);
4
4
  }
5
+ import.meta.vitest?.test("isIpAddress", ({ expect }) => {
6
+ // Test valid IPv4 addresses
7
+ expect(isIpAddress("192.168.1.1")).toBe(true);
8
+ expect(isIpAddress("127.0.0.1")).toBe(true);
9
+ expect(isIpAddress("0.0.0.0")).toBe(true);
10
+ expect(isIpAddress("255.255.255.255")).toBe(true);
11
+ // Test valid IPv6 addresses
12
+ expect(isIpAddress("::1")).toBe(true);
13
+ expect(isIpAddress("2001:db8::")).toBe(true);
14
+ expect(isIpAddress("2001:db8:85a3:8d3:1319:8a2e:370:7348")).toBe(true);
15
+ // Test invalid IP addresses
16
+ expect(isIpAddress("")).toBe(false);
17
+ expect(isIpAddress("not an ip")).toBe(false);
18
+ expect(isIpAddress("256.256.256.256")).toBe(false);
19
+ expect(isIpAddress("192.168.1")).toBe(false);
20
+ expect(isIpAddress("192.168.1.1.1")).toBe(false);
21
+ expect(isIpAddress("2001:db8::xyz")).toBe(false);
22
+ });
5
23
  export function assertIpAddress(ip) {
6
24
  if (!isIpAddress(ip)) {
7
25
  throw new Error(`Invalid IP address: ${ip}`);
8
26
  }
9
27
  }
28
+ import.meta.vitest?.test("assertIpAddress", ({ expect }) => {
29
+ // Test with valid IPv4 address
30
+ expect(() => assertIpAddress("192.168.1.1")).not.toThrow();
31
+ // Test with valid IPv6 address
32
+ expect(() => assertIpAddress("::1")).not.toThrow();
33
+ // Test with invalid IP addresses
34
+ expect(() => assertIpAddress("")).toThrow("Invalid IP address: ");
35
+ expect(() => assertIpAddress("not an ip")).toThrow("Invalid IP address: not an ip");
36
+ expect(() => assertIpAddress("256.256.256.256")).toThrow("Invalid IP address: 256.256.256.256");
37
+ expect(() => assertIpAddress("192.168.1")).toThrow("Invalid IP address: 192.168.1");
38
+ });
@@ -18,9 +18,144 @@ export function isJson(value) {
18
18
  }
19
19
  }
20
20
  }
21
+ import.meta.vitest?.test("isJson", ({ expect }) => {
22
+ // Test primitive values
23
+ expect(isJson(null)).toBe(true);
24
+ expect(isJson(true)).toBe(true);
25
+ expect(isJson(false)).toBe(true);
26
+ expect(isJson(123)).toBe(true);
27
+ expect(isJson("string")).toBe(true);
28
+ // Test arrays
29
+ expect(isJson([])).toBe(true);
30
+ expect(isJson([1, 2, 3])).toBe(true);
31
+ expect(isJson(["a", "b", "c"])).toBe(true);
32
+ expect(isJson([1, "a", true, null])).toBe(true);
33
+ expect(isJson([1, [2, 3], { a: "b" }])).toBe(true);
34
+ // Test objects
35
+ expect(isJson({})).toBe(true);
36
+ expect(isJson({ a: 1, b: 2 })).toBe(true);
37
+ expect(isJson({ a: "string", b: true, c: null })).toBe(true);
38
+ expect(isJson({ a: [1, 2, 3], b: { c: "d" } })).toBe(true);
39
+ // Test invalid JSON values
40
+ expect(isJson(undefined)).toBe(false);
41
+ expect(isJson(() => { })).toBe(false);
42
+ expect(isJson(Symbol())).toBe(false);
43
+ expect(isJson(BigInt(123))).toBe(false);
44
+ // Test arrays with invalid JSON values
45
+ expect(isJson([1, undefined, 3])).toBe(false);
46
+ expect(isJson([1, () => { }, 3])).toBe(false);
47
+ // Test objects with invalid JSON values
48
+ expect(isJson({ a: 1, b: undefined })).toBe(false);
49
+ expect(isJson({ a: 1, b: () => { } })).toBe(false);
50
+ });
21
51
  export function parseJson(json) {
22
52
  return Result.fromThrowing(() => JSON.parse(json));
23
53
  }
54
+ import.meta.vitest?.test("parseJson", ({ expect }) => {
55
+ // Test valid JSON strings
56
+ const nullResult = parseJson("null");
57
+ expect(nullResult.status).toBe("ok");
58
+ if (nullResult.status === "ok") {
59
+ expect(nullResult.data).toBe(null);
60
+ }
61
+ const trueResult = parseJson("true");
62
+ expect(trueResult.status).toBe("ok");
63
+ if (trueResult.status === "ok") {
64
+ expect(trueResult.data).toBe(true);
65
+ }
66
+ const numberResult = parseJson("123");
67
+ expect(numberResult.status).toBe("ok");
68
+ if (numberResult.status === "ok") {
69
+ expect(numberResult.data).toBe(123);
70
+ }
71
+ const stringResult = parseJson('"string"');
72
+ expect(stringResult.status).toBe("ok");
73
+ if (stringResult.status === "ok") {
74
+ expect(stringResult.data).toBe("string");
75
+ }
76
+ const emptyArrayResult = parseJson("[]");
77
+ expect(emptyArrayResult.status).toBe("ok");
78
+ if (emptyArrayResult.status === "ok") {
79
+ expect(emptyArrayResult.data).toEqual([]);
80
+ }
81
+ const arrayResult = parseJson("[1,2,3]");
82
+ expect(arrayResult.status).toBe("ok");
83
+ if (arrayResult.status === "ok") {
84
+ expect(arrayResult.data).toEqual([1, 2, 3]);
85
+ }
86
+ const emptyObjectResult = parseJson("{}");
87
+ expect(emptyObjectResult.status).toBe("ok");
88
+ if (emptyObjectResult.status === "ok") {
89
+ expect(emptyObjectResult.data).toEqual({});
90
+ }
91
+ const objectResult = parseJson('{"a":1,"b":"string"}');
92
+ expect(objectResult.status).toBe("ok");
93
+ if (objectResult.status === "ok") {
94
+ expect(objectResult.data).toEqual({ a: 1, b: "string" });
95
+ }
96
+ // Test invalid JSON strings
97
+ expect(parseJson("").status).toBe("error");
98
+ expect(parseJson("undefined").status).toBe("error");
99
+ expect(parseJson("{").status).toBe("error");
100
+ expect(parseJson('{"a":1,}').status).toBe("error");
101
+ expect(parseJson("function(){}").status).toBe("error");
102
+ });
24
103
  export function stringifyJson(json) {
25
104
  return Result.fromThrowing(() => JSON.stringify(json));
26
105
  }
106
+ import.meta.vitest?.test("stringifyJson", ({ expect }) => {
107
+ // Test primitive values
108
+ const nullResult = stringifyJson(null);
109
+ expect(nullResult.status).toBe("ok");
110
+ if (nullResult.status === "ok") {
111
+ expect(nullResult.data).toBe("null");
112
+ }
113
+ const trueResult = stringifyJson(true);
114
+ expect(trueResult.status).toBe("ok");
115
+ if (trueResult.status === "ok") {
116
+ expect(trueResult.data).toBe("true");
117
+ }
118
+ const numberResult = stringifyJson(123);
119
+ expect(numberResult.status).toBe("ok");
120
+ if (numberResult.status === "ok") {
121
+ expect(numberResult.data).toBe("123");
122
+ }
123
+ const stringResult = stringifyJson("string");
124
+ expect(stringResult.status).toBe("ok");
125
+ if (stringResult.status === "ok") {
126
+ expect(stringResult.data).toBe('"string"');
127
+ }
128
+ // Test arrays
129
+ const emptyArrayResult = stringifyJson([]);
130
+ expect(emptyArrayResult.status).toBe("ok");
131
+ if (emptyArrayResult.status === "ok") {
132
+ expect(emptyArrayResult.data).toBe("[]");
133
+ }
134
+ const arrayResult = stringifyJson([1, 2, 3]);
135
+ expect(arrayResult.status).toBe("ok");
136
+ if (arrayResult.status === "ok") {
137
+ expect(arrayResult.data).toBe("[1,2,3]");
138
+ }
139
+ // Test objects
140
+ const emptyObjectResult = stringifyJson({});
141
+ expect(emptyObjectResult.status).toBe("ok");
142
+ if (emptyObjectResult.status === "ok") {
143
+ expect(emptyObjectResult.data).toBe("{}");
144
+ }
145
+ const objectResult = stringifyJson({ a: 1, b: "string" });
146
+ expect(objectResult.status).toBe("ok");
147
+ if (objectResult.status === "ok") {
148
+ expect(objectResult.data).toBe('{"a":1,"b":"string"}');
149
+ }
150
+ // Test nested structures
151
+ const nested = { a: [1, 2, 3], b: { c: "d" } };
152
+ const nestedResult = stringifyJson(nested);
153
+ expect(nestedResult.status).toBe("ok");
154
+ if (nestedResult.status === "ok") {
155
+ expect(nestedResult.data).toBe('{"a":[1,2,3],"b":{"c":"d"}}');
156
+ }
157
+ // Test circular references (should error)
158
+ const circular = { a: 1 };
159
+ circular.self = circular;
160
+ expect(stringifyJson(circular).status).toBe("error");
161
+ });
@@ -13,6 +13,20 @@ export class WeakRefIfAvailable {
13
13
  return this._ref.deref();
14
14
  }
15
15
  }
16
+ import.meta.vitest?.test("WeakRefIfAvailable", ({ expect }) => {
17
+ // Test with an object
18
+ const obj = { id: 1, name: "test" };
19
+ const weakRef = new WeakRefIfAvailable(obj);
20
+ // Test deref returns the original object
21
+ expect(weakRef.deref()).toBe(obj);
22
+ // Test with a different object
23
+ const obj2 = { id: 2, name: "test2" };
24
+ const weakRef2 = new WeakRefIfAvailable(obj2);
25
+ expect(weakRef2.deref()).toBe(obj2);
26
+ expect(weakRef2.deref()).not.toBe(obj);
27
+ // We can't easily test garbage collection in this environment,
28
+ // but we can verify the basic functionality works
29
+ });
16
30
  /**
17
31
  * A WeakMap-like object that can be iterated over.
18
32
  *
@@ -62,6 +76,56 @@ export class IterableWeakMap {
62
76
  }
63
77
  }
64
78
  _a = Symbol.toStringTag;
79
+ import.meta.vitest?.test("IterableWeakMap", ({ expect }) => {
80
+ // Test basic functionality
81
+ const map = new IterableWeakMap();
82
+ // Create object keys
83
+ const obj1 = { id: 1 };
84
+ const obj2 = { id: 2 };
85
+ // Test set and get
86
+ map.set(obj1, "value1");
87
+ expect(map.get(obj1)).toBe("value1");
88
+ // Test has
89
+ expect(map.has(obj1)).toBe(true);
90
+ expect(map.has(obj2)).toBe(false);
91
+ expect(map.has({ id: 1 })).toBe(false); // Different object with same content
92
+ // Test with multiple keys
93
+ map.set(obj2, "value2");
94
+ expect(map.get(obj2)).toBe("value2");
95
+ expect(map.get(obj1)).toBe("value1"); // Original still exists
96
+ // Test delete
97
+ expect(map.delete(obj1)).toBe(true);
98
+ expect(map.has(obj1)).toBe(false);
99
+ expect(map.get(obj1)).toBeUndefined();
100
+ expect(map.has(obj2)).toBe(true); // Other key still exists
101
+ // Test delete non-existent key
102
+ expect(map.delete({ id: 3 })).toBe(false);
103
+ // Test iteration
104
+ const iterMap = new IterableWeakMap();
105
+ const iterObj1 = { id: 1 };
106
+ const iterObj2 = { id: 2 };
107
+ const iterObj3 = { id: 3 };
108
+ iterMap.set(iterObj1, 1);
109
+ iterMap.set(iterObj2, 2);
110
+ iterMap.set(iterObj3, 3);
111
+ const entries = Array.from(iterMap);
112
+ expect(entries.length).toBe(3);
113
+ // Find entries by their values since we can't directly compare objects in the array
114
+ const values = entries.map(entry => entry[1]);
115
+ expect(values).toContain(1);
116
+ expect(values).toContain(2);
117
+ expect(values).toContain(3);
118
+ // Test constructor with entries
119
+ const initialEntries = [
120
+ [{ id: 4 }, "initial1"],
121
+ [{ id: 5 }, "initial2"]
122
+ ];
123
+ const mapWithEntries = new IterableWeakMap(initialEntries);
124
+ // We can't directly access the initial entries since they're different object references
125
+ // But we can verify the map has the correct number of entries
126
+ const entriesFromConstructor = Array.from(mapWithEntries);
127
+ expect(entriesFromConstructor.length).toBe(2);
128
+ });
65
129
  /**
66
130
  * A map that is a IterableWeakMap for object keys and a regular Map for primitive keys. Also provides iteration over both
67
131
  * object and primitive keys.
@@ -117,6 +181,45 @@ export class MaybeWeakMap {
117
181
  }
118
182
  }
119
183
  _b = Symbol.toStringTag;
184
+ import.meta.vitest?.test("MaybeWeakMap", ({ expect }) => {
185
+ // Test with primitive keys
186
+ const map = new MaybeWeakMap();
187
+ // Test with string keys
188
+ map.set("key1", 1);
189
+ map.set("key2", 2);
190
+ expect(map.get("key1")).toBe(1);
191
+ expect(map.get("key2")).toBe(2);
192
+ expect(map.has("key1")).toBe(true);
193
+ expect(map.has("nonexistent")).toBe(false);
194
+ // Test with object keys
195
+ const obj1 = { id: 1 };
196
+ const obj2 = { id: 2 };
197
+ map.set(obj1, 3);
198
+ map.set(obj2, 4);
199
+ expect(map.get(obj1)).toBe(3);
200
+ expect(map.get(obj2)).toBe(4);
201
+ expect(map.has(obj1)).toBe(true);
202
+ // Test delete with primitive key
203
+ expect(map.delete("key1")).toBe(true);
204
+ expect(map.has("key1")).toBe(false);
205
+ expect(map.delete("nonexistent")).toBe(false);
206
+ // Test delete with object key
207
+ expect(map.delete(obj1)).toBe(true);
208
+ expect(map.has(obj1)).toBe(false);
209
+ // Test iteration
210
+ const entries = Array.from(map);
211
+ expect(entries.length).toBe(2);
212
+ expect(entries).toContainEqual(["key2", 2]);
213
+ expect(entries).toContainEqual([obj2, 4]);
214
+ // Test constructor with entries
215
+ const initialEntries = [
216
+ ["initial1", 10],
217
+ [{ id: 3 }, 20]
218
+ ];
219
+ const mapWithEntries = new MaybeWeakMap(initialEntries);
220
+ expect(mapWithEntries.get("initial1")).toBe(10);
221
+ expect(mapWithEntries.get(initialEntries[1][0])).toBe(20);
222
+ });
120
223
  /**
121
224
  * A map that stores values indexed by an array of keys. If the keys are objects and the environment supports WeakRefs,
122
225
  * they are stored in a WeakMap.
@@ -198,3 +301,45 @@ export class DependenciesMap {
198
301
  }
199
302
  }
200
303
  _c = Symbol.toStringTag;
304
+ import.meta.vitest?.test("DependenciesMap", ({ expect }) => {
305
+ // Test basic functionality
306
+ const map = new DependenciesMap();
307
+ // Test set and get
308
+ map.set(["key", 1], "value1");
309
+ expect(map.get(["key", 1])).toBe("value1");
310
+ // Test has
311
+ expect(map.has(["key", 1])).toBe(true);
312
+ expect(map.has(["key", 2])).toBe(false);
313
+ // Test with different dependencies
314
+ map.set(["key", 2], "value2");
315
+ expect(map.get(["key", 2])).toBe("value2");
316
+ expect(map.get(["key", 1])).toBe("value1"); // Original still exists
317
+ // Test delete
318
+ expect(map.delete(["key", 1])).toBe(true);
319
+ expect(map.has(["key", 1])).toBe(false);
320
+ expect(map.get(["key", 1])).toBeUndefined();
321
+ expect(map.has(["key", 2])).toBe(true); // Other key still exists
322
+ // Test delete non-existent key
323
+ expect(map.delete(["nonexistent", 1])).toBe(false);
324
+ // Test clear
325
+ map.clear();
326
+ expect(map.has(["key", 2])).toBe(false);
327
+ // Test with object keys
328
+ const objMap = new DependenciesMap();
329
+ const obj1 = { id: 1 };
330
+ const obj2 = { id: 2 };
331
+ objMap.set([obj1, 1], "object1");
332
+ objMap.set([obj2, 2], "object2");
333
+ expect(objMap.get([obj1, 1])).toBe("object1");
334
+ expect(objMap.get([obj2, 2])).toBe("object2");
335
+ // Test iteration
336
+ const iterMap = new DependenciesMap();
337
+ iterMap.set(["a"], 1);
338
+ iterMap.set(["b"], 2);
339
+ iterMap.set(["c"], 3);
340
+ const entries = Array.from(iterMap);
341
+ expect(entries.length).toBe(3);
342
+ expect(entries).toContainEqual([["a"], 1]);
343
+ expect(entries).toContainEqual([["b"], 2]);
344
+ expect(entries).toContainEqual([["c"], 3]);
345
+ });
@@ -4,3 +4,15 @@
4
4
  export function remainder(n, d) {
5
5
  return ((n % d) + Math.abs(d)) % d;
6
6
  }
7
+ import.meta.vitest?.test("remainder", ({ expect }) => {
8
+ expect(remainder(10, 3)).toBe(1);
9
+ expect(remainder(10, 5)).toBe(0);
10
+ expect(remainder(10, 7)).toBe(3);
11
+ // Test with negative numbers
12
+ expect(remainder(-10, 3)).toBe(2);
13
+ expect(remainder(-5, 2)).toBe(1);
14
+ expect(remainder(-7, 4)).toBe(1);
15
+ // Test with decimal numbers
16
+ expect(remainder(10.5, 3)).toBeCloseTo(1.5);
17
+ expect(remainder(-10.5, 3)).toBeCloseTo(1.5);
18
+ });
@@ -21,9 +21,52 @@ export function prettyPrintWithMagnitudes(num) {
21
21
  }
22
22
  return toFixedMax(num, 1); // Handle numbers less than 1,000 without suffix.
23
23
  }
24
+ import.meta.vitest?.test("prettyPrintWithMagnitudes", ({ expect }) => {
25
+ // Test different magnitudes
26
+ expect(prettyPrintWithMagnitudes(1000)).toBe("1k");
27
+ expect(prettyPrintWithMagnitudes(1500)).toBe("1.5k");
28
+ expect(prettyPrintWithMagnitudes(1000000)).toBe("1M");
29
+ expect(prettyPrintWithMagnitudes(1500000)).toBe("1.5M");
30
+ expect(prettyPrintWithMagnitudes(1000000000)).toBe("1bn");
31
+ expect(prettyPrintWithMagnitudes(1500000000)).toBe("1.5bn");
32
+ expect(prettyPrintWithMagnitudes(1000000000000)).toBe("1bln");
33
+ expect(prettyPrintWithMagnitudes(1500000000000)).toBe("1.5bln");
34
+ expect(prettyPrintWithMagnitudes(1000000000000000)).toBe("1trln");
35
+ expect(prettyPrintWithMagnitudes(1500000000000000)).toBe("1.5trln");
36
+ // Test small numbers
37
+ expect(prettyPrintWithMagnitudes(100)).toBe("100");
38
+ expect(prettyPrintWithMagnitudes(0)).toBe("0");
39
+ expect(prettyPrintWithMagnitudes(0.5)).toBe("0.5");
40
+ // Test negative numbers
41
+ expect(prettyPrintWithMagnitudes(-1000)).toBe("-1k");
42
+ expect(prettyPrintWithMagnitudes(-1500000)).toBe("-1.5M");
43
+ // Test special cases
44
+ expect(prettyPrintWithMagnitudes(NaN)).toBe("NaN");
45
+ expect(prettyPrintWithMagnitudes(Infinity)).toBe("∞");
46
+ expect(prettyPrintWithMagnitudes(-Infinity)).toBe("-∞");
47
+ });
24
48
  export function toFixedMax(num, maxDecimals) {
25
49
  return num.toFixed(maxDecimals).replace(/\.?0+$/, "");
26
50
  }
51
+ import.meta.vitest?.test("toFixedMax", ({ expect }) => {
52
+ expect(toFixedMax(1, 2)).toBe("1");
53
+ expect(toFixedMax(1.2, 2)).toBe("1.2");
54
+ expect(toFixedMax(1.23, 2)).toBe("1.23");
55
+ expect(toFixedMax(1.234, 2)).toBe("1.23");
56
+ expect(toFixedMax(1.0, 2)).toBe("1");
57
+ expect(toFixedMax(1.20, 2)).toBe("1.2");
58
+ expect(toFixedMax(0, 2)).toBe("0");
59
+ });
27
60
  export function numberCompare(a, b) {
28
61
  return Math.sign(a - b);
29
62
  }
63
+ import.meta.vitest?.test("numberCompare", ({ expect }) => {
64
+ expect(numberCompare(1, 2)).toBe(-1);
65
+ expect(numberCompare(2, 1)).toBe(1);
66
+ expect(numberCompare(1, 1)).toBe(0);
67
+ expect(numberCompare(0, 0)).toBe(0);
68
+ expect(numberCompare(-1, -2)).toBe(1);
69
+ expect(numberCompare(-2, -1)).toBe(-1);
70
+ expect(numberCompare(-1, 1)).toBe(-1);
71
+ expect(numberCompare(1, -1)).toBe(1);
72
+ });