@locustjs/test 1.3.1 → 1.5.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.
Files changed (4) hide show
  1. package/index.cjs.js +346 -231
  2. package/index.esm.js +1471 -842
  3. package/package.json +2 -2
  4. package/tests/index.js +19 -20
package/index.cjs.js CHANGED
@@ -1,573 +1,645 @@
1
- import { equals, isString, isNumber, isDate, isBool, isBasic, isPrimitive, isEmpty, isSomeString, isObject, isSomeObject, isFunction, isNumeric, isArray, isIterable, isSomeArray, isSubClassOf } from '@locustjs/base';
2
- import { Exception } from '@locustjs/exception';
3
- import fs from 'fs';
4
- import path from 'path';
1
+ import { equals, isString, isNumber, isDate, isBool, isBasic, isPrimitive, isEmpty, isSomeString, isObject, isSomeObject, isFunction, isNumeric, isArray, isIterable, isSomeArray, isSubClassOf } from "@locustjs/base";
2
+ import { Exception } from "@locustjs/exception";
3
+ import fs from "fs";
4
+ import path from "path";
5
+ class TestException extends Exception {}
5
6
  class Expect {
6
7
  constructor(value) {
7
8
  this.value = value;
9
+ this._expected = false;
10
+ }
11
+ get expected() {
12
+ return this._expected;
8
13
  }
9
14
  toBe(value) {
15
+ this._expected = true;
10
16
  if (this.value === value) {} else {
11
- throw new Exception({
17
+ throw new TestException({
12
18
  message: `${this.value} is not equal to ${value}`,
13
19
  code: 1000,
14
- status: 'not-eq'
20
+ status: "not-eq"
15
21
  });
16
22
  }
17
23
  return this;
18
24
  }
19
25
  toBeGt(value) {
26
+ this._expected = true;
20
27
  if (this.value <= value) {
21
- throw new Exception({
28
+ throw new TestException({
22
29
  message: `${this.value} is not greater than ${value}`,
23
30
  code: 1001,
24
- status: 'lte'
31
+ status: "lte"
25
32
  });
26
33
  }
27
34
  return this;
28
35
  }
36
+ toBeGreaterThan(value) {
37
+ return this.toBeGt(value);
38
+ }
29
39
  toBeGte(value) {
40
+ this._expected = true;
30
41
  if (this.value < value) {
31
- throw new Exception({
42
+ throw new TestException({
32
43
  message: `${this.value} is not greater than or equal to ${value}`,
33
44
  code: 1002,
34
- status: 'lt'
45
+ status: "lt"
35
46
  });
36
47
  }
37
48
  return this;
38
49
  }
50
+ toBeGreaterThanOrEqualTo(value) {
51
+ return this.toBeGte(value);
52
+ }
39
53
  toBeLt(value) {
54
+ this._expected = true;
40
55
  if (this.value >= value) {
41
- throw new Exception({
56
+ throw new TestException({
42
57
  message: `${this.value} is not less than ${value}`,
43
58
  code: 1003,
44
- status: 'gte'
59
+ status: "gte"
45
60
  });
46
61
  }
47
62
  return this;
48
63
  }
64
+ toBeLowerThan(value) {
65
+ return this.toBeLt(value);
66
+ }
49
67
  toBeLte(value) {
68
+ this._expected = true;
50
69
  if (this.value > value) {
51
- throw new Exception({
70
+ throw new TestException({
52
71
  message: `${this.value} is not less than or equal to ${value}`,
53
72
  code: 1004,
54
- status: 'gt'
73
+ status: "gt"
55
74
  });
56
75
  }
57
76
  return this;
58
77
  }
78
+ toBeLowerThanOrEqualTo(value) {
79
+ return this.toBeLte(value);
80
+ }
59
81
  toBeBetween(n, m) {
82
+ this._expected = true;
60
83
  if (!(this.value >= n && this.value < m)) {
61
- throw new Exception({
84
+ throw new TestException({
62
85
  message: `${this.value} is not between ${n} and ${m}`,
63
86
  code: 1024,
64
- status: 'between'
87
+ status: "between"
65
88
  });
66
89
  }
67
90
  return this;
68
91
  }
69
92
  toBeOfType(type) {
93
+ this._expected = true;
70
94
  if (typeof this.value !== type) {
71
- throw new Exception({
95
+ throw new TestException({
72
96
  message: `${this.value} is not of type ${type}`,
73
97
  code: 1025,
74
- status: 'of-type'
98
+ status: "of-type"
75
99
  });
76
100
  }
77
101
  return this;
78
102
  }
79
103
  toBeString() {
104
+ this._expected = true;
80
105
  if (!isString(this.value)) {
81
- throw new Exception({
106
+ throw new TestException({
82
107
  message: `${this.value} is not string`,
83
108
  code: 1026,
84
- status: 'is-string'
109
+ status: "is-string"
85
110
  });
86
111
  }
87
112
  return this;
88
113
  }
89
114
  toBeSomeString() {
115
+ this._expected = true;
90
116
  if (!isSomeString(this.value)) {
91
- throw new Exception({
117
+ throw new TestException({
92
118
  message: `${this.value} is not some string`,
93
119
  code: 1027,
94
- status: 'is-some-string'
120
+ status: "is-some-string"
95
121
  });
96
122
  }
97
123
  return this;
98
124
  }
99
125
  toBeNumber() {
126
+ this._expected = true;
100
127
  if (!isNumber(this.value)) {
101
- throw new Exception({
128
+ throw new TestException({
102
129
  message: `${this.value} is not number`,
103
130
  code: 1028,
104
- status: 'is-number'
131
+ status: "is-number"
105
132
  });
106
133
  }
107
134
  return this;
108
135
  }
109
136
  toBeDate() {
137
+ this._expected = true;
110
138
  if (!isDate(this.value)) {
111
- throw new Exception({
139
+ throw new TestException({
112
140
  message: `${this.value} is not date`,
113
141
  code: 1029,
114
- status: 'is-date'
142
+ status: "is-date"
115
143
  });
116
144
  }
117
145
  return this;
118
146
  }
119
147
  toBeBool() {
148
+ this._expected = true;
120
149
  if (!isBool(this.value)) {
121
- throw new Exception({
150
+ throw new TestException({
122
151
  message: `${this.value} is not bool`,
123
152
  code: 1030,
124
- status: 'is-bool'
153
+ status: "is-bool"
125
154
  });
126
155
  }
127
156
  return this;
128
157
  }
129
158
  toBeBasicType() {
159
+ this._expected = true;
130
160
  if (!isBasic(this.value)) {
131
- throw new Exception({
161
+ throw new TestException({
132
162
  message: `${this.value} is not basic type`,
133
163
  code: 1031,
134
- status: 'is-basic-type'
164
+ status: "is-basic-type"
135
165
  });
136
166
  }
137
167
  return this;
138
168
  }
139
169
  toBePrimitive() {
170
+ this._expected = true;
140
171
  if (!isPrimitive(this.value)) {
141
- throw new Exception({
172
+ throw new TestException({
142
173
  message: `${this.value} is not primitive type`,
143
174
  code: 1032,
144
- status: 'is-primitive'
175
+ status: "is-primitive"
145
176
  });
146
177
  }
147
178
  return this;
148
179
  }
149
180
  toBeEmpty() {
181
+ this._expected = true;
150
182
  if (!isEmpty(this.value)) {
151
- throw new Exception({
183
+ throw new TestException({
152
184
  message: `${this.value} is not empty`,
153
185
  code: 1033,
154
- status: 'is-empty'
186
+ status: "is-empty"
155
187
  });
156
188
  }
157
189
  return this;
158
190
  }
159
191
  toBeObject() {
192
+ this._expected = true;
160
193
  if (!isObject(this.value)) {
161
- throw new Exception({
194
+ throw new TestException({
162
195
  message: `${this.value} is not object`,
163
196
  code: 1034,
164
- status: 'is-object'
197
+ status: "is-object"
165
198
  });
166
199
  }
167
200
  return this;
168
201
  }
169
202
  toBeSomeObject() {
203
+ this._expected = true;
170
204
  if (!isSomeObject(this.value)) {
171
- throw new Exception({
205
+ throw new TestException({
172
206
  message: `${this.value} is not some object`,
173
207
  code: 1035,
174
- status: 'is-some-object'
208
+ status: "is-some-object"
175
209
  });
176
210
  }
177
211
  return this;
178
212
  }
179
213
  toBeFunction() {
214
+ this._expected = true;
180
215
  if (!isFunction(this.value)) {
181
- throw new Exception({
216
+ throw new TestException({
182
217
  message: `${this.value} is not function`,
183
218
  code: 1036,
184
- status: 'is-function'
219
+ status: "is-function"
185
220
  });
186
221
  }
187
222
  return this;
188
223
  }
189
224
  toBeNumeric() {
225
+ this._expected = true;
190
226
  if (!isNumeric(this.value)) {
191
- throw new Exception({
227
+ throw new TestException({
192
228
  message: `${this.value} is not numeric`,
193
229
  code: 1037,
194
- status: 'is-numeric'
230
+ status: "is-numeric"
195
231
  });
196
232
  }
197
233
  return this;
198
234
  }
199
235
  toBeArray() {
236
+ this._expected = true;
200
237
  if (!isArray(this.value)) {
201
- throw new Exception({
238
+ throw new TestException({
202
239
  message: `${this.value} is not array`,
203
240
  code: 1038,
204
- status: 'is-array'
241
+ status: "is-array"
205
242
  });
206
243
  }
207
244
  return this;
208
245
  }
209
246
  toBeSomeArray() {
247
+ this._expected = true;
210
248
  if (!isSomeArray(this.value)) {
211
- throw new Exception({
249
+ throw new TestException({
212
250
  message: `${this.value} is not some array`,
213
251
  code: 1039,
214
- status: 'is-some-array'
252
+ status: "is-some-array"
215
253
  });
216
254
  }
217
255
  return this;
218
256
  }
219
257
  toBeIterable() {
258
+ this._expected = true;
220
259
  if (!isIterable(this.value)) {
221
- throw new Exception({
260
+ throw new TestException({
222
261
  message: `${this.value} is not iterable`,
223
262
  code: 1040,
224
- status: 'is-iterable'
263
+ status: "is-iterable"
225
264
  });
226
265
  }
227
266
  return this;
228
267
  }
229
268
  toBeSubClassOf(type) {
269
+ this._expected = true;
230
270
  if (!isSubClassOf(this.value, type)) {
231
- throw new Exception({
271
+ throw new TestException({
232
272
  message: `${this.value} is not subclass of ${type}`,
233
273
  code: 1041,
234
- status: 'is-subclass-of'
274
+ status: "is-subclass-of"
235
275
  });
236
276
  }
237
277
  return this;
238
278
  }
239
279
  toBeInstanceOf(type) {
280
+ this._expected = true;
240
281
  if (!(this.value instanceof type)) {
241
- throw new Exception({
282
+ throw new TestException({
242
283
  message: `${this.value} is not instance of ${type}`,
243
284
  code: 1042,
244
- status: 'instanceof'
285
+ status: "instanceof"
245
286
  });
246
287
  }
247
288
  return this;
248
289
  }
249
290
  toMatch(pattern, flags) {
291
+ this._expected = true;
250
292
  const r = new RegExp(pattern, flags);
251
293
  if (!r.test(this.value)) {
252
- throw new Exception({
294
+ throw new TestException({
253
295
  message: `${this.value} does not match ${pattern}`,
254
296
  code: 1043,
255
- status: 'match'
297
+ status: "match"
256
298
  });
257
299
  }
258
300
  return this;
259
301
  }
260
302
  notToBe(value) {
303
+ this._expected = true;
261
304
  if (this.value === value) {
262
- throw new Exception({
305
+ throw new TestException({
263
306
  message: `${value} is equal to ${this.value}`,
264
307
  code: 1005,
265
- status: 'eq'
308
+ status: "eq"
266
309
  });
267
310
  }
268
311
  return this;
269
312
  }
270
313
  toBeDefined() {
314
+ this._expected = true;
271
315
  if (this.value === undefined) {
272
- throw new Exception({
316
+ throw new TestException({
273
317
  message: `value is undefined`,
274
318
  code: 1006,
275
- status: 'undefined'
319
+ status: "undefined"
276
320
  });
277
321
  }
278
322
  return this;
279
323
  }
280
324
  toBeUndefined() {
325
+ this._expected = true;
281
326
  if (this.value !== undefined) {
282
- throw new Exception({
327
+ throw new TestException({
283
328
  message: `value is defined`,
284
329
  code: 1007,
285
- status: 'defined'
330
+ status: "defined"
286
331
  });
287
332
  }
288
333
  return this;
289
334
  }
290
335
  toBeNull() {
336
+ this._expected = true;
291
337
  if (this.value !== null) {
292
- throw new Exception({
338
+ throw new TestException({
293
339
  message: `value is not null`,
294
340
  code: 1008,
295
- status: 'not-null'
341
+ status: "not-null"
296
342
  });
297
343
  }
298
344
  return this;
299
345
  }
300
346
  notToBeNull() {
347
+ this._expected = true;
301
348
  if (this.value === null) {
302
- throw new Exception({
349
+ throw new TestException({
303
350
  message: `value is null`,
304
351
  code: 1009,
305
- status: 'null'
352
+ status: "null"
306
353
  });
307
354
  }
308
355
  return this;
309
356
  }
310
357
  toBeNullOrUndefined() {
358
+ this._expected = true;
311
359
  if (this.value == null) {} else {
312
- throw new Exception({
360
+ throw new TestException({
313
361
  message: `value is not null/undefined`,
314
362
  code: 1010,
315
- status: 'not-null-or-undefined'
363
+ status: "not-null-or-undefined"
316
364
  });
317
365
  }
318
366
  return this;
319
367
  }
320
368
  notToBeNullOrUndefined() {
369
+ this._expected = true;
321
370
  if (this.value == null) {
322
- throw new Exception({
371
+ throw new TestException({
323
372
  message: `value is null/undefined`,
324
373
  code: 1011,
325
- status: 'null-or-undefined'
374
+ status: "null-or-undefined"
326
375
  });
327
376
  }
328
377
  return this;
329
378
  }
330
379
  notToBeBetween(n, m) {
380
+ this._expected = true;
331
381
  if (this.value >= n && this.value < m) {
332
- throw new Exception({
382
+ throw new TestException({
333
383
  message: `${this.value} is between ${n} and ${m}`,
334
384
  code: 1044,
335
- status: 'not-between'
385
+ status: "not-between"
336
386
  });
337
387
  }
338
388
  return this;
339
389
  }
340
390
  notToBeOfType(type) {
391
+ this._expected = true;
341
392
  if (typeof this.value === type) {
342
- throw new Exception({
393
+ throw new TestException({
343
394
  message: `${this.value} is of type ${type}`,
344
395
  code: 1045,
345
- status: 'not-oftype'
396
+ status: "not-oftype"
346
397
  });
347
398
  }
348
399
  return this;
349
400
  }
350
401
  notToBeString() {
402
+ this._expected = true;
351
403
  if (isString(this.value)) {
352
- throw new Exception({
404
+ throw new TestException({
353
405
  message: `${this.value} is string`,
354
406
  code: 1046,
355
- status: 'not-is-string'
407
+ status: "not-is-string"
356
408
  });
357
409
  }
358
410
  return this;
359
411
  }
360
412
  notToBeSomeString() {
413
+ this._expected = true;
361
414
  if (isSomeString(this.value)) {
362
- throw new Exception({
415
+ throw new TestException({
363
416
  message: `${this.value} is some string`,
364
417
  code: 1047,
365
- status: 'not-is-some-string'
418
+ status: "not-is-some-string"
366
419
  });
367
420
  }
368
421
  return this;
369
422
  }
370
423
  notToBeNumber() {
424
+ this._expected = true;
371
425
  if (isNumber(this.value)) {
372
- throw new Exception({
426
+ throw new TestException({
373
427
  message: `${this.value} is number`,
374
428
  code: 1048,
375
- status: 'not-is-number'
429
+ status: "not-is-number"
376
430
  });
377
431
  }
378
432
  return this;
379
433
  }
380
434
  notToBeDate() {
435
+ this._expected = true;
381
436
  if (isDate(this.value)) {
382
- throw new Exception({
437
+ throw new TestException({
383
438
  message: `${this.value} is date`,
384
439
  code: 1049,
385
- status: 'not-is-date'
440
+ status: "not-is-date"
386
441
  });
387
442
  }
388
443
  return this;
389
444
  }
390
445
  notToBeBool() {
446
+ this._expected = true;
391
447
  if (isBool(this.value)) {
392
- throw new Exception({
448
+ throw new TestException({
393
449
  message: `${this.value} is bool`,
394
450
  code: 1050,
395
- status: 'not-is-bool'
451
+ status: "not-is-bool"
396
452
  });
397
453
  }
398
454
  return this;
399
455
  }
400
456
  notToBeBasicType() {
457
+ this._expected = true;
401
458
  if (isBasic(this.value)) {
402
- throw new Exception({
459
+ throw new TestException({
403
460
  message: `${this.value} is basic type`,
404
461
  code: 1051,
405
- status: 'not-is-basic-type'
462
+ status: "not-is-basic-type"
406
463
  });
407
464
  }
408
465
  return this;
409
466
  }
410
467
  notToBePrimitive() {
468
+ this._expected = true;
411
469
  if (isPrimitive(this.value)) {
412
- throw new Exception({
470
+ throw new TestException({
413
471
  message: `${this.value} is primitive type`,
414
472
  code: 1052,
415
- status: 'not-is-primitive'
473
+ status: "not-is-primitive"
416
474
  });
417
475
  }
418
476
  return this;
419
477
  }
420
478
  notToBeEmpty() {
479
+ this._expected = true;
421
480
  if (isEmpty(this.value)) {
422
- throw new Exception({
481
+ throw new TestException({
423
482
  message: `${this.value} is empty`,
424
483
  code: 1053,
425
- status: 'not-is-empty'
484
+ status: "not-is-empty"
426
485
  });
427
486
  }
428
487
  return this;
429
488
  }
430
489
  notToBeObject() {
490
+ this._expected = true;
431
491
  if (isObject(this.value)) {
432
- throw new Exception({
492
+ throw new TestException({
433
493
  message: `${this.value} is object`,
434
494
  code: 1054,
435
- status: 'not-is-object'
495
+ status: "not-is-object"
436
496
  });
437
497
  }
438
498
  return this;
439
499
  }
440
500
  notToBeSomeObject() {
501
+ this._expected = true;
441
502
  if (isSomeObject(this.value)) {
442
- throw new Exception({
503
+ throw new TestException({
443
504
  message: `${this.value} is some object`,
444
505
  code: 1055,
445
- status: 'not-is-some-object'
506
+ status: "not-is-some-object"
446
507
  });
447
508
  }
448
509
  return this;
449
510
  }
450
511
  notToBeFunction() {
512
+ this._expected = true;
451
513
  if (isFunction(this.value)) {
452
- throw new Exception({
514
+ throw new TestException({
453
515
  message: `${this.value} is function`,
454
516
  code: 1056,
455
- status: 'not-is-function'
517
+ status: "not-is-function"
456
518
  });
457
519
  }
458
520
  return this;
459
521
  }
460
522
  notToBeNumeric() {
523
+ this._expected = true;
461
524
  if (isNumeric(this.value)) {
462
- throw new Exception({
525
+ throw new TestException({
463
526
  message: `${this.value} is numeric`,
464
527
  code: 1057,
465
- status: 'not-is-numeric'
528
+ status: "not-is-numeric"
466
529
  });
467
530
  }
468
531
  return this;
469
532
  }
470
533
  notToBeArray() {
534
+ this._expected = true;
471
535
  if (isArray(this.value)) {
472
- throw new Exception({
536
+ throw new TestException({
473
537
  message: `${this.value} is array`,
474
538
  code: 1058,
475
- status: 'not-is-array'
539
+ status: "not-is-array"
476
540
  });
477
541
  }
478
542
  return this;
479
543
  }
480
544
  toBeEmptyArray() {
545
+ this._expected = true;
481
546
  if (isSomeArray(this.value)) {
482
- throw new Exception({
547
+ throw new TestException({
483
548
  message: `${this.value} is some array`,
484
549
  code: 1059,
485
- status: 'to-be-empty-array'
550
+ status: "to-be-empty-array"
486
551
  });
487
552
  }
488
553
  return this;
489
554
  }
490
555
  notToBeIterable() {
556
+ this._expected = true;
491
557
  if (isIterable(this.value)) {
492
- throw new Exception({
558
+ throw new TestException({
493
559
  message: `${this.value} is iterable`,
494
560
  code: 1060,
495
- status: 'not-iterable'
561
+ status: "not-iterable"
496
562
  });
497
563
  }
498
564
  return this;
499
565
  }
500
566
  notToBeSubClassOf(type) {
567
+ this._expected = true;
501
568
  if (isSubClassOf(this.value, type)) {
502
- throw new Exception({
569
+ throw new TestException({
503
570
  message: `${this.value} is subclass of ${type}`,
504
571
  code: 1061,
505
- status: 'not-subclassof'
572
+ status: "not-subclassof"
506
573
  });
507
574
  }
508
575
  return this;
509
576
  }
510
577
  notToBeInstanceOf(type) {
578
+ this._expected = true;
511
579
  if (this.value instanceof type) {
512
- throw new Exception({
580
+ throw new TestException({
513
581
  message: `${this.value} is instance of ${type}`,
514
582
  code: 1062,
515
- status: 'not-instanceof'
583
+ status: "not-instanceof"
516
584
  });
517
585
  }
518
586
  return this;
519
587
  }
520
588
  doesNotMatch(pattern, flags) {
589
+ this._expected = true;
521
590
  const r = new RegExp(pattern, flags);
522
591
  if (r.test(this.value)) {
523
- throw new Exception({
592
+ throw new TestException({
524
593
  message: `${this.value} matches ${pattern}`,
525
594
  code: 1063,
526
- status: 'not-match'
595
+ status: "not-match"
527
596
  });
528
597
  }
529
598
  return this;
530
599
  }
531
600
  toBeValid(fnValidation) {
601
+ this._expected = true;
532
602
  if (!isFunction(fnValidation)) {
533
- throw new Exception({
603
+ throw new TestException({
534
604
  message: `fnValidation is not function`,
535
605
  code: 1064,
536
- status: 'to-be-valid'
606
+ status: "to-be-valid"
537
607
  });
538
608
  }
539
609
  if (!fnValidation(this.value)) {
540
- throw new Exception({
610
+ throw new TestException({
541
611
  message: `${this.value} is not valid`,
542
612
  code: 1065,
543
- status: 'to-be-valid'
613
+ status: "to-be-valid"
544
614
  });
545
615
  }
546
616
  return this;
547
617
  }
548
618
  notToBeValid(fnValidation) {
619
+ this._expected = true;
549
620
  if (!isFunction(fnValidation)) {
550
- throw new Exception({
621
+ throw new TestException({
551
622
  message: `fnValidation is not function`,
552
623
  code: 1066,
553
- status: 'not-to-be-valid'
624
+ status: "not-to-be-valid"
554
625
  });
555
626
  }
556
627
  if (fnValidation(this.value)) {
557
- throw new Exception({
628
+ throw new TestException({
558
629
  message: `${this.value} is valid`,
559
630
  code: 1067,
560
- status: 'not-to-be-valid'
631
+ status: "not-to-be-valid"
561
632
  });
562
633
  }
563
634
  return this;
564
635
  }
565
636
  toThrow(ex, shape = false, strict = false) {
637
+ this._expected = true;
566
638
  if (!isFunction(this.value)) {
567
- throw new Exception({
639
+ throw new TestException({
568
640
  message: `given argument is not a function.`,
569
641
  code: 1012,
570
- status: 'not-func'
642
+ status: "not-func"
571
643
  });
572
644
  }
573
645
  let ok = false;
@@ -578,64 +650,65 @@ class Expect {
578
650
  if (ex !== undefined) {
579
651
  if (isPrimitive(ex)) {
580
652
  if (e !== ex) {
581
- throw new Exception({
653
+ throw new TestException({
582
654
  message: `given function threw incorrect error.`,
583
655
  code: 1018,
584
- status: 'incorrect-throw-error'
656
+ status: "incorrect-throw-error"
585
657
  });
586
658
  }
587
659
  } else if (isFunction(ex)) {
588
660
  if (!(e instanceof ex)) {
589
- throw new Exception({
661
+ throw new TestException({
590
662
  message: `given function threw incorrect instance.`,
591
663
  code: 1019,
592
- status: 'incorrect-throw-instance'
664
+ status: "incorrect-throw-instance"
593
665
  });
594
666
  }
595
667
  } else if (isObject(ex)) {
596
668
  if (shape) {
597
669
  if (!equals(e, ex, strict)) {
598
- throw new Exception({
670
+ throw new TestException({
599
671
  message: `given function threw incorrect object shape.`,
600
672
  code: 1020,
601
- status: 'incorrect-throw-shape'
673
+ status: "incorrect-throw-shape"
602
674
  });
603
675
  }
604
676
  } else {
605
677
  if (e !== ex) {
606
- throw new Exception({
678
+ throw new TestException({
607
679
  message: `given function threw incorrect object.`,
608
680
  code: 1021,
609
- status: 'incorrect-throw-object'
681
+ status: "incorrect-throw-object"
610
682
  });
611
683
  }
612
684
  }
613
685
  } else {
614
686
  if (e !== ex) {
615
- throw new Exception({
687
+ throw new TestException({
616
688
  message: `given function threw incorrect value.`,
617
689
  code: 1022,
618
- status: 'incorrect-throw-value'
690
+ status: "incorrect-throw-value"
619
691
  });
620
692
  }
621
693
  }
622
694
  }
623
695
  }
624
696
  if (ok) {
625
- throw new Exception({
697
+ throw new TestException({
626
698
  message: `given function ran without throwing any errors.`,
627
699
  code: 1013,
628
- status: 'ran-to-completion'
700
+ status: "ran-to-completion"
629
701
  });
630
702
  }
631
703
  return this;
632
704
  }
633
705
  async toThrowAsync(ex, shape = false, strict = false) {
706
+ this._expected = true;
634
707
  if (!isFunction(this.value)) {
635
- throw new Exception({
708
+ throw new TestException({
636
709
  message: `given argument is not a function.`,
637
710
  code: 1012,
638
- status: 'not-func'
711
+ status: "not-func"
639
712
  });
640
713
  }
641
714
  let ok = false;
@@ -646,64 +719,65 @@ class Expect {
646
719
  if (ex !== undefined) {
647
720
  if (isPrimitive(ex)) {
648
721
  if (e !== ex) {
649
- throw new Exception({
722
+ throw new TestException({
650
723
  message: `given function threw incorrect error.`,
651
724
  code: 1018,
652
- status: 'incorrect-throw-error'
725
+ status: "incorrect-throw-error"
653
726
  });
654
727
  }
655
728
  } else if (isFunction(ex)) {
656
729
  if (!(e instanceof ex)) {
657
- throw new Exception({
730
+ throw new TestException({
658
731
  message: `given function threw incorrect instance.`,
659
732
  code: 1019,
660
- status: 'incorrect-throw-instance'
733
+ status: "incorrect-throw-instance"
661
734
  });
662
735
  }
663
736
  } else if (isObject(ex)) {
664
737
  if (shape) {
665
738
  if (!equals(e, ex, strict)) {
666
- throw new Exception({
739
+ throw new TestException({
667
740
  message: `given function threw incorrect object shape.`,
668
741
  code: 1020,
669
- status: 'incorrect-throw-shape'
742
+ status: "incorrect-throw-shape"
670
743
  });
671
744
  }
672
745
  } else {
673
746
  if (e !== ex) {
674
- throw new Exception({
747
+ throw new TestException({
675
748
  message: `given function threw incorrect object.`,
676
749
  code: 1021,
677
- status: 'incorrect-throw-object'
750
+ status: "incorrect-throw-object"
678
751
  });
679
752
  }
680
753
  }
681
754
  } else {
682
755
  if (e !== ex) {
683
- throw new Exception({
756
+ throw new TestException({
684
757
  message: `given function threw incorrect value.`,
685
758
  code: 1022,
686
- status: 'incorrect-throw-value'
759
+ status: "incorrect-throw-value"
687
760
  });
688
761
  }
689
762
  }
690
763
  }
691
764
  }
692
765
  if (ok) {
693
- throw new Exception({
766
+ throw new TestException({
694
767
  message: `given function ran without throwing any errors.`,
695
768
  code: 1013,
696
- status: 'ran-to-completion'
769
+ status: "ran-to-completion"
697
770
  });
698
771
  }
699
772
  return this;
700
773
  }
701
774
  notToThrow(ex, shape = false, strict = false) {
775
+ this._expected = true;
702
776
  if (!isFunction(this.value)) {
703
- throw new Exception({
777
+ throw new TestException({
704
778
  message: `given argument is not a function.`,
705
779
  code: 1012,
706
- status: 'not-func'
780
+ status: "not-func"
707
781
  });
708
782
  }
709
783
  let ok = true;
@@ -716,65 +790,66 @@ class Expect {
716
790
  if (ex !== undefined) {
717
791
  if (isPrimitive(ex)) {
718
792
  if (e === ex) {
719
- throw new Exception({
793
+ throw new TestException({
720
794
  message: `given function threw incorrect error.`,
721
795
  code: 1018,
722
- status: 'incorrect-throw-error'
796
+ status: "incorrect-throw-error"
723
797
  });
724
798
  }
725
799
  } else if (isFunction(ex)) {
726
800
  if (e instanceof ex) {
727
- throw new Exception({
801
+ throw new TestException({
728
802
  message: `given function threw incorrect instance.`,
729
803
  code: 1019,
730
- status: 'incorrect-throw-instance'
804
+ status: "incorrect-throw-instance"
731
805
  });
732
806
  }
733
807
  } else if (isObject(ex)) {
734
808
  if (shape) {
735
809
  if (equals(e, ex, strict)) {
736
- throw new Exception({
810
+ throw new TestException({
737
811
  message: `given function threw incorrect object shape.`,
738
812
  code: 1020,
739
- status: 'incorrect-throw-shape'
813
+ status: "incorrect-throw-shape"
740
814
  });
741
815
  }
742
816
  } else {
743
817
  if (e === ex) {
744
- throw new Exception({
818
+ throw new TestException({
745
819
  message: `given function threw incorrect object.`,
746
820
  code: 1021,
747
- status: 'incorrect-throw-object'
821
+ status: "incorrect-throw-object"
748
822
  });
749
823
  }
750
824
  }
751
825
  } else {
752
826
  if (e === ex) {
753
- throw new Exception({
827
+ throw new TestException({
754
828
  message: `given function threw incorrect value.`,
755
829
  code: 1022,
756
- status: 'incorrect-throw-value'
830
+ status: "incorrect-throw-value"
757
831
  });
758
832
  }
759
833
  }
760
834
  }
761
835
  }
762
836
  if (ok) {
763
- throw new Exception({
837
+ throw new TestException({
764
838
  message: `given function threw an error.`,
765
839
  code: 1014,
766
- status: 'ran-to-error',
840
+ status: "ran-to-error",
767
841
  innerException: error
768
842
  });
769
843
  }
770
844
  return this;
771
845
  }
772
846
  async notToThrowAsync(ex, shape = false, strict = false) {
847
+ this._expected = true;
773
848
  if (!isFunction(this.value)) {
774
- throw new Exception({
849
+ throw new TestException({
775
850
  message: `given argument is not a function.`,
776
851
  code: 1012,
777
- status: 'not-func'
852
+ status: "not-func"
778
853
  });
779
854
  }
780
855
  let ok = true;
@@ -787,101 +862,110 @@ class Expect {
787
862
  if (ex !== undefined) {
788
863
  if (isPrimitive(ex)) {
789
864
  if (e === ex) {
790
- throw new Exception({
865
+ throw new TestException({
791
866
  message: `given function threw incorrect error.`,
792
867
  code: 1018,
793
- status: 'incorrect-throw-error'
868
+ status: "incorrect-throw-error"
794
869
  });
795
870
  }
796
871
  } else if (isFunction(ex)) {
797
872
  if (e instanceof ex) {
798
- throw new Exception({
873
+ throw new TestException({
799
874
  message: `given function threw incorrect instance.`,
800
875
  code: 1019,
801
- status: 'incorrect-throw-instance'
876
+ status: "incorrect-throw-instance"
802
877
  });
803
878
  }
804
879
  } else if (isObject(ex)) {
805
880
  if (shape) {
806
881
  if (equals(e, ex, strict)) {
807
- throw new Exception({
882
+ throw new TestException({
808
883
  message: `given function threw incorrect object shape.`,
809
884
  code: 1020,
810
- status: 'incorrect-throw-shape'
885
+ status: "incorrect-throw-shape"
811
886
  });
812
887
  }
813
888
  } else {
814
889
  if (e === ex) {
815
- throw new Exception({
890
+ throw new TestException({
816
891
  message: `given function threw incorrect object.`,
817
892
  code: 1021,
818
- status: 'incorrect-throw-object'
893
+ status: "incorrect-throw-object"
819
894
  });
820
895
  }
821
896
  }
822
897
  } else {
823
898
  if (e === ex) {
824
- throw new Exception({
899
+ throw new TestException({
825
900
  message: `given function threw incorrect value.`,
826
901
  code: 1022,
827
- status: 'incorrect-throw-value'
902
+ status: "incorrect-throw-value"
828
903
  });
829
904
  }
830
905
  }
831
906
  }
832
907
  }
833
908
  if (ok) {
834
- throw new Exception({
909
+ throw new TestException({
835
910
  message: `given function threw an error.`,
836
911
  code: 1014,
837
- status: 'ran-to-error',
912
+ status: "ran-to-error",
838
913
  innerException: error
839
914
  });
840
915
  }
841
916
  return this;
842
917
  }
843
918
  toBeTruthy() {
919
+ this._expected = true;
844
920
  if (this.value) {} else {
845
- throw new Exception({
921
+ throw new TestException({
846
922
  message: `${this.value} is not truthy`,
847
923
  code: 1015,
848
- status: 'not-truthy'
924
+ status: "not-truthy"
849
925
  });
850
926
  }
851
927
  return this;
852
928
  }
929
+ toBeTrue() {
930
+ return this.toBeTruthy();
931
+ }
853
932
  toBeFalsy() {
933
+ this._expected = true;
854
934
  if (!this.value) {} else {
855
- throw new Exception({
935
+ throw new TestException({
856
936
  message: `${this.value} is not falsy`,
857
937
  code: 1016,
858
- status: 'not-falsy'
938
+ status: "not-falsy"
859
939
  });
860
940
  }
861
941
  return this;
862
942
  }
943
+ toBeFalse() {
944
+ return this.toBeFalsy();
945
+ }
863
946
  toBeNaN() {
947
+ this._expected = true;
864
948
  if (isNaN(this.value)) {} else {
865
- throw new Exception({
949
+ throw new TestException({
866
950
  message: `${this.value} is not NaN`,
867
951
  code: 1017,
868
- status: 'not-nan'
952
+ status: "not-nan"
869
953
  });
870
954
  }
871
955
  return this;
872
956
  }
873
957
  notToBeNaN() {
958
+ this._expected = true;
874
959
  if (!isNaN(this.value)) {} else {
875
- throw new Exception({
960
+ throw new TestException({
876
961
  message: `${this.value} is NaN`,
877
962
  code: 1023,
878
- status: 'is-nan'
963
+ status: "is-nan"
879
964
  });
880
965
  }
881
966
  return this;
882
967
  }
883
968
  }
884
- const expect = x => new Expect(x);
885
969
  class Test {
886
970
  constructor(name, fn) {
887
971
  this.name = name;
@@ -891,25 +975,31 @@ class Test {
891
975
  return new Promise(res => {
892
976
  const start = new Date();
893
977
  if (isFunction(this.fn)) {
978
+ const _expect = new Expect();
894
979
  try {
895
- const _result = this.fn(expect);
980
+ const _result = this.fn(x => {
981
+ _expect.value = x;
982
+ return _expect;
983
+ });
896
984
  if (_result && isFunction(_result.then)) {
897
985
  _result.then(result => {
898
986
  res({
899
987
  success: true,
900
988
  test: this.name,
901
989
  result,
902
- time: new Date() - start
990
+ time: new Date() - start,
991
+ expected: _expect.expected
903
992
  });
904
993
  }).catch(ex => {
905
994
  res({
906
995
  success: false,
907
996
  test: this.name,
908
997
  time: new Date() - start,
909
- err: new Exception({
998
+ expected: _expect.expected,
999
+ err: new TestException({
910
1000
  message: `test '${this.name}' failed.`,
911
1001
  code: 501,
912
- status: 'failed',
1002
+ status: "failed",
913
1003
  innerException: ex
914
1004
  })
915
1005
  });
@@ -919,7 +1009,8 @@ class Test {
919
1009
  success: true,
920
1010
  test: this.name,
921
1011
  time: new Date() - start,
922
- result: _result
1012
+ result: _result,
1013
+ expected: _expect.expected
923
1014
  });
924
1015
  }
925
1016
  } catch (ex) {
@@ -927,10 +1018,11 @@ class Test {
927
1018
  success: false,
928
1019
  test: this.name,
929
1020
  time: new Date() - start,
930
- err: new Exception({
1021
+ expected: _expect.expected,
1022
+ err: new TestException({
931
1023
  message: `test '${this.name}' failed.`,
932
1024
  code: 501,
933
- status: 'failed',
1025
+ status: "failed",
934
1026
  innerException: ex
935
1027
  })
936
1028
  });
@@ -940,34 +1032,46 @@ class Test {
940
1032
  success: false,
941
1033
  test: this.name,
942
1034
  time: new Date() - start,
943
- err: new Exception({
1035
+ err: new TestException({
944
1036
  message: `test '${this.name}' does not have a function to be called.`,
945
1037
  code: 500,
946
- status: 'no-func'
1038
+ status: "no-func"
947
1039
  })
948
1040
  });
949
1041
  }
950
1042
  });
951
1043
  }
952
1044
  }
953
- const ConsoleColors = {
954
- BackColor: {
955
- Black: 40
956
- },
957
- ForeColor: {
958
- Red: 31,
959
- Green: 32,
960
- White: 37,
961
- Gray: 90
962
- },
963
- Modifier: {
964
- Reset: "\x1b[0m"
965
- }
966
- };
1045
+ const reset = "\x1b[0m";
1046
+ const bright = "\x1b[1m";
1047
+ const dim = "\x1b[2m";
1048
+ const underscore = "\x1b[4m";
1049
+ const blink = "\x1b[5m";
1050
+ const reverse = "\x1b[7m";
1051
+ const hidden = "\x1b[8m";
1052
+ const fgBlack = "\x1b[30m";
1053
+ const fgRed = "\x1b[31m";
1054
+ const fgGreen = "\x1b[32m";
1055
+ const fgYellow = "\x1b[33m";
1056
+ const fgBlue = "\x1b[34m";
1057
+ const fgMagenta = "\x1b[35m";
1058
+ const fgCyan = "\x1b[36m";
1059
+ const fgWhite = "\x1b[37m";
1060
+ const fgGray = "\x1b[90m";
1061
+ const bgBlack = "\x1b[40m";
1062
+ const bgRed = "\x1b[41m";
1063
+ const bgGreen = "\x1b[42m";
1064
+ const bgYellow = "\x1b[43m";
1065
+ const bgBlue = "\x1b[44m";
1066
+ const bgMagenta = "\x1b[45m";
1067
+ const bgCyan = "\x1b[46m";
1068
+ const bgWhite = "\x1b[47m";
1069
+ const bgGray = "\x1b[100m";
967
1070
  class TestRunner {
968
1071
  constructor() {
969
1072
  this._passed = 0;
970
1073
  this._failed = 0;
1074
+ this._unknown = 0;
971
1075
  this._results = [];
972
1076
  this._errors = [];
973
1077
  }
@@ -979,10 +1083,10 @@ class TestRunner {
979
1083
  this._errors.push({
980
1084
  index: i,
981
1085
  test: test.name,
982
- err: new Exception({
1086
+ err: new TestException({
983
1087
  message: `onProgress failed for test '${test.name} at index ${i}'.`,
984
1088
  code: 1500,
985
- status: 'progress-failed',
1089
+ status: "progress-failed",
986
1090
  innerException: ex
987
1091
  })
988
1092
  });
@@ -990,7 +1094,9 @@ class TestRunner {
990
1094
  }
991
1095
  const tr = await test.run();
992
1096
  this._results.push(tr);
993
- if (tr.success) {
1097
+ if (!tr.expected) {
1098
+ this._unknown++;
1099
+ } else if (tr.success) {
994
1100
  this._passed++;
995
1101
  } else {
996
1102
  this._failed++;
@@ -1026,10 +1132,10 @@ class TestRunner {
1026
1132
  }).filter(test => test instanceof Test).map((test, i) => this._runSingle(test, onProgress, i));
1027
1133
  Promise.all(_tests).then(_ => res(this.result)).catch(ex => {
1028
1134
  this._errors.push({
1029
- err: new Exception({
1135
+ err: new TestException({
1030
1136
  message: `not all tests succeeded. check errors.`,
1031
1137
  code: 1503,
1032
- status: 'partial-finished',
1138
+ status: "partial-finished",
1033
1139
  innerException: ex
1034
1140
  })
1035
1141
  });
@@ -1037,20 +1143,20 @@ class TestRunner {
1037
1143
  });
1038
1144
  } else {
1039
1145
  this._errors.push({
1040
- err: new Exception({
1146
+ err: new TestException({
1041
1147
  message: `invalid tests. expected array or a single test.`,
1042
1148
  code: 1502,
1043
- status: 'invalid-tests'
1149
+ status: "invalid-tests"
1044
1150
  })
1045
1151
  });
1046
1152
  res(this.result);
1047
1153
  }
1048
1154
  } else {
1049
1155
  this._errors.push({
1050
- err: new Exception({
1156
+ err: new TestException({
1051
1157
  message: `no tests given to be ran.`,
1052
1158
  code: 1501,
1053
- status: 'no-tests'
1159
+ status: "no-tests"
1054
1160
  })
1055
1161
  });
1056
1162
  res(this.result);
@@ -1062,24 +1168,29 @@ class TestRunner {
1062
1168
  }
1063
1169
  report(detailed) {
1064
1170
  let time = 0;
1065
- console.log('Finished.\n');
1171
+ console.log("Finished.\n");
1066
1172
  for (let i = 0; i < this._results.length; i++) {
1067
1173
  const result = this._results[i];
1174
+ const t = `(${this._getTime(result.time)})`;
1068
1175
  if (detailed) {
1069
- let message = '\n';
1070
- if (result.success) {
1071
- message += `${i + 1}. \x1b[${ConsoleColors.ForeColor.White}m${result.test}: \x1b[${ConsoleColors.ForeColor.Green}m passed ${ConsoleColors.Modifier.Reset} (${this._getTime(result.time)})`;
1176
+ let message = "\n" + (i + 1) + ". ";
1177
+ if (!result.expected) {
1178
+ message += `${bright}${fgWhite}${result.test}: ${fgMagenta}expect not used${reset} ${t}`;
1179
+ } else if (result.success) {
1180
+ message += `${fgWhite}${result.test}: ${fgGreen}passed${reset} ${t}`;
1072
1181
  } else {
1073
- message += `${i + 1}. \x1b[${ConsoleColors.ForeColor.White}m${result.test}: \x1b[${ConsoleColors.ForeColor.Red}m failed ${ConsoleColors.Modifier.Reset} (${this._getTime(result.time)})`;
1074
- message += '\n';
1075
- message += `\x1b[${ConsoleColors.ForeColor.White}m${result.err.code}: ${result.err.toString()} ${ConsoleColors.Modifier.Reset}`;
1182
+ message += `${bright}${fgWhite}${result.test}: ${fgRed}failed${reset} ${t}`;
1183
+ message += "\n";
1184
+ let err = result.err.toString().split("\n");
1185
+ err = err.map((msg, i) => `\t${i == err.length - 1 ? `${fgYellow}` : `${fgGray}error ${result.err.code}: `}${msg}${reset}`).join("\n");
1186
+ message += `${fgGray}${err} ${reset}`;
1076
1187
  }
1077
1188
  console.log(message);
1078
1189
  }
1079
1190
  time += result.time;
1080
1191
  }
1081
1192
  if (detailed && this._errors.length) {
1082
- console.log('Errors:');
1193
+ console.log("Errors:");
1083
1194
  for (let error of this._errors) {
1084
1195
  if (error.index !== undefined) {
1085
1196
  console.log(`${error.index}. ${error.test}: ${error.err.innerException.toString()}`);
@@ -1088,22 +1199,22 @@ class TestRunner {
1088
1199
  }
1089
1200
  }
1090
1201
  }
1091
- const text = (detailed ? '\n' : '') + `Tests: ${this._passed + this._failed}` + '\n' + `Time: ${time / 1000} sec` + '\n\n' + (this._passed > 0 ? `\x1b[${ConsoleColors.ForeColor.Green}m ${this._passed} tests passed${ConsoleColors.Modifier.Reset}` : '0 tests passed') + ', ' + (this._failed > 0 ? `\x1b[${ConsoleColors.ForeColor.Red}m ${this._failed} tests failed${ConsoleColors.Modifier.Reset}` : '0 tests failed') + '\n';
1202
+ const text = (detailed ? "\n" : "") + `${bright}Number of tests: ${reset}${this._passed + this._failed}` + "\n" + `${bright}Total Time: ${reset}${time / 1000} sec` + "\n\n" + (this._passed > 0 ? `${fgGreen} ${this._passed} test(s) passed${reset}` : `0 tests passed${reset}`) + ", " + (this._failed > 0 ? `${fgRed} ${this._failed} test(s) failed${reset}` : `0 tests failed${reset}`) + (this._unknown > 0 ? `, ${fgMagenta} ${this._unknown} test(s) are unknown${reset}` : ``) + "\n";
1092
1203
  console.log(text);
1093
1204
  }
1094
1205
  log(filename) {
1095
1206
  const content = JSON.stringify({
1096
1207
  results: this._results,
1097
1208
  errors: this._errors
1098
- }, null, '\t');
1209
+ }, null, "\t");
1099
1210
  if (filename == null) {
1100
1211
  const d = new Date();
1101
- const year = d.getFullYear().toString().padStart(4, '0');
1102
- const month = (d.getMonth() + 1).toString().padStart(2, '0');
1103
- const day = d.getDate().toString().padStart(2, '0');
1104
- const hours = d.getHours().toString().padStart(2, '0');
1105
- const minutes = d.getMinutes().toString().padStart(2, '0');
1106
- const seconds = d.getSeconds().toString().padStart(2, '0');
1212
+ const year = d.getFullYear().toString().padStart(4, "0");
1213
+ const month = (d.getMonth() + 1).toString().padStart(2, "0");
1214
+ const day = d.getDate().toString().padStart(2, "0");
1215
+ const hours = d.getHours().toString().padStart(2, "0");
1216
+ const minutes = d.getMinutes().toString().padStart(2, "0");
1217
+ const seconds = d.getSeconds().toString().padStart(2, "0");
1107
1218
  filename = `test-${year}-${month}-${day}-${hours}${minutes}${seconds}.json`;
1108
1219
  }
1109
1220
  const filepath = path.join(process.cwd(), filename);
@@ -1111,9 +1222,13 @@ class TestRunner {
1111
1222
  fs.writeFileSync(filepath, content);
1112
1223
  console.log(`tests outcome wrote in ${filename}.`);
1113
1224
  } catch (ex) {
1114
- console.log('writing tests outcome failed.\n' + ex);
1225
+ console.log("writing tests outcome failed.\n" + ex);
1115
1226
  }
1116
1227
  }
1228
+ static start(tests) {
1229
+ const tr = new TestRunner();
1230
+ tr.run(tests).then(result => tr.report(result.failed > 0));
1231
+ }
1117
1232
  }
1118
1233
  export default TestRunner;
1119
- export { Test, Expect, expect };
1234
+ export { Test, Expect, TestException };