bun-sticky 1.0.3 → 1.0.5

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.
@@ -1,1321 +0,0 @@
1
- /**
2
- * 🥐 BUN STICKY - WJTTC CHAMPIONSHIP TEST SUITE
3
- *
4
- * THE BEST BUN TEST SUITE IN THE AI ERA
5
- *
6
- * Philosophy:
7
- * - FULL Bun test API - Every feature, no shortcuts
8
- * - WJTTC Standards - F1-grade, championship quality
9
- * - META TESTING - Tests that test the tests
10
- * - BREAK IT - So they never know it was ever broken
11
- *
12
- * Bun Test Features:
13
- * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
14
- * ✓ test() / describe()
15
- * ✓ test.each() / describe.each()
16
- * ✓ test.concurrent()
17
- * ✓ test.todo() / test.skip() / test.only()
18
- * ✓ test.if() / test.skipIf()
19
- * ✓ test.failing() - Expected failures
20
- * ✓ beforeAll() / afterAll() / beforeEach() / afterEach()
21
- * ✓ mock() / spyOn() / mockImplementation()
22
- * ✓ toMatchSnapshot() / toMatchInlineSnapshot()
23
- * ✓ setSystemTime() - Time mocking
24
- * ✓ expect.assertions() / expect.hasAssertions()
25
- * ✓ expect.extend() - Custom matchers
26
- * ✓ Async/Promise testing
27
- * ✓ Error/Throw testing
28
- * ✓ Timeout testing
29
- * ✓ All 40+ matchers
30
- * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
31
- *
32
- * Run: bun test
33
- * Run with todos: bun test --todo
34
- * Update snapshots: bun test -u
35
- */
36
-
37
- import {
38
- describe,
39
- test,
40
- expect,
41
- beforeAll,
42
- afterAll,
43
- beforeEach,
44
- afterEach,
45
- mock,
46
- spyOn,
47
- setSystemTime,
48
- } from "bun:test";
49
- import { $ } from "bun";
50
-
51
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
52
- // CUSTOM MATCHERS - Extend expect()
53
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
54
-
55
- expect.extend({
56
- toBeValidScore(received: number) {
57
- const pass = received >= 0 && received <= 105;
58
- return {
59
- pass,
60
- message: () =>
61
- pass
62
- ? `Expected ${received} not to be a valid score (0-105)`
63
- : `Expected ${received} to be a valid score (0-105)`,
64
- };
65
- },
66
- toBeValidTier(received: { emoji: string; name: string; color: string }) {
67
- const validEmojis = ["🍊", "🏆", "🥇", "🥈", "🥉", "🟢", "🟡", "🔴", "⚪"];
68
- const pass = validEmojis.includes(received.emoji);
69
- return {
70
- pass,
71
- message: () =>
72
- pass
73
- ? `Expected tier not to be valid`
74
- : `Expected tier to be valid, got ${received.emoji}`,
75
- };
76
- },
77
- toHaveSlotCount(received: Record<string, unknown>, expected: number) {
78
- const count = Object.keys(received).length;
79
- const pass = count === expected;
80
- return {
81
- pass,
82
- message: () =>
83
- pass
84
- ? `Expected not to have ${expected} slots`
85
- : `Expected ${expected} slots, got ${count}`,
86
- };
87
- },
88
- });
89
-
90
- // Type declarations for custom matchers
91
- declare module "bun:test" {
92
- interface Matchers<T> {
93
- toBeValidScore(): void;
94
- toBeValidTier(): void;
95
- toHaveSlotCount(expected: number): void;
96
- }
97
- }
98
-
99
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
100
- // TIER 0: META TESTING - Tests that test the tests
101
- // "We break it so they never know it was ever broken"
102
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
103
-
104
- describe("Tier 0: META TESTING", () => {
105
- test("T0.01 - This test file exists", async () => {
106
- const file = Bun.file("./tests/sticky.test.ts");
107
- expect(await file.exists()).toBe(true);
108
- });
109
-
110
- test("T0.02 - Test file is TypeScript", async () => {
111
- const path = "./tests/sticky.test.ts";
112
- expect(path.endsWith(".ts")).toBe(true);
113
- });
114
-
115
- test("T0.03 - Test file imports bun:test", async () => {
116
- const content = await Bun.file("./tests/sticky.test.ts").text();
117
- expect(content).toContain('from "bun:test"');
118
- });
119
-
120
- test("T0.04 - Test file has describe blocks", async () => {
121
- const content = await Bun.file("./tests/sticky.test.ts").text();
122
- const describeCount = (content.match(/describe\(/g) || []).length;
123
- expect(describeCount).toBeGreaterThan(10);
124
- });
125
-
126
- test("T0.05 - Test file has test blocks", async () => {
127
- const content = await Bun.file("./tests/sticky.test.ts").text();
128
- const testCount = (content.match(/\btest\(/g) || []).length;
129
- expect(testCount).toBeGreaterThan(50);
130
- });
131
-
132
- test("T0.06 - Test file uses mock()", async () => {
133
- const content = await Bun.file("./tests/sticky.test.ts").text();
134
- expect(content).toContain("mock(");
135
- });
136
-
137
- test("T0.07 - Test file uses spyOn()", async () => {
138
- const content = await Bun.file("./tests/sticky.test.ts").text();
139
- expect(content).toContain("spyOn(");
140
- });
141
-
142
- test("T0.08 - Test file uses toMatchSnapshot()", async () => {
143
- const content = await Bun.file("./tests/sticky.test.ts").text();
144
- expect(content).toContain("toMatchSnapshot()");
145
- });
146
-
147
- test("T0.09 - Test file uses test.each()", async () => {
148
- const content = await Bun.file("./tests/sticky.test.ts").text();
149
- expect(content).toContain("test.each(");
150
- });
151
-
152
- test("T0.10 - Test file uses beforeAll/afterAll", async () => {
153
- const content = await Bun.file("./tests/sticky.test.ts").text();
154
- expect(content).toContain("beforeAll(");
155
- expect(content).toContain("afterAll(");
156
- });
157
-
158
- test("T0.11 - Snapshot directory exists after tests", async () => {
159
- // Snapshots are created in __snapshots__
160
- const snapshotDir = Bun.file("./tests/__snapshots__");
161
- // This will pass after first run
162
- expect(true).toBe(true);
163
- });
164
-
165
- test("T0.12 - expect.extend() is used for custom matchers", async () => {
166
- const content = await Bun.file("./tests/sticky.test.ts").text();
167
- expect(content).toContain("expect.extend(");
168
- });
169
- });
170
-
171
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
172
- // TIER 1: CORE PARSING (20%)
173
- // The foundation - if this breaks, everything breaks
174
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
175
-
176
- describe("Tier 1: Core Parsing", () => {
177
- test("T1.01 - Parse simple YAML key-value", async () => {
178
- const { parseYaml } = await import("../lib/parser.ts");
179
- const result = parseYaml("name: test");
180
- expect(result.name).toBe("test");
181
- });
182
-
183
- test("T1.02 - Parse nested YAML structure", async () => {
184
- const { parseYaml } = await import("../lib/parser.ts");
185
- const yaml = `
186
- project:
187
- name: test
188
- goal: testing
189
- `;
190
- const result = parseYaml(yaml);
191
- expect(result.project).toBeDefined();
192
- expect((result.project as any).name).toBe("test");
193
- });
194
-
195
- test("T1.03 - Skip comments", async () => {
196
- const { parseYaml } = await import("../lib/parser.ts");
197
- const yaml = `
198
- # This is a comment
199
- name: test
200
- # Another comment
201
- `;
202
- const result = parseYaml(yaml);
203
- expect(result.name).toBe("test");
204
- expect(Object.keys(result).length).toBe(1);
205
- });
206
-
207
- test("T1.04 - Handle empty lines", async () => {
208
- const { parseYaml } = await import("../lib/parser.ts");
209
- const yaml = `
210
- name: test
211
-
212
- goal: testing
213
-
214
- `;
215
- const result = parseYaml(yaml);
216
- expect(result.name).toBe("test");
217
- expect(result.goal).toBe("testing");
218
- });
219
-
220
- test("T1.05 - Strip quotes from values", async () => {
221
- const { parseYaml } = await import("../lib/parser.ts");
222
- const yaml = `
223
- single: 'quoted'
224
- double: "quoted"
225
- `;
226
- const result = parseYaml(yaml);
227
- expect(result.single).toBe("quoted");
228
- expect(result.double).toBe("quoted");
229
- });
230
-
231
- test("T1.06 - Handle inline arrays", async () => {
232
- const { parseYaml } = await import("../lib/parser.ts");
233
- const yaml = `stack: [Bun, TypeScript, FAF]`;
234
- const result = parseYaml(yaml);
235
- expect(Array.isArray(result.stack)).toBe(true);
236
- expect((result.stack as string[]).length).toBe(3);
237
- });
238
-
239
- // ★ test.each() - Parameterized tests
240
- test.each([
241
- ["name: hello", "name", "hello"],
242
- ["version: 1.0.0", "version", "1.0.0"],
243
- ["type: cli", "type", "cli"],
244
- ["score: 100", "score", "100"],
245
- ])("T1.07 - Parse '%s' → %s=%s", async (yaml, key, value) => {
246
- const { parseYaml } = await import("../lib/parser.ts");
247
- const result = parseYaml(yaml);
248
- expect(result[key]).toBe(value);
249
- });
250
-
251
- // Edge case: empty value creates nested object (YAML spec behavior)
252
- test("T1.08 - Empty value creates nested object", async () => {
253
- const { parseYaml } = await import("../lib/parser.ts");
254
- const result = parseYaml("empty:");
255
- expect(typeof result.empty).toBe("object");
256
- });
257
-
258
- test("T1.09 - getNestedValue deep path", async () => {
259
- const { getNestedValue } = await import("../lib/parser.ts");
260
- const obj = { a: { b: { c: { d: "deep" } } } };
261
- expect(getNestedValue(obj, "a.b.c.d")).toBe("deep");
262
- });
263
-
264
- test("T1.10 - getNestedValue missing path returns undefined", async () => {
265
- const { getNestedValue } = await import("../lib/parser.ts");
266
- const obj = { a: { b: 1 } };
267
- expect(getNestedValue(obj, "a.b.c.d")).toBeUndefined();
268
- });
269
-
270
- test("T1.11 - hasValue returns true for filled", async () => {
271
- const { hasValue } = await import("../lib/parser.ts");
272
- expect(hasValue({ name: "test" }, "name")).toBe(true);
273
- });
274
-
275
- test("T1.12 - hasValue returns false for empty string", async () => {
276
- const { hasValue } = await import("../lib/parser.ts");
277
- expect(hasValue({ name: "" }, "name")).toBe(false);
278
- expect(hasValue({ name: " " }, "name")).toBe(false);
279
- });
280
- });
281
-
282
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
283
- // TIER 2: SCORING ENGINE (25%)
284
- // Wolfejam slot-based scoring - the math must be exact
285
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
286
-
287
- describe("Tier 2: Scoring Engine", () => {
288
- // ★ expect.assertions() - Ensure exact assertion count
289
- test("T2.01 - Empty FAF scores 0%", async () => {
290
- expect.assertions(2);
291
- const { calculateScore } = await import("../lib/scorer.ts");
292
- const result = calculateScore({});
293
- expect(result.score).toBe(0);
294
- expect(result.filled).toBe(0);
295
- });
296
-
297
- test("T2.02 - CLI type has 9 applicable slots", async () => {
298
- expect.hasAssertions();
299
- const { calculateScore } = await import("../lib/scorer.ts");
300
- const cliFaf = { project: { type: "cli" } };
301
- const result = calculateScore(cliFaf);
302
- expect(result.projectType).toBe("cli");
303
- expect(result.total).toBe(9);
304
- });
305
-
306
- test("T2.03 - Fullstack type has 21 applicable slots", async () => {
307
- const { calculateScore } = await import("../lib/scorer.ts");
308
- const fullFaf = { project: { type: "fullstack" } };
309
- const result = calculateScore(fullFaf);
310
- expect(result.projectType).toBe("fullstack");
311
- expect(result.total).toBe(21);
312
- });
313
-
314
- test("T2.04 - Full CLI scores 100%", async () => {
315
- const { calculateScore } = await import("../lib/scorer.ts");
316
- const fullCli = {
317
- project: {
318
- type: "cli",
319
- name: "test",
320
- goal: "testing",
321
- main_language: "TypeScript",
322
- },
323
- human_context: {
324
- who: "developers",
325
- what: "a tool",
326
- why: "to help",
327
- where: "terminal",
328
- when: "always",
329
- how: "bun run",
330
- },
331
- };
332
- const result = calculateScore(fullCli);
333
- expect(result.score).toBe(100);
334
- expect(result.filled).toBe(9);
335
- expect(result.total).toBe(9);
336
- });
337
-
338
- test("T2.05 - Partial CLI scores correctly", async () => {
339
- const { calculateScore } = await import("../lib/scorer.ts");
340
- const partial = {
341
- project: { type: "cli", name: "test" },
342
- };
343
- const result = calculateScore(partial);
344
- expect(result.filled).toBe(1);
345
- expect(result.total).toBe(9);
346
- expect(result.score).toBe(11);
347
- });
348
-
349
- test("T2.06 - 21 total slots defined", async () => {
350
- const { SLOTS } = await import("../lib/scorer.ts");
351
- const totalSlots =
352
- SLOTS.project.length +
353
- SLOTS.frontend.length +
354
- SLOTS.backend.length +
355
- SLOTS.universal.length +
356
- SLOTS.human.length;
357
- expect(totalSlots).toBe(21);
358
- });
359
-
360
- test("T2.07 - SLOTS structure snapshot", async () => {
361
- const { SLOTS } = await import("../lib/scorer.ts");
362
- expect(SLOTS).toMatchSnapshot();
363
- });
364
-
365
- // ★ test.each() with describe.each pattern
366
- test.each([
367
- ["project", 3],
368
- ["frontend", 4],
369
- ["backend", 5],
370
- ["universal", 3],
371
- ["human", 6],
372
- ] as const)("T2.08 - %s section has %d slots", async (section, count) => {
373
- const { SLOTS } = await import("../lib/scorer.ts");
374
- expect(SLOTS[section].length).toBe(count);
375
- });
376
-
377
- test.each([
378
- ["cli", 9],
379
- ["library", 9],
380
- ["api", 17],
381
- ["webapp", 16],
382
- ["fullstack", 21],
383
- ["mobile", 9],
384
- ["unknown", 9],
385
- ] as const)("T2.09 - Type '%s' has %d slots", async (type, slots) => {
386
- const { calculateScore } = await import("../lib/scorer.ts");
387
- const faf = { project: { type } };
388
- const result = calculateScore(faf);
389
- expect(result.total).toBe(slots);
390
- });
391
-
392
- test("T2.10 - Type detection infers fullstack", async () => {
393
- const { detectProjectType } = await import("../lib/scorer.ts");
394
- const faf = { stack: { frontend: "React", backend: "Express" } };
395
- expect(detectProjectType(faf)).toBe("fullstack");
396
- });
397
-
398
- test("T2.11 - Type detection infers webapp", async () => {
399
- const { detectProjectType } = await import("../lib/scorer.ts");
400
- const faf = { stack: { frontend: "React" } };
401
- expect(detectProjectType(faf)).toBe("webapp");
402
- });
403
-
404
- test("T2.12 - Type detection infers api", async () => {
405
- const { detectProjectType } = await import("../lib/scorer.ts");
406
- const faf = { stack: { database: "PostgreSQL" } };
407
- expect(detectProjectType(faf)).toBe("api");
408
- });
409
-
410
- // ★ Custom matcher usage
411
- test("T2.13 - Score is valid (custom matcher)", async () => {
412
- const { calculateScore } = await import("../lib/scorer.ts");
413
- const result = calculateScore({ project: { name: "test" } });
414
- expect(result.score).toBeValidScore();
415
- });
416
-
417
- test("T2.14 - Full CLI result snapshot", async () => {
418
- const { calculateScore } = await import("../lib/scorer.ts");
419
- const fullCli = {
420
- project: {
421
- type: "cli",
422
- name: "test",
423
- goal: "goal",
424
- main_language: "TS",
425
- },
426
- human_context: {
427
- who: "a",
428
- what: "b",
429
- why: "c",
430
- where: "d",
431
- when: "e",
432
- how: "f",
433
- },
434
- };
435
- const result = calculateScore(fullCli);
436
- expect(result).toMatchSnapshot();
437
- });
438
-
439
- test("T2.15 - TYPE_CATEGORIES snapshot", async () => {
440
- const { TYPE_CATEGORIES } = await import("../lib/scorer.ts");
441
- expect(TYPE_CATEGORIES).toMatchSnapshot();
442
- });
443
- });
444
-
445
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
446
- // TIER 3: TIER SYSTEM (15%)
447
- // Medals must be correct
448
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
449
-
450
- describe("Tier 3: Tier System", () => {
451
- // ★ test.each() - All tier boundaries
452
- test.each([
453
- [110, "🍊", "Big Orange"],
454
- [105, "🍊", "Big Orange"],
455
- [100, "🏆", "Trophy"],
456
- [99, "🥇", "Gold"],
457
- [98, "🥈", "Silver"],
458
- [95, "🥈", "Silver"],
459
- [94, "🥉", "Bronze"],
460
- [85, "🥉", "Bronze"],
461
- [84, "🟢", "Green"],
462
- [70, "🟢", "Green"],
463
- [69, "🟡", "Yellow"],
464
- [55, "🟡", "Yellow"],
465
- [54, "🔴", "Red"],
466
- [1, "🔴", "Red"],
467
- [0, "⚪", "Empty"],
468
- ] as const)("T3.01-%03d%% = %s %s", async (score, emoji, name) => {
469
- const { getTier } = await import("../lib/tier.ts");
470
- const tier = getTier(score);
471
- expect(tier.emoji).toBe(emoji);
472
- expect(tier.name).toBe(name);
473
- });
474
-
475
- test("T3.02 - isLaunchReady boundary", async () => {
476
- const { isLaunchReady } = await import("../lib/tier.ts");
477
- expect(isLaunchReady(84)).toBe(false);
478
- expect(isLaunchReady(85)).toBe(true);
479
- expect(isLaunchReady(100)).toBe(true);
480
- });
481
-
482
- test("T3.03 - Tier has color property", async () => {
483
- const { getTier } = await import("../lib/tier.ts");
484
- const tier = getTier(100);
485
- expect(tier).toHaveProperty("color");
486
- expect(typeof tier.color).toBe("string");
487
- });
488
-
489
- // ★ Custom matcher
490
- test("T3.04 - All tiers are valid (custom matcher)", async () => {
491
- const { getTier } = await import("../lib/tier.ts");
492
- for (const score of [0, 50, 70, 85, 95, 99, 100, 105]) {
493
- expect(getTier(score)).toBeValidTier();
494
- }
495
- });
496
-
497
- test("T3.05 - Tier color contains ANSI escape", async () => {
498
- const { getTier } = await import("../lib/tier.ts");
499
- const tier = getTier(100);
500
- expect(tier.color).toContain("\x1b[");
501
- });
502
- });
503
-
504
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
505
- // TIER 4: CLI COMMANDS (15%)
506
- // Commands must work
507
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
508
-
509
- describe("Tier 4: CLI Commands", () => {
510
- const CLI = "./index.ts";
511
-
512
- test("T4.01 - --version returns version", async () => {
513
- const result = await $`bun run ${CLI} --version`.text();
514
- expect(result.trim()).toMatch(/^bun-sticky v\d+\.\d+\.\d+$/);
515
- });
516
-
517
- test("T4.02 - help shows all commands", async () => {
518
- const result = await $`bun run ${CLI} help`.text();
519
- expect(result).toContain("score");
520
- expect(result).toContain("init");
521
- expect(result).toContain("sync");
522
- expect(result).toContain("version");
523
- expect(result).toContain("help");
524
- });
525
-
526
- test("T4.03 - unknown command shows help", async () => {
527
- const result = await $`bun run ${CLI} unknown`.text();
528
- expect(result).toContain("Commands");
529
- });
530
-
531
- test("T4.04 - Banner shows Bun Sticky", async () => {
532
- const result = await $`bun run ${CLI} help`.text();
533
- expect(result).toContain("Bun Sticky");
534
- expect(result).toContain("🥐");
535
- });
536
-
537
- test("T4.05 - Banner shows tagline", async () => {
538
- const result = await $`bun run ${CLI} help`.text();
539
- expect(result).toContain("Fastest bun under the sum");
540
- });
541
-
542
- // ★ test.each() - Flag variants
543
- test.each(["--version", "-v", "version"])(
544
- "T4.06 - '%s' returns version",
545
- async (flag) => {
546
- const result = await $`bun run ${CLI} ${flag}`.text();
547
- expect(result).toContain("bun-sticky v");
548
- }
549
- );
550
-
551
- test.each(["--help", "-h", "help"])(
552
- "T4.07 - '%s' shows help",
553
- async (flag) => {
554
- const result = await $`bun run ${CLI} ${flag}`.text();
555
- expect(result).toContain("Commands");
556
- }
557
- );
558
-
559
- test("T4.08 - Score shows project name", async () => {
560
- const result = await $`bun run ${CLI} score`.text();
561
- expect(result).toContain("Project:");
562
- });
563
-
564
- test("T4.09 - Score shows type", async () => {
565
- const result = await $`bun run ${CLI} score`.text();
566
- expect(result).toContain("Type:");
567
- });
568
-
569
- test("T4.10 - Score shows percentage", async () => {
570
- const result = await $`bun run ${CLI} score`.text();
571
- expect(result).toMatch(/\d+%/);
572
- });
573
- });
574
-
575
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
576
- // TIER 5: FILE OPERATIONS (10%)
577
- // Bun.file() must work
578
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
579
-
580
- describe("Tier 5: File Operations", () => {
581
- const TEST_DIR = "/tmp/bun-sticky-test-" + Date.now();
582
-
583
- beforeAll(async () => {
584
- await $`mkdir -p ${TEST_DIR}`;
585
- });
586
-
587
- afterAll(async () => {
588
- await $`rm -rf ${TEST_DIR}`;
589
- });
590
-
591
- test("T5.01 - Init creates project.faf", async () => {
592
- await $`cd ${TEST_DIR} && bun run ${process.cwd()}/index.ts init test-project`;
593
- const file = Bun.file(`${TEST_DIR}/project.faf`);
594
- expect(await file.exists()).toBe(true);
595
- });
596
-
597
- test("T5.02 - Init includes project name", async () => {
598
- const content = await Bun.file(`${TEST_DIR}/project.faf`).text();
599
- expect(content).toContain("test-project");
600
- });
601
-
602
- test("T5.03 - Init includes faf_version", async () => {
603
- const content = await Bun.file(`${TEST_DIR}/project.faf`).text();
604
- expect(content).toContain("faf_version:");
605
- });
606
-
607
- test("T5.04 - Sync creates CLAUDE.md", async () => {
608
- await $`cd ${TEST_DIR} && bun run ${process.cwd()}/index.ts sync`;
609
- const file = Bun.file(`${TEST_DIR}/CLAUDE.md`);
610
- expect(await file.exists()).toBe(true);
611
- });
612
-
613
- test("T5.05 - CLAUDE.md contains project name", async () => {
614
- const content = await Bun.file(`${TEST_DIR}/CLAUDE.md`).text();
615
- expect(content).toContain("test-project");
616
- });
617
-
618
- test("T5.06 - CLAUDE.md contains score", async () => {
619
- const content = await Bun.file(`${TEST_DIR}/CLAUDE.md`).text();
620
- expect(content).toMatch(/\d+%/);
621
- });
622
-
623
- test("T5.07 - Bun.file() size check", async () => {
624
- const file = Bun.file(`${TEST_DIR}/project.faf`);
625
- expect(file.size).toBeGreaterThan(0);
626
- });
627
- });
628
-
629
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
630
- // TIER 6: PERFORMANCE (10%)
631
- // Speed is the mission
632
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
633
-
634
- describe("Tier 6: Performance", () => {
635
- test("T6.01 - Cold start under 50ms", async () => {
636
- const start = performance.now();
637
- await $`bun run ./index.ts --version`.quiet();
638
- const elapsed = performance.now() - start;
639
- expect(elapsed).toBeLessThan(50);
640
- });
641
-
642
- test("T6.02 - Score command under 100ms", async () => {
643
- const start = performance.now();
644
- await $`bun run ./index.ts score`.quiet();
645
- const elapsed = performance.now() - start;
646
- expect(elapsed).toBeLessThan(100);
647
- });
648
-
649
- test("T6.03 - Help under 50ms", async () => {
650
- const start = performance.now();
651
- await $`bun run ./index.ts help`.quiet();
652
- const elapsed = performance.now() - start;
653
- expect(elapsed).toBeLessThan(50);
654
- });
655
-
656
- test("T6.04 - 10x faster than 334ms Node baseline", async () => {
657
- const NODE_BASELINE = 334;
658
- const TARGET = NODE_BASELINE / 10 + 20; // 53.4ms with generous margin
659
-
660
- const start = performance.now();
661
- await $`bun run ./index.ts score`.quiet();
662
- const elapsed = performance.now() - start;
663
-
664
- expect(elapsed).toBeLessThan(TARGET);
665
- });
666
-
667
- // ★ test.concurrent() - Parallel execution
668
- test.concurrent("T6.05 - Concurrent: version", async () => {
669
- const start = performance.now();
670
- await $`bun run ./index.ts --version`.quiet();
671
- expect(performance.now() - start).toBeLessThan(100);
672
- });
673
-
674
- test.concurrent("T6.06 - Concurrent: help", async () => {
675
- const start = performance.now();
676
- await $`bun run ./index.ts help`.quiet();
677
- expect(performance.now() - start).toBeLessThan(100);
678
- });
679
-
680
- test.concurrent("T6.07 - Concurrent: score", async () => {
681
- const start = performance.now();
682
- await $`bun run ./index.ts score`.quiet();
683
- expect(performance.now() - start).toBeLessThan(100);
684
- });
685
- });
686
-
687
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
688
- // TIER 7: WJTTC CHAMPIONSHIP (5%)
689
- // The championship extras
690
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
691
-
692
- describe("Tier 7: WJTTC Championship", () => {
693
- test("T7.01 - Zero dependencies", async () => {
694
- const pkg = await Bun.file("./package.json").json();
695
- const deps = Object.keys(pkg.dependencies || {});
696
- expect(deps.length).toBe(0);
697
- });
698
-
699
- test("T7.02 - Pure Bun APIs only", async () => {
700
- const content = await Bun.file("./index.ts").text();
701
- expect(content).not.toContain("require(");
702
- expect(content).not.toContain("from 'fs'");
703
- expect(content).not.toContain("from 'path'");
704
- });
705
-
706
- test("T7.03 - TypeScript native (no build step)", async () => {
707
- const files = await $`ls *.ts`.text();
708
- expect(files).toContain("index.ts");
709
- const hasDist = await Bun.file("./dist").exists();
710
- expect(hasDist).toBe(false);
711
- });
712
-
713
- test("T7.04 - Single entry point", async () => {
714
- const pkg = await Bun.file("./package.json").json();
715
- expect(pkg.main).toBe("index.ts");
716
- });
717
-
718
- test("T7.05 - Croissant branding present", async () => {
719
- const content = await Bun.file("./index.ts").text();
720
- expect(content).toContain("🥐");
721
- expect(content).toContain("Bun Sticky");
722
- expect(content).toContain("Fastest bun under the sum");
723
- });
724
-
725
- test("T7.06 - Package.json metadata", async () => {
726
- const pkg = await Bun.file("./package.json").json();
727
- expect(pkg.name).toBe("bun-sticky");
728
- expect(pkg.type).toBe("module");
729
- expect(pkg).toHaveProperty("bin");
730
- });
731
-
732
- test("T7.07 - Wolfejam scoring (NOT Elon weights)", async () => {
733
- const content = await Bun.file("./lib/scorer.ts").text();
734
- expect(content).toContain("SLOTS");
735
- expect(content).not.toContain("0.40");
736
- expect(content).not.toContain("0.35");
737
- expect(content).not.toContain("0.15");
738
- expect(content).not.toContain("0.10");
739
- });
740
- });
741
-
742
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
743
- // TIER 8: MOCKING & SPYING
744
- // Advanced Bun test features
745
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
746
-
747
- describe("Tier 8: Mocking & Spying", () => {
748
- test("T8.01 - Mock function tracks calls", () => {
749
- const mockFn = mock(() => 42);
750
- mockFn();
751
- mockFn();
752
- mockFn();
753
- expect(mockFn).toHaveBeenCalledTimes(3);
754
- });
755
-
756
- test("T8.02 - Mock function returns value", () => {
757
- const mockFn = mock(() => "mocked");
758
- expect(mockFn()).toBe("mocked");
759
- });
760
-
761
- test("T8.03 - Mock with implementation", () => {
762
- const mockFn = mock((x: number) => x * 2);
763
- expect(mockFn(5)).toBe(10);
764
- expect(mockFn).toHaveBeenCalledWith(5);
765
- });
766
-
767
- test("T8.04 - Mock tracks arguments", () => {
768
- const mockFn = mock((a: string, b: number) => `${a}${b}`);
769
- mockFn("test", 123);
770
- expect(mockFn).toHaveBeenCalledWith("test", 123);
771
- });
772
-
773
- test("T8.05 - Mock reset", () => {
774
- const mockFn = mock(() => 1);
775
- mockFn();
776
- mockFn();
777
- expect(mockFn).toHaveBeenCalledTimes(2);
778
- mockFn.mockClear();
779
- expect(mockFn).toHaveBeenCalledTimes(0);
780
- });
781
-
782
- test("T8.06 - Spy on console.log", () => {
783
- const spy = spyOn(console, "log").mockImplementation(() => {});
784
- console.log("test message");
785
- expect(spy).toHaveBeenCalledWith("test message");
786
- spy.mockRestore();
787
- });
788
-
789
- test("T8.07 - Spy on console.error", () => {
790
- const spy = spyOn(console, "error").mockImplementation(() => {});
791
- console.error("error message");
792
- expect(spy).toHaveBeenCalledWith("error message");
793
- spy.mockRestore();
794
- });
795
-
796
- test("T8.08 - Mock implementation change", () => {
797
- const mockFn = mock(() => 1);
798
- expect(mockFn()).toBe(1);
799
- mockFn.mockImplementation(() => 2);
800
- expect(mockFn()).toBe(2);
801
- });
802
-
803
- test("T8.09 - Mock return value", () => {
804
- const mockFn = mock(() => 0);
805
- mockFn.mockReturnValue(42);
806
- expect(mockFn()).toBe(42);
807
- });
808
- });
809
-
810
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
811
- // TIER 9: TIME MOCKING
812
- // setSystemTime() - Control time itself
813
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
814
-
815
- describe("Tier 9: Time Mocking", () => {
816
- afterEach(() => {
817
- setSystemTime(); // Reset to real time
818
- });
819
-
820
- test("T9.01 - setSystemTime() freezes time", () => {
821
- const fixedDate = new Date("2025-01-01T00:00:00Z");
822
- setSystemTime(fixedDate);
823
- expect(new Date().getTime()).toBe(fixedDate.getTime());
824
- });
825
-
826
- test("T9.02 - Time can be set to any date", () => {
827
- const past = new Date("2000-01-01T00:00:00Z");
828
- setSystemTime(past);
829
- expect(new Date().getFullYear()).toBe(2000);
830
- });
831
-
832
- test("T9.03 - Date.now() respects mocked time", () => {
833
- const fixed = new Date("2025-06-15T12:00:00Z");
834
- setSystemTime(fixed);
835
- expect(Date.now()).toBe(fixed.getTime());
836
- });
837
-
838
- test("T9.04 - Reset to real time", () => {
839
- setSystemTime(new Date("1999-01-01"));
840
- setSystemTime(); // Reset
841
- expect(new Date().getFullYear()).toBeGreaterThanOrEqual(2024);
842
- });
843
- });
844
-
845
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
846
- // TIER 10: EXTENDED MATCHERS
847
- // Full matcher coverage - 40+ matchers
848
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
849
-
850
- describe("Tier 10: Extended Matchers", () => {
851
- // Equality
852
- test("T10.01 - toBe", () => {
853
- expect(1).toBe(1);
854
- expect("a").toBe("a");
855
- });
856
-
857
- test("T10.02 - toEqual", () => {
858
- expect({ a: 1 }).toEqual({ a: 1 });
859
- expect([1, 2]).toEqual([1, 2]);
860
- });
861
-
862
- test("T10.03 - toStrictEqual", () => {
863
- expect({ a: 1 }).toStrictEqual({ a: 1 });
864
- });
865
-
866
- // Truthiness
867
- test("T10.04 - toBeTruthy / toBeFalsy", () => {
868
- expect(1).toBeTruthy();
869
- expect("a").toBeTruthy();
870
- expect(0).toBeFalsy();
871
- expect("").toBeFalsy();
872
- });
873
-
874
- test("T10.05 - toBeNull / toBeUndefined / toBeDefined", () => {
875
- expect(null).toBeNull();
876
- expect(undefined).toBeUndefined();
877
- expect(1).toBeDefined();
878
- });
879
-
880
- test("T10.06 - toBeNaN", () => {
881
- expect(NaN).toBeNaN();
882
- expect(0 / 0).toBeNaN();
883
- });
884
-
885
- // Numbers
886
- test("T10.07 - toBeGreaterThan / toBeLessThan", () => {
887
- expect(10).toBeGreaterThan(5);
888
- expect(5).toBeLessThan(10);
889
- });
890
-
891
- test("T10.08 - toBeGreaterThanOrEqual / toBeLessThanOrEqual", () => {
892
- expect(10).toBeGreaterThanOrEqual(10);
893
- expect(10).toBeLessThanOrEqual(10);
894
- });
895
-
896
- test("T10.09 - toBeCloseTo", () => {
897
- expect(0.1 + 0.2).toBeCloseTo(0.3, 5);
898
- });
899
-
900
- // Strings
901
- test("T10.10 - toContain (string)", () => {
902
- expect("hello world").toContain("world");
903
- });
904
-
905
- test("T10.11 - toMatch (regex)", () => {
906
- expect("hello world").toMatch(/world/);
907
- expect("test123").toMatch(/\d+/);
908
- });
909
-
910
- test("T10.12 - toStartWith / toEndWith", () => {
911
- expect("hello world").toStartWith("hello");
912
- expect("hello world").toEndWith("world");
913
- });
914
-
915
- // Arrays
916
- test("T10.13 - toContain (array)", () => {
917
- expect([1, 2, 3]).toContain(2);
918
- });
919
-
920
- test("T10.14 - toContainEqual", () => {
921
- expect([{ a: 1 }, { b: 2 }]).toContainEqual({ a: 1 });
922
- });
923
-
924
- test("T10.15 - toHaveLength", () => {
925
- expect([1, 2, 3]).toHaveLength(3);
926
- expect("hello").toHaveLength(5);
927
- });
928
-
929
- // Objects
930
- test("T10.16 - toHaveProperty", () => {
931
- expect({ a: { b: 1 } }).toHaveProperty("a.b", 1);
932
- });
933
-
934
- test("T10.17 - toMatchObject", () => {
935
- expect({ a: 1, b: 2 }).toMatchObject({ a: 1 });
936
- });
937
-
938
- // Types
939
- test("T10.18 - toBeInstanceOf", () => {
940
- expect([]).toBeInstanceOf(Array);
941
- expect(new Date()).toBeInstanceOf(Date);
942
- });
943
-
944
- test("T10.19 - toBeTypeOf", () => {
945
- expect("hello").toBeTypeOf("string");
946
- expect(123).toBeTypeOf("number");
947
- expect({}).toBeTypeOf("object");
948
- });
949
-
950
- // Errors
951
- test("T10.20 - toThrow", () => {
952
- expect(() => {
953
- throw new Error("test");
954
- }).toThrow();
955
- expect(() => {
956
- throw new Error("test");
957
- }).toThrow("test");
958
- });
959
-
960
- test("T10.21 - toThrowError", () => {
961
- expect(() => {
962
- throw new TypeError("type error");
963
- }).toThrowError(TypeError);
964
- });
965
-
966
- // Negation
967
- test("T10.22 - .not modifier", () => {
968
- expect(1).not.toBe(2);
969
- expect([1, 2]).not.toContain(3);
970
- expect("hello").not.toMatch(/xyz/);
971
- });
972
-
973
- // Async
974
- test("T10.23 - resolves", async () => {
975
- await expect(Promise.resolve(1)).resolves.toBe(1);
976
- });
977
-
978
- test("T10.24 - rejects", async () => {
979
- await expect(Promise.reject(new Error("fail"))).rejects.toThrow("fail");
980
- });
981
- });
982
-
983
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
984
- // TIER 11: LIFECYCLE HOOKS
985
- // beforeEach / afterEach isolation
986
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
987
-
988
- describe("Tier 11: Lifecycle Hooks", () => {
989
- let counter = 0;
990
- let setupRan = false;
991
-
992
- beforeAll(() => {
993
- setupRan = true;
994
- });
995
-
996
- beforeEach(() => {
997
- counter = 0;
998
- });
999
-
1000
- afterEach(() => {
1001
- // Cleanup
1002
- });
1003
-
1004
- afterAll(() => {
1005
- // Final cleanup
1006
- });
1007
-
1008
- test("T11.01 - beforeAll ran", () => {
1009
- expect(setupRan).toBe(true);
1010
- });
1011
-
1012
- test("T11.02 - Counter starts at 0", () => {
1013
- expect(counter).toBe(0);
1014
- counter++;
1015
- expect(counter).toBe(1);
1016
- });
1017
-
1018
- test("T11.03 - Counter reset by beforeEach", () => {
1019
- expect(counter).toBe(0);
1020
- });
1021
-
1022
- test("T11.04 - Each test isolated", () => {
1023
- counter = 100;
1024
- expect(counter).toBe(100);
1025
- });
1026
-
1027
- test("T11.05 - Previous test doesn't affect this", () => {
1028
- expect(counter).toBe(0);
1029
- });
1030
- });
1031
-
1032
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1033
- // TIER 12: ASYNC & PROMISE TESTING
1034
- // Comprehensive async patterns
1035
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1036
-
1037
- describe("Tier 12: Async & Promise Testing", () => {
1038
- test("T12.01 - Async/await test", async () => {
1039
- const result = await Promise.resolve(42);
1040
- expect(result).toBe(42);
1041
- });
1042
-
1043
- test("T12.02 - Promise.all", async () => {
1044
- const results = await Promise.all([
1045
- Promise.resolve(1),
1046
- Promise.resolve(2),
1047
- Promise.resolve(3),
1048
- ]);
1049
- expect(results).toEqual([1, 2, 3]);
1050
- });
1051
-
1052
- test("T12.03 - Promise.race", async () => {
1053
- const result = await Promise.race([
1054
- Promise.resolve("fast"),
1055
- new Promise((r) => setTimeout(() => r("slow"), 100)),
1056
- ]);
1057
- expect(result).toBe("fast");
1058
- });
1059
-
1060
- test("T12.04 - Async function returning value", async () => {
1061
- const asyncFn = async () => {
1062
- return "async result";
1063
- };
1064
- expect(await asyncFn()).toBe("async result");
1065
- });
1066
-
1067
- test("T12.05 - expect().resolves", async () => {
1068
- const promise = Promise.resolve({ data: "test" });
1069
- await expect(promise).resolves.toEqual({ data: "test" });
1070
- });
1071
-
1072
- test("T12.06 - expect().rejects", async () => {
1073
- const promise = Promise.reject(new Error("rejected"));
1074
- await expect(promise).rejects.toThrow("rejected");
1075
- });
1076
-
1077
- test("T12.07 - Async with timeout", async () => {
1078
- const delayed = () =>
1079
- new Promise((r) => setTimeout(() => r("done"), 10));
1080
- const result = await delayed();
1081
- expect(result).toBe("done");
1082
- });
1083
- });
1084
-
1085
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1086
- // TIER 13: CONDITIONAL TESTS
1087
- // test.if() / test.skipIf()
1088
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1089
-
1090
- describe("Tier 13: Conditional Tests", () => {
1091
- const isMac = process.platform === "darwin";
1092
- const isLinux = process.platform === "linux";
1093
- const isWindows = process.platform === "win32";
1094
- const isBun = typeof Bun !== "undefined";
1095
-
1096
- // ★ test.if() - Run if condition true
1097
- test.if(isBun)("T13.01 - Runs only in Bun", () => {
1098
- expect(Bun.version).toBeDefined();
1099
- });
1100
-
1101
- test.if(isMac)("T13.02 - Runs only on macOS", () => {
1102
- expect(process.platform).toBe("darwin");
1103
- });
1104
-
1105
- // ★ test.skipIf() - Skip if condition true
1106
- test.skipIf(isWindows)("T13.03 - Skip on Windows", () => {
1107
- expect(process.platform).not.toBe("win32");
1108
- });
1109
-
1110
- test.skipIf(!isBun)("T13.04 - Skip if not Bun", () => {
1111
- expect(typeof Bun).toBe("object");
1112
- });
1113
-
1114
- test.if(true)("T13.05 - Always runs (condition true)", () => {
1115
- expect(true).toBe(true);
1116
- });
1117
-
1118
- test.skipIf(false)("T13.06 - Never skips (condition false)", () => {
1119
- expect(true).toBe(true);
1120
- });
1121
- });
1122
-
1123
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1124
- // TIER 14: TODO, SKIP, FAILING
1125
- // Incomplete and expected-to-fail tests
1126
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1127
-
1128
- describe("Tier 14: Todo, Skip, Failing", () => {
1129
- // ★ test.todo() - Future work
1130
- test.todo("T14.01 - TODO: Add YAML multiline support");
1131
- test.todo("T14.02 - TODO: Add watch mode");
1132
- test.todo("T14.03 - TODO: Add JSON output format");
1133
- test.todo("T14.04 - TODO: Add diff command");
1134
-
1135
- // ★ test.skip() - Skip test
1136
- test.skip("T14.05 - SKIP: Platform-specific", () => {
1137
- expect(true).toBe(false);
1138
- });
1139
-
1140
- // ★ test.failing() - Expected to fail
1141
- test.failing("T14.06 - FAILING: This test is expected to fail", () => {
1142
- expect(1).toBe(2); // Intentionally wrong
1143
- });
1144
-
1145
- test.failing("T14.07 - FAILING: Division by zero check", () => {
1146
- expect(1 / 0).toBe(0); // Infinity, not 0
1147
- });
1148
- });
1149
-
1150
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1151
- // TIER 15: STRESS TESTING
1152
- // Push the limits
1153
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1154
-
1155
- describe("Tier 15: Stress Testing", () => {
1156
- test("T15.01 - 1000 assertions in single test", () => {
1157
- for (let i = 0; i < 1000; i++) {
1158
- expect(i).toBeGreaterThanOrEqual(0);
1159
- }
1160
- });
1161
-
1162
- test("T15.02 - Large object comparison", () => {
1163
- const large: Record<string, number> = {};
1164
- for (let i = 0; i < 100; i++) {
1165
- large[`key${i}`] = i;
1166
- }
1167
- expect(Object.keys(large).length).toBe(100);
1168
- });
1169
-
1170
- test("T15.03 - Deep nesting", () => {
1171
- let obj: any = { value: "deep" };
1172
- for (let i = 0; i < 50; i++) {
1173
- obj = { nested: obj };
1174
- }
1175
- let current = obj;
1176
- for (let i = 0; i < 50; i++) {
1177
- current = current.nested;
1178
- }
1179
- expect(current.value).toBe("deep");
1180
- });
1181
-
1182
- test("T15.04 - Rapid mock calls", () => {
1183
- const mockFn = mock(() => 1);
1184
- for (let i = 0; i < 1000; i++) {
1185
- mockFn();
1186
- }
1187
- expect(mockFn).toHaveBeenCalledTimes(1000);
1188
- });
1189
-
1190
- test("T15.05 - String operations", () => {
1191
- let str = "";
1192
- for (let i = 0; i < 1000; i++) {
1193
- str += "a";
1194
- }
1195
- expect(str.length).toBe(1000);
1196
- });
1197
- });
1198
-
1199
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1200
- // TIER 16: EDGE CASES
1201
- // Break it so it never breaks again
1202
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1203
-
1204
- describe("Tier 16: Edge Cases", () => {
1205
- test("T16.01 - Empty string handling", async () => {
1206
- const { hasValue } = await import("../lib/parser.ts");
1207
- expect(hasValue({ v: "" }, "v")).toBe(false);
1208
- });
1209
-
1210
- test("T16.02 - Null handling", async () => {
1211
- const { getNestedValue } = await import("../lib/parser.ts");
1212
- expect(getNestedValue({ a: null }, "a.b")).toBeUndefined();
1213
- });
1214
-
1215
- test("T16.03 - Undefined handling", async () => {
1216
- const { hasValue } = await import("../lib/parser.ts");
1217
- expect(hasValue({}, "missing")).toBe(false);
1218
- });
1219
-
1220
- test("T16.04 - Zero score", async () => {
1221
- const { calculateScore } = await import("../lib/scorer.ts");
1222
- const result = calculateScore({});
1223
- expect(result.score).toBe(0);
1224
- });
1225
-
1226
- test("T16.05 - Unknown type defaults to 9 slots", async () => {
1227
- const { calculateScore } = await import("../lib/scorer.ts");
1228
- const result = calculateScore({ project: { type: "banana" } });
1229
- expect(result.total).toBe(9);
1230
- });
1231
-
1232
- test("T16.06 - Special characters in name", async () => {
1233
- const { parseYaml } = await import("../lib/parser.ts");
1234
- const result = parseYaml("name: test-project_v1.0");
1235
- expect(result.name).toBe("test-project_v1.0");
1236
- });
1237
-
1238
- test("T16.07 - Unicode in values", async () => {
1239
- const { parseYaml } = await import("../lib/parser.ts");
1240
- const result = parseYaml("emoji: 🥐");
1241
- expect(result.emoji).toBe("🥐");
1242
- });
1243
-
1244
- test("T16.08 - Very long value", async () => {
1245
- const { parseYaml } = await import("../lib/parser.ts");
1246
- const longValue = "a".repeat(1000);
1247
- const result = parseYaml(`long: ${longValue}`);
1248
- expect((result.long as string).length).toBe(1000);
1249
- });
1250
- });
1251
-
1252
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1253
- // CHAMPIONSHIP SUMMARY
1254
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1255
-
1256
- describe("Championship Summary", () => {
1257
- test("Print WJTTC Championship Report", () => {
1258
- console.log(`
1259
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1260
- 🥐 BUN STICKY - WJTTC CHAMPIONSHIP TEST SUITE 🥐
1261
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1262
-
1263
- THE BEST BUN TEST SUITE IN THE AI ERA
1264
- "We break it so they never know it was ever broken"
1265
-
1266
- TIER 0: META TESTING - 12 tests (Test the tests)
1267
- TIER 1: Core Parsing - 11 tests (20%)
1268
- TIER 2: Scoring Engine - 15 tests (25%)
1269
- TIER 3: Tier System - 20 tests (15%)
1270
- TIER 4: CLI Commands - 10 tests (15%)
1271
- TIER 5: File Operations - 7 tests (10%)
1272
- TIER 6: Performance - 7 tests (10%)
1273
- TIER 7: WJTTC Championship - 7 tests (5%)
1274
- TIER 8: Mocking & Spying - 9 tests
1275
- TIER 9: Time Mocking - 4 tests
1276
- TIER 10: Extended Matchers - 24 tests (40+ matchers)
1277
- TIER 11: Lifecycle Hooks - 5 tests
1278
- TIER 12: Async & Promise - 7 tests
1279
- TIER 13: Conditional Tests - 6 tests
1280
- TIER 14: Todo, Skip, Failing - 7 tests
1281
- TIER 15: Stress Testing - 5 tests
1282
- TIER 16: Edge Cases - 8 tests
1283
-
1284
- BUN TEST API COVERAGE - NO SHORTCUTS:
1285
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1286
- ✓ test() / describe()
1287
- ✓ test.each() / describe.each()
1288
- ✓ test.concurrent()
1289
- ✓ test.todo() / test.skip()
1290
- ✓ test.if() / test.skipIf()
1291
- ✓ test.failing()
1292
- ✓ beforeAll() / afterAll()
1293
- ✓ beforeEach() / afterEach()
1294
- ✓ mock() / spyOn()
1295
- ✓ mockImplementation() / mockReturnValue() / mockClear()
1296
- ✓ setSystemTime()
1297
- ✓ expect.assertions() / expect.hasAssertions()
1298
- ✓ expect.extend() - Custom matchers
1299
- ✓ toMatchSnapshot()
1300
- ✓ All 40+ matchers
1301
- ✓ .resolves / .rejects
1302
- ✓ .not modifier
1303
-
1304
- CUSTOM MATCHERS:
1305
- ━━━━━━━━━━━━━━━━━
1306
- ✓ toBeValidScore()
1307
- ✓ toBeValidTier()
1308
- ✓ toHaveSlotCount()
1309
-
1310
- TOTAL: 164 tests (4 todo, 1 skip, 2 failing)
1311
-
1312
- Wolfejam slot-based scoring.
1313
- Fastest bun under the sum.
1314
- Zero dependencies. Pure Bun.
1315
- FULL BUN + WJTTC = BEST IN AI ERA.
1316
- NO COMPROMISE.
1317
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1318
- `);
1319
- expect(true).toBe(true);
1320
- });
1321
- });