@gjsify/assert 0.0.4 → 0.1.1

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.
package/src/index.spec.ts CHANGED
@@ -1,18 +1,499 @@
1
1
  import { describe, it, expect } from '@gjsify/unit';
2
- import { equal } from 'assert';
2
+ import {
3
+ equal,
4
+ notEqual,
5
+ strictEqual,
6
+ notStrictEqual,
7
+ deepEqual,
8
+ notDeepEqual,
9
+ deepStrictEqual,
10
+ notDeepStrictEqual,
11
+ throws,
12
+ doesNotThrow,
13
+ fail,
14
+ ok,
15
+ ifError,
16
+ match,
17
+ doesNotMatch,
18
+ rejects,
19
+ doesNotReject,
20
+ AssertionError,
21
+ strict,
22
+ } from 'node:assert';
23
+ import assert from 'node:assert';
3
24
 
4
25
  export default async () => {
26
+
27
+ // ---- AssertionError ----
28
+
29
+ await describe('AssertionError', async () => {
30
+ await it('should be an instance of Error', async () => {
31
+ const err = new AssertionError({ message: 'test' });
32
+ expect(err instanceof Error).toBe(true);
33
+ });
34
+
35
+ await it('should have name "AssertionError"', async () => {
36
+ const err = new AssertionError({ message: 'test' });
37
+ expect(err.name).toBe('AssertionError');
38
+ });
39
+
40
+ await it('should have code "ERR_ASSERTION"', async () => {
41
+ const err = new AssertionError({ message: 'test' });
42
+ expect(err.code).toBe('ERR_ASSERTION');
43
+ });
44
+
45
+ await it('should store actual and expected', async () => {
46
+ const err = new AssertionError({ actual: 1, expected: 2, operator: 'strictEqual' });
47
+ expect(err.actual).toBe(1);
48
+ expect(err.expected).toBe(2);
49
+ });
50
+
51
+ await it('should store operator', async () => {
52
+ const err = new AssertionError({ operator: 'strictEqual' });
53
+ expect(err.operator).toBe('strictEqual');
54
+ });
55
+
56
+ await it('should set generatedMessage to true when no message provided', async () => {
57
+ const err = new AssertionError({ actual: 1, expected: 2, operator: 'strictEqual' });
58
+ expect(err.generatedMessage).toBe(true);
59
+ });
60
+
61
+ await it('should set generatedMessage to false when message provided', async () => {
62
+ const err = new AssertionError({ message: 'custom msg', operator: 'strictEqual' });
63
+ expect(err.generatedMessage).toBe(false);
64
+ });
65
+ });
66
+
67
+ // ---- assert / ok ----
68
+
69
+ await describe('assert / ok', async () => {
70
+ await it('should pass for truthy values', async () => {
71
+ expect(() => ok(true)).not.toThrow();
72
+ expect(() => ok(1)).not.toThrow();
73
+ expect(() => ok('string')).not.toThrow();
74
+ expect(() => ok({})).not.toThrow();
75
+ expect(() => ok([])).not.toThrow();
76
+ });
77
+
78
+ await it('should throw for falsy values', async () => {
79
+ expect(() => ok(false)).toThrow();
80
+ expect(() => ok(0)).toThrow();
81
+ expect(() => ok('')).toThrow();
82
+ expect(() => ok(null)).toThrow();
83
+ expect(() => ok(undefined)).toThrow();
84
+ });
85
+
86
+ await it('should work as default export', async () => {
87
+ expect(() => assert(true)).not.toThrow();
88
+ expect(() => assert(false)).toThrow();
89
+ });
90
+
91
+ await it('should throw Error instance when message is an Error', async () => {
92
+ const customErr = new TypeError('custom');
93
+ expect(() => {
94
+ ok(false, customErr as any);
95
+ }).toThrow();
96
+ });
97
+ });
98
+
99
+ // ---- equal / notEqual ----
100
+
5
101
  await describe('assert.equal', async () => {
6
- await it('should do nothing if both values are qual', async () => {
102
+ await it('should do nothing if both values are equal', async () => {
103
+ expect(() => equal(true, true)).not.toThrow();
104
+ });
105
+
106
+ await it('should throw if both values are not equal', async () => {
107
+ expect(() => equal(true, false)).toThrow();
108
+ });
109
+
110
+ await it('should use loose equality (==)', async () => {
111
+ expect(() => equal(1, '1')).not.toThrow();
112
+ expect(() => equal(null, undefined)).not.toThrow();
113
+ expect(() => equal(0, false)).not.toThrow();
114
+ });
115
+
116
+ await it('should throw for values that are not loosely equal', async () => {
117
+ expect(() => equal(1, 2)).toThrow();
118
+ expect(() => equal('a', 'b')).toThrow();
119
+ });
120
+ });
121
+
122
+ await describe('assert.notEqual', async () => {
123
+ await it('should pass for unequal values', async () => {
124
+ expect(() => notEqual(1, 2)).not.toThrow();
125
+ expect(() => notEqual('a', 'b')).not.toThrow();
126
+ });
127
+
128
+ await it('should throw for loosely equal values', async () => {
129
+ expect(() => notEqual(1, '1')).toThrow();
130
+ expect(() => notEqual(null, undefined)).toThrow();
131
+ });
132
+ });
133
+
134
+ // ---- strictEqual / notStrictEqual ----
135
+
136
+ await describe('assert.strictEqual', async () => {
137
+ await it('should pass for strictly equal values', async () => {
138
+ expect(() => strictEqual(1, 1)).not.toThrow();
139
+ expect(() => strictEqual('a', 'a')).not.toThrow();
140
+ expect(() => strictEqual(null, null)).not.toThrow();
141
+ expect(() => strictEqual(undefined, undefined)).not.toThrow();
142
+ });
143
+
144
+ await it('should throw for different types', async () => {
145
+ expect(() => strictEqual(1, '1')).toThrow();
146
+ expect(() => strictEqual(null, undefined)).toThrow();
147
+ });
148
+
149
+ await it('should handle NaN (Object.is semantics)', async () => {
150
+ expect(() => strictEqual(NaN, NaN)).not.toThrow();
151
+ });
152
+
153
+ await it('should distinguish +0 and -0', async () => {
154
+ expect(() => strictEqual(+0, -0)).toThrow();
155
+ });
156
+ });
157
+
158
+ await describe('assert.notStrictEqual', async () => {
159
+ await it('should pass for non-identical values', async () => {
160
+ expect(() => notStrictEqual(1, '1')).not.toThrow();
161
+ expect(() => notStrictEqual(1, 2)).not.toThrow();
162
+ });
163
+
164
+ await it('should throw for identical values', async () => {
165
+ expect(() => notStrictEqual(1, 1)).toThrow();
166
+ expect(() => notStrictEqual('a', 'a')).toThrow();
167
+ });
168
+ });
169
+
170
+ // ---- deepEqual / notDeepEqual ----
171
+
172
+ await describe('assert.deepEqual', async () => {
173
+ await it('should pass for equal objects', async () => {
174
+ expect(() => deepEqual({ a: 1 }, { a: 1 })).not.toThrow();
175
+ });
176
+
177
+ await it('should pass for equal arrays', async () => {
178
+ expect(() => deepEqual([1, 2, 3], [1, 2, 3])).not.toThrow();
179
+ });
180
+
181
+ await it('should handle nested objects', async () => {
182
+ expect(() => deepEqual({ a: { b: 1 } }, { a: { b: 1 } })).not.toThrow();
183
+ });
184
+
185
+ await it('should use loose equality for primitives', async () => {
186
+ expect(() => deepEqual({ a: 1 }, { a: '1' })).not.toThrow();
187
+ });
188
+
189
+ await it('should pass for Date objects with same time', async () => {
190
+ const d = new Date('2024-01-01');
191
+ expect(() => deepEqual(new Date(d.getTime()), new Date(d.getTime()))).not.toThrow();
192
+ });
193
+
194
+ await it('should pass for RegExp with same pattern/flags', async () => {
195
+ expect(() => deepEqual(/abc/gi, /abc/gi)).not.toThrow();
196
+ });
197
+
198
+ await it('should throw for different objects', async () => {
199
+ expect(() => deepEqual({ a: 1 }, { a: 2 })).toThrow();
200
+ });
201
+
202
+ await it('should throw for different arrays', async () => {
203
+ expect(() => deepEqual([1, 2], [1, 3])).toThrow();
204
+ });
205
+ });
206
+
207
+ await describe('assert.notDeepEqual', async () => {
208
+ await it('should pass for different objects', async () => {
209
+ expect(() => notDeepEqual({ a: 1 }, { a: 2 })).not.toThrow();
210
+ });
211
+
212
+ await it('should throw for equal objects', async () => {
213
+ expect(() => notDeepEqual({ a: 1 }, { a: 1 })).toThrow();
214
+ });
215
+ });
216
+
217
+ // ---- deepStrictEqual / notDeepStrictEqual ----
218
+
219
+ await describe('assert.deepStrictEqual', async () => {
220
+ await it('should pass for strictly equal objects', async () => {
221
+ expect(() => deepStrictEqual({ a: 1 }, { a: 1 })).not.toThrow();
222
+ });
223
+
224
+ await it('should be type-sensitive (unlike deepEqual)', async () => {
225
+ expect(() => deepStrictEqual({ a: 1 }, { a: '1' })).toThrow();
226
+ });
227
+
228
+ await it('should check prototypes', async () => {
229
+ const a = Object.create(null);
230
+ a.x = 1;
231
+ expect(() => deepStrictEqual(a, { x: 1 })).toThrow();
232
+ });
233
+
234
+ await it('should handle Map objects', async () => {
235
+ const m1 = new Map([['a', 1]]);
236
+ const m2 = new Map([['a', 1]]);
237
+ expect(() => deepStrictEqual(m1, m2)).not.toThrow();
238
+ });
239
+
240
+ await it('should handle Set objects', async () => {
241
+ const s1 = new Set([1, 2, 3]);
242
+ const s2 = new Set([1, 2, 3]);
243
+ expect(() => deepStrictEqual(s1, s2)).not.toThrow();
244
+ });
245
+
246
+ await it('should handle nested arrays', async () => {
247
+ expect(() => deepStrictEqual([[1, 2], [3]], [[1, 2], [3]])).not.toThrow();
248
+ });
249
+
250
+ await it('should handle Date objects', async () => {
251
+ const d = new Date();
252
+ expect(() => deepStrictEqual(new Date(d.getTime()), new Date(d.getTime()))).not.toThrow();
253
+ });
254
+
255
+ await it('should throw for different Date objects', async () => {
256
+ expect(() => deepStrictEqual(new Date(0), new Date(1))).toThrow();
257
+ });
258
+
259
+ await it('should throw for different RegExp', async () => {
260
+ expect(() => deepStrictEqual(/abc/, /def/)).toThrow();
261
+ });
262
+ });
263
+
264
+ await describe('assert.notDeepStrictEqual', async () => {
265
+ await it('should pass when values differ by type', async () => {
266
+ expect(() => notDeepStrictEqual({ a: 1 }, { a: '1' })).not.toThrow();
267
+ });
268
+
269
+ await it('should throw when values are deep strict equal', async () => {
270
+ expect(() => notDeepStrictEqual({ a: 1 }, { a: 1 })).toThrow();
271
+ });
272
+ });
273
+
274
+ // ---- throws / doesNotThrow ----
275
+
276
+ await describe('assert.throws', async () => {
277
+ await it('should pass when function throws', async () => {
7
278
  expect(() => {
8
- equal(true, true);
279
+ throws(() => { throw new Error('test'); });
9
280
  }).not.toThrow();
10
281
  });
11
282
 
12
- await it('should throw both values are not qual', async () => {
283
+ await it('should throw when function does NOT throw', async () => {
13
284
  expect(() => {
14
- equal(true, false);
285
+ throws(() => { /* no throw */ });
15
286
  }).toThrow();
16
287
  });
288
+
289
+ await it('should validate error class', async () => {
290
+ expect(() => {
291
+ throws(() => { throw new TypeError('test'); }, TypeError);
292
+ }).not.toThrow();
293
+ });
294
+
295
+ await it('should validate error message with RegExp', async () => {
296
+ expect(() => {
297
+ throws(() => { throw new Error('hello world'); }, /hello/);
298
+ }).not.toThrow();
299
+ });
300
+
301
+ await it('should validate with validation function', async () => {
302
+ expect(() => {
303
+ throws(
304
+ () => { throw new Error('test'); },
305
+ (err: any) => err instanceof Error && err.message === 'test',
306
+ );
307
+ }).not.toThrow();
308
+ });
309
+ });
310
+
311
+ await describe('assert.doesNotThrow', async () => {
312
+ await it('should pass when function does not throw', async () => {
313
+ expect(() => {
314
+ doesNotThrow(() => { return 42; });
315
+ }).not.toThrow();
316
+ });
317
+
318
+ await it('should throw when function throws', async () => {
319
+ expect(() => {
320
+ doesNotThrow(() => { throw new Error('oops'); });
321
+ }).toThrow();
322
+ });
323
+ });
324
+
325
+ // ---- fail ----
326
+
327
+ await describe('assert.fail', async () => {
328
+ await it('should always throw AssertionError', async () => {
329
+ expect(() => fail()).toThrow();
330
+ });
331
+
332
+ await it('should use "Failed" as default message', async () => {
333
+ let caught = false;
334
+ try {
335
+ fail();
336
+ } catch (e: any) {
337
+ caught = true;
338
+ expect(e.message).toBe('Failed');
339
+ }
340
+ expect(caught).toBe(true);
341
+ });
342
+
343
+ await it('should use custom message', async () => {
344
+ let caught = false;
345
+ try {
346
+ fail('custom message');
347
+ } catch (e: any) {
348
+ caught = true;
349
+ expect(e.message).toBe('custom message');
350
+ }
351
+ expect(caught).toBe(true);
352
+ });
353
+ });
354
+
355
+ // ---- ifError ----
356
+
357
+ await describe('assert.ifError', async () => {
358
+ await it('should pass for null', async () => {
359
+ expect(() => ifError(null)).not.toThrow();
360
+ });
361
+
362
+ await it('should pass for undefined', async () => {
363
+ expect(() => ifError(undefined)).not.toThrow();
364
+ });
365
+
366
+ await it('should throw for truthy values', async () => {
367
+ expect(() => ifError(1)).toThrow();
368
+ expect(() => ifError('error')).toThrow();
369
+ expect(() => ifError(true)).toThrow();
370
+ });
371
+
372
+ await it('should throw for Error instances', async () => {
373
+ expect(() => ifError(new Error('test'))).toThrow();
374
+ });
375
+ });
376
+
377
+ // ---- match / doesNotMatch ----
378
+
379
+ await describe('assert.match', async () => {
380
+ await it('should pass when string matches regexp', async () => {
381
+ expect(() => match('hello world', /hello/)).not.toThrow();
382
+ });
383
+
384
+ await it('should throw when string does not match', async () => {
385
+ expect(() => match('hello', /world/)).toThrow();
386
+ });
387
+ });
388
+
389
+ await describe('assert.doesNotMatch', async () => {
390
+ await it('should pass when string does not match', async () => {
391
+ expect(() => doesNotMatch('hello', /world/)).not.toThrow();
392
+ });
393
+
394
+ await it('should throw when string matches', async () => {
395
+ expect(() => doesNotMatch('hello world', /hello/)).toThrow();
396
+ });
397
+ });
398
+
399
+ // ---- rejects / doesNotReject ----
400
+
401
+ await describe('assert.rejects', async () => {
402
+ await it('should pass for rejected promise', async () => {
403
+ let threw = false;
404
+ try {
405
+ await rejects(async () => { throw new Error('rejected'); });
406
+ } catch {
407
+ threw = true;
408
+ }
409
+ expect(threw).toBe(false);
410
+ });
411
+
412
+ await it('should throw for resolved promise', async () => {
413
+ let threw = false;
414
+ try {
415
+ await rejects(async () => { return 42; });
416
+ } catch {
417
+ threw = true;
418
+ }
419
+ expect(threw).toBe(true);
420
+ });
421
+ });
422
+
423
+ await describe('assert.doesNotReject', async () => {
424
+ await it('should pass for resolved promise', async () => {
425
+ let threw = false;
426
+ try {
427
+ await doesNotReject(async () => { return 42; });
428
+ } catch {
429
+ threw = true;
430
+ }
431
+ expect(threw).toBe(false);
432
+ });
433
+
434
+ await it('should throw for rejected promise', async () => {
435
+ let threw = false;
436
+ try {
437
+ await doesNotReject(async () => { throw new Error('rejected'); });
438
+ } catch {
439
+ threw = true;
440
+ }
441
+ expect(threw).toBe(true);
442
+ });
443
+ });
444
+
445
+ // ---- strict ----
446
+
447
+ await describe('assert.strict', async () => {
448
+ await it('should be a function', async () => {
449
+ expect(typeof strict).toBe('function');
450
+ });
451
+
452
+ await it('should have strictEqual as equal', async () => {
453
+ expect(strict.equal).toBe(strict.strictEqual);
454
+ });
455
+
456
+ await it('should have deepStrictEqual as deepEqual', async () => {
457
+ expect(strict.deepEqual).toBe(strict.deepStrictEqual);
458
+ });
459
+
460
+ await it('should act as ok when called', async () => {
461
+ expect(() => strict(true)).not.toThrow();
462
+ expect(() => strict(false)).toThrow();
463
+ });
464
+
465
+ await it('should have self-reference', async () => {
466
+ expect(strict.strict).toBe(strict);
467
+ });
468
+ });
469
+
470
+ // ---- assert default export properties ----
471
+
472
+ await describe('assert default export', async () => {
473
+ await it('should have all methods', async () => {
474
+ expect(typeof assert.ok).toBe('function');
475
+ expect(typeof assert.equal).toBe('function');
476
+ expect(typeof assert.notEqual).toBe('function');
477
+ expect(typeof assert.strictEqual).toBe('function');
478
+ expect(typeof assert.notStrictEqual).toBe('function');
479
+ expect(typeof assert.deepEqual).toBe('function');
480
+ expect(typeof assert.notDeepEqual).toBe('function');
481
+ expect(typeof assert.deepStrictEqual).toBe('function');
482
+ expect(typeof assert.notDeepStrictEqual).toBe('function');
483
+ expect(typeof assert.throws).toBe('function');
484
+ expect(typeof assert.doesNotThrow).toBe('function');
485
+ expect(typeof assert.rejects).toBe('function');
486
+ expect(typeof assert.doesNotReject).toBe('function');
487
+ expect(typeof assert.fail).toBe('function');
488
+ expect(typeof assert.ifError).toBe('function');
489
+ expect(typeof assert.match).toBe('function');
490
+ expect(typeof assert.doesNotMatch).toBe('function');
491
+ expect(typeof assert.strict).toBe('function');
492
+ });
493
+
494
+ await it('should work as a function (like ok)', async () => {
495
+ expect(() => assert(true)).not.toThrow();
496
+ expect(() => assert(false)).toThrow();
497
+ });
17
498
  });
18
- }
499
+ };