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,9 +1,9 @@
1
- import { rainbow } from "as-rainbow";
2
1
  import { Time } from "..";
3
2
  import { Expectation } from "./expectation";
4
3
  import { Tests } from "./tests";
5
- import { term } from "../util/term";
6
4
  import { Log } from "./log";
5
+ import { after_each_callback, before_each_callback } from "..";
6
+ import { sendSuiteEnd, sendSuiteStart } from "../util/wipc";
7
7
 
8
8
 
9
9
  @json
@@ -20,6 +20,10 @@ export class Suite {
20
20
  public logs: Log[] = [];
21
21
  public kind: string;
22
22
 
23
+
24
+ @omit
25
+ public parent: Suite | null = null;
26
+
23
27
  public verdict: string = "none";
24
28
 
25
29
  public callback: () => void;
@@ -38,6 +42,7 @@ export class Suite {
38
42
  this.suites.push(suite);
39
43
  suite.depth = this.depth + 1;
40
44
  suite.file = this.file;
45
+ suite.parent = this;
41
46
  }
42
47
  addLog(log: Log): void {
43
48
  log.order = this.order++;
@@ -52,50 +57,81 @@ export class Suite {
52
57
  // @ts-ignore
53
58
  depth++;
54
59
  this.time.start = performance.now();
55
- const suiteDepth = " ".repeat(this.depth + 1);
56
- const suiteLn = term.write(
57
- `${suiteDepth}${rainbow.bgBlackBright(" ... ")} ${rainbow.dimMk(this.description)}\n`,
58
- );
59
- term.write("\n");
60
+ sendSuiteStart(this.file, this.depth, this.kind, this.description);
61
+ const isSkippedCase =
62
+ this.kind == "xdescribe" ||
63
+ this.kind == "xtest" ||
64
+ this.kind == "xit";
65
+ const isTestCase =
66
+ this.kind == "test" ||
67
+ this.kind == "it" ||
68
+ this.kind == "xtest" ||
69
+ this.kind == "xit";
70
+
71
+ if (isSkippedCase) {
72
+ this.time.end = performance.now();
73
+ this.verdict = "skip";
74
+ // @ts-ignore
75
+ depth--;
76
+ sendSuiteEnd(
77
+ this.file,
78
+ this.depth,
79
+ this.kind,
80
+ this.description,
81
+ this.verdict,
82
+ );
83
+ return;
84
+ }
85
+
86
+ // @ts-ignore
87
+ if (isTestCase && before_each_callback) before_each_callback();
60
88
  this.callback();
89
+ // @ts-ignore
90
+ if (isTestCase && after_each_callback) after_each_callback();
61
91
  this.time.end = performance.now();
62
92
  // @ts-ignore
63
93
  depth--;
64
94
 
65
- let suiteNone = true;
95
+ let hasFail = false;
96
+ let hasOk = false;
97
+ let hasSkip = false;
66
98
  for (let i = 0; i < this.suites.length; i++) {
67
99
  const suite = unchecked(this.suites[i]);
68
100
  suite.run();
69
101
  if (suite.verdict == "fail") {
70
- this.verdict = "fail";
71
- suiteNone = false;
102
+ hasFail = true;
72
103
  } else if (suite.verdict == "ok") {
73
- suiteNone = false;
104
+ hasOk = true;
105
+ } else if (suite.verdict == "skip") {
106
+ hasSkip = true;
74
107
  }
75
108
  }
76
109
  for (let i = 0; i < this.tests.length; i++) {
77
110
  const test = unchecked(this.tests[i]);
78
111
  if (test.verdict == "fail") {
79
- this.verdict = "fail";
80
- suiteNone = false;
112
+ hasFail = true;
81
113
  } else if (test.verdict == "ok") {
82
- suiteNone = false;
114
+ hasOk = true;
115
+ } else if (test.verdict == "skip") {
116
+ hasSkip = true;
83
117
  }
84
118
  }
85
119
 
86
- if (this.verdict == "fail") {
87
- suiteLn.edit(
88
- `${suiteDepth}${rainbow.bgRed(" FAIL ")} ${rainbow.dimMk(this.description)}\n`,
89
- );
90
- } else if (!suiteNone || this.tests.length) {
120
+ if (hasFail) {
121
+ this.verdict = "fail";
122
+ } else if (hasOk) {
91
123
  this.verdict = "ok";
92
- suiteLn.edit(
93
- `${suiteDepth}${rainbow.bgGreenBright(" PASS ")} ${rainbow.dimMk(this.description)}\n`,
94
- );
124
+ } else if (hasSkip) {
125
+ this.verdict = "skip";
95
126
  } else {
96
- suiteLn.edit(
97
- `${suiteDepth}${rainbow.bgBlackBright(" EMPTY ")} ${rainbow.dimMk(this.description)}\n`,
98
- );
127
+ this.verdict = "none";
99
128
  }
129
+ sendSuiteEnd(
130
+ this.file,
131
+ this.depth,
132
+ this.kind,
133
+ this.description,
134
+ this.verdict,
135
+ );
100
136
  }
101
137
  }
@@ -9,4 +9,6 @@ export class Tests {
9
9
  public left: JSON.Raw = JSON.Raw.from("");
10
10
  public right: JSON.Raw = JSON.Raw.from("");
11
11
  public instr: string = "";
12
+ public message: string = "";
13
+ public location: string = "";
12
14
  }
@@ -0,0 +1,286 @@
1
+ // @ts-ignore
2
+ @external("env", "process.stdout.write")
3
+ declare function process_stdout_write(data: ArrayBuffer): void;
4
+
5
+ // @ts-ignore
6
+ @external("env", "process.stdin.read")
7
+ declare function process_stdin_read(max: i32): ArrayBuffer;
8
+
9
+ // @ts-ignore
10
+ @external("wasi_snapshot_preview1", "fd_write")
11
+ declare function wasi_fd_write(
12
+ fd: i32,
13
+ iovs: usize,
14
+ iovsLen: i32,
15
+ written: usize,
16
+ ): i32;
17
+
18
+ // @ts-ignore
19
+ @external("wasi_snapshot_preview1", "fd_read")
20
+ declare function wasi_fd_read(
21
+ fd: i32,
22
+ iovs: usize,
23
+ iovsLen: i32,
24
+ read: usize,
25
+ ): i32;
26
+
27
+ const MAGIC_W: u8 = 0x57; // W
28
+ const MAGIC_I: u8 = 0x49; // I
29
+ const MAGIC_P: u8 = 0x50; // P
30
+ const MAGIC_C: u8 = 0x43; // C
31
+ const HEADER_SIZE: i32 = 9;
32
+ const IOV_SIZE: usize = sizeof<usize>() * 2;
33
+ const U32_SIZE: usize = sizeof<u32>();
34
+
35
+ // @ts-ignore
36
+ const IS_BINDINGS: bool = isDefined(AS_TEST_BINDINGS);
37
+
38
+ enum MessageType {
39
+ OPEN = 0x00,
40
+ CLOSE = 0x01,
41
+ CALL = 0x02,
42
+ DATA = 0x03,
43
+ }
44
+
45
+ export class SnapshotReply {
46
+ public ok: bool = false;
47
+ public expected: string = "";
48
+ }
49
+
50
+ export function sendAssertionFailure(
51
+ key: string,
52
+ instr: string,
53
+ left: string,
54
+ right: string,
55
+ message: string,
56
+ ): void {
57
+ sendJson(
58
+ MessageType.CALL,
59
+ `{"kind":"event:assert-fail","key":${q(key)},"instr":${q(instr)},"left":${q(left)},"right":${q(right)},"message":${q(message)}}`,
60
+ );
61
+ }
62
+
63
+ export function sendFileStart(file: string): void {
64
+ sendJson(MessageType.CALL, `{"kind":"event:file-start","file":${q(file)}}`);
65
+ }
66
+
67
+ export function sendFileEnd(file: string, verdict: string, time: string): void {
68
+ sendJson(
69
+ MessageType.CALL,
70
+ `{"kind":"event:file-end","file":${q(file)},"verdict":${q(verdict)},"time":${q(time)}}`,
71
+ );
72
+ }
73
+
74
+ export function sendSuiteStart(
75
+ file: string,
76
+ depth: i32,
77
+ kind: string,
78
+ description: string,
79
+ ): void {
80
+ sendJson(
81
+ MessageType.CALL,
82
+ `{"kind":"event:suite-start","file":${q(file)},"depth":${depth.toString()},"suiteKind":${q(kind)},"description":${q(description)}}`,
83
+ );
84
+ }
85
+
86
+ export function sendSuiteEnd(
87
+ file: string,
88
+ depth: i32,
89
+ kind: string,
90
+ description: string,
91
+ verdict: string,
92
+ ): void {
93
+ sendJson(
94
+ MessageType.CALL,
95
+ `{"kind":"event:suite-end","file":${q(file)},"depth":${depth.toString()},"suiteKind":${q(kind)},"description":${q(description)},"verdict":${q(verdict)}}`,
96
+ );
97
+ }
98
+
99
+ export function snapshotAssert(key: string, actual: string): SnapshotReply {
100
+ sendJson(
101
+ MessageType.CALL,
102
+ `{"kind":"snapshot:assert","key":${q(key)},"actual":${q(actual)}}`,
103
+ );
104
+ const response = readFrame();
105
+ if (response == null || response.type != MessageType.CALL) {
106
+ return new SnapshotReply();
107
+ }
108
+ const body = String.UTF8.decode(response.payload);
109
+ if (!body.length) {
110
+ return new SnapshotReply();
111
+ }
112
+ const sep = body.indexOf("\n");
113
+ if (sep < 0) return new SnapshotReply();
114
+ const reply = new SnapshotReply();
115
+ reply.ok = body.slice(0, sep) == "1";
116
+ reply.expected = body.slice(sep + 1);
117
+ return reply;
118
+ }
119
+
120
+ export function sendReport(report: string): void {
121
+ sendFrame(MessageType.DATA, String.UTF8.encode(report));
122
+ }
123
+
124
+ export function sendWarning(message: string): void {
125
+ writeStdout(String.UTF8.encode("[WARN] " + message + "\n"));
126
+ }
127
+
128
+ function sendJson(type: MessageType, body: string): void {
129
+ sendFrame(type, String.UTF8.encode(body));
130
+ }
131
+
132
+ function sendFrame(type: MessageType, payload: ArrayBuffer): void {
133
+ const payloadLen = payload.byteLength;
134
+ const out = new ArrayBuffer(HEADER_SIZE + payloadLen);
135
+ const ptr = changetype<usize>(out);
136
+
137
+ store<u8>(ptr, MAGIC_W, 0);
138
+ store<u8>(ptr, MAGIC_I, 1);
139
+ store<u8>(ptr, MAGIC_P, 2);
140
+ store<u8>(ptr, MAGIC_C, 3);
141
+ store<u8>(ptr, <u8>type, 4);
142
+ store<u32>(ptr, <u32>payloadLen, 5);
143
+
144
+ if (payloadLen) {
145
+ memory.copy(ptr + HEADER_SIZE, changetype<usize>(payload), payloadLen);
146
+ }
147
+
148
+ writeStdout(out);
149
+ }
150
+
151
+ class Frame {
152
+ constructor(
153
+ public type: MessageType,
154
+ public payload: ArrayBuffer,
155
+ ) {}
156
+ }
157
+
158
+ function readFrame(): Frame | null {
159
+ const header = readExact(HEADER_SIZE);
160
+ if (header.byteLength < HEADER_SIZE) return null;
161
+ const head = changetype<usize>(header);
162
+ if (
163
+ load<u8>(head, 0) != MAGIC_W ||
164
+ load<u8>(head, 1) != MAGIC_I ||
165
+ load<u8>(head, 2) != MAGIC_P ||
166
+ load<u8>(head, 3) != MAGIC_C
167
+ ) {
168
+ return null;
169
+ }
170
+ const type = <MessageType>load<u8>(head, 4);
171
+ const length = load<u32>(head, 5);
172
+ const payload = readExact(<i32>length);
173
+ if (payload.byteLength < <i32>length) return null;
174
+ return new Frame(type, payload);
175
+ }
176
+
177
+ function readExact(length: i32): ArrayBuffer {
178
+ const out = new ArrayBuffer(length);
179
+ let offset = 0;
180
+ while (offset < length) {
181
+ const chunk = readStdin(length - offset);
182
+ const size = chunk.byteLength;
183
+ if (!size) break;
184
+ memory.copy(
185
+ changetype<usize>(out) + offset,
186
+ changetype<usize>(chunk),
187
+ size,
188
+ );
189
+ offset += size;
190
+ }
191
+
192
+ if (offset == length) return out;
193
+
194
+ const partial = new ArrayBuffer(offset);
195
+ if (offset) {
196
+ memory.copy(changetype<usize>(partial), changetype<usize>(out), offset);
197
+ }
198
+ return partial;
199
+ }
200
+
201
+ function writeStdout(data: ArrayBuffer): void {
202
+ if (IS_BINDINGS) {
203
+ process_stdout_write(data);
204
+ return;
205
+ }
206
+ wasiWriteAll(data);
207
+ }
208
+
209
+ function readStdin(max: i32): ArrayBuffer {
210
+ if (max <= 0) return new ArrayBuffer(0);
211
+ if (IS_BINDINGS) {
212
+ return process_stdin_read(max);
213
+ }
214
+ return wasiRead(max);
215
+ }
216
+
217
+ function wasiWriteAll(data: ArrayBuffer): void {
218
+ const total = data.byteLength;
219
+ if (!total) return;
220
+
221
+ const iovec = new ArrayBuffer(<i32>IOV_SIZE);
222
+ const writtenBuf = new ArrayBuffer(<i32>U32_SIZE);
223
+ let offset: i32 = 0;
224
+ while (offset < total) {
225
+ const left = total - offset;
226
+ const ptr = changetype<usize>(data) + <usize>offset;
227
+ const iovPtr = changetype<usize>(iovec);
228
+ const writtenPtr = changetype<usize>(writtenBuf);
229
+ store<usize>(iovPtr, ptr, 0);
230
+ store<usize>(iovPtr, <usize>left, sizeof<usize>());
231
+ store<u32>(writtenPtr, 0, 0);
232
+ const errno = wasi_fd_write(1, iovPtr, 1, writtenPtr);
233
+ if (errno != 0) return;
234
+ const written = <i32>load<u32>(writtenPtr, 0);
235
+ if (written <= 0) return;
236
+ offset += written;
237
+ }
238
+ }
239
+
240
+ function wasiRead(max: i32): ArrayBuffer {
241
+ const out = new ArrayBuffer(max);
242
+ const iovec = new ArrayBuffer(<i32>IOV_SIZE);
243
+ const readBuf = new ArrayBuffer(<i32>U32_SIZE);
244
+ const iovPtr = changetype<usize>(iovec);
245
+ const readPtr = changetype<usize>(readBuf);
246
+
247
+ store<usize>(iovPtr, changetype<usize>(out), 0);
248
+ store<usize>(iovPtr, <usize>max, sizeof<usize>());
249
+ store<u32>(readPtr, 0, 0);
250
+
251
+ const errno = wasi_fd_read(0, iovPtr, 1, readPtr);
252
+ if (errno != 0) return new ArrayBuffer(0);
253
+
254
+ const size = <i32>load<u32>(readPtr, 0);
255
+ if (size <= 0) return new ArrayBuffer(0);
256
+ if (size == max) return out;
257
+
258
+ const partial = new ArrayBuffer(size);
259
+ memory.copy(changetype<usize>(partial), changetype<usize>(out), size);
260
+ return partial;
261
+ }
262
+
263
+ function q(value: string): string {
264
+ return '"' + escape(value) + '"';
265
+ }
266
+
267
+ function escape(value: string): string {
268
+ let out = "";
269
+ for (let i = 0; i < value.length; i++) {
270
+ const ch = value.charCodeAt(i);
271
+ if (ch == 34) {
272
+ out += '\\"';
273
+ } else if (ch == 92) {
274
+ out += "\\\\";
275
+ } else if (ch == 10) {
276
+ out += "\\n";
277
+ } else if (ch == 13) {
278
+ out += "\\r";
279
+ } else if (ch == 9) {
280
+ out += "\\t";
281
+ } else {
282
+ out += String.fromCharCode(ch);
283
+ }
284
+ }
285
+ return out;
286
+ }
package/bin/build.js CHANGED
@@ -1,82 +1,118 @@
1
- import { existsSync, readFileSync } from "fs";
1
+ import { existsSync } from "fs";
2
2
  import { glob } from "glob";
3
3
  import chalk from "chalk";
4
4
  import { execSync } from "child_process";
5
5
  import * as path from "path";
6
- import { loadConfig } from "./util.js";
7
- const CONFIG_PATH = path.join(process.cwd(), "./as-test.config.json");
8
- const PKG_PATH = path.join(process.cwd(), "./package.json");
9
- export async function build() {
10
- let config = loadConfig(CONFIG_PATH, true);
11
- const ASCONFIG_PATH = path.join(process.cwd(), config.config);
12
- if (config.config && config.config !== "none" && !existsSync(ASCONFIG_PATH)) {
13
- console.log(`${chalk.bgMagentaBright(" WARN ")}${chalk.dim(":")} Could not locate asconfig.json file! If you do not want to provide a config, set "config": "none"`);
14
- }
6
+ import { getPkgRunner, loadConfig } from "./util.js";
7
+ const DEFAULT_CONFIG_PATH = path.join(process.cwd(), "./as-test.config.json");
8
+ export async function build(configPath = DEFAULT_CONFIG_PATH, selectors = []) {
9
+ const config = loadConfig(configPath, false);
15
10
  ensureDeps(config);
16
- let pkgRunner = getPkgRunner();
17
- const inputFiles = await glob(config.input);
18
- let buildArgs = getBuildArgs(config);
11
+ const pkgRunner = getPkgRunner();
12
+ const inputPatterns = resolveInputPatterns(config.input, selectors);
13
+ const inputFiles = await glob(inputPatterns);
14
+ const buildArgs = getBuildArgs(config);
19
15
  for (const file of inputFiles) {
20
16
  let cmd = `${pkgRunner} asc ${file}${buildArgs}`;
21
17
  const outFile = `${config.outDir}/${file.slice(file.lastIndexOf("/") + 1).replace(".ts", ".wasm")}`;
22
18
  if (config.outDir) {
23
19
  cmd += " -o " + outFile;
24
20
  }
25
- buildFile(cmd);
21
+ try {
22
+ buildFile(cmd);
23
+ }
24
+ catch (error) {
25
+ throw new Error(`Failed to build ${path.basename(file)} with ${getBuildStderr(error)}`);
26
+ }
27
+ }
28
+ }
29
+ function resolveInputPatterns(configured, selectors) {
30
+ const configuredInputs = Array.isArray(configured) ? configured : [configured];
31
+ if (!selectors.length)
32
+ return configuredInputs;
33
+ const patterns = new Set();
34
+ for (const selector of selectors) {
35
+ if (!selector)
36
+ continue;
37
+ if (isBareSuiteSelector(selector)) {
38
+ const base = stripSuiteSuffix(selector);
39
+ for (const configuredInput of configuredInputs) {
40
+ patterns.add(path.join(path.dirname(configuredInput), `${base}.spec.ts`));
41
+ }
42
+ continue;
43
+ }
44
+ patterns.add(selector);
26
45
  }
46
+ return [...patterns];
47
+ }
48
+ function isBareSuiteSelector(selector) {
49
+ return (!selector.includes("/") &&
50
+ !selector.includes("\\") &&
51
+ !/[*?[\]{}]/.test(selector));
52
+ }
53
+ function stripSuiteSuffix(selector) {
54
+ return selector.replace(/\.spec\.ts$/, "").replace(/\.ts$/, "");
27
55
  }
28
56
  function ensureDeps(config) {
29
- const pkg = JSON.parse(readFileSync(PKG_PATH).toString());
30
57
  if (config.buildOptions.target == "wasi") {
31
58
  if (!existsSync("./node_modules/@assemblyscript/wasi-shim/asconfig.json")) {
32
59
  console.log(`${chalk.bgRed(" ERROR ")}${chalk.dim(":")} could not find @assemblyscript/wasi-shim! Add it to your dependencies to run with WASI!`);
33
60
  process.exit(1);
34
61
  }
35
- if (pkg.dependencies &&
36
- !Object.keys(pkg.dependencies).includes("@assemblyscript/wasi-shim") &&
37
- pkg.devDependencies &&
38
- !Object.keys(pkg.devDependencies).includes("@assemblyscript/wasi-shim") &&
39
- pkg.peerDependencies &&
40
- !Object.keys(pkg.peerDependencies).includes("@assemblyscript/wasi-shim") &&
41
- existsSync("./node_modules/@assemblyscript/wasi-shim/asconfig.json")) {
42
- console.log(`${chalk.bold.bgMagentaBright(" WARN ")}${chalk.dim(":")} @assemblyscript/wasi-shim is not included in project dependencies!"`);
43
- }
44
62
  }
45
- }
46
- function getPkgRunner() {
47
- switch (process.env.npm_config_user_agent) {
48
- case "pnpm": {
49
- return "pnpx";
50
- }
51
- case "yarn": {
52
- return "yarn";
53
- }
54
- case "bun": {
55
- return "bunx";
56
- }
63
+ if (!hasJsonAsTransform()) {
64
+ console.log(`${chalk.bgRed(" ERROR ")}${chalk.dim(":")} could not find json-as. Install it to compile as-test suites.`);
65
+ process.exit(1);
57
66
  }
58
- return "npx";
59
67
  }
60
68
  function buildFile(command) {
61
- execSync(command, { stdio: "inherit" });
69
+ execSync(command, {
70
+ stdio: ["ignore", "pipe", "pipe"],
71
+ encoding: "utf8",
72
+ });
73
+ }
74
+ function getBuildStderr(error) {
75
+ const err = error;
76
+ const stderr = err?.stderr;
77
+ if (typeof stderr == "string") {
78
+ const trimmed = stderr.trim();
79
+ if (trimmed.length)
80
+ return trimmed;
81
+ }
82
+ else if (stderr instanceof Buffer) {
83
+ const trimmed = stderr.toString("utf8").trim();
84
+ if (trimmed.length)
85
+ return trimmed;
86
+ }
87
+ const message = typeof err?.message == "string" ? err.message.trim() : "";
88
+ return message || "unknown error";
62
89
  }
63
90
  function getBuildArgs(config) {
64
91
  let buildArgs = "";
65
- buildArgs += " --transform as-test/transform --transform json-as/transform";
92
+ buildArgs += " --transform as-test/transform";
93
+ buildArgs += " --transform json-as/transform";
94
+ if (hasTryAsRuntime()) {
95
+ buildArgs += " --transform try-as/transform";
96
+ }
66
97
  if (config.config && config.config !== "none") {
67
98
  buildArgs += " --config " + config.config;
68
99
  }
100
+ if (hasTryAsRuntime()) {
101
+ buildArgs += " --use AS_TEST_TRY_AS=1";
102
+ }
69
103
  // Should also strip any bindings-enabling from asconfig
70
104
  if (config.buildOptions.target == "bindings") {
105
+ buildArgs += " --use AS_TEST_BINDINGS=1";
71
106
  buildArgs += " --bindings raw --exportRuntime --exportStart _start";
72
107
  }
73
108
  else if (config.buildOptions.target == "wasi") {
109
+ buildArgs += " --use AS_TEST_WASI=1";
74
110
  buildArgs +=
75
111
  " --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json";
76
112
  }
77
113
  else {
78
- console.log(`${chalk.bgRed(" ERROR ")}${chalk.dim(":")} could determine target in config! Set target to 'bindings' or 'wasi'`);
79
- process.exit(0);
114
+ console.log(`${chalk.bgRed(" ERROR ")}${chalk.dim(":")} could not determine target in config! Set target to 'bindings' or 'wasi'`);
115
+ process.exit(1);
80
116
  }
81
117
  if (config.buildOptions.args.length &&
82
118
  config.buildOptions.args.find((v) => v.length > 0)) {
@@ -84,3 +120,12 @@ function getBuildArgs(config) {
84
120
  }
85
121
  return buildArgs;
86
122
  }
123
+ function hasTryAsRuntime() {
124
+ return (existsSync(path.join(process.cwd(), "node_modules/try-as")) ||
125
+ existsSync(path.join(process.cwd(), "node_modules/try-as/package.json")));
126
+ }
127
+ function hasJsonAsTransform() {
128
+ return (existsSync(path.join(process.cwd(), "node_modules/json-as/transform.js")) ||
129
+ existsSync(path.join(process.cwd(), "node_modules/json-as/transform.ts")) ||
130
+ existsSync(path.join(process.cwd(), "node_modules/json-as/transform")));
131
+ }