as-test 0.2.1 → 0.3.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 (54) hide show
  1. package/.github/workflows/as-test.yml +3 -0
  2. package/CHANGELOG.md +1 -1
  3. package/README.md +73 -68
  4. package/as-test.config.json +7 -10
  5. package/assembly/__tests__/array.spec.ts +19 -0
  6. package/assembly/__tests__/math.spec.ts +16 -0
  7. package/assembly/__tests__/sleep.spec.ts +28 -0
  8. package/assembly/index.ts +181 -165
  9. package/assembly/src/expectation.ts +119 -112
  10. package/assembly/src/log.ts +19 -0
  11. package/assembly/src/suite.ts +99 -0
  12. package/assembly/src/tests.ts +10 -0
  13. package/assembly/tsconfig.json +1 -1
  14. package/assembly/util/helpers.ts +0 -33
  15. package/assembly/util/term.ts +55 -0
  16. package/assets/img/download.png +0 -0
  17. package/bin/about.js +135 -0
  18. package/bin/build.js +72 -131
  19. package/bin/index.js +70 -112
  20. package/bin/init.js +211 -39
  21. package/bin/reporter.js +1 -0
  22. package/bin/run.js +226 -68
  23. package/bin/types.js +25 -31
  24. package/bin/util.js +44 -20
  25. package/cli/build.ts +70 -109
  26. package/cli/index.ts +148 -159
  27. package/cli/init.ts +235 -34
  28. package/cli/reporter.ts +1 -0
  29. package/cli/run.ts +266 -57
  30. package/cli/types.ts +6 -11
  31. package/cli/util.ts +35 -0
  32. package/package.json +6 -2
  33. package/run/package.json +27 -0
  34. package/tests/array.run.js +7 -0
  35. package/tests/math.run.js +7 -0
  36. package/tests/sleep.run.js +7 -0
  37. package/transform/lib/coverage.js +325 -319
  38. package/transform/lib/index.js +51 -31
  39. package/transform/lib/index.js.map +1 -1
  40. package/transform/lib/mock.js +60 -52
  41. package/transform/lib/mock.js.map +1 -1
  42. package/transform/package.json +1 -1
  43. package/transform/src/index.ts +22 -3
  44. package/transform/src/mock.ts +1 -1
  45. package/asconfig.json +0 -31
  46. package/assembly/__tests__/example.spec.ts +0 -79
  47. package/assembly/reporters/tap.ts +0 -30
  48. package/assembly/src/group.ts +0 -44
  49. package/assembly/src/node.ts +0 -13
  50. package/test.config.json +0 -0
  51. package/tests/test.tap +0 -14
  52. package/unision +0 -38
  53. package/unision.pub +0 -1
  54. package/utils.ts +0 -1
@@ -1,19 +1,19 @@
1
- import { rainbow } from "as-rainbow";
2
- import { diff, visualize } from "../util/helpers";
3
- import { Node } from "./node";
4
- import { Verdict, after_each_callback, before_each_callback } from "..";
5
-
6
- export class Expectation<T> extends Node {
7
- public verdict: Verdict = Verdict.Unreachable;
8
- private left: T;
9
- private _left: string | null = null;
10
- private right: u64 = 0;
11
- private _right: string | null = null;
1
+ import { visualize } from "../util/helpers";
2
+ import { Tests } from "./tests";
3
+ import { after_each_callback, before_each_callback } from "..";
4
+
5
+
6
+ @json
7
+ export class Expectation<T> extends Tests {
8
+ public verdict: string = "none";
9
+ private _left: T;
10
+ // @ts-ignore
11
+ private _right: u64 = 0;
12
+ // @ts-ignore
12
13
  private _not: boolean = false;
13
- private op: string = "=";
14
14
  constructor(left: T) {
15
15
  super();
16
- this.left = left;
16
+ this._left = left;
17
17
  }
18
18
  get not(): Expectation<T> {
19
19
  this._not = true;
@@ -26,14 +26,17 @@ export class Expectation<T> extends Node {
26
26
  */
27
27
  toBeNull(): void {
28
28
  this.verdict =
29
- isNullable<T>() && changetype<usize>(this.left)
30
- ? Verdict.Ok
31
- : Verdict.Fail;
29
+ isNullable<T>() && changetype<usize>(this._left) ? "ok" : "fail";
32
30
 
33
31
  // @ts-ignore
34
- store<T>(changetype<usize>(this), null, offsetof<Expectation<T>>("right"));
32
+ store<T>(changetype<usize>(this), null, offsetof<Expectation<T>>("_right"));
33
+
34
+ this.instr = "toBeNull";
35
35
 
36
- this.op = "=";
36
+ this.left = visualize<T>(this._left);
37
+ this.right = visualize<T>(
38
+ load<T>(changetype<usize>(this), offsetof<Expectation<T>>("_right")),
39
+ );
37
40
 
38
41
  // @ts-ignore
39
42
  if (after_each_callback) after_each_callback();
@@ -50,10 +53,19 @@ export class Expectation<T> extends Node {
50
53
  if (!isInteger<T>() && !isFloat<T>())
51
54
  ERROR("toBeGreaterThan() can only be used on number types!");
52
55
 
53
- this.verdict = this.left > value ? Verdict.Ok : Verdict.Fail;
54
- store<T>(changetype<usize>(this), value, offsetof<Expectation<T>>("right"));
56
+ this.verdict = this._left > value ? "ok" : "fail";
57
+ store<T>(
58
+ changetype<usize>(this),
59
+ value,
60
+ offsetof<Expectation<T>>("_right"),
61
+ );
55
62
 
56
- this.op = ">";
63
+ this.instr = "toBeGreaterThan";
64
+
65
+ this.left = visualize<T>(this._left);
66
+ this.right = visualize<T>(
67
+ load<T>(changetype<usize>(this), offsetof<Expectation<T>>("_right")),
68
+ );
57
69
 
58
70
  // @ts-ignore
59
71
  if (after_each_callback) after_each_callback();
@@ -70,10 +82,19 @@ export class Expectation<T> extends Node {
70
82
  if (!isInteger<T>() && !isFloat<T>())
71
83
  ERROR("toBeGreaterOrEqualTo() can only be used on number types!");
72
84
 
73
- this.verdict = this.left >= value ? Verdict.Ok : Verdict.Fail;
74
- store<T>(changetype<usize>(this), value, offsetof<Expectation<T>>("right"));
85
+ this.verdict = this._left >= value ? "ok" : "fail";
86
+ store<T>(
87
+ changetype<usize>(this),
88
+ value,
89
+ offsetof<Expectation<T>>("_right"),
90
+ );
75
91
 
76
- this.op = ">=";
92
+ this.instr = "toBeGreaterThanOrEqualTo";
93
+
94
+ this.left = visualize<T>(this._left);
95
+ this.right = visualize<T>(
96
+ load<T>(changetype<usize>(this), offsetof<Expectation<T>>("_right")),
97
+ );
77
98
 
78
99
  // @ts-ignore
79
100
  if (after_each_callback) after_each_callback();
@@ -90,10 +111,19 @@ export class Expectation<T> extends Node {
90
111
  if (!isInteger<T>() && !isFloat<T>())
91
112
  ERROR("toBeLessThan() can only be used on number types!");
92
113
 
93
- this.verdict = this.left < value ? Verdict.Ok : Verdict.Fail;
94
- store<T>(changetype<usize>(this), value, offsetof<Expectation<T>>("right"));
114
+ this.verdict = this._left < value ? "ok" : "fail";
115
+ store<T>(
116
+ changetype<usize>(this),
117
+ value,
118
+ offsetof<Expectation<T>>("_right"),
119
+ );
120
+
121
+ this.instr = "toBeLessThan";
95
122
 
96
- this.op = "<";
123
+ this.left = visualize<T>(this._left);
124
+ this.right = visualize<T>(
125
+ load<T>(changetype<usize>(this), offsetof<Expectation<T>>("_right")),
126
+ );
97
127
 
98
128
  // @ts-ignore
99
129
  if (after_each_callback) after_each_callback();
@@ -110,10 +140,19 @@ export class Expectation<T> extends Node {
110
140
  if (!isInteger<T>() && !isFloat<T>())
111
141
  ERROR("toBeLessThanOrEqualTo() can only be used on number types!");
112
142
 
113
- this.verdict = this.left <= value ? Verdict.Ok : Verdict.Fail;
114
- store<T>(changetype<usize>(this), value, offsetof<Expectation<T>>("right"));
143
+ this.verdict = this._left <= value ? "ok" : "fail";
144
+ store<T>(
145
+ changetype<usize>(this),
146
+ value,
147
+ offsetof<Expectation<T>>("_right"),
148
+ );
149
+
150
+ this.instr = "toBeLessThanOrEqualTo";
115
151
 
116
- this.op = "<=";
152
+ this.left = visualize<T>(this._left);
153
+ this.right = visualize<T>(
154
+ load<T>(changetype<usize>(this), offsetof<Expectation<T>>("_right")),
155
+ );
117
156
 
118
157
  // @ts-ignore
119
158
  if (after_each_callback) after_each_callback();
@@ -126,12 +165,12 @@ export class Expectation<T> extends Node {
126
165
  * @returns - void
127
166
  */
128
167
  toBeString(): void {
129
- this.verdict = isString<T>() ? Verdict.Ok : Verdict.Fail;
168
+ this.verdict = isString<T>() ? "ok" : "fail";
130
169
 
131
- this._left = nameof<T>();
132
- this._right = "string";
170
+ this.left = nameof<T>();
171
+ this.right = "string";
133
172
 
134
- this.op = "type";
173
+ this.instr = "toBeString";
135
174
 
136
175
  // @ts-ignore
137
176
  if (after_each_callback) after_each_callback();
@@ -144,12 +183,12 @@ export class Expectation<T> extends Node {
144
183
  * @returns - void
145
184
  */
146
185
  toBeBoolean(): void {
147
- this.verdict = isBoolean<T>() ? Verdict.Ok : Verdict.Fail;
186
+ this.verdict = isBoolean<T>() ? "ok" : "fail";
148
187
 
149
- this._left = nameof<T>();
150
- this._right = "boolean";
188
+ this.left = nameof<T>();
189
+ this.right = "boolean";
151
190
 
152
- this.op = "type";
191
+ this.instr = "toBeBoolean";
153
192
 
154
193
  // @ts-ignore
155
194
  if (after_each_callback) after_each_callback();
@@ -162,12 +201,12 @@ export class Expectation<T> extends Node {
162
201
  * @returns - void
163
202
  */
164
203
  toBeArray(): void {
165
- this.verdict = isArray<T>() ? Verdict.Ok : Verdict.Fail;
204
+ this.verdict = isArray<T>() ? "ok" : "fail";
166
205
 
167
- this._left = nameof<T>();
168
- this._right = "Array<any>";
206
+ this.left = nameof<T>();
207
+ this.right = "Array<any>";
169
208
 
170
- this.op = "type";
209
+ this.instr = "toBeArray";
171
210
 
172
211
  // @ts-ignore
173
212
  if (after_each_callback) after_each_callback();
@@ -180,12 +219,12 @@ export class Expectation<T> extends Node {
180
219
  * @returns - void
181
220
  */
182
221
  toBeNumber(): void {
183
- this.verdict = isFloat<T>() || isInteger<T>() ? Verdict.Ok : Verdict.Fail;
222
+ this.verdict = isFloat<T>() || isInteger<T>() ? "ok" : "fail";
184
223
 
185
- this._left = nameof<T>();
186
- this._right = "number";
224
+ this.left = nameof<T>();
225
+ this.right = "number";
187
226
 
188
- this.op = "type";
227
+ this.instr = "toBeNumber";
189
228
 
190
229
  // @ts-ignore
191
230
  if (after_each_callback) after_each_callback();
@@ -198,12 +237,12 @@ export class Expectation<T> extends Node {
198
237
  * @returns - void
199
238
  */
200
239
  toBeInteger(): void {
201
- this.verdict = isInteger<T>() ? Verdict.Ok : Verdict.Fail;
240
+ this.verdict = isInteger<T>() ? "ok" : "fail";
202
241
 
203
- this._left = nameof<T>();
204
- this._right = "float";
242
+ this.left = nameof<T>();
243
+ this.right = "float";
205
244
 
206
- this.op = "type";
245
+ this.instr = "toBeInteger";
207
246
 
208
247
  // @ts-ignore
209
248
  if (after_each_callback) after_each_callback();
@@ -216,12 +255,12 @@ export class Expectation<T> extends Node {
216
255
  * @returns - void
217
256
  */
218
257
  toBeFloat(): void {
219
- this.verdict = isFloat<T>() ? Verdict.Ok : Verdict.Fail;
258
+ this.verdict = isFloat<T>() ? "ok" : "fail";
220
259
 
221
- this._left = nameof<T>();
222
- this._right = "integer";
260
+ this.left = nameof<T>();
261
+ this.right = "integer";
223
262
 
224
- this.op = "type";
263
+ this.instr = "toBeFloat";
225
264
 
226
265
  // @ts-ignore
227
266
  if (after_each_callback) after_each_callback();
@@ -234,16 +273,14 @@ export class Expectation<T> extends Node {
234
273
  * @returns - void
235
274
  */
236
275
  toBeFinite(): void {
237
- // @ts-ignore
238
276
  this.verdict =
239
- (isFloat<T>() || isInteger<T>()) && isFinite(this.left)
240
- ? Verdict.Ok
241
- : Verdict.Fail;
277
+ // @ts-ignore
278
+ (isFloat<T>() || isInteger<T>()) && isFinite(this._left) ? "ok" : "fail";
242
279
 
243
- this._left = "Infinity";
244
- this._right = "Finite";
280
+ this.left = "Infinity";
281
+ this.right = "Finite";
245
282
 
246
- this.op = "=";
283
+ this.instr = "toBeFinite";
247
284
 
248
285
  // @ts-ignore
249
286
  if (after_each_callback) after_each_callback();
@@ -258,15 +295,15 @@ export class Expectation<T> extends Node {
258
295
  * @returns - void
259
296
  */
260
297
  toHaveLength(value: i32): void {
261
- // @ts-ignore
262
298
  this.verdict =
263
- isArray<T>() && this.left.length == value ? Verdict.Ok : Verdict.Fail;
299
+ // @ts-ignore
300
+ isArray<T>() && this._left.length == value ? "ok" : "fail";
264
301
 
265
302
  // @ts-ignore
266
- this._left = this.left.length.toString();
267
- this._right = value.toString();
303
+ this.left = this._left.length.toString();
304
+ this.right = value.toString();
268
305
 
269
- this.op = "length";
306
+ this.instr = "toHaveLength";
270
307
 
271
308
  // @ts-ignore
272
309
  if (after_each_callback) after_each_callback();
@@ -282,14 +319,14 @@ export class Expectation<T> extends Node {
282
319
  */
283
320
  // @ts-ignore
284
321
  toContain(value: valueof<T>): void {
285
- // @ts-ignore
286
322
  this.verdict =
287
- isArray<T>() && this.left.includes(value) ? Verdict.Ok : Verdict.Fail;
323
+ // @ts-ignore
324
+ isArray<T>() && this._left.includes(value) ? "ok" : "fail";
288
325
 
289
326
  // @ts-ignore
290
- this._left = "includes value";
291
- this._right = "does not include value";
292
- this.op = "=";
327
+ this.left = "includes value";
328
+ this.right = "does not include value";
329
+ this.instr = "toContain";
293
330
 
294
331
  // @ts-ignore
295
332
  if (after_each_callback) after_each_callback();
@@ -306,60 +343,30 @@ export class Expectation<T> extends Node {
306
343
  store<T>(
307
344
  changetype<usize>(this),
308
345
  equals,
309
- offsetof<Expectation<T>>("right"),
346
+ offsetof<Expectation<T>>("_right"),
310
347
  );
311
348
  if (isBoolean<T>()) {
312
- this.verdict = this.left === equals ? Verdict.Ok : Verdict.Fail;
349
+ this.verdict = this._left === equals ? "ok" : "fail";
313
350
  } else if (isString<T>()) {
314
- this.verdict = this.left === equals ? Verdict.Ok : Verdict.Fail;
351
+ this.verdict = this._left === equals ? "ok" : "fail";
315
352
  } else if (isInteger<T>() || isFloat<T>()) {
316
- this.verdict = this.left === equals ? Verdict.Ok : Verdict.Fail;
353
+ this.verdict = this._left === equals ? "ok" : "fail";
317
354
  } else if (isArray<T>()) {
318
355
  // getArrayDepth<T>();
319
356
  } else {
320
- this.verdict = Verdict.Unreachable;
357
+ this.verdict = "none";
321
358
  }
322
359
 
323
- this.op = "=";
360
+ this.instr = "toBe";
361
+
362
+ this.left = visualize<T>(this._left);
363
+ this.right = visualize<T>(
364
+ load<T>(changetype<usize>(this), offsetof<Expectation<T>>("_right")),
365
+ );
324
366
 
325
367
  // @ts-ignore
326
368
  if (after_each_callback) after_each_callback();
327
369
  // @ts-ignore
328
370
  if (before_each_callback) before_each_callback();
329
371
  }
330
-
331
- report(): string | null {
332
- if (!this._not && this.verdict === Verdict.Ok) return null;
333
-
334
- const left = this._left || visualize(this.left);
335
- const right =
336
- this._right ||
337
- visualize(
338
- load<T>(changetype<usize>(this), offsetof<Expectation<T>>("right")),
339
- );
340
-
341
- if (this._not) {
342
- if (this.verdict === Verdict.Fail) return null;
343
- const dif = diff(left, right, true);
344
- return (
345
- rainbow.red(" - Test failed") +
346
- "\n" +
347
- rainbow.italicMk(
348
- ` ${rainbow.dimMk("(expected) ->")} ${dif.left.toString()}\n ${rainbow.dimMk("[ !" + this.op + " ]")}\n ${rainbow.dimMk("(recieved) ->")} ${dif.right.toString()}`,
349
- )
350
- );
351
- }
352
-
353
- if (left == right) return null;
354
-
355
- const dif = diff(left, right);
356
-
357
- return (
358
- rainbow.red(" - Test failed") +
359
- "\n" +
360
- rainbow.italicMk(
361
- ` ${rainbow.dimMk("(expected) ->")} ${dif.left.toString()}\n ${rainbow.dimMk("[ " + this.op + " ]")}\n ${rainbow.dimMk("(recieved) ->")} ${dif.right.toString()}`,
362
- )
363
- );
364
- }
365
372
  }
@@ -0,0 +1,19 @@
1
+ import { rainbow } from "as-rainbow";
2
+ import { term } from "../util/term";
3
+
4
+
5
+ @json
6
+ export class Log {
7
+ public order: i32 = 0;
8
+ public depth: i32 = 0;
9
+ public text: string;
10
+ constructor(text: string) {
11
+ this.text = text;
12
+ }
13
+ display(): void {
14
+ term.write(
15
+ " ".repeat(this.depth + 1) +
16
+ `${rainbow.bgBlackBright(" LOG ")}${rainbow.dimMk(": " + this.text)}\n`,
17
+ );
18
+ }
19
+ }
@@ -0,0 +1,99 @@
1
+ import { rainbow } from "as-rainbow";
2
+ import { Time } from "..";
3
+ import { Expectation } from "./expectation";
4
+ import { Tests } from "./tests";
5
+ import { term } from "../util/term";
6
+ import { Log } from "./log";
7
+
8
+
9
+ @json
10
+ export class Suite {
11
+ public file: string = "unknown";
12
+ public order: i32 = 0;
13
+ public time: Time = new Time();
14
+ public description: string;
15
+ public depth: i32 = 0;
16
+ public suites: Suite[] = [];
17
+ public tests: Tests[] = [];
18
+ public logs: Log[] = [];
19
+ public kind: string;
20
+
21
+ public verdict: string = "none";
22
+
23
+ public callback: () => void;
24
+ constructor(description: string, callback: () => void, kind: string) {
25
+ this.description = description;
26
+ this.callback = callback;
27
+ this.kind = kind;
28
+ }
29
+
30
+ addExpectation<T extends Expectation<unknown>>(test: T): void {
31
+ test.order = this.order++;
32
+ this.tests.push(test);
33
+ }
34
+ addSuite(suite: Suite): void {
35
+ suite.order = this.order++;
36
+ this.suites.push(suite);
37
+ suite.depth = this.depth + 1;
38
+ suite.file = this.file;
39
+ }
40
+ addLog(log: Log): void {
41
+ log.order = this.order++;
42
+ this.logs.push(log);
43
+ log.depth = this.depth + 1;
44
+ log.display();
45
+ }
46
+
47
+ run(): void {
48
+ // @ts-ignore
49
+ current_suite = this;
50
+ // @ts-ignore
51
+ depth++;
52
+ this.time.start = performance.now();
53
+ const suiteDepth = " ".repeat(this.depth + 1);
54
+ const suiteLn = term.write(
55
+ `${suiteDepth}${rainbow.bgBlackBright(" ... ")} ${rainbow.dimMk(this.description)}\n`,
56
+ );
57
+ term.write("\n");
58
+ this.callback();
59
+ this.time.end = performance.now();
60
+ // @ts-ignore
61
+ depth--;
62
+
63
+ let suiteNone = true;
64
+ for (let i = 0; i < this.suites.length; i++) {
65
+ const suite = unchecked(this.suites[i]);
66
+ suite.run();
67
+ if (suite.verdict == "fail") {
68
+ this.verdict = "fail";
69
+ suiteNone = false;
70
+ } else if (suite.verdict == "ok") {
71
+ suiteNone = false;
72
+ }
73
+ }
74
+ for (let i = 0; i < this.tests.length; i++) {
75
+ const test = unchecked(this.tests[i]);
76
+ if (test.verdict == "fail") {
77
+ this.verdict = "fail";
78
+ suiteNone = false;
79
+ } else if (test.verdict == "ok") {
80
+ suiteNone = false;
81
+ }
82
+ }
83
+
84
+ if (this.verdict == "fail") {
85
+ suiteLn.edit(
86
+ `${suiteDepth}${rainbow.bgRed(" FAIL ")} ${rainbow.dimMk(this.description)}\n`,
87
+ );
88
+ } else if (!suiteNone || this.tests.length) {
89
+ this.verdict = "ok";
90
+ suiteLn.edit(
91
+ `${suiteDepth}${rainbow.bgGreenBright(" PASS ")} ${rainbow.dimMk(this.description)}\n`,
92
+ );
93
+ } else {
94
+ suiteLn.edit(
95
+ `${suiteDepth}${rainbow.bgBlackBright(" EMPTY ")} ${rainbow.dimMk(this.description)}\n`,
96
+ );
97
+ }
98
+ }
99
+ }
@@ -0,0 +1,10 @@
1
+
2
+ @json
3
+ export class Tests {
4
+ public order: i32 = 0;
5
+ public type!: string;
6
+ public verdict: string = "none";
7
+ public left: string = "";
8
+ public right: string = "";
9
+ public instr: string = "";
10
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "extends": "assemblyscript/std/assembly.json",
3
- "include": ["./**/*.ts"],
3
+ "include": ["./**/*.ts", "../reporters/report.ts"],
4
4
  "compilerOptions": {
5
5
  /* Visit https://aka.ms/tsconfig to read more about this file */
6
6
  /* Projects */
@@ -79,39 +79,6 @@ export function diff(left: string, right: string, not: boolean = false): Diff {
79
79
  };
80
80
  }
81
81
 
82
- class Unit {
83
- name: string;
84
- divisor: number;
85
- }
86
-
87
- export function formatTime(ms: number): string {
88
- if (ms < 0) {
89
- throw new Error("Time should be a non-negative number.");
90
- }
91
-
92
- // Convert milliseconds to microseconds
93
- const us = ms * 1000;
94
-
95
- const units: Unit[] = [
96
- { name: "μs", divisor: 1 },
97
- { name: "ms", divisor: 1000 },
98
- { name: "s", divisor: 1000 * 1000 },
99
- { name: "m", divisor: 60 * 1000 * 1000 },
100
- { name: "h", divisor: 60 * 60 * 1000 * 1000 },
101
- { name: "d", divisor: 24 * 60 * 60 * 1000 * 1000 },
102
- ];
103
-
104
- for (let i = units.length - 1; i >= 0; i--) {
105
- const unit = units[i];
106
- if (us >= unit.divisor) {
107
- const value = Math.round((us / unit.divisor) * 1000) / 1000;
108
- return `${value}${unit.name}`;
109
- }
110
- }
111
-
112
- return `${us}us`;
113
- }
114
-
115
82
  // @ts-ignore
116
83
  @inline
117
84
  export function colorText(format: i32[], text: string): string {
@@ -0,0 +1,55 @@
1
+ // @ts-ignore
2
+ @external("env", "process.stdout.write")
3
+ declare function process_stdout_write(data: string): void;
4
+
5
+ export class TermLine {
6
+ public start: i32 = 0;
7
+ public end: i32 = 0;
8
+ constructor(start: i32 = 0, end: i32 = 0) {
9
+ this.start = start;
10
+ this.end = end;
11
+ }
12
+ edit(data: string): TermLine {
13
+ let end = this.end;
14
+ while (--end >= this.start) {
15
+ term.clearLn(end);
16
+ }
17
+ writeRaw(data);
18
+ term.resetCursor();
19
+ return new TermLine(this.end);
20
+ }
21
+ clear(): void {
22
+ term.clearLn(this.start);
23
+ }
24
+ }
25
+
26
+ export namespace term {
27
+ export let lines: i32 = 0;
28
+ export function write(data: string): TermLine {
29
+ const start = term.lines;
30
+ for (let i = 0; i < data.length; i++) {
31
+ const code = data.charCodeAt(i);
32
+ if (code === 10) term.lines++;
33
+ }
34
+ writeRaw(data);
35
+ return new TermLine(start, term.lines);
36
+ }
37
+ export function clearLn(line: i32): void {
38
+ writeRaw(`\u001B[${term.lines - line}A`);
39
+ writeRaw("\x1B[2K");
40
+ writeRaw("\x1B[0G");
41
+ }
42
+ export function resetCursor(): void {
43
+ writeRaw("\x1B[999B");
44
+ writeRaw("\x1B[0G");
45
+ }
46
+ }
47
+
48
+ export function writeRaw(data: string): void {
49
+ // @ts-ignore
50
+ if (isDefined(ASC_WASI)) {
51
+ process.stdout.write(data);
52
+ } else {
53
+ process_stdout_write(data);
54
+ }
55
+ }
Binary file