@techstream/quark-core 1.2.0 → 1.4.0

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,1376 +0,0 @@
1
-
2
- > @techstream/quark-core@1.1.0 test /Users/david/Projects/quark/packages/core
3
- > node --test $(find src -name '*.test.js')
4
-
5
- TAP version 13
6
- # Subtest: Auth Module
7
- # Subtest: createAuthConfig returns valid config
8
- ok 1 - createAuthConfig returns valid config
9
- ---
10
- duration_ms: 0.58
11
- ...
12
- # Subtest: createAuthConfig throws when secret is missing
13
- ok 2 - createAuthConfig throws when secret is missing
14
- ---
15
- duration_ms: 0.200583
16
- ...
17
- # Subtest: createAuthConfig with custom options
18
- ok 3 - createAuthConfig with custom options
19
- ---
20
- duration_ms: 2.045958
21
- ...
22
- # Subtest: isAuthenticated returns true for valid session
23
- ok 4 - isAuthenticated returns true for valid session
24
- ---
25
- duration_ms: 0.199166
26
- ...
27
- # Subtest: isAuthenticated returns false for invalid session
28
- ok 5 - isAuthenticated returns false for invalid session
29
- ---
30
- duration_ms: 0.134083
31
- ...
32
- # Subtest: getUserId extracts user ID
33
- ok 6 - getUserId extracts user ID
34
- ---
35
- duration_ms: 0.248875
36
- ...
37
- # Subtest: getUserId returns null when missing
38
- ok 7 - getUserId returns null when missing
39
- ---
40
- duration_ms: 0.105833
41
- ...
42
- # Subtest: getUserEmail extracts user email
43
- ok 8 - getUserEmail extracts user email
44
- ---
45
- duration_ms: 0.249333
46
- ...
47
- # Subtest: getUserEmail returns null when missing
48
- ok 9 - getUserEmail returns null when missing
49
- ---
50
- duration_ms: 0.347875
51
- ...
52
- # Subtest: requireAuth returns user ID for authenticated session
53
- ok 10 - requireAuth returns user ID for authenticated session
54
- ---
55
- duration_ms: 0.399833
56
- ...
57
- # Subtest: requireAuth throws error for unauthenticated session
58
- ok 11 - requireAuth throws error for unauthenticated session
59
- ---
60
- duration_ms: 3.111042
61
- ...
62
- 1..11
63
- ok 1 - Auth Module
64
- ---
65
- duration_ms: 15.232709
66
- ...
67
- # Subtest: authorization
68
- # Subtest: can()
69
- # Subtest: returns true for admin with wildcard permissions
70
- ok 1 - returns true for admin with wildcard permissions
71
- ---
72
- duration_ms: 0.507625
73
- ...
74
- # Subtest: returns true for editor with post actions
75
- ok 2 - returns true for editor with post actions
76
- ---
77
- duration_ms: 1.255542
78
- ...
79
- # Subtest: returns true for editor reading users
80
- ok 3 - returns true for editor reading users
81
- ---
82
- duration_ms: 0.320166
83
- ...
84
- # Subtest: returns false for editor trying to delete users
85
- ok 4 - returns false for editor trying to delete users
86
- ---
87
- duration_ms: 0.549416
88
- ...
89
- # Subtest: returns false for viewer trying to write
90
- ok 5 - returns false for viewer trying to write
91
- ---
92
- duration_ms: 1.045167
93
- ...
94
- # Subtest: returns true for viewer reading posts and users
95
- ok 6 - returns true for viewer reading posts and users
96
- ---
97
- duration_ms: 0.359541
98
- ...
99
- # Subtest: owner can update their own resource
100
- ok 7 - owner can update their own resource
101
- ---
102
- duration_ms: 0.295208
103
- ...
104
- # Subtest: owner can delete their own resource
105
- ok 8 - owner can delete their own resource
106
- ---
107
- duration_ms: 0.181833
108
- ...
109
- # Subtest: non-owner cannot update another user's resource
110
- ok 9 - non-owner cannot update another user's resource
111
- ---
112
- duration_ms: 0.412
113
- ...
114
- # Subtest: ownership does not apply for non-owner actions
115
- ok 10 - ownership does not apply for non-owner actions
116
- ---
117
- duration_ms: 0.588875
118
- ...
119
- # Subtest: applies defaultRole when user has no role
120
- ok 11 - applies defaultRole when user has no role
121
- ---
122
- duration_ms: 0.178208
123
- ...
124
- 1..11
125
- ok 1 - can()
126
- ---
127
- duration_ms: 6.784042
128
- type: 'suite'
129
- ...
130
- # Subtest: authorize()
131
- # Subtest: throws ForbiddenError when denied
132
- ok 1 - throws ForbiddenError when denied
133
- ---
134
- duration_ms: 2.188333
135
- ...
136
- # Subtest: does not throw when allowed
137
- ok 2 - does not throw when allowed
138
- ---
139
- duration_ms: 0.476291
140
- ...
141
- # Subtest: includes user and action information in error message
142
- ok 3 - includes user and action information in error message
143
- ---
144
- duration_ms: 0.675292
145
- ...
146
- 1..3
147
- ok 2 - authorize()
148
- ---
149
- duration_ms: 3.576584
150
- type: 'suite'
151
- ...
152
- # Subtest: hasPermission()
153
- # Subtest: returns true for exact match
154
- ok 1 - returns true for exact match
155
- ---
156
- duration_ms: 0.232167
157
- ...
158
- # Subtest: returns false for no match
159
- ok 2 - returns false for no match
160
- ---
161
- duration_ms: 0.140833
162
- ...
163
- # Subtest: returns true with resource wildcard
164
- ok 3 - returns true with resource wildcard
165
- ---
166
- duration_ms: 0.497041
167
- ...
168
- # Subtest: returns true with action wildcard
169
- ok 4 - returns true with action wildcard
170
- ---
171
- duration_ms: 0.062375
172
- ...
173
- # Subtest: returns false for unknown role
174
- ok 5 - returns false for unknown role
175
- ---
176
- duration_ms: 0.054
177
- ...
178
- 1..5
179
- ok 3 - hasPermission()
180
- ---
181
- duration_ms: 1.097583
182
- type: 'suite'
183
- ...
184
- # Subtest: getRolePermissions()
185
- # Subtest: returns permissions for a valid role
186
- ok 1 - returns permissions for a valid role
187
- ---
188
- duration_ms: 0.2155
189
- ...
190
- # Subtest: returns empty array for unknown role
191
- ok 2 - returns empty array for unknown role
192
- ---
193
- duration_ms: 0.054833
194
- ...
195
- 1..2
196
- ok 4 - getRolePermissions()
197
- ---
198
- duration_ms: 0.312042
199
- type: 'suite'
200
- ...
201
- # Subtest: addRole() and removeRole()
202
- # Subtest: addRole() makes new role available
203
- ok 1 - addRole() makes new role available
204
- ---
205
- duration_ms: 0.086542
206
- ...
207
- # Subtest: removeRole() removes a role
208
- ok 2 - removeRole() removes a role
209
- ---
210
- duration_ms: 0.186833
211
- ...
212
- 1..2
213
- ok 5 - addRole() and removeRole()
214
- ---
215
- duration_ms: 0.305125
216
- type: 'suite'
217
- ...
218
- # Subtest: extendPolicy()
219
- # Subtest: merges new roles into existing policy
220
- ok 1 - merges new roles into existing policy
221
- ---
222
- duration_ms: 0.107375
223
- ...
224
- # Subtest: preserves existing roles when extending
225
- ok 2 - preserves existing roles when extending
226
- ---
227
- duration_ms: 0.060708
228
- ...
229
- # Subtest: can override defaultRole
230
- ok 3 - can override defaultRole
231
- ---
232
- duration_ms: 0.05475
233
- ...
234
- 1..3
235
- ok 6 - extendPolicy()
236
- ---
237
- duration_ms: 0.260583
238
- type: 'suite'
239
- ...
240
- # Subtest: requireRole()
241
- # Subtest: does not throw when session user has an allowed role
242
- ok 1 - does not throw when session user has an allowed role
243
- ---
244
- duration_ms: 0.319125
245
- ...
246
- # Subtest: throws ForbiddenError when session user role is not allowed
247
- ok 2 - throws ForbiddenError when session user role is not allowed
248
- ---
249
- duration_ms: 0.166958
250
- ...
251
- # Subtest: throws ForbiddenError when session has no role
252
- ok 3 - throws ForbiddenError when session has no role
253
- ---
254
- duration_ms: 0.078583
255
- ...
256
- # Subtest: throws ForbiddenError when session has no user
257
- ok 4 - throws ForbiddenError when session has no user
258
- ---
259
- duration_ms: 0.070334
260
- ...
261
- 1..4
262
- ok 7 - requireRole()
263
- ---
264
- duration_ms: 0.788084
265
- type: 'suite'
266
- ...
267
- # Subtest: withAuthorization()
268
- # Subtest: calls handler when authorized
269
- ok 1 - calls handler when authorized
270
- ---
271
- duration_ms: 0.142541
272
- ...
273
- # Subtest: throws ForbiddenError when not authorized
274
- ok 2 - throws ForbiddenError when not authorized
275
- ---
276
- duration_ms: 0.142833
277
- ...
278
- # Subtest: throws ForbiddenError when no user in session
279
- ok 3 - throws ForbiddenError when no user in session
280
- ---
281
- duration_ms: 0.081917
282
- ...
283
- # Subtest: passes context from getContext to authorization
284
- ok 4 - passes context from getContext to authorization
285
- ---
286
- duration_ms: 0.150084
287
- ...
288
- 1..4
289
- ok 8 - withAuthorization()
290
- ---
291
- duration_ms: 0.572833
292
- type: 'suite'
293
- ...
294
- # Subtest: default instance
295
- # Subtest: exports a working default authorization instance
296
- ok 1 - exports a working default authorization instance
297
- ---
298
- duration_ms: 0.088083
299
- ...
300
- 1..1
301
- ok 9 - default instance
302
- ---
303
- duration_ms: 0.122041
304
- type: 'suite'
305
- ...
306
- # Subtest: defaultPolicy
307
- # Subtest: is exported and has expected structure
308
- ok 1 - is exported and has expected structure
309
- ---
310
- duration_ms: 0.125
311
- ...
312
- 1..1
313
- ok 10 - defaultPolicy
314
- ---
315
- duration_ms: 0.157417
316
- type: 'suite'
317
- ...
318
- 1..10
319
- ok 2 - authorization
320
- ---
321
- duration_ms: 14.719875
322
- type: 'suite'
323
- ...
324
- # Subtest: createCache
325
- # Subtest: get
326
- # Subtest: returns null for a missing key
327
- ok 1 - returns null for a missing key
328
- ---
329
- duration_ms: 1.125792
330
- ...
331
- # Subtest: returns parsed JSON for an existing key
332
- ok 2 - returns parsed JSON for an existing key
333
- ---
334
- duration_ms: 0.845167
335
- ...
336
- # Subtest: returns null for invalid JSON
337
- ok 3 - returns null for invalid JSON
338
- ---
339
- duration_ms: 0.209209
340
- ...
341
- 1..3
342
- ok 1 - get
343
- ---
344
- duration_ms: 2.914666
345
- type: 'suite'
346
- ...
347
- # Subtest: set
348
- # Subtest: round-trips JSON values through set/get
349
- ok 1 - round-trips JSON values through set/get
350
- ---
351
- duration_ms: 0.302791
352
- ...
353
- # Subtest: passes TTL to Redis expire
354
- ok 2 - passes TTL to Redis expire
355
- ---
356
- duration_ms: 0.200375
357
- ...
358
- # Subtest: uses defaultTTL when no TTL is provided
359
- ok 3 - uses defaultTTL when no TTL is provided
360
- ---
361
- duration_ms: 0.084875
362
- ...
363
- 1..3
364
- ok 2 - set
365
- ---
366
- duration_ms: 0.813333
367
- type: 'suite'
368
- ...
369
- # Subtest: del
370
- # Subtest: removes a key
371
- ok 1 - removes a key
372
- ---
373
- duration_ms: 0.093417
374
- ...
375
- 1..1
376
- ok 3 - del
377
- ---
378
- duration_ms: 0.13925
379
- type: 'suite'
380
- ...
381
- # Subtest: invalidate
382
- # Subtest: deletes all keys matching a pattern
383
- ok 1 - deletes all keys matching a pattern
384
- ---
385
- duration_ms: 3.474292
386
- ...
387
- # Subtest: does nothing when no keys match
388
- ok 2 - does nothing when no keys match
389
- ---
390
- duration_ms: 0.539709
391
- ...
392
- 1..2
393
- ok 4 - invalidate
394
- ---
395
- duration_ms: 4.152541
396
- type: 'suite'
397
- ...
398
- # Subtest: getOrSet
399
- # Subtest: calls factory on cache miss and caches the result
400
- ok 1 - calls factory on cache miss and caches the result
401
- ---
402
- duration_ms: 0.363167
403
- ...
404
- # Subtest: returns cached value without calling factory on hit
405
- ok 2 - returns cached value without calling factory on hit
406
- ---
407
- duration_ms: 0.356667
408
- ...
409
- 1..2
410
- ok 5 - getOrSet
411
- ---
412
- duration_ms: 0.81975
413
- type: 'suite'
414
- ...
415
- # Subtest: wrap
416
- # Subtest: creates a cached function
417
- ok 1 - creates a cached function
418
- ---
419
- duration_ms: 0.337709
420
- ...
421
- # Subtest: uses keyGenerator when provided
422
- ok 2 - uses keyGenerator when provided
423
- ---
424
- duration_ms: 0.310917
425
- ...
426
- # Subtest: caches different args separately
427
- ok 3 - caches different args separately
428
- ---
429
- duration_ms: 0.256291
430
- ...
431
- 1..3
432
- ok 6 - wrap
433
- ---
434
- duration_ms: 1.0145
435
- type: 'suite'
436
- ...
437
- 1..6
438
- ok 3 - createCache
439
- ---
440
- duration_ms: 10.707208
441
- type: 'suite'
442
- ...
443
- # Subtest: CSRF Module
444
- # Subtest: generateCsrfToken creates a secure token
445
- ok 1 - generateCsrfToken creates a secure token
446
- ---
447
- duration_ms: 1.233625
448
- ...
449
- # Subtest: validateCsrfToken accepts valid token
450
- ok 2 - validateCsrfToken accepts valid token
451
- ---
452
- duration_ms: 0.407167
453
- ...
454
- # Subtest: validateCsrfToken rejects missing header token
455
- ok 3 - validateCsrfToken rejects missing header token
456
- ---
457
- duration_ms: 8.670167
458
- ...
459
- # Subtest: validateCsrfToken rejects missing session token
460
- ok 4 - validateCsrfToken rejects missing session token
461
- ---
462
- duration_ms: 0.176042
463
- ...
464
- # Subtest: validateCsrfToken rejects mismatched tokens
465
- ok 5 - validateCsrfToken rejects mismatched tokens
466
- ---
467
- duration_ms: 0.137083
468
- ...
469
- # Subtest: validateCsrfToken rejects tokens of different lengths
470
- ok 6 - validateCsrfToken rejects tokens of different lengths
471
- ---
472
- duration_ms: 0.123417
473
- ...
474
- # Subtest: requireCsrfToken skips GET requests
475
- ok 7 - requireCsrfToken skips GET requests
476
- ---
477
- duration_ms: 0.086667
478
- ...
479
- # Subtest: requireCsrfToken skips NextAuth routes
480
- ok 8 - requireCsrfToken skips NextAuth routes
481
- ---
482
- duration_ms: 0.18725
483
- ...
484
- # Subtest: requireCsrfToken validates POST with cookie token
485
- ok 9 - requireCsrfToken validates POST with cookie token
486
- ---
487
- duration_ms: 0.262916
488
- ...
489
- # Subtest: requireCsrfToken throws when cookie is missing
490
- ok 10 - requireCsrfToken throws when cookie is missing
491
- ---
492
- duration_ms: 0.54325
493
- ...
494
- # Subtest: withCsrfProtection wraps handler
495
- ok 11 - withCsrfProtection wraps handler
496
- ---
497
- duration_ms: 1.465666
498
- ...
499
- 1..11
500
- ok 4 - CSRF Module
501
- ---
502
- duration_ms: 15.138958
503
- ...
504
- # Subtest: Email Service
505
- # Subtest: createEmailService returns object with sendEmail method
506
- ok 1 - createEmailService returns object with sendEmail method
507
- ---
508
- duration_ms: 0.379625
509
- ...
510
- # Subtest: SMTP provider: uses Mailhog defaults when no SMTP_HOST set
511
- ok 2 - SMTP provider: uses Mailhog defaults when no SMTP_HOST set
512
- ---
513
- duration_ms: 0.0815
514
- ...
515
- # Subtest: SMTP provider: uses explicit SMTP_HOST/SMTP_PORT when set
516
- ok 3 - SMTP provider: uses explicit SMTP_HOST/SMTP_PORT when set
517
- ---
518
- duration_ms: 0.065
519
- ...
520
- # Subtest: Resend provider: throws if RESEND_API_KEY missing
521
- ok 4 - Resend provider: throws if RESEND_API_KEY missing
522
- ---
523
- duration_ms: 0.402167
524
- ...
525
- # Subtest: Resend provider: calls fetch with correct URL, headers, and body
526
- ok 5 - Resend provider: calls fetch with correct URL, headers, and body
527
- ---
528
- duration_ms: 0.6785
529
- ...
530
- # Subtest: Resend provider: throws on non-ok response
531
- ok 6 - Resend provider: throws on non-ok response
532
- ---
533
- duration_ms: 0.210583
534
- ...
535
- # Subtest: Resend provider: handles non-JSON error response
536
- ok 7 - Resend provider: handles non-JSON error response
537
- ---
538
- duration_ms: 0.138333
539
- ...
540
- # Subtest: default provider is smtp
541
- ok 8 - default provider is smtp
542
- ---
543
- duration_ms: 0.19125
544
- ...
545
- # Subtest: respects options.from override
546
- ok 9 - respects options.from override
547
- ---
548
- duration_ms: 0.25675
549
- ...
550
- # Subtest: input validation: rejects empty 'to'
551
- ok 10 - input validation: rejects empty 'to'
552
- ---
553
- duration_ms: 0.1935
554
- ...
555
- # Subtest: input validation: rejects empty 'subject'
556
- ok 11 - input validation: rejects empty 'subject'
557
- ---
558
- duration_ms: 0.838042
559
- ...
560
- # Subtest: input validation: rejects empty 'html'
561
- ok 12 - input validation: rejects empty 'html'
562
- ---
563
- duration_ms: 0.102958
564
- ...
565
- 1..12
566
- ok 5 - Email Service
567
- ---
568
- duration_ms: 7.765042
569
- ...
570
- # 08:02:47.492 ERROR [quark] test error {"error":{"name":"AppError","message":"test error","code":"INTERNAL_ERROR","statusCode":500,"timestamp":"2026-02-15T08:02:47.489Z"},"context":{"requestId":"123","breadcrumbs":[]},"stack":"Error: test error\\n at TestContext.<anonymous> (file:///Users/david/Projects/quark/packages/core/src/error-reporter.test.js:61:18)\\n at Test.runInAsyncScope (node:async_hooks:211:14)\\n at Test.run (node:internal/test_runner/test:979:25)\\n at async Promise.all (index 0)\\n at async Suite.run (node:internal/test_runner/test:1358:7)\\n at async Suite.processPendingSubtests (node:internal/test_runner/test:677:7)"}
571
- # 08:02:47.494 ERROR [quark] test {"error":{"name":"AppError","message":"test","code":"INTERNAL_ERROR","statusCode":500,"timestamp":"2026-02-15T08:02:47.494Z"},"context":{"breadcrumbs":[]},"stack":"Error: test\\n at file:///Users/david/Projects/quark/packages/core/src/error-reporter.test.js:81:46\\n at getActual (node:assert:840:5)\\n at Function.doesNotThrow (node:assert:1006:32)\\n at TestContext.<anonymous> (file:///Users/david/Projects/quark/packages/core/src/error-reporter.test.js:81:11)\\n at Test.runInAsyncScope (node:async_hooks:211:14)\\n at Test.run (node:internal/test_runner/test:979:25)\\n at async Suite.processPendingSubtests (node:internal/test_runner/test:677:7)"}
572
- # 08:02:47.494 WARN  [quark] hello {"extra":true}
573
- # 08:02:47.494 ERROR [quark] test {"error":{"name":"AppError","message":"test","code":"INTERNAL_ERROR","statusCode":500,"timestamp":"2026-02-15T08:02:47.494Z"},"context":{"user":{"id":"u1","email":"a@b.com"},"breadcrumbs":[]},"stack":"Error: test\\n at TestContext.<anonymous> (file:///Users/david/Projects/quark/packages/core/src/error-reporter.test.js:121:20)\\n at Test.runInAsyncScope (node:async_hooks:211:14)\\n at Test.run (node:internal/test_runner/test:979:25)\\n at async Promise.all (index 0)\\n at async Suite.run (node:internal/test_runner/test:1358:7)\\n at async Suite.processPendingSubtests (node:internal/test_runner/test:677:7)"}
574
- # 08:02:47.495 ERROR [quark] test {"error":{"name":"AppError","message":"test","code":"INTERNAL_ERROR","statusCode":500,"timestamp":"2026-02-15T08:02:47.495Z"},"context":{"breadcrumbs":[{"message":"clicked button","category":"ui","data":{"buttonId":"submit"},"timestamp":"2026-02-15T08:02:47.495Z"},{"message":"navigated","category":"navigation","data":{},"timestamp":"2026-02-15T08:02:47.495Z"}]},"stack":"Error: test\\n at TestContext.<anonymous> (file:///Users/david/Projects/quark/packages/core/src/error-reporter.test.js:154:20)\\n at Test.runInAsyncScope (node:async_hooks:211:14)\\n at Test.run (node:internal/test_runner/test:979:25)\\n at async Promise.all (index 0)\\n at async Suite.run (node:internal/test_runner/test:1358:7)\\n at async Suite.processPendingSubtests (node:internal/test_runner/test:677:7)"}
575
- # 08:02:47.494 INFO  [quark] hello
576
- # 08:02:47.496 ERROR [quark] custom test {"error":{"name":"AppError","message":"custom test","code":"INTERNAL_ERROR","statusCode":500,"timestamp":"2026-02-15T08:02:47.496Z"},"context":{"route":"/api/test","user":{"id":"u1"},"breadcrumbs":[{"message":"init","category":"app","data":{},"timestamp":"2026-02-15T08:02:47.496Z"}]},"stack":"Error: custom test\\n at TestContext.<anonymous> (file:///Users/david/Projects/quark/packages/core/src/error-reporter.test.js:208:18)\\n at Test.runInAsyncScope (node:async_hooks:211:14)\\n at Test.run (node:internal/test_runner/test:979:25)\\n at async Promise.all (index 0)\\n at async Suite.run (node:internal/test_runner/test:1358:7)\\n at async Suite.processPendingSubtests (node:internal/test_runner/test:677:7)"}
577
- # 08:02:47.497 ERROR [quark] test {"error":{"name":"AppError","message":"test","code":"INTERNAL_ERROR","statusCode":500,"timestamp":"2026-02-15T08:02:47.497Z"},"context":{"breadcrumbs":[]},"stack":"Error: test\\n at file:///Users/david/Projects/quark/packages/core/src/error-reporter.test.js:233:46\\n at getActual (node:assert:840:5)\\n at Function.doesNotThrow (node:assert:1006:32)\\n at TestContext.<anonymous> (file:///Users/david/Projects/quark/packages/core/src/error-reporter.test.js:233:11)\\n at Test.runInAsyncScope (node:async_hooks:211:14)\\n at Test.run (node:internal/test_runner/test:979:25)\\n at async Suite.processPendingSubtests (node:internal/test_runner/test:677:7)"}
578
- # Subtest: ErrorReporter
579
- # Subtest: default instance
580
- # Subtest: has console adapter registered by default
581
- ok 1 - has console adapter registered by default
582
- ---
583
- duration_ms: 0.591958
584
- ...
585
- # Subtest: global singleton has console adapter
586
- ok 2 - global singleton has console adapter
587
- ---
588
- duration_ms: 0.124
589
- ...
590
- 1..2
591
- ok 1 - default instance
592
- ---
593
- duration_ms: 1.015125
594
- type: 'suite'
595
- ...
596
- # Subtest: use()
597
- # Subtest: adds an adapter
598
- ok 1 - adds an adapter
599
- ---
600
- duration_ms: 0.258292
601
- ...
602
- # Subtest: throws if adapter has no name
603
- ok 2 - throws if adapter has no name
604
- ---
605
- duration_ms: 0.373667
606
- ...
607
- # Subtest: throws if adapter has no report function
608
- ok 3 - throws if adapter has no report function
609
- ---
610
- duration_ms: 0.227333
611
- ...
612
- 1..3
613
- ok 2 - use()
614
- ---
615
- duration_ms: 2.241208
616
- type: 'suite'
617
- ...
618
- # Subtest: report()
619
- # Subtest: calls all registered adapters
620
- ok 1 - calls all registered adapters
621
- ---
622
- duration_ms: 4.431458
623
- ...
624
- # Subtest: swallows adapter errors without throwing
625
- ok 2 - swallows adapter errors without throwing
626
- ---
627
- duration_ms: 0.367625
628
- ...
629
- 1..2
630
- ok 3 - report()
631
- ---
632
- duration_ms: 5.000792
633
- type: 'suite'
634
- ...
635
- # Subtest: captureMessage()
636
- # Subtest: calls adapters that support captureMessage
637
- ok 1 - calls adapters that support captureMessage
638
- ---
639
- duration_ms: 0.17075
640
- ...
641
- # Subtest: skips adapters without captureMessage
642
- ok 2 - skips adapters without captureMessage
643
- ---
644
- duration_ms: 0.205916
645
- ...
646
- 1..2
647
- ok 4 - captureMessage()
648
- ---
649
- duration_ms: 0.430625
650
- type: 'suite'
651
- ...
652
- # Subtest: setUser()
653
- # Subtest: includes user in subsequent reports
654
- ok 1 - includes user in subsequent reports
655
- ---
656
- duration_ms: 0.4615
657
- ...
658
- # Subtest: forwards user to adapters with setUser
659
- ok 2 - forwards user to adapters with setUser
660
- ---
661
- duration_ms: 0.082208
662
- ...
663
- 1..2
664
- ok 5 - setUser()
665
- ---
666
- duration_ms: 0.584167
667
- type: 'suite'
668
- ...
669
- # Subtest: addBreadcrumb()
670
- # Subtest: stores breadcrumbs and attaches them to report context
671
- ok 1 - stores breadcrumbs and attaches them to report context
672
- ---
673
- duration_ms: 0.226708
674
- ...
675
- # Subtest: circular buffer keeps max 50 breadcrumbs
676
- ok 2 - circular buffer keeps max 50 breadcrumbs
677
- ---
678
- duration_ms: 0.238708
679
- ...
680
- # Subtest: forwards breadcrumbs to adapters that support it
681
- ok 3 - forwards breadcrumbs to adapters that support it
682
- ---
683
- duration_ms: 0.301125
684
- ...
685
- 1..3
686
- ok 6 - addBreadcrumb()
687
- ---
688
- duration_ms: 0.876333
689
- type: 'suite'
690
- ...
691
- # Subtest: custom adapter receives correct data
692
- # Subtest: passes error and enriched context
693
- ok 1 - passes error and enriched context
694
- ---
695
- duration_ms: 0.17775
696
- ...
697
- 1..1
698
- ok 7 - custom adapter receives correct data
699
- ---
700
- duration_ms: 0.318208
701
- type: 'suite'
702
- ...
703
- # Subtest: createSentryAdapter()
704
- # Subtest: returns a valid adapter shape
705
- ok 1 - returns a valid adapter shape
706
- ---
707
- duration_ms: 0.711667
708
- ...
709
- # Subtest: can be registered without errors
710
- ok 2 - can be registered without errors
711
- ---
712
- duration_ms: 0.449166
713
- ...
714
- 1..2
715
- ok 8 - createSentryAdapter()
716
- ---
717
- duration_ms: 1.244333
718
- type: 'suite'
719
- ...
720
- 1..8
721
- ok 6 - ErrorReporter
722
- ---
723
- duration_ms: 12.297875
724
- type: 'suite'
725
- ...
726
- # 08:02:47.506 ERROR [quark] test {"error":{"name":"ValidationError","message":"test","code":"VALIDATION_ERROR","statusCode":400,"timestamp":"2026-02-15T08:02:47.503Z","details":null},"context":{"userId":"123","action":"test","breadcrumbs":[]},"stack":"ValidationError: test\\n at TestContext.<anonymous> (file:///Users/david/Projects/quark/packages/core/src/errors.test.js:124:17)\\n at Test.runInAsyncScope (node:async_hooks:211:14)\\n at Test.run (node:internal/test_runner/test:979:25)\\n at Test.start (node:internal/test_runner/test:877:17)\\n at TestContext.test (node:internal/test_runner/test:307:20)\\n at TestContext.<anonymous> (file:///Users/david/Projects/quark/packages/core/src/errors.test.js:122:10)\\n at async Test.run (node:internal/test_runner/test:980:9)\\n at async startSubtestAfterBootstrap (node:internal/test_runner/harness:296:3)"}
727
- # Subtest: Error Module
728
- # Subtest: AppError has correct properties
729
- ok 1 - AppError has correct properties
730
- ---
731
- duration_ms: 4.095334
732
- ...
733
- # Subtest: AppError.toJSON() serializes correctly
734
- ok 2 - AppError.toJSON() serializes correctly
735
- ---
736
- duration_ms: 0.205333
737
- ...
738
- # Subtest: ValidationError has status 400
739
- ok 3 - ValidationError has status 400
740
- ---
741
- duration_ms: 0.168375
742
- ...
743
- # Subtest: UnauthorizedError has status 401
744
- ok 4 - UnauthorizedError has status 401
745
- ---
746
- duration_ms: 0.631375
747
- ...
748
- # Subtest: ForbiddenError has status 403
749
- ok 5 - ForbiddenError has status 403
750
- ---
751
- duration_ms: 0.157625
752
- ...
753
- # Subtest: NotFoundError has status 404
754
- ok 6 - NotFoundError has status 404
755
- ---
756
- duration_ms: 0.268083
757
- ...
758
- # Subtest: ConflictError has status 409
759
- ok 7 - ConflictError has status 409
760
- ---
761
- duration_ms: 0.159625
762
- ...
763
- # Subtest: RateLimitError has status 429
764
- ok 8 - RateLimitError has status 429
765
- ---
766
- duration_ms: 0.430542
767
- ...
768
- # Subtest: DatabaseError wraps database errors
769
- ok 9 - DatabaseError wraps database errors
770
- ---
771
- duration_ms: 0.4655
772
- ...
773
- # Subtest: ServiceError includes service name
774
- ok 10 - ServiceError includes service name
775
- ---
776
- duration_ms: 0.348833
777
- ...
778
- # Subtest: getErrorMessage extracts from various types
779
- ok 11 - getErrorMessage extracts from various types
780
- ---
781
- duration_ms: 0.144458
782
- ...
783
- # Subtest: getStatusCode returns correct code
784
- ok 12 - getStatusCode returns correct code
785
- ---
786
- duration_ms: 0.23025
787
- ...
788
- # Subtest: normalizeError converts to AppError
789
- ok 13 - normalizeError converts to AppError
790
- ---
791
- duration_ms: 0.082208
792
- ...
793
- # Subtest: normalizeError handles string errors
794
- ok 14 - normalizeError handles string errors
795
- ---
796
- duration_ms: 0.046042
797
- ...
798
- # Subtest: normalizeError handles non-Error objects
799
- ok 15 - normalizeError handles non-Error objects
800
- ---
801
- duration_ms: 0.045125
802
- ...
803
- # Subtest: logError handles errors with context
804
- ok 16 - logError handles errors with context
805
- ---
806
- duration_ms: 3.53825
807
- ...
808
- 1..16
809
- ok 7 - Error Module
810
- ---
811
- duration_ms: 13.927375
812
- ...
813
- # Subtest: Logger
814
- # Subtest: creates logger with default options
815
- ok 1 - creates logger with default options
816
- ---
817
- duration_ms: 3.107167
818
- ...
819
- # Subtest: default logger instance exists with name 'quark'
820
- ok 2 - default logger instance exists with name 'quark'
821
- ---
822
- duration_ms: 1.476708
823
- ...
824
- # Subtest: log level filtering: debug hidden at info level
825
- ok 3 - log level filtering: debug hidden at info level
826
- ---
827
- duration_ms: 0.350166
828
- ...
829
- # Subtest: log level filtering: debug visible at debug level
830
- ok 4 - log level filtering: debug visible at debug level
831
- ---
832
- duration_ms: 0.33625
833
- ...
834
- # Subtest: respects LOG_LEVEL env var
835
- ok 5 - respects LOG_LEVEL env var
836
- ---
837
- duration_ms: 0.1785
838
- ...
839
- # Subtest: child logger inherits parent context
840
- ok 6 - child logger inherits parent context
841
- ---
842
- duration_ms: 0.127458
843
- ...
844
- # Subtest: child logger merges context without mutating parent
845
- ok 7 - child logger merges context without mutating parent
846
- ---
847
- duration_ms: 0.166583
848
- ...
849
- # Subtest: structured output contains required fields
850
- ok 8 - structured output contains required fields
851
- ---
852
- duration_ms: 0.10825
853
- ...
854
- # Subtest: error and fatal use console.error
855
- ok 9 - error and fatal use console.error
856
- ---
857
- duration_ms: 1.137416
858
- ...
859
- # Subtest: warn uses console.warn
860
- ok 10 - warn uses console.warn
861
- ---
862
- duration_ms: 0.628625
863
- ...
864
- # Subtest: dev mode outputs colorized non-JSON string
865
- ok 11 - dev mode outputs colorized non-JSON string
866
- ---
867
- duration_ms: 0.511041
868
- ...
869
- # Subtest: call-site data overrides default context
870
- ok 12 - call-site data overrides default context
871
- ---
872
- duration_ms: 0.255792
873
- ...
874
- 1..12
875
- ok 8 - Logger
876
- ---
877
- duration_ms: 9.611084
878
- type: 'suite'
879
- ...
880
- # Subtest: requestLogger
881
- # Subtest: creates child logger with request fields
882
- ok 1 - creates child logger with request fields
883
- ---
884
- duration_ms: 0.38825
885
- ...
886
- # Subtest: generates requestId when header is missing
887
- ok 2 - generates requestId when header is missing
888
- ---
889
- duration_ms: 1.539459
890
- ...
891
- 1..2
892
- ok 9 - requestLogger
893
- ---
894
- duration_ms: 2.011083
895
- type: 'suite'
896
- ...
897
- # Subtest: Rate Limiter Module
898
- # Subtest: createRateLimiter creates memory limiter by default
899
- ok 1 - createRateLimiter creates memory limiter by default
900
- ---
901
- duration_ms: 0.345625
902
- ...
903
- # Subtest: createRateLimiter throws error for Redis without client
904
- ok 2 - createRateLimiter throws error for Redis without client
905
- ---
906
- duration_ms: 0.183167
907
- ...
908
- # Subtest: Memory rate limiter allows requests under limit
909
- ok 3 - Memory rate limiter allows requests under limit
910
- ---
911
- duration_ms: 0.153167
912
- ...
913
- # Subtest: Memory rate limiter blocks requests over limit
914
- ok 4 - Memory rate limiter blocks requests over limit
915
- ---
916
- duration_ms: 0.710458
917
- ...
918
- # Subtest: Memory rate limiter resets after window
919
- ok 5 - Memory rate limiter resets after window
920
- ---
921
- duration_ms: 21.516667
922
- ...
923
- # Subtest: Memory rate limiter can reset a key
924
- ok 6 - Memory rate limiter can reset a key
925
- ---
926
- duration_ms: 0.142125
927
- ...
928
- # Subtest: Memory rate limiter can clear all keys
929
- ok 7 - Memory rate limiter can clear all keys
930
- ---
931
- duration_ms: 0.093292
932
- ...
933
- # Subtest: RATE_LIMIT_PRESETS have correct structure
934
- ok 8 - RATE_LIMIT_PRESETS have correct structure
935
- ---
936
- duration_ms: 0.14525
937
- ...
938
- # Subtest: createRateLimitMiddleware returns a function
939
- ok 9 - createRateLimitMiddleware returns a function
940
- ---
941
- duration_ms: 0.224208
942
- ...
943
- # Subtest: createRateLimitMiddleware works with API preset
944
- ok 10 - createRateLimitMiddleware works with API preset
945
- ---
946
- duration_ms: 0.192458
947
- ...
948
- # Subtest: Cleanup interval is started for memory limiter
949
- ok 11 - Cleanup interval is started for memory limiter
950
- ---
951
- duration_ms: 0.106041
952
- ...
953
- 1..11
954
- ok 10 - Rate Limiter Module
955
- ---
956
- duration_ms: 25.494834
957
- ...
958
- # Subtest: Factories
959
- # Subtest: createTestUser returns correct shape with defaults
960
- ok 1 - createTestUser returns correct shape with defaults
961
- ---
962
- duration_ms: 0.474084
963
- ...
964
- # Subtest: createTestUser applies overrides
965
- ok 2 - createTestUser applies overrides
966
- ---
967
- duration_ms: 0.078333
968
- ...
969
- # Subtest: createTestUser generates unique IDs
970
- ok 3 - createTestUser generates unique IDs
971
- ---
972
- duration_ms: 0.070208
973
- ...
974
- # Subtest: createTestPost returns correct shape with defaults
975
- ok 4 - createTestPost returns correct shape with defaults
976
- ---
977
- duration_ms: 0.075792
978
- ...
979
- # Subtest: createTestPost applies overrides including boolean false
980
- ok 5 - createTestPost applies overrides including boolean false
981
- ---
982
- duration_ms: 0.055584
983
- ...
984
- # Subtest: createTestPost keeps published false when explicitly set
985
- ok 6 - createTestPost keeps published false when explicitly set
986
- ---
987
- duration_ms: 0.105084
988
- ...
989
- # Subtest: createTestSession returns session with embedded user
990
- ok 7 - createTestSession returns session with embedded user
991
- ---
992
- duration_ms: 2.945625
993
- ...
994
- # Subtest: createTestSession applies user overrides
995
- ok 8 - createTestSession applies user overrides
996
- ---
997
- duration_ms: 0.536416
998
- ...
999
- # Subtest: createTestSession applies top-level overrides
1000
- ok 9 - createTestSession applies top-level overrides
1001
- ---
1002
- duration_ms: 0.398
1003
- ...
1004
- 1..9
1005
- ok 11 - Factories
1006
- ---
1007
- duration_ms: 6.166041
1008
- ...
1009
- # Subtest: Mock Prisma
1010
- # Subtest: records method calls with args
1011
- ok 1 - records method calls with args
1012
- ---
1013
- duration_ms: 0.906834
1014
- ...
1015
- # Subtest: returns null by default for unconfigured methods
1016
- ok 2 - returns null by default for unconfigured methods
1017
- ---
1018
- duration_ms: 0.672833
1019
- ...
1020
- # Subtest: returns configured values via mockReturn
1021
- ok 3 - returns configured values via mockReturn
1022
- ---
1023
- duration_ms: 0.089708
1024
- ...
1025
- # Subtest: supports function return values
1026
- ok 4 - supports function return values
1027
- ---
1028
- duration_ms: 0.061833
1029
- ...
1030
- # Subtest: supports overrides in constructor
1031
- ok 5 - supports overrides in constructor
1032
- ---
1033
- duration_ms: 0.056583
1034
- ...
1035
- # Subtest: reset clears calls and return values
1036
- ok 6 - reset clears calls and return values
1037
- ---
1038
- duration_ms: 0.067959
1039
- ...
1040
- # Subtest: handles multiple models independently
1041
- ok 7 - handles multiple models independently
1042
- ---
1043
- duration_ms: 0.113417
1044
- ...
1045
- 1..7
1046
- ok 12 - Mock Prisma
1047
- ---
1048
- duration_ms: 2.54825
1049
- ...
1050
- # Subtest: Mock Request
1051
- # Subtest: has correct defaults
1052
- ok 1 - has correct defaults
1053
- ---
1054
- duration_ms: 0.085833
1055
- ...
1056
- # Subtest: headers.get is case-insensitive
1057
- ok 2 - headers.get is case-insensitive
1058
- ---
1059
- duration_ms: 0.056916
1060
- ...
1061
- # Subtest: returns null for missing headers
1062
- ok 3 - returns null for missing headers
1063
- ---
1064
- duration_ms: 0.032958
1065
- ...
1066
- # Subtest: json() returns body
1067
- ok 4 - json() returns body
1068
- ---
1069
- duration_ms: 0.047792
1070
- ...
1071
- # Subtest: cookies.get returns cookie object
1072
- ok 5 - cookies.get returns cookie object
1073
- ---
1074
- duration_ms: 0.05225
1075
- ...
1076
- # Subtest: cookies.get returns undefined for missing cookie
1077
- ok 6 - cookies.get returns undefined for missing cookie
1078
- ---
1079
- duration_ms: 0.031292
1080
- ...
1081
- # Subtest: nextUrl is a URL object
1082
- ok 7 - nextUrl is a URL object
1083
- ---
1084
- duration_ms: 0.063625
1085
- ...
1086
- 1..7
1087
- ok 13 - Mock Request
1088
- ---
1089
- duration_ms: 0.53225
1090
- ...
1091
- # Subtest: Mock Response
1092
- # Subtest: has default status 200
1093
- ok 1 - has default status 200
1094
- ---
1095
- duration_ms: 0.061167
1096
- ...
1097
- # Subtest: json() sets body and content-type
1098
- ok 2 - json() sets body and content-type
1099
- ---
1100
- duration_ms: 0.105542
1101
- ...
1102
- # Subtest: redirect() sets status and location
1103
- ok 3 - redirect() sets status and location
1104
- ---
1105
- duration_ms: 0.037084
1106
- ...
1107
- # Subtest: cookies can be set and retrieved
1108
- ok 4 - cookies can be set and retrieved
1109
- ---
1110
- duration_ms: 0.042167
1111
- ...
1112
- 1..4
1113
- ok 14 - Mock Response
1114
- ---
1115
- duration_ms: 0.348667
1116
- ...
1117
- # Subtest: Mock Redis
1118
- # Subtest: get/set stores and retrieves values
1119
- ok 1 - get/set stores and retrieves values
1120
- ---
1121
- duration_ms: 0.110625
1122
- ...
1123
- # Subtest: get returns null for missing keys
1124
- ok 2 - get returns null for missing keys
1125
- ---
1126
- duration_ms: 0.038083
1127
- ...
1128
- # Subtest: initialData pre-populates the store
1129
- ok 3 - initialData pre-populates the store
1130
- ---
1131
- duration_ms: 0.035416
1132
- ...
1133
- # Subtest: del removes keys and returns count
1134
- ok 4 - del removes keys and returns count
1135
- ---
1136
- duration_ms: 0.059917
1137
- ...
1138
- # Subtest: keys filters by prefix pattern
1139
- ok 5 - keys filters by prefix pattern
1140
- ---
1141
- duration_ms: 0.153834
1142
- ...
1143
- # Subtest: incr increments numeric values
1144
- ok 6 - incr increments numeric values
1145
- ---
1146
- duration_ms: 0.053875
1147
- ...
1148
- # Subtest: exists returns count of existing keys
1149
- ok 7 - exists returns count of existing keys
1150
- ---
1151
- duration_ms: 0.057083
1152
- ...
1153
- # Subtest: pipeline batches commands
1154
- ok 8 - pipeline batches commands
1155
- ---
1156
- duration_ms: 0.286458
1157
- ...
1158
- # Subtest: records all method calls
1159
- ok 9 - records all method calls
1160
- ---
1161
- duration_ms: 0.096792
1162
- ...
1163
- # Subtest: reset clears store and calls
1164
- ok 10 - reset clears store and calls
1165
- ---
1166
- duration_ms: 0.067417
1167
- ...
1168
- # Subtest: ping returns PONG
1169
- ok 11 - ping returns PONG
1170
- ---
1171
- duration_ms: 0.043875
1172
- ...
1173
- 1..11
1174
- ok 15 - Mock Redis
1175
- ---
1176
- duration_ms: 1.6705
1177
- ...
1178
- # Subtest: captureConsole
1179
- # Subtest: captures console output and restores
1180
- ok 1 - captures console output and restores
1181
- ---
1182
- duration_ms: 0.133416
1183
- ...
1184
- # Subtest: captures info and debug
1185
- ok 2 - captures info and debug
1186
- ---
1187
- duration_ms: 0.0445
1188
- ...
1189
- 1..2
1190
- ok 16 - captureConsole
1191
- ---
1192
- duration_ms: 0.256
1193
- ...
1194
- # Subtest: createTestContext
1195
- # Subtest: saves and restores env variables
1196
- ok 1 - saves and restores env variables
1197
- ---
1198
- duration_ms: 0.101167
1199
- ...
1200
- # Subtest: deletes env var when set to undefined
1201
- ok 2 - deletes env var when set to undefined
1202
- ---
1203
- duration_ms: 0.065875
1204
- ...
1205
- # Subtest: runs cleanup functions in LIFO order
1206
- ok 3 - runs cleanup functions in LIFO order
1207
- ---
1208
- duration_ms: 0.06975
1209
- ...
1210
- # Subtest: cleanup runs async cleanup functions
1211
- ok 4 - cleanup runs async cleanup functions
1212
- ---
1213
- duration_ms: 12.176542
1214
- ...
1215
- 1..4
1216
- ok 17 - createTestContext
1217
- ---
1218
- duration_ms: 12.569541
1219
- ...
1220
- # Subtest: waitFor
1221
- # Subtest: resolves when assertion passes immediately
1222
- ok 1 - resolves when assertion passes immediately
1223
- ---
1224
- duration_ms: 0.0725
1225
- ...
1226
- # Subtest: resolves when assertion eventually passes
1227
- ok 2 - resolves when assertion eventually passes
1228
- ---
1229
- duration_ms: 21.538375
1230
- ...
1231
- # Subtest: throws last error on timeout
1232
- ok 3 - throws last error on timeout
1233
- ---
1234
- duration_ms: 109.074833
1235
- ...
1236
- 1..3
1237
- ok 18 - waitFor
1238
- ---
1239
- duration_ms: 130.950542
1240
- ...
1241
- # Subtest: assertThrows
1242
- # Subtest: passes when async function throws expected error
1243
- ok 1 - passes when async function throws expected error
1244
- ---
1245
- duration_ms: 0.239834
1246
- ...
1247
- # Subtest: fails when function does not throw
1248
- ok 2 - fails when function does not throw
1249
- ---
1250
- duration_ms: 0.377541
1251
- ...
1252
- # Subtest: fails when error class does not match
1253
- ok 3 - fails when error class does not match
1254
- ---
1255
- duration_ms: 0.101167
1256
- ...
1257
- # Subtest: fails when message pattern does not match
1258
- ok 4 - fails when message pattern does not match
1259
- ---
1260
- duration_ms: 0.144084
1261
- ...
1262
- # Subtest: works with string message pattern
1263
- ok 5 - works with string message pattern
1264
- ---
1265
- duration_ms: 0.050042
1266
- ...
1267
- # Subtest: works without ErrorClass (just message)
1268
- ok 6 - works without ErrorClass (just message)
1269
- ---
1270
- duration_ms: 0.044459
1271
- ...
1272
- 1..6
1273
- ok 19 - assertThrows
1274
- ---
1275
- duration_ms: 1.231875
1276
- ...
1277
- # Subtest: Utils Module
1278
- # Subtest: retryAsync succeeds on first attempt
1279
- ok 1 - retryAsync succeeds on first attempt
1280
- ---
1281
- duration_ms: 0.321417
1282
- ...
1283
- # Subtest: retryAsync retries on failure
1284
- ok 2 - retryAsync retries on failure
1285
- ---
1286
- duration_ms: 31.962417
1287
- ...
1288
- # Subtest: retryAsync throws after max attempts
1289
- ok 3 - retryAsync throws after max attempts
1290
- ---
1291
- duration_ms: 31.149042
1292
- ...
1293
- # Subtest: sleep delays execution
1294
- ok 4 - sleep delays execution
1295
- ---
1296
- duration_ms: 51.887167
1297
- ...
1298
- # Subtest: validateEnv checks required variables
1299
- ok 5 - validateEnv checks required variables
1300
- ---
1301
- duration_ms: 0.131708
1302
- ...
1303
- # Subtest: validateEnv throws on missing variables
1304
- ok 6 - validateEnv throws on missing variables
1305
- ---
1306
- duration_ms: 0.150417
1307
- ...
1308
- # Subtest: deepMerge merges objects
1309
- ok 7 - deepMerge merges objects
1310
- ---
1311
- duration_ms: 0.415542
1312
- ...
1313
- # Subtest: deepMerge handles nested objects
1314
- ok 8 - deepMerge handles nested objects
1315
- ---
1316
- duration_ms: 0.220333
1317
- ...
1318
- # Subtest: isObject identifies objects
1319
- ok 9 - isObject identifies objects
1320
- ---
1321
- duration_ms: 0.20025
1322
- ...
1323
- # Subtest: normalizeErrorMessage handles various types
1324
- ok 10 - normalizeErrorMessage handles various types
1325
- ---
1326
- duration_ms: 0.135334
1327
- ...
1328
- # Subtest: randomString generates random strings
1329
- ok 11 - randomString generates random strings
1330
- ---
1331
- duration_ms: 0.168958
1332
- ...
1333
- # Subtest: randomString respects length parameter
1334
- ok 12 - randomString respects length parameter
1335
- ---
1336
- duration_ms: 0.046125
1337
- ...
1338
- # Subtest: sanitizeId converts to valid IDs
1339
- ok 13 - sanitizeId converts to valid IDs
1340
- ---
1341
- duration_ms: 0.12375
1342
- ...
1343
- # Subtest: formatBytes formats file sizes
1344
- ok 14 - formatBytes formats file sizes
1345
- ---
1346
- duration_ms: 0.053291
1347
- ...
1348
- # Subtest: debounce delays function execution
1349
- ok 15 - debounce delays function execution
1350
- ---
1351
- duration_ms: 51.01325
1352
- ...
1353
- # Subtest: memoize caches function results
1354
- ok 16 - memoize caches function results
1355
- ---
1356
- duration_ms: 0.146458
1357
- ...
1358
- # Subtest: memoize respects TTL
1359
- ok 17 - memoize respects TTL
1360
- ---
1361
- duration_ms: 50.514458
1362
- ...
1363
- 1..17
1364
- ok 20 - Utils Module
1365
- ---
1366
- duration_ms: 220.542041
1367
- ...
1368
- 1..20
1369
- # tests 227
1370
- # suites 29
1371
- # pass 227
1372
- # fail 0
1373
- # cancelled 0
1374
- # skipped 0
1375
- # todo 0
1376
- # duration_ms 497.736