@b9g/libuild 0.1.21 → 0.1.23

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.
@@ -0,0 +1,337 @@
1
+ /// <reference types="./test-browser.d.ts" />
2
+ import "./_chunks/chunk-IBOCQ33F.js";
3
+
4
+ // src/test-browser.ts
5
+ var ExpectError = class extends Error {
6
+ constructor(message) {
7
+ super(message);
8
+ this.name = "ExpectError";
9
+ }
10
+ };
11
+ function stringify(value) {
12
+ if (value === void 0)
13
+ return "undefined";
14
+ if (value === null)
15
+ return "null";
16
+ if (typeof value === "function")
17
+ return "[Function]";
18
+ if (typeof value === "symbol")
19
+ return value.toString();
20
+ try {
21
+ return JSON.stringify(value);
22
+ } catch {
23
+ return String(value);
24
+ }
25
+ }
26
+ function deepEqual(a, b) {
27
+ if (a === b)
28
+ return true;
29
+ if (typeof a !== typeof b)
30
+ return false;
31
+ if (a === null || b === null)
32
+ return a === b;
33
+ if (typeof a !== "object")
34
+ return a === b;
35
+ if (Array.isArray(a) && Array.isArray(b)) {
36
+ if (a.length !== b.length)
37
+ return false;
38
+ return a.every((item, i) => deepEqual(item, b[i]));
39
+ }
40
+ if (Array.isArray(a) !== Array.isArray(b))
41
+ return false;
42
+ const aKeys = Object.keys(a);
43
+ const bKeys = Object.keys(b);
44
+ if (aKeys.length !== bKeys.length)
45
+ return false;
46
+ return aKeys.every(
47
+ (key) => deepEqual(
48
+ a[key],
49
+ b[key]
50
+ )
51
+ );
52
+ }
53
+ function createMatchers(actual, negated = false) {
54
+ const assert = (pass, message, negatedMessage) => {
55
+ const shouldPass = negated ? !pass : pass;
56
+ if (!shouldPass) {
57
+ throw new ExpectError(negated ? negatedMessage : message);
58
+ }
59
+ };
60
+ const matchers = {
61
+ toBe(expected) {
62
+ assert(
63
+ actual === expected,
64
+ `Expected ${stringify(actual)} to be ${stringify(expected)}`,
65
+ `Expected ${stringify(actual)} not to be ${stringify(expected)}`
66
+ );
67
+ },
68
+ toEqual(expected) {
69
+ assert(
70
+ deepEqual(actual, expected),
71
+ `Expected ${stringify(actual)} to equal ${stringify(expected)}`,
72
+ `Expected ${stringify(actual)} not to equal ${stringify(expected)}`
73
+ );
74
+ },
75
+ toStrictEqual(expected) {
76
+ assert(
77
+ deepEqual(actual, expected),
78
+ `Expected ${stringify(actual)} to strictly equal ${stringify(expected)}`,
79
+ `Expected ${stringify(actual)} not to strictly equal ${stringify(expected)}`
80
+ );
81
+ },
82
+ toBeTruthy() {
83
+ assert(
84
+ Boolean(actual),
85
+ `Expected ${stringify(actual)} to be truthy`,
86
+ `Expected ${stringify(actual)} not to be truthy`
87
+ );
88
+ },
89
+ toBeFalsy() {
90
+ assert(
91
+ !actual,
92
+ `Expected ${stringify(actual)} to be falsy`,
93
+ `Expected ${stringify(actual)} not to be falsy`
94
+ );
95
+ },
96
+ toBeNull() {
97
+ assert(
98
+ actual === null,
99
+ `Expected ${stringify(actual)} to be null`,
100
+ `Expected ${stringify(actual)} not to be null`
101
+ );
102
+ },
103
+ toBeUndefined() {
104
+ assert(
105
+ actual === void 0,
106
+ `Expected ${stringify(actual)} to be undefined`,
107
+ `Expected ${stringify(actual)} not to be undefined`
108
+ );
109
+ },
110
+ toBeDefined() {
111
+ assert(
112
+ actual !== void 0,
113
+ `Expected ${stringify(actual)} to be defined`,
114
+ `Expected ${stringify(actual)} not to be defined`
115
+ );
116
+ },
117
+ toBeNaN() {
118
+ assert(
119
+ Number.isNaN(actual),
120
+ `Expected ${stringify(actual)} to be NaN`,
121
+ `Expected ${stringify(actual)} not to be NaN`
122
+ );
123
+ },
124
+ toBeGreaterThan(expected) {
125
+ assert(
126
+ actual > expected,
127
+ `Expected ${stringify(actual)} to be greater than ${expected}`,
128
+ `Expected ${stringify(actual)} not to be greater than ${expected}`
129
+ );
130
+ },
131
+ toBeGreaterThanOrEqual(expected) {
132
+ assert(
133
+ actual >= expected,
134
+ `Expected ${stringify(actual)} to be greater than or equal to ${expected}`,
135
+ `Expected ${stringify(actual)} not to be greater than or equal to ${expected}`
136
+ );
137
+ },
138
+ toBeLessThan(expected) {
139
+ assert(
140
+ actual < expected,
141
+ `Expected ${stringify(actual)} to be less than ${expected}`,
142
+ `Expected ${stringify(actual)} not to be less than ${expected}`
143
+ );
144
+ },
145
+ toBeLessThanOrEqual(expected) {
146
+ assert(
147
+ actual <= expected,
148
+ `Expected ${stringify(actual)} to be less than or equal to ${expected}`,
149
+ `Expected ${stringify(actual)} not to be less than or equal to ${expected}`
150
+ );
151
+ },
152
+ toContain(expected) {
153
+ const contains = Array.isArray(actual) ? actual.includes(expected) : typeof actual === "string" && typeof expected === "string" ? actual.includes(expected) : false;
154
+ assert(
155
+ contains,
156
+ `Expected ${stringify(actual)} to contain ${stringify(expected)}`,
157
+ `Expected ${stringify(actual)} not to contain ${stringify(expected)}`
158
+ );
159
+ },
160
+ toHaveLength(expected) {
161
+ const len = actual.length;
162
+ assert(
163
+ len === expected,
164
+ `Expected length ${len} to be ${expected}`,
165
+ `Expected length ${len} not to be ${expected}`
166
+ );
167
+ },
168
+ toMatch(expected) {
169
+ const regex = typeof expected === "string" ? new RegExp(expected) : expected;
170
+ assert(
171
+ regex.test(actual),
172
+ `Expected ${stringify(actual)} to match ${expected}`,
173
+ `Expected ${stringify(actual)} not to match ${expected}`
174
+ );
175
+ },
176
+ toThrow(expected) {
177
+ let threw = false;
178
+ let error;
179
+ try {
180
+ actual();
181
+ } catch (e) {
182
+ threw = true;
183
+ error = e;
184
+ }
185
+ if (expected === void 0) {
186
+ assert(
187
+ threw,
188
+ `Expected function to throw`,
189
+ `Expected function not to throw`
190
+ );
191
+ } else if (typeof expected === "string") {
192
+ assert(
193
+ threw && error.message.includes(expected),
194
+ `Expected function to throw error containing "${expected}"`,
195
+ `Expected function not to throw error containing "${expected}"`
196
+ );
197
+ } else if (expected instanceof RegExp) {
198
+ assert(
199
+ threw && expected.test(error.message),
200
+ `Expected function to throw error matching ${expected}`,
201
+ `Expected function not to throw error matching ${expected}`
202
+ );
203
+ } else if (expected instanceof Error) {
204
+ assert(
205
+ threw && error.message === expected.message,
206
+ `Expected function to throw ${expected.message}`,
207
+ `Expected function not to throw ${expected.message}`
208
+ );
209
+ }
210
+ },
211
+ toBeInstanceOf(expected) {
212
+ assert(
213
+ actual instanceof expected,
214
+ `Expected ${stringify(actual)} to be instance of ${expected.name}`,
215
+ `Expected ${stringify(actual)} not to be instance of ${expected.name}`
216
+ );
217
+ },
218
+ get not() {
219
+ return createMatchers(actual, !negated);
220
+ }
221
+ };
222
+ return matchers;
223
+ }
224
+ function expect(actual) {
225
+ return createMatchers(actual);
226
+ }
227
+ globalThis.__LIBUILD_TEST__ = {
228
+ ended: false,
229
+ failed: 0,
230
+ passed: 0,
231
+ errors: []
232
+ };
233
+ var tests = [];
234
+ var rootSuite = {
235
+ name: "",
236
+ parent: null,
237
+ beforeAll: [],
238
+ afterAll: [],
239
+ beforeEach: [],
240
+ afterEach: []
241
+ };
242
+ var currentSuite = rootSuite;
243
+ function describe(name, fn) {
244
+ const suite = {
245
+ name,
246
+ parent: currentSuite,
247
+ beforeAll: [],
248
+ afterAll: [],
249
+ beforeEach: [],
250
+ afterEach: []
251
+ };
252
+ const prev = currentSuite;
253
+ currentSuite = suite;
254
+ fn();
255
+ currentSuite = prev;
256
+ }
257
+ function test(name, fn) {
258
+ tests.push({ name, fn, suite: currentSuite });
259
+ }
260
+ var it = test;
261
+ function beforeEach(fn) {
262
+ currentSuite.beforeEach.push(fn);
263
+ }
264
+ function afterEach(fn) {
265
+ currentSuite.afterEach.push(fn);
266
+ }
267
+ function beforeAll(fn) {
268
+ currentSuite.beforeAll.push(fn);
269
+ }
270
+ function afterAll(fn) {
271
+ currentSuite.afterAll.push(fn);
272
+ }
273
+ function getSuiteChain(suite) {
274
+ const chain = [];
275
+ let s = suite;
276
+ while (s) {
277
+ chain.unshift(s);
278
+ s = s.parent;
279
+ }
280
+ return chain;
281
+ }
282
+ function getFullName(t) {
283
+ const chain = getSuiteChain(t.suite);
284
+ const names = chain.map((s) => s.name).filter(Boolean);
285
+ names.push(t.name);
286
+ return names.join(" > ");
287
+ }
288
+ queueMicrotask(async () => {
289
+ const suiteRan = /* @__PURE__ */ new Set();
290
+ for (const t of tests) {
291
+ const fullName = getFullName(t);
292
+ const chain = getSuiteChain(t.suite);
293
+ try {
294
+ for (const suite of chain) {
295
+ if (!suiteRan.has(suite)) {
296
+ for (const hook of suite.beforeAll)
297
+ await hook();
298
+ suiteRan.add(suite);
299
+ }
300
+ }
301
+ for (const suite of chain) {
302
+ for (const hook of suite.beforeEach)
303
+ await hook();
304
+ }
305
+ await t.fn();
306
+ for (const suite of [...chain].reverse()) {
307
+ for (const hook of suite.afterEach)
308
+ await hook();
309
+ }
310
+ console.log("\u2713", fullName);
311
+ globalThis.__LIBUILD_TEST__.passed++;
312
+ } catch (e) {
313
+ console.error("\u2717", fullName);
314
+ console.error(" ", e.message);
315
+ globalThis.__LIBUILD_TEST__.failed++;
316
+ globalThis.__LIBUILD_TEST__.errors.push({
317
+ name: fullName,
318
+ error: e.message || String(e)
319
+ });
320
+ }
321
+ }
322
+ for (const suite of [...suiteRan].reverse()) {
323
+ for (const hook of suite.afterAll)
324
+ await hook();
325
+ }
326
+ globalThis.__LIBUILD_TEST__.ended = true;
327
+ });
328
+ export {
329
+ afterAll,
330
+ afterEach,
331
+ beforeAll,
332
+ beforeEach,
333
+ describe,
334
+ expect,
335
+ it,
336
+ test
337
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Bun test shim for @b9g/libuild/test
3
+ *
4
+ * Simply re-exports bun:test which already has Jest-compatible APIs.
5
+ */
6
+ export { describe, test, it, expect, beforeAll, afterAll, beforeEach, afterEach, } from "bun:test";
@@ -0,0 +1,24 @@
1
+ /// <reference types="./test-bun.d.ts" />
2
+ import "./_chunks/chunk-IBOCQ33F.js";
3
+
4
+ // src/test-bun.ts
5
+ import {
6
+ describe,
7
+ test,
8
+ it,
9
+ expect,
10
+ beforeAll,
11
+ afterAll,
12
+ beforeEach,
13
+ afterEach
14
+ } from "bun:test";
15
+ export {
16
+ afterAll,
17
+ afterEach,
18
+ beforeAll,
19
+ beforeEach,
20
+ describe,
21
+ expect,
22
+ it,
23
+ test
24
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Node.js test shim for @b9g/libuild/test
3
+ *
4
+ * Combines node:test runner with Jest's expect matchers.
5
+ */
6
+ import { describe, test, it, before, after, beforeEach, afterEach } from "node:test";
7
+ export { expect } from "expect";
8
+ export { describe, test, it, before as beforeAll, after as afterAll, beforeEach, afterEach, };
@@ -0,0 +1,24 @@
1
+ /// <reference types="./test-node.d.ts" />
2
+ import "./_chunks/chunk-IBOCQ33F.js";
3
+
4
+ // src/test-node.ts
5
+ import {
6
+ describe,
7
+ test,
8
+ it,
9
+ before,
10
+ after,
11
+ beforeEach,
12
+ afterEach
13
+ } from "node:test";
14
+ import { expect } from "expect";
15
+ export {
16
+ after as afterAll,
17
+ afterEach,
18
+ before as beforeAll,
19
+ beforeEach,
20
+ describe,
21
+ expect,
22
+ it,
23
+ test
24
+ };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @b9g/libuild test runner
3
+ *
4
+ * Cross-platform test execution for Bun, Node, and browsers.
5
+ */
6
+ export type Platform = "bun" | "node" | "chromium" | "firefox" | "webkit";
7
+ export interface TestRunnerOptions {
8
+ /** Working directory */
9
+ cwd: string;
10
+ /** Test file patterns */
11
+ patterns: string[];
12
+ /** Platforms to run on (bun, node, chromium, firefox, webkit) */
13
+ platforms: Platform[];
14
+ /** Enable debug mode (keeps browser open) */
15
+ debug: boolean;
16
+ /** Test timeout in ms */
17
+ timeout: number;
18
+ /** Watch mode */
19
+ watch: boolean;
20
+ }
21
+ export interface TestResult {
22
+ platform: string;
23
+ passed: number;
24
+ failed: number;
25
+ errors: Array<{
26
+ name: string;
27
+ error: string;
28
+ }>;
29
+ }
30
+ /**
31
+ * Main test runner
32
+ */
33
+ export declare function runTests(options?: Partial<TestRunnerOptions>): Promise<boolean>;
34
+ /**
35
+ * Detect available platforms
36
+ */
37
+ export declare function detectPlatforms(): Promise<("bun" | "node" | "browser")[]>;