as-test 0.4.3 → 0.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 (67) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +196 -82
  3. package/as-test.config.schema.json +137 -0
  4. package/assembly/coverage.ts +19 -0
  5. package/assembly/index.ts +172 -85
  6. package/assembly/src/expectation.ts +263 -199
  7. package/assembly/src/log.ts +1 -9
  8. package/assembly/src/suite.ts +61 -25
  9. package/assembly/src/tests.ts +2 -0
  10. package/assembly/util/wipc.ts +286 -0
  11. package/bin/build.js +86 -41
  12. package/bin/index.js +337 -68
  13. package/bin/init.js +441 -183
  14. package/bin/reporter.js +1 -1
  15. package/bin/reporters/default.js +379 -0
  16. package/bin/reporters/types.js +1 -0
  17. package/bin/run.js +882 -194
  18. package/bin/types.js +14 -7
  19. package/bin/util.js +54 -3
  20. package/package.json +34 -16
  21. package/transform/lib/builder.js +169 -169
  22. package/transform/lib/builder.js.map +1 -1
  23. package/transform/lib/coverage.js +47 -1
  24. package/transform/lib/coverage.js.map +1 -1
  25. package/transform/lib/index.js +70 -0
  26. package/transform/lib/index.js.map +1 -1
  27. package/transform/lib/location.js +20 -0
  28. package/transform/lib/location.js.map +1 -0
  29. package/transform/lib/log.js +118 -0
  30. package/transform/lib/log.js.map +1 -0
  31. package/transform/lib/mock.js +2 -2
  32. package/transform/lib/mock.js.map +1 -1
  33. package/transform/lib/util.js +3 -3
  34. package/transform/lib/util.js.map +1 -1
  35. package/.github/workflows/as-test.yml +0 -26
  36. package/.prettierrc +0 -3
  37. package/as-test.config.json +0 -19
  38. package/assembly/__tests__/array.spec.ts +0 -25
  39. package/assembly/__tests__/math.spec.ts +0 -16
  40. package/assembly/__tests__/mock.spec.ts +0 -22
  41. package/assembly/__tests__/mock.ts +0 -7
  42. package/assembly/__tests__/sleep.spec.ts +0 -28
  43. package/assembly/tsconfig.json +0 -97
  44. package/assets/img/screenshot.png +0 -0
  45. package/cli/build.ts +0 -117
  46. package/cli/index.ts +0 -190
  47. package/cli/init.ts +0 -247
  48. package/cli/reporter.ts +0 -1
  49. package/cli/run.ts +0 -286
  50. package/cli/tsconfig.json +0 -9
  51. package/cli/types.ts +0 -29
  52. package/cli/util.ts +0 -65
  53. package/run/package.json +0 -27
  54. package/tests/array.run.js +0 -7
  55. package/tests/math.run.js +0 -7
  56. package/tests/mock.run.js +0 -14
  57. package/tests/sleep.run.js +0 -7
  58. package/transform/src/builder.ts +0 -1474
  59. package/transform/src/coverage.ts +0 -580
  60. package/transform/src/index.ts +0 -73
  61. package/transform/src/linker.ts +0 -41
  62. package/transform/src/mock.ts +0 -163
  63. package/transform/src/range.ts +0 -12
  64. package/transform/src/types.ts +0 -35
  65. package/transform/src/util.ts +0 -81
  66. package/transform/src/visitor.ts +0 -744
  67. package/transform/tsconfig.json +0 -10
@@ -1,7 +1,13 @@
1
1
  import { visualize } from "../util/helpers";
2
2
  import { Tests } from "./tests";
3
- import { after_each_callback, before_each_callback } from "..";
4
3
  import { JSON } from "json-as";
4
+ import {
5
+ sendAssertionFailure,
6
+ sendWarning,
7
+ snapshotAssert,
8
+ } from "../util/wipc";
9
+
10
+ let warnedToThrowDisabled = false;
5
11
 
6
12
 
7
13
  @json
@@ -10,382 +16,416 @@ export class Expectation<T> extends Tests {
10
16
  public right: JSON.Raw = JSON.Raw.from("");
11
17
  public left: JSON.Raw = JSON.Raw.from("");
12
18
 
19
+
13
20
  @omit
14
21
  private _left: T;
15
22
 
23
+
16
24
  @omit
17
25
  // @ts-ignore
18
26
  private _right: u64 = 0;
19
27
 
28
+
20
29
  @omit
21
30
  // @ts-ignore
22
31
  private _not: boolean = false;
23
- constructor(left: T) {
32
+
33
+ @omit
34
+ // @ts-ignore
35
+ private _skip: boolean = false;
36
+
37
+
38
+ @omit
39
+ private _message: string = "";
40
+
41
+
42
+ @omit
43
+ private _snapshotKey: string = "";
44
+
45
+
46
+ @omit
47
+ private _location: string = "";
48
+
49
+ constructor(
50
+ left: T,
51
+ message: string = "",
52
+ snapshotKey: string = "",
53
+ location: string = "",
54
+ ) {
24
55
  super();
25
56
  this._left = left;
57
+ this._message = message;
58
+ this._snapshotKey = snapshotKey;
59
+ this._location = location;
60
+ this.location = location;
26
61
  }
62
+
27
63
  get not(): Expectation<T> {
28
64
  this._not = true;
29
65
  return this;
30
66
  }
31
67
 
68
+ skip(): Expectation<T> {
69
+ this._skip = true;
70
+ return this;
71
+ }
72
+
73
+ private _resolve(
74
+ passed: bool,
75
+ instr: string,
76
+ left: string,
77
+ right: string,
78
+ ): void {
79
+ if (this._skip) {
80
+ this.verdict = "skip";
81
+ this.instr = instr;
82
+ this.left.set(left);
83
+ this.right.set(right);
84
+ this.message = "";
85
+ this._not = false;
86
+ return;
87
+ }
88
+ const isFail = this._not ? passed : !passed;
89
+ this.verdict = isFail ? "fail" : "ok";
90
+ this.instr = instr;
91
+ this.left.set(left);
92
+ this.right.set(right);
93
+ this.message = isFail ? this._message : "";
94
+ if (isFail) {
95
+ sendAssertionFailure(this._snapshotKey, instr, left, right, this.message);
96
+ }
97
+ this._not = false;
98
+ }
99
+
32
100
  /**
33
101
  * Tests if a == null
34
- * @returns - void
35
102
  */
36
103
  toBeNull(): void {
37
- this.verdict =
38
- isNullable<T>() && changetype<usize>(this._left) ? "ok" : "fail";
104
+ const passed =
105
+ (isNullable<T>() && changetype<usize>(this._left) == 0) ||
106
+ (isInteger<T>() && nameof<T>() == "usize" && this._left == 0);
39
107
 
40
108
  // @ts-ignore
41
109
  store<T>(changetype<usize>(this), null, offsetof<Expectation<T>>("_right"));
42
-
43
- this.instr = "toBeNull";
44
-
45
- this.left.set(visualize<T>(this._left));
46
- this.right.set(
110
+ this._resolve(
111
+ passed,
112
+ "toBeNull",
113
+ visualize<T>(this._left),
47
114
  visualize<T>(
48
115
  load<T>(changetype<usize>(this), offsetof<Expectation<T>>("_right")),
49
116
  ),
50
117
  );
51
-
52
- // @ts-ignore
53
- if (after_each_callback) after_each_callback();
54
- // @ts-ignore
55
- if (before_each_callback) before_each_callback();
56
118
  }
57
119
 
58
120
  /**
59
121
  * Tests if a > b
60
- * @param number equals - The value to test
61
- * @returns - void
62
122
  */
63
123
  toBeGreaterThan(value: T): void {
64
124
  if (!isInteger<T>() && !isFloat<T>())
65
125
  ERROR("toBeGreaterThan() can only be used on number types!");
66
126
 
67
- this.verdict = this._left > value ? "ok" : "fail";
68
127
  store<T>(
69
128
  changetype<usize>(this),
70
129
  value,
71
130
  offsetof<Expectation<T>>("_right"),
72
131
  );
73
-
74
- this.instr = "toBeGreaterThan";
75
-
76
- this.left.set(visualize<T>(this._left));
77
- this.right.set(
132
+ this._resolve(
133
+ this._left > value,
134
+ "toBeGreaterThan",
135
+ visualize<T>(this._left),
78
136
  visualize<T>(
79
137
  load<T>(changetype<usize>(this), offsetof<Expectation<T>>("_right")),
80
138
  ),
81
139
  );
82
-
83
- // @ts-ignore
84
- if (after_each_callback) after_each_callback();
85
- // @ts-ignore
86
- if (before_each_callback) before_each_callback();
87
140
  }
88
141
 
89
142
  /**
90
143
  * Tests if a >= b
91
- * @param number equals - The value to test
92
- * @returns - void
93
144
  */
94
145
  toBeGreaterOrEqualTo(value: T): void {
95
146
  if (!isInteger<T>() && !isFloat<T>())
96
147
  ERROR("toBeGreaterOrEqualTo() can only be used on number types!");
97
148
 
98
- this.verdict = this._left >= value ? "ok" : "fail";
99
149
  store<T>(
100
150
  changetype<usize>(this),
101
151
  value,
102
152
  offsetof<Expectation<T>>("_right"),
103
153
  );
104
-
105
- this.instr = "toBeGreaterThanOrEqualTo";
106
-
107
- this.left.set(visualize<T>(this._left));
108
- this.right.set(
154
+ this._resolve(
155
+ this._left >= value,
156
+ "toBeGreaterThanOrEqualTo",
157
+ visualize<T>(this._left),
109
158
  visualize<T>(
110
159
  load<T>(changetype<usize>(this), offsetof<Expectation<T>>("_right")),
111
160
  ),
112
161
  );
113
-
114
- // @ts-ignore
115
- if (after_each_callback) after_each_callback();
116
- // @ts-ignore
117
- if (before_each_callback) before_each_callback();
118
162
  }
119
163
 
120
164
  /**
121
165
  * Tests if a < b
122
- * @param number equals - The value to test
123
- * @returns - void
124
166
  */
125
167
  toBeLessThan(value: T): void {
126
168
  if (!isInteger<T>() && !isFloat<T>())
127
169
  ERROR("toBeLessThan() can only be used on number types!");
128
170
 
129
- this.verdict = this._left < value ? "ok" : "fail";
130
171
  store<T>(
131
172
  changetype<usize>(this),
132
173
  value,
133
174
  offsetof<Expectation<T>>("_right"),
134
175
  );
135
-
136
- this.instr = "toBeLessThan";
137
-
138
- this.left.set(visualize<T>(this._left));
139
- this.right.set(
176
+ this._resolve(
177
+ this._left < value,
178
+ "toBeLessThan",
179
+ visualize<T>(this._left),
140
180
  visualize<T>(
141
181
  load<T>(changetype<usize>(this), offsetof<Expectation<T>>("_right")),
142
182
  ),
143
183
  );
144
-
145
- // @ts-ignore
146
- if (after_each_callback) after_each_callback();
147
- // @ts-ignore
148
- if (before_each_callback) before_each_callback();
149
184
  }
150
185
 
151
186
  /**
152
187
  * Tests if a <= b
153
- * @param number equals - The value to test
154
- * @returns - void
155
188
  */
156
189
  toBeLessThanOrEqualTo(value: T): void {
157
190
  if (!isInteger<T>() && !isFloat<T>())
158
191
  ERROR("toBeLessThanOrEqualTo() can only be used on number types!");
159
192
 
160
- this.verdict = this._left <= value ? "ok" : "fail";
161
193
  store<T>(
162
194
  changetype<usize>(this),
163
195
  value,
164
196
  offsetof<Expectation<T>>("_right"),
165
197
  );
166
-
167
- this.instr = "toBeLessThanOrEqualTo";
168
-
169
- this.left.set(visualize<T>(this._left));
170
- this.right.set(
198
+ this._resolve(
199
+ this._left <= value,
200
+ "toBeLessThanOrEqualTo",
201
+ visualize<T>(this._left),
171
202
  visualize<T>(
172
203
  load<T>(changetype<usize>(this), offsetof<Expectation<T>>("_right")),
173
204
  ),
174
205
  );
175
-
176
- // @ts-ignore
177
- if (after_each_callback) after_each_callback();
178
- // @ts-ignore
179
- if (before_each_callback) before_each_callback();
180
206
  }
181
207
 
182
208
  /**
183
209
  * Tests if a is string
184
- * @returns - void
185
210
  */
186
211
  toBeString(): void {
187
- this.verdict = isString<T>() ? "ok" : "fail";
188
-
189
- this.left.set(nameof<T>());
190
- this.right.set("string");
191
-
192
- this.instr = "toBeString";
193
-
194
- // @ts-ignore
195
- if (after_each_callback) after_each_callback();
196
- // @ts-ignore
197
- if (before_each_callback) before_each_callback();
212
+ this._resolve(isString<T>(), "toBeString", q(nameof<T>()), q("string"));
198
213
  }
199
214
 
200
215
  /**
201
216
  * Tests if a is boolean
202
- * @returns - void
203
217
  */
204
218
  toBeBoolean(): void {
205
- this.verdict = isBoolean<T>() ? "ok" : "fail";
206
-
207
- this.left.set(nameof<T>());
208
- this.right.set("boolean");
209
-
210
- this.instr = "toBeBoolean";
211
-
212
- // @ts-ignore
213
- if (after_each_callback) after_each_callback();
214
- // @ts-ignore
215
- if (before_each_callback) before_each_callback();
219
+ this._resolve(isBoolean<T>(), "toBeBoolean", q(nameof<T>()), q("boolean"));
216
220
  }
217
221
 
218
222
  /**
219
223
  * Tests if a is array
220
- * @returns - void
221
224
  */
222
225
  toBeArray(): void {
223
- this.verdict = isArray<T>() ? "ok" : "fail";
224
-
225
- this.left.set(nameof<T>());
226
- this.right.set("Array<any>");
227
-
228
- this.instr = "toBeArray";
229
-
230
- // @ts-ignore
231
- if (after_each_callback) after_each_callback();
232
- // @ts-ignore
233
- if (before_each_callback) before_each_callback();
226
+ this._resolve(isArray<T>(), "toBeArray", q(nameof<T>()), q("Array<any>"));
234
227
  }
235
228
 
236
229
  /**
237
230
  * Tests if a is number
238
- * @returns - void
239
231
  */
240
232
  toBeNumber(): void {
241
- this.verdict = isFloat<T>() || isInteger<T>() ? "ok" : "fail";
242
-
243
- this.left.set(nameof<T>());
244
- this.right.set("number");
245
-
246
- this.instr = "toBeNumber";
247
-
248
- // @ts-ignore
249
- if (after_each_callback) after_each_callback();
250
- // @ts-ignore
251
- if (before_each_callback) before_each_callback();
233
+ this._resolve(
234
+ isFloat<T>() || isInteger<T>(),
235
+ "toBeNumber",
236
+ q(nameof<T>()),
237
+ q("number"),
238
+ );
252
239
  }
253
240
 
254
241
  /**
255
242
  * Tests if a is integer
256
- * @returns - void
257
243
  */
258
244
  toBeInteger(): void {
259
- this.verdict = isInteger<T>() ? "ok" : "fail";
260
-
261
- this.left.set(nameof<T>());
262
- this.right.set("float");
263
-
264
- this.instr = "toBeInteger";
265
-
266
- // @ts-ignore
267
- if (after_each_callback) after_each_callback();
268
- // @ts-ignore
269
- if (before_each_callback) before_each_callback();
245
+ this._resolve(isInteger<T>(), "toBeInteger", q(nameof<T>()), q("integer"));
270
246
  }
271
247
 
272
248
  /**
273
249
  * Tests if a is float
274
- * @returns - void
275
250
  */
276
251
  toBeFloat(): void {
277
- this.verdict = isFloat<T>() ? "ok" : "fail";
278
-
279
- this.left.set(nameof<T>());
280
- this.right.set("integer");
281
-
282
- this.instr = "toBeFloat";
283
-
284
- // @ts-ignore
285
- if (after_each_callback) after_each_callback();
286
- // @ts-ignore
287
- if (before_each_callback) before_each_callback();
252
+ this._resolve(isFloat<T>(), "toBeFloat", q(nameof<T>()), q("float"));
288
253
  }
289
254
 
290
255
  /**
291
256
  * Tests if a is finite
292
- * @returns - void
293
257
  */
294
258
  toBeFinite(): void {
295
- this.verdict =
296
- // @ts-ignore
297
- (isFloat<T>() || isInteger<T>()) && isFinite(this._left) ? "ok" : "fail";
259
+ // @ts-ignore
260
+ const passed = (isFloat<T>() || isInteger<T>()) && isFinite(this._left);
261
+ this._resolve(passed, "toBeFinite", q("Infinity"), q("Finite"));
262
+ }
298
263
 
299
- this.left.set("Infinity");
300
- this.right.set("Finite");
264
+ /**
265
+ * Tests if a value is truthy
266
+ */
267
+ toBeTruthy(): void {
268
+ this._resolve(
269
+ isTruthy<T>(this._left),
270
+ "toBeTruthy",
271
+ q("falsy"),
272
+ q("truthy"),
273
+ );
274
+ }
275
+
276
+ /**
277
+ * Tests if a value is falsy
278
+ */
279
+ toBeFalsy(): void {
280
+ this._resolve(
281
+ !isTruthy<T>(this._left),
282
+ "toBeFalsy",
283
+ q("truthy"),
284
+ q("falsy"),
285
+ );
286
+ }
301
287
 
302
- this.instr = "toBeFinite";
288
+ /**
289
+ * Tests if a floating-point number is close to expected
290
+ */
291
+ toBeCloseTo(expected: T, precision: i32 = 2): void {
292
+ if (!isFloat<T>() && !isInteger<T>())
293
+ ERROR("toBeCloseTo() can only be used on number types!");
294
+ const factor = Math.pow(10, precision as f64);
295
+ const delta = Math.abs((this._left as f64) - (expected as f64));
296
+ const passed = delta < 0.5 / factor;
297
+ this._resolve(
298
+ passed,
299
+ "toBeCloseTo",
300
+ visualize<T>(this._left),
301
+ visualize<T>(expected),
302
+ );
303
+ }
303
304
 
305
+ /**
306
+ * Tests if a string contains substring
307
+ */
308
+ toMatch(value: string): void {
309
+ if (!isString<T>()) ERROR("toMatch() can only be used on string types!");
304
310
  // @ts-ignore
305
- if (after_each_callback) after_each_callback();
311
+ const passed = this._left.indexOf(value) >= 0;
306
312
  // @ts-ignore
307
- if (before_each_callback) before_each_callback();
313
+ this._resolve(passed, "toMatch", q(this._left as string), q(value));
308
314
  }
309
315
 
310
316
  /**
311
- * Tests if an array has length x
312
- *
313
- * @param {i32} value - The value to check
314
- * @returns - void
317
+ * Tests if a string starts with the provided prefix.
315
318
  */
316
- toHaveLength(value: i32): void {
317
- this.verdict =
318
- // @ts-ignore
319
- isArray<T>() && this._left.length == value ? "ok" : "fail";
320
-
319
+ toStartWith(value: string): void {
320
+ if (!isString<T>()) ERROR("toStartWith() can only be used on string types!");
321
321
  // @ts-ignore
322
- this.left.set(this._left.length.toString());
323
- this.right.set(value.toString());
322
+ const left = this._left as string;
323
+ const passed = left.indexOf(value) == 0;
324
+ this._resolve(passed, "toStartWith", q(left), q(value));
325
+ }
324
326
 
325
- this.instr = "toHaveLength";
327
+ /**
328
+ * Tests if a string ends with the provided suffix.
329
+ */
330
+ toEndWith(value: string): void {
331
+ if (!isString<T>()) ERROR("toEndWith() can only be used on string types!");
332
+ // @ts-ignore
333
+ const left = this._left as string;
334
+ const idx = left.lastIndexOf(value);
335
+ const passed = idx >= 0 && idx + value.length == left.length;
336
+ this._resolve(passed, "toEndWith", q(left), q(value));
337
+ }
326
338
 
339
+ /**
340
+ * Tests if an array has length x
341
+ */
342
+ toHaveLength(value: i32): void {
327
343
  // @ts-ignore
328
- if (after_each_callback) after_each_callback();
344
+ const leftLen = this._left.length as i32;
329
345
  // @ts-ignore
330
- if (before_each_callback) before_each_callback();
346
+ const passed = isArray<T>() && leftLen == value;
347
+ this._resolve(passed, "toHaveLength", leftLen.toString(), value.toString());
331
348
  }
332
349
 
333
350
  /**
334
351
  * Tests if an array contains an element
335
- *
336
- * @param { valueof<T> } value - The value to check
337
- * @returns - void
338
352
  */
339
353
  // @ts-ignore
340
354
  toContain(value: valueof<T>): void {
341
- this.verdict =
342
- // @ts-ignore
343
- isArray<T>() && this._left.includes(value) ? "ok" : "fail";
355
+ // @ts-ignore
356
+ const passed = isArray<T>() && this._left.includes(value);
357
+ this._resolve(
358
+ passed,
359
+ "toContain",
360
+ q("includes value"),
361
+ q("does not include value"),
362
+ );
363
+ }
364
+
365
+ /**
366
+ * Tests if serialized value matches stored snapshot.
367
+ */
368
+ toMatchSnapshot(name: string = ""): void {
369
+ let key = this._snapshotKey;
370
+ if (name.length) key += "::" + name;
344
371
 
345
- this.left.set("includes value");
346
- this.right.set("does not include value");
347
- this.instr = "toContain";
372
+ const actual = JSON.stringify<T>(this._left);
373
+ const res = snapshotAssert(key, actual);
374
+ this._resolve(res.ok, "toMatchSnapshot", actual, res.expected);
375
+ }
376
+
377
+ /**
378
+ * Delegates throw assertions to try-as when available.
379
+ * If try-as is unavailable, this matcher is disabled and warns once.
380
+ */
381
+ toThrow(): void {
382
+ // @ts-ignore
383
+ if (!isDefined(AS_TEST_TRY_AS)) {
384
+ if (!warnedToThrowDisabled) {
385
+ sendWarning(
386
+ 'toThrow() is disabled because try-as is not installed. Install and import "try-as" to enable it.',
387
+ );
388
+ warnedToThrowDisabled = true;
389
+ }
390
+ this._resolve(true, "toThrow", q("disabled"), q("disabled"));
391
+ return;
392
+ }
348
393
 
349
394
  // @ts-ignore
350
- if (after_each_callback) after_each_callback();
351
- // @ts-ignore
352
- if (before_each_callback) before_each_callback();
395
+ const passed = __ExceptionState.Failures > 0;
396
+ if (passed) {
397
+ // @ts-ignore
398
+ __ExceptionState.Failures--;
399
+ }
400
+ this._resolve(passed, "toThrow", q("throws"), q("throws"));
353
401
  }
354
402
 
355
403
  /**
356
404
  * Tests for equality
357
- * @param {T} equals - The value to test
358
- * @returns - void
359
405
  */
360
406
  toBe(equals: T): void {
407
+ let passed = false;
361
408
  if (isArray<T>()) {
362
409
  // @ts-ignore
363
- this.verdict = arrayEquals(this._left, equals) ? "ok" : "fail";
364
- } else if (isBoolean<T>()) {
365
- this.verdict = this._left === equals ? "ok" : "fail";
366
- } else if (isString<T>()) {
367
- this.verdict = this._left === equals ? "ok" : "fail";
368
- } else if (isInteger<T>() || isFloat<T>()) {
369
- this.verdict = this._left === equals ? "ok" : "fail";
410
+ passed = arrayEquals(this._left, equals);
411
+ } else if (
412
+ isBoolean<T>() ||
413
+ isString<T>() ||
414
+ isInteger<T>() ||
415
+ isFloat<T>()
416
+ ) {
417
+ passed = this._left === equals;
370
418
  } else {
371
- this.verdict = "none";
419
+ // Fallback for reference/value types where strict equality is not enough.
420
+ passed = JSON.stringify<T>(this._left) == JSON.stringify<T>(equals);
372
421
  }
373
422
 
374
- this.instr = "toBe";
375
-
376
- this.left.set(JSON.stringify<T>(this._left));
377
- this.right.set(JSON.stringify<T>(equals));
378
-
379
- // @ts-ignore
380
- if (after_each_callback) after_each_callback();
381
- // @ts-ignore
382
- if (before_each_callback) before_each_callback();
383
-
384
- // store<T>(
385
- // changetype<usize>(this),
386
- // equals,
387
- // offsetof<Expectation<T>>("_right"),
388
- // );
423
+ this._resolve(
424
+ passed,
425
+ "toBe",
426
+ JSON.stringify<T>(this._left),
427
+ JSON.stringify<T>(equals),
428
+ );
389
429
  }
390
430
  }
391
431
 
@@ -393,3 +433,27 @@ function arrayEquals<T extends any[]>(a: T, b: T): boolean {
393
433
  if (a.length != b.length) return false;
394
434
  return JSON.stringify(a) == JSON.stringify(b);
395
435
  }
436
+
437
+ function isTruthy<T>(value: T): bool {
438
+ if (isBoolean<T>()) {
439
+ return value as bool;
440
+ }
441
+ if (isString<T>()) {
442
+ // @ts-ignore
443
+ return (value as string).length > 0;
444
+ }
445
+ if (isInteger<T>()) {
446
+ return value != 0;
447
+ }
448
+ if (isFloat<T>()) {
449
+ return value != 0.0 && !isNaN(value as f64);
450
+ }
451
+ if (isNullable<T>()) {
452
+ return changetype<usize>(value) != 0;
453
+ }
454
+ return true;
455
+ }
456
+
457
+ function q(value: string): string {
458
+ return JSON.stringify<string>(value);
459
+ }
@@ -1,6 +1,3 @@
1
- import { rainbow } from "as-rainbow";
2
- import { term } from "../util/term";
3
-
4
1
 
5
2
  @json
6
3
  export class Log {
@@ -10,10 +7,5 @@ export class Log {
10
7
  constructor(text: string) {
11
8
  this.text = text;
12
9
  }
13
- display(): void {
14
- term.write(
15
- " ".repeat(this.depth + 1) +
16
- `${rainbow.bgBlackBright(" LOG ")}${rainbow.dimMk(": " + this.text)}\n`,
17
- );
18
- }
10
+ display(): void {}
19
11
  }