ic-mops 1.11.1 → 2.0.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.
- package/.DS_Store +0 -0
- package/.eslintrc.json +7 -7
- package/CHANGELOG.md +15 -0
- package/api/actors.ts +41 -37
- package/api/downloadPackageFiles.ts +75 -61
- package/api/getHighestVersion.ts +5 -5
- package/api/index.ts +4 -4
- package/api/network.ts +19 -21
- package/api/resolveVersion.ts +14 -11
- package/bin/mops.js +1 -1
- package/bun.lock +234 -198
- package/bundle/bench/bench-canister.mo +2 -2
- package/bundle/bench/user-bench.mo +0 -4
- package/bundle/bin/mops.js +1 -1
- package/bundle/cli.js +1000 -924
- package/bundle/cli.tgz +0 -0
- package/bundle/declarations/bench/bench.did +3 -3
- package/bundle/declarations/bench/bench.did.d.ts +3 -3
- package/bundle/declarations/bench/index.d.ts +3 -3
- package/bundle/declarations/bench/index.js +1 -1
- package/bundle/declarations/main/index.d.ts +3 -3
- package/bundle/declarations/main/index.js +1 -1
- package/bundle/declarations/main/main.did +78 -121
- package/bundle/declarations/main/main.did.d.ts +48 -98
- package/bundle/declarations/main/main.did.js +53 -107
- package/bundle/declarations/storage/index.d.ts +3 -3
- package/bundle/declarations/storage/index.js +4 -4
- package/bundle/declarations/storage/storage.did.d.ts +3 -3
- package/bundle/package.json +6 -5
- package/bundle/templates/mops-publish.yml +3 -3
- package/bundle/templates/mops-test.yml +3 -3
- package/bundle-package-json.ts +8 -8
- package/cache.ts +80 -65
- package/check-requirements.ts +49 -45
- package/cli.ts +577 -376
- package/commands/add.ts +142 -129
- package/commands/available-updates.ts +55 -28
- package/commands/bench/bench-canister.mo +114 -108
- package/commands/bench/user-bench.mo +6 -6
- package/commands/bench-replica.ts +146 -106
- package/commands/bench.ts +563 -497
- package/commands/build.ts +177 -0
- package/commands/bump.ts +68 -57
- package/commands/check-candid.ts +24 -0
- package/commands/docs-coverage.ts +124 -102
- package/commands/docs.ts +118 -108
- package/commands/format.ts +171 -155
- package/commands/init.ts +301 -275
- package/commands/install/install-all.ts +75 -62
- package/commands/install/install-dep.ts +43 -28
- package/commands/install/install-deps.ts +23 -15
- package/commands/install/install-local-dep.ts +42 -34
- package/commands/install/install-mops-dep.ts +154 -123
- package/commands/install/sync-local-cache.ts +39 -35
- package/commands/maintainer.ts +109 -99
- package/commands/outdated.ts +31 -18
- package/commands/owner.ts +107 -99
- package/commands/publish.ts +534 -443
- package/commands/remove.ts +119 -89
- package/commands/replica.ts +391 -303
- package/commands/search.ts +42 -36
- package/commands/self.ts +63 -56
- package/commands/sources.ts +66 -49
- package/commands/sync.ts +92 -75
- package/commands/template.ts +145 -102
- package/commands/test/mmf1.ts +146 -119
- package/commands/test/reporters/compact-reporter.ts +87 -84
- package/commands/test/reporters/files-reporter.ts +56 -51
- package/commands/test/reporters/reporter.ts +12 -6
- package/commands/test/reporters/silent-reporter.ts +58 -59
- package/commands/test/reporters/verbose-reporter.ts +66 -54
- package/commands/test/test.ts +497 -460
- package/commands/test/utils.ts +85 -6
- package/commands/toolchain/index.ts +363 -322
- package/commands/toolchain/moc.ts +78 -50
- package/commands/toolchain/pocket-ic.ts +41 -34
- package/commands/toolchain/toolchain-utils.ts +92 -72
- package/commands/toolchain/wasmtime.ts +37 -34
- package/commands/update.ts +91 -56
- package/commands/user.ts +90 -81
- package/commands/watch/deployer.ts +188 -152
- package/commands/watch/error-checker.ts +90 -80
- package/commands/watch/formatter.ts +72 -60
- package/commands/watch/generator.ts +116 -96
- package/commands/watch/globMoFiles.ts +13 -13
- package/commands/watch/parseDfxJson.ts +63 -57
- package/commands/watch/tester.ts +83 -65
- package/commands/watch/warning-checker.ts +149 -136
- package/commands/watch/watch.ts +123 -95
- package/declarations/bench/bench.did.d.ts +3 -3
- package/declarations/bench/index.d.ts +3 -3
- package/declarations/bench/index.js +1 -1
- package/declarations/main/index.d.ts +3 -3
- package/declarations/main/index.js +1 -1
- package/declarations/main/main.did.d.ts +3 -3
- package/declarations/storage/index.d.ts +3 -3
- package/declarations/storage/index.js +4 -4
- package/declarations/storage/storage.did.d.ts +3 -3
- package/dist/api/actors.d.ts +4 -4
- package/dist/api/actors.js +8 -8
- package/dist/api/downloadPackageFiles.d.ts +2 -2
- package/dist/api/downloadPackageFiles.js +10 -10
- package/dist/api/getHighestVersion.js +1 -1
- package/dist/api/index.d.ts +4 -4
- package/dist/api/index.js +4 -4
- package/dist/api/network.js +9 -9
- package/dist/api/resolveVersion.js +3 -3
- package/dist/bin/mops.js +1 -1
- package/dist/bundle-package-json.js +8 -8
- package/dist/cache.js +22 -17
- package/dist/check-requirements.js +11 -11
- package/dist/cli.js +283 -186
- package/dist/commands/add.d.ts +1 -1
- package/dist/commands/add.js +41 -38
- package/dist/commands/available-updates.d.ts +1 -1
- package/dist/commands/available-updates.js +32 -14
- package/dist/commands/bench/bench-canister.mo +114 -108
- package/dist/commands/bench/user-bench.mo +6 -6
- package/dist/commands/bench-replica.d.ts +6 -5
- package/dist/commands/bench-replica.js +58 -36
- package/dist/commands/bench.d.ts +5 -5
- package/dist/commands/bench.js +134 -118
- package/dist/commands/build.d.ts +7 -0
- package/dist/commands/build.js +121 -0
- package/dist/commands/bump.js +27 -18
- package/dist/commands/check-candid.d.ts +4 -0
- package/dist/commands/check-candid.js +15 -0
- package/dist/commands/docs-coverage.d.ts +1 -1
- package/dist/commands/docs-coverage.js +45 -31
- package/dist/commands/docs.d.ts +1 -1
- package/dist/commands/docs.js +39 -38
- package/dist/commands/format.js +31 -27
- package/dist/commands/init.js +102 -92
- package/dist/commands/install/install-all.d.ts +2 -2
- package/dist/commands/install/install-all.js +23 -21
- package/dist/commands/install/install-dep.d.ts +1 -1
- package/dist/commands/install/install-dep.js +21 -8
- package/dist/commands/install/install-deps.d.ts +1 -1
- package/dist/commands/install/install-deps.js +1 -1
- package/dist/commands/install/install-local-dep.js +11 -9
- package/dist/commands/install/install-mops-dep.d.ts +1 -1
- package/dist/commands/install/install-mops-dep.js +32 -27
- package/dist/commands/install/sync-local-cache.js +10 -10
- package/dist/commands/maintainer.js +21 -21
- package/dist/commands/outdated.js +16 -6
- package/dist/commands/owner.js +21 -21
- package/dist/commands/publish.js +148 -128
- package/dist/commands/remove.d.ts +1 -1
- package/dist/commands/remove.js +42 -30
- package/dist/commands/replica.d.ts +9 -8
- package/dist/commands/replica.js +105 -65
- package/dist/commands/search.js +15 -13
- package/dist/commands/self.js +31 -28
- package/dist/commands/sources.d.ts +5 -1
- package/dist/commands/sources.js +23 -17
- package/dist/commands/sync.d.ts +1 -1
- package/dist/commands/sync.js +38 -25
- package/dist/commands/template.js +66 -56
- package/dist/commands/test/mmf1.d.ts +3 -3
- package/dist/commands/test/mmf1.js +33 -31
- package/dist/commands/test/reporters/compact-reporter.d.ts +3 -3
- package/dist/commands/test/reporters/compact-reporter.js +19 -15
- package/dist/commands/test/reporters/files-reporter.d.ts +3 -3
- package/dist/commands/test/reporters/files-reporter.js +18 -14
- package/dist/commands/test/reporters/reporter.d.ts +2 -2
- package/dist/commands/test/reporters/silent-reporter.d.ts +3 -3
- package/dist/commands/test/reporters/silent-reporter.js +4 -4
- package/dist/commands/test/reporters/verbose-reporter.d.ts +3 -3
- package/dist/commands/test/reporters/verbose-reporter.js +17 -13
- package/dist/commands/test/test.d.ts +4 -4
- package/dist/commands/test/test.js +151 -181
- package/dist/commands/test/utils.d.ts +6 -0
- package/dist/commands/test/utils.js +63 -2
- package/dist/commands/toolchain/index.d.ts +1 -1
- package/dist/commands/toolchain/index.js +81 -69
- package/dist/commands/toolchain/moc.d.ts +1 -1
- package/dist/commands/toolchain/moc.js +48 -24
- package/dist/commands/toolchain/pocket-ic.js +12 -12
- package/dist/commands/toolchain/toolchain-utils.d.ts +2 -0
- package/dist/commands/toolchain/toolchain-utils.js +32 -23
- package/dist/commands/toolchain/wasmtime.js +11 -11
- package/dist/commands/update.d.ts +1 -1
- package/dist/commands/update.js +30 -12
- package/dist/commands/user.js +31 -28
- package/dist/commands/watch/deployer.d.ts +4 -4
- package/dist/commands/watch/deployer.js +45 -36
- package/dist/commands/watch/error-checker.d.ts +2 -2
- package/dist/commands/watch/error-checker.js +27 -27
- package/dist/commands/watch/formatter.d.ts +4 -4
- package/dist/commands/watch/formatter.js +17 -17
- package/dist/commands/watch/generator.d.ts +3 -3
- package/dist/commands/watch/generator.js +28 -23
- package/dist/commands/watch/globMoFiles.js +8 -8
- package/dist/commands/watch/parseDfxJson.d.ts +2 -2
- package/dist/commands/watch/parseDfxJson.js +9 -9
- package/dist/commands/watch/tester.d.ts +4 -4
- package/dist/commands/watch/tester.js +23 -21
- package/dist/commands/watch/warning-checker.d.ts +3 -3
- package/dist/commands/watch/warning-checker.js +36 -36
- package/dist/commands/watch/watch.js +45 -32
- package/dist/declarations/bench/bench.did.d.ts +3 -3
- package/dist/declarations/bench/index.d.ts +3 -3
- package/dist/declarations/bench/index.js +1 -1
- package/dist/declarations/main/index.d.ts +3 -3
- package/dist/declarations/main/index.js +1 -1
- package/dist/declarations/main/main.did.d.ts +3 -3
- package/dist/declarations/storage/index.d.ts +3 -3
- package/dist/declarations/storage/index.js +4 -4
- package/dist/declarations/storage/storage.did.d.ts +3 -3
- package/dist/environments/nodejs/cli.d.ts +1 -0
- package/dist/environments/nodejs/cli.js +4 -0
- package/dist/environments/web/cli.d.ts +1 -0
- package/dist/environments/web/cli.js +4 -0
- package/dist/error.d.ts +1 -0
- package/dist/error.js +5 -0
- package/dist/fix-dist.js +5 -5
- package/dist/helpers/find-changelog-entry.js +8 -5
- package/dist/helpers/get-dep-name.d.ts +1 -0
- package/dist/helpers/get-dep-name.js +4 -1
- package/dist/helpers/get-dfx-version.js +4 -4
- package/dist/helpers/get-moc-path.js +8 -7
- package/dist/helpers/get-moc-version.js +10 -7
- package/dist/helpers/get-package-id.js +2 -2
- package/dist/helpers/is-candid-compatible.d.ts +1 -0
- package/dist/helpers/is-candid-compatible.js +20 -0
- package/dist/integrity.d.ts +1 -1
- package/dist/integrity.js +47 -38
- package/dist/jest.config.d.ts +11 -0
- package/dist/jest.config.js +14 -0
- package/dist/mops.d.ts +6 -6
- package/dist/mops.js +87 -80
- package/dist/notify-installs.js +4 -4
- package/dist/package.json +11 -10
- package/dist/pem.d.ts +3 -3
- package/dist/pem.js +20 -12
- package/dist/release-cli.js +20 -20
- package/dist/resolve-packages.d.ts +1 -1
- package/dist/resolve-packages.js +52 -36
- package/dist/templates/mops-publish.yml +3 -3
- package/dist/templates/mops-test.yml +3 -3
- package/dist/templates/src/lib.mo +13 -13
- package/dist/templates/test/lib.test.mo +2 -2
- package/dist/templates.js +1 -1
- package/dist/tests/cli.test.d.ts +1 -0
- package/dist/tests/cli.test.js +63 -0
- package/dist/types.d.ts +14 -4
- package/dist/vessel.d.ts +2 -2
- package/dist/vessel.js +41 -34
- package/dist/wasm/pkg/bundler/package.json +20 -0
- package/dist/wasm/pkg/bundler/wasm.d.ts +3 -0
- package/dist/wasm/pkg/bundler/wasm.js +5 -0
- package/dist/wasm/pkg/bundler/wasm_bg.js +93 -0
- package/dist/wasm/pkg/bundler/wasm_bg.wasm +0 -0
- package/dist/wasm/pkg/bundler/wasm_bg.wasm.d.ts +8 -0
- package/dist/wasm/pkg/nodejs/package.json +14 -0
- package/dist/wasm/pkg/nodejs/wasm.d.ts +3 -0
- package/dist/wasm/pkg/nodejs/wasm.js +98 -0
- package/dist/wasm/pkg/nodejs/wasm_bg.wasm +0 -0
- package/dist/wasm/pkg/nodejs/wasm_bg.wasm.d.ts +8 -0
- package/dist/wasm/pkg/web/package.json +18 -0
- package/dist/wasm/pkg/web/wasm.d.ts +35 -0
- package/dist/wasm/pkg/web/wasm.js +191 -0
- package/dist/wasm/pkg/web/wasm_bg.wasm +0 -0
- package/dist/wasm/pkg/web/wasm_bg.wasm.d.ts +8 -0
- package/dist/wasm.d.ts +5 -0
- package/dist/wasm.js +10 -0
- package/environments/nodejs/cli.ts +6 -0
- package/environments/web/cli.ts +6 -0
- package/error.ts +6 -0
- package/fix-dist.ts +5 -5
- package/global.d.ts +3 -3
- package/helpers/find-changelog-entry.ts +26 -23
- package/helpers/get-dep-name.ts +7 -3
- package/helpers/get-dfx-version.ts +8 -9
- package/helpers/get-moc-path.ts +25 -26
- package/helpers/get-moc-version.ts +21 -19
- package/helpers/get-package-id.ts +4 -4
- package/helpers/is-candid-compatible.ts +22 -0
- package/integrity.ts +270 -236
- package/jest.config.js +14 -0
- package/mops.ts +238 -215
- package/notify-installs.ts +16 -17
- package/package.json +21 -15
- package/parallel.ts +28 -24
- package/pem.ts +55 -47
- package/release-cli.ts +73 -39
- package/resolve-packages.ts +231 -189
- package/templates/mops-publish.yml +3 -3
- package/templates/mops-test.yml +3 -3
- package/templates/src/lib.mo +13 -13
- package/templates/test/lib.test.mo +2 -2
- package/templates.ts +4 -4
- package/tests/__snapshots__/cli.test.ts.snap +202 -0
- package/tests/build/error/candid/bar.did +3 -0
- package/tests/build/error/dfx.json +12 -0
- package/tests/build/error/mops.toml +9 -0
- package/tests/build/error/src/Bar.mo +5 -0
- package/tests/build/error/src/Foo.mo +5 -0
- package/tests/build/success/.dfx/local/canister_ids.json +17 -0
- package/tests/build/success/.dfx/local/canisters/bar/bar.did +3 -0
- package/tests/build/success/.dfx/local/canisters/bar/bar.most +4 -0
- package/tests/build/success/.dfx/local/canisters/bar/bar.wasm +0 -0
- package/tests/build/success/.dfx/local/canisters/bar/constructor.did +3 -0
- package/tests/build/success/.dfx/local/canisters/bar/index.js +42 -0
- package/tests/build/success/.dfx/local/canisters/bar/init_args.txt +1 -0
- package/tests/build/success/.dfx/local/canisters/bar/service.did +3 -0
- package/tests/build/success/.dfx/local/canisters/bar/service.did.d.ts +7 -0
- package/tests/build/success/.dfx/local/canisters/bar/service.did.js +4 -0
- package/tests/build/success/.dfx/local/canisters/foo/constructor.did +3 -0
- package/tests/build/success/.dfx/local/canisters/foo/foo.did +3 -0
- package/tests/build/success/.dfx/local/canisters/foo/foo.most +4 -0
- package/tests/build/success/.dfx/local/canisters/foo/foo.wasm +0 -0
- package/tests/build/success/.dfx/local/canisters/foo/index.js +42 -0
- package/tests/build/success/.dfx/local/canisters/foo/init_args.txt +1 -0
- package/tests/build/success/.dfx/local/canisters/foo/service.did +3 -0
- package/tests/build/success/.dfx/local/canisters/foo/service.did.d.ts +7 -0
- package/tests/build/success/.dfx/local/canisters/foo/service.did.js +4 -0
- package/tests/build/success/.dfx/local/lsp/ucwa4-rx777-77774-qaada-cai.did +3 -0
- package/tests/build/success/.dfx/local/lsp/ulvla-h7777-77774-qaacq-cai.did +3 -0
- package/tests/build/success/.dfx/local/network-id +4 -0
- package/tests/build/success/candid/bar.did +3 -0
- package/tests/build/success/dfx.json +12 -0
- package/tests/build/success/mops.toml +9 -0
- package/tests/build/success/src/Bar.mo +5 -0
- package/tests/build/success/src/Foo.mo +5 -0
- package/tests/check-candid/a.did +3 -0
- package/tests/check-candid/b.did +5 -0
- package/tests/check-candid/c.did +3 -0
- package/tests/cli.test.ts +82 -0
- package/tsconfig.json +26 -19
- package/types.ts +41 -31
- package/vessel.ts +219 -187
- package/wasm/Cargo.lock +1475 -0
- package/wasm/Cargo.toml +28 -0
- package/wasm/pkg/bundler/package.json +20 -0
- package/wasm/pkg/bundler/wasm.d.ts +3 -0
- package/wasm/pkg/bundler/wasm.js +5 -0
- package/wasm/pkg/bundler/wasm_bg.js +93 -0
- package/wasm/pkg/bundler/wasm_bg.wasm +0 -0
- package/wasm/pkg/bundler/wasm_bg.wasm.d.ts +8 -0
- package/wasm/pkg/nodejs/package.json +14 -0
- package/wasm/pkg/nodejs/wasm.d.ts +3 -0
- package/wasm/pkg/nodejs/wasm.js +98 -0
- package/wasm/pkg/nodejs/wasm_bg.wasm +0 -0
- package/wasm/pkg/nodejs/wasm_bg.wasm.d.ts +8 -0
- package/wasm/pkg/web/package.json +18 -0
- package/wasm/pkg/web/wasm.d.ts +35 -0
- package/wasm/pkg/web/wasm.js +191 -0
- package/wasm/pkg/web/wasm_bg.wasm +0 -0
- package/wasm/pkg/web/wasm_bg.wasm.d.ts +8 -0
- package/wasm/src/lib.rs +17 -0
- package/wasm.ts +16 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import chalk from
|
|
2
|
-
import { absToRel } from
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { absToRel } from "../utils.js";
|
|
3
3
|
export class VerboseReporter {
|
|
4
4
|
passed = 0;
|
|
5
5
|
failed = 0;
|
|
@@ -7,11 +7,11 @@ export class VerboseReporter {
|
|
|
7
7
|
#startTime = Date.now();
|
|
8
8
|
#curFileIndex = 0;
|
|
9
9
|
addFiles(files) {
|
|
10
|
-
console.log(
|
|
10
|
+
console.log("Test files:");
|
|
11
11
|
for (let file of files) {
|
|
12
12
|
console.log(chalk.gray(`• ${absToRel(file)}`));
|
|
13
13
|
}
|
|
14
|
-
console.log(
|
|
14
|
+
console.log("=".repeat(50));
|
|
15
15
|
}
|
|
16
16
|
addRun(file, mmf, state, mode, progressive = false) {
|
|
17
17
|
if (progressive) {
|
|
@@ -31,21 +31,25 @@ export class VerboseReporter {
|
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
done() {
|
|
34
|
-
console.log(
|
|
34
|
+
console.log("=".repeat(50));
|
|
35
35
|
if (this.failed) {
|
|
36
|
-
console.log(chalk.redBright(
|
|
36
|
+
console.log(chalk.redBright("Tests failed"));
|
|
37
37
|
}
|
|
38
38
|
else {
|
|
39
|
-
console.log(chalk.greenBright(
|
|
39
|
+
console.log(chalk.greenBright("Tests passed"));
|
|
40
40
|
}
|
|
41
|
-
console.log(`Done in ${chalk.gray(((Date.now() - this.#startTime) / 1000).toFixed(2) +
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
console.log(`Done in ${chalk.gray(((Date.now() - this.#startTime) / 1000).toFixed(2) + "s")}` +
|
|
42
|
+
`, passed ${chalk.greenBright(this.passed)}` +
|
|
43
|
+
(this.skipped
|
|
44
|
+
? `, skipped ${chalk[this.skipped ? "yellowBright" : "gray"](this.skipped)}`
|
|
45
|
+
: "") +
|
|
46
|
+
(this.failed
|
|
47
|
+
? `, failed ${chalk[this.failed ? "redBright" : "gray"](this.failed)}`
|
|
48
|
+
: ""));
|
|
45
49
|
return this.failed === 0;
|
|
46
50
|
}
|
|
47
51
|
_printStart(file, mode) {
|
|
48
|
-
this.#curFileIndex++ && console.log(
|
|
49
|
-
console.log(`Running ${chalk.gray(absToRel(file))} ${mode ===
|
|
52
|
+
this.#curFileIndex++ && console.log("-".repeat(50));
|
|
53
|
+
console.log(`Running ${chalk.gray(absToRel(file))} ${mode === "interpreter" ? "" : chalk.gray(`(${mode})`)}`);
|
|
50
54
|
}
|
|
51
55
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Reporter } from
|
|
2
|
-
import { TestMode } from
|
|
3
|
-
type ReporterName =
|
|
4
|
-
type ReplicaName =
|
|
1
|
+
import { Reporter } from "./reporters/reporter.js";
|
|
2
|
+
import { TestMode } from "../../types.js";
|
|
3
|
+
type ReporterName = "verbose" | "files" | "compact" | "silent";
|
|
4
|
+
type ReplicaName = "dfx" | "pocket-ic" | "dfx-pocket-ic";
|
|
5
5
|
type TestOptions = {
|
|
6
6
|
watch: boolean;
|
|
7
7
|
reporter: ReporterName;
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import process from
|
|
2
|
-
import { spawn } from
|
|
3
|
-
import path from
|
|
4
|
-
import fs from
|
|
5
|
-
import os from
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import { getDfxVersion } from
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import os from "node:os";
|
|
6
|
+
import { PassThrough } from "node:stream";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
import { globSync } from "glob";
|
|
9
|
+
import chokidar from "chokidar";
|
|
10
|
+
import debounce from "debounce";
|
|
11
|
+
import { SemVer } from "semver";
|
|
12
|
+
import { sources } from "../sources.js";
|
|
13
|
+
import { getRootDir, readConfig } from "../../mops.js";
|
|
14
|
+
import { parallel } from "../../parallel.js";
|
|
15
|
+
import { MMF1 } from "./mmf1.js";
|
|
16
|
+
import { absToRel, pipeMMF, pipeStderrToMMF, pipeStdoutToMMF, } from "./utils.js";
|
|
17
|
+
import { VerboseReporter } from "./reporters/verbose-reporter.js";
|
|
18
|
+
import { FilesReporter } from "./reporters/files-reporter.js";
|
|
19
|
+
import { CompactReporter } from "./reporters/compact-reporter.js";
|
|
20
|
+
import { SilentReporter } from "./reporters/silent-reporter.js";
|
|
21
|
+
import { toolchain } from "../toolchain/index.js";
|
|
22
|
+
import { Replica } from "../replica.js";
|
|
23
|
+
import { getDfxVersion } from "../../helpers/get-dfx-version.js";
|
|
24
24
|
let ignore = [
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
"**/node_modules/**",
|
|
26
|
+
"**/.mops/**",
|
|
27
|
+
"**/.vessel/**",
|
|
28
|
+
"**/.git/**",
|
|
29
29
|
];
|
|
30
30
|
let globConfig = {
|
|
31
31
|
nocase: true,
|
|
@@ -41,18 +41,19 @@ async function startReplicaOnce(replica, type) {
|
|
|
41
41
|
}
|
|
42
42
|
return replicaStartPromise;
|
|
43
43
|
}
|
|
44
|
-
export async function test(filter =
|
|
44
|
+
export async function test(filter = "", options = {}) {
|
|
45
45
|
let config = readConfig();
|
|
46
46
|
let rootDir = getRootDir();
|
|
47
|
-
let replicaType = options.replica ??
|
|
48
|
-
|
|
47
|
+
let replicaType = options.replica ??
|
|
48
|
+
(config.toolchain?.["pocket-ic"] ? "pocket-ic" : "dfx");
|
|
49
|
+
if (replicaType === "pocket-ic" && !config.toolchain?.["pocket-ic"]) {
|
|
49
50
|
let dfxVersion = getDfxVersion();
|
|
50
|
-
if (!dfxVersion || new SemVer(dfxVersion).compare(
|
|
51
|
-
console.log(chalk.red(
|
|
51
|
+
if (!dfxVersion || new SemVer(dfxVersion).compare("0.24.1") < 0) {
|
|
52
|
+
console.log(chalk.red("Please update dfx to the version >=0.24.1 or specify pocket-ic version in mops.toml"));
|
|
52
53
|
process.exit(1);
|
|
53
54
|
}
|
|
54
55
|
else {
|
|
55
|
-
replicaType =
|
|
56
|
+
replicaType = "dfx-pocket-ic";
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
replica.type = replicaType;
|
|
@@ -60,14 +61,14 @@ export async function test(filter = '', options = {}) {
|
|
|
60
61
|
if (options.watch) {
|
|
61
62
|
replica.ttl = 60 * 15; // 15 minutes
|
|
62
63
|
let sigint = false;
|
|
63
|
-
process.on(
|
|
64
|
+
process.on("SIGINT", () => {
|
|
64
65
|
if (sigint) {
|
|
65
|
-
console.log(
|
|
66
|
+
console.log("Force exit");
|
|
66
67
|
process.exit(0);
|
|
67
68
|
}
|
|
68
69
|
sigint = true;
|
|
69
70
|
if (replicaStartPromise) {
|
|
70
|
-
console.log(
|
|
71
|
+
console.log("Stopping replica...");
|
|
71
72
|
replica.stop(true).then(() => {
|
|
72
73
|
process.exit(0);
|
|
73
74
|
});
|
|
@@ -84,22 +85,19 @@ export async function test(filter = '', options = {}) {
|
|
|
84
85
|
controller.abort();
|
|
85
86
|
await curRun;
|
|
86
87
|
console.clear();
|
|
87
|
-
process.stdout.write(
|
|
88
|
+
process.stdout.write("\x1Bc");
|
|
88
89
|
controller = new AbortController();
|
|
89
90
|
curRun = runAll(options.reporter, filter, options.mode, replicaType, true, controller.signal);
|
|
90
91
|
await curRun;
|
|
91
|
-
console.log(
|
|
92
|
-
console.log(
|
|
93
|
-
console.log(chalk.gray(
|
|
92
|
+
console.log("-".repeat(50));
|
|
93
|
+
console.log("Waiting for file changes...");
|
|
94
|
+
console.log(chalk.gray(`Press ${chalk.gray("Ctrl+C")} to exit.`));
|
|
94
95
|
}, 200);
|
|
95
|
-
let watcher = chokidar.watch([
|
|
96
|
-
path.join(rootDir, '**/*.mo'),
|
|
97
|
-
path.join(rootDir, 'mops.toml'),
|
|
98
|
-
], {
|
|
96
|
+
let watcher = chokidar.watch([path.join(rootDir, "**/*.mo"), path.join(rootDir, "mops.toml")], {
|
|
99
97
|
ignored: ignore,
|
|
100
98
|
ignoreInitial: true,
|
|
101
99
|
});
|
|
102
|
-
watcher.on(
|
|
100
|
+
watcher.on("all", () => {
|
|
103
101
|
run();
|
|
104
102
|
});
|
|
105
103
|
run();
|
|
@@ -111,21 +109,21 @@ export async function test(filter = '', options = {}) {
|
|
|
111
109
|
}
|
|
112
110
|
}
|
|
113
111
|
}
|
|
114
|
-
let mocPath =
|
|
115
|
-
let wasmtimePath =
|
|
116
|
-
async function runAll(reporterName, filter =
|
|
112
|
+
let mocPath = "";
|
|
113
|
+
let wasmtimePath = "";
|
|
114
|
+
async function runAll(reporterName, filter = "", mode = "interpreter", replicaType, watch = false, signal) {
|
|
117
115
|
let done = await testWithReporter(reporterName, filter, mode, replicaType, watch, signal);
|
|
118
116
|
return done;
|
|
119
117
|
}
|
|
120
|
-
export async function testWithReporter(reporterName, filter =
|
|
118
|
+
export async function testWithReporter(reporterName, filter = "", defaultMode = "interpreter", replicaType, watch = false, signal) {
|
|
121
119
|
let rootDir = getRootDir();
|
|
122
120
|
let files = [];
|
|
123
|
-
let libFiles = globSync(
|
|
121
|
+
let libFiles = globSync("**/test?(s)/lib.mo", globConfig);
|
|
124
122
|
if (libFiles[0]) {
|
|
125
123
|
files = [libFiles[0]];
|
|
126
124
|
}
|
|
127
125
|
else {
|
|
128
|
-
let globStr =
|
|
126
|
+
let globStr = "**/test?(s)/**/*.test.mo";
|
|
129
127
|
if (filter) {
|
|
130
128
|
globStr = `**/test?(s)/**/*${filter}*.mo`;
|
|
131
129
|
}
|
|
@@ -136,26 +134,26 @@ export async function testWithReporter(reporterName, filter = '', defaultMode =
|
|
|
136
134
|
console.log(`No test files found for filter '${filter}'`);
|
|
137
135
|
return false;
|
|
138
136
|
}
|
|
139
|
-
console.log(
|
|
140
|
-
console.log(
|
|
137
|
+
console.log("No test files found");
|
|
138
|
+
console.log("Put your tests in 'test' directory in *.test.mo files");
|
|
141
139
|
return false;
|
|
142
140
|
}
|
|
143
141
|
let reporter;
|
|
144
|
-
if (!reporterName || typeof reporterName ===
|
|
142
|
+
if (!reporterName || typeof reporterName === "string") {
|
|
145
143
|
if (!reporterName) {
|
|
146
|
-
reporterName = files.length > 1 ?
|
|
144
|
+
reporterName = files.length > 1 ? "files" : "verbose";
|
|
147
145
|
}
|
|
148
|
-
if (reporterName ==
|
|
149
|
-
reporter = new CompactReporter;
|
|
146
|
+
if (reporterName == "compact") {
|
|
147
|
+
reporter = new CompactReporter();
|
|
150
148
|
}
|
|
151
|
-
else if (reporterName ==
|
|
152
|
-
reporter = new FilesReporter;
|
|
149
|
+
else if (reporterName == "files") {
|
|
150
|
+
reporter = new FilesReporter();
|
|
153
151
|
}
|
|
154
|
-
else if (reporterName ==
|
|
155
|
-
reporter = new SilentReporter;
|
|
152
|
+
else if (reporterName == "silent") {
|
|
153
|
+
reporter = new SilentReporter();
|
|
156
154
|
}
|
|
157
155
|
else {
|
|
158
|
-
reporter = new VerboseReporter;
|
|
156
|
+
reporter = new VerboseReporter();
|
|
159
157
|
}
|
|
160
158
|
}
|
|
161
159
|
else {
|
|
@@ -165,45 +163,59 @@ export async function testWithReporter(reporterName, filter = '', defaultMode =
|
|
|
165
163
|
let config = readConfig();
|
|
166
164
|
let sourcesArr = await sources();
|
|
167
165
|
if (!mocPath) {
|
|
168
|
-
mocPath = await toolchain.bin(
|
|
166
|
+
mocPath = await toolchain.bin("moc", { fallback: true });
|
|
169
167
|
}
|
|
170
|
-
let testTempDir = path.join(getRootDir(),
|
|
168
|
+
let testTempDir = path.join(getRootDir(), ".mops/.test/");
|
|
171
169
|
replica.dir = testTempDir;
|
|
172
170
|
fs.rmSync(testTempDir, { recursive: true, force: true });
|
|
173
171
|
fs.mkdirSync(testTempDir, { recursive: true });
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
let mmf = new MMF1('store', absToRel(file));
|
|
179
|
-
// mode overrides
|
|
180
|
-
let lines = fs.readFileSync(file, 'utf8').split('\n');
|
|
172
|
+
let filesWithMode = files.map((file) => {
|
|
173
|
+
let lines = fs.readFileSync(file, "utf8").split("\n");
|
|
181
174
|
let mode = defaultMode;
|
|
182
|
-
if (lines.includes(
|
|
183
|
-
mode =
|
|
175
|
+
if (lines.includes("// @testmode wasi")) {
|
|
176
|
+
mode = "wasi";
|
|
184
177
|
}
|
|
185
|
-
else if (lines.includes(
|
|
186
|
-
|
|
178
|
+
else if (lines.includes("// @testmode replica") ||
|
|
179
|
+
lines.find((line) => line.match(/^(persistent )?actor( class)?/))) {
|
|
180
|
+
mode = "replica";
|
|
187
181
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
182
|
+
return { file, mode };
|
|
183
|
+
});
|
|
184
|
+
let hasWasiTests = filesWithMode.some(({ mode }) => mode === "wasi");
|
|
185
|
+
let hasReplicaTests = filesWithMode.some(({ mode }) => mode === "replica");
|
|
186
|
+
// prepare wasmtime path
|
|
187
|
+
if (hasWasiTests && !wasmtimePath) {
|
|
188
|
+
// ensure wasmtime is installed or specified in config
|
|
189
|
+
if (config.toolchain?.wasmtime) {
|
|
190
|
+
wasmtimePath = await toolchain.bin("wasmtime");
|
|
191
|
+
}
|
|
192
|
+
// fallback wasmtime to global binary if not specified in config (legacy)
|
|
193
|
+
else {
|
|
194
|
+
wasmtimePath = "wasmtime";
|
|
195
|
+
console.log(chalk.yellow("Warning:"), 'Wasmtime is not specified in config. Using global binary "wasmtime". This will be removed in the future.');
|
|
196
|
+
console.log(`Run ${chalk.green("mops toolchain use wasmtime")} or add ${chalk.green('wasmtime = "<version>"')} in mops.toml to avoid breaking changes with future versions of mops.`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
let runTestFile = async ({ file, mode, }) => {
|
|
200
|
+
if (signal?.aborted) {
|
|
201
|
+
return;
|
|
199
202
|
}
|
|
203
|
+
// print logs immediately for replica tests because we run them one-by-one
|
|
204
|
+
let mmf = new MMF1(mode === "replica" ? "print" : "store", absToRel(file));
|
|
200
205
|
let promise = new Promise((resolve) => {
|
|
201
|
-
let mocArgs = [
|
|
206
|
+
let mocArgs = [
|
|
207
|
+
"--hide-warnings",
|
|
208
|
+
"--error-detail=2",
|
|
209
|
+
...sourcesArr.join(" ").split(" "),
|
|
210
|
+
file,
|
|
211
|
+
].filter((x) => x);
|
|
202
212
|
// interpret
|
|
203
|
-
if (mode ===
|
|
204
|
-
let proc = spawn(mocPath, [
|
|
205
|
-
|
|
206
|
-
|
|
213
|
+
if (mode === "interpreter") {
|
|
214
|
+
let proc = spawn(mocPath, ["-r", "-ref-system-api", ...mocArgs], {
|
|
215
|
+
signal,
|
|
216
|
+
});
|
|
217
|
+
proc.addListener("error", (error) => {
|
|
218
|
+
if (error?.code === "ABORT_ERR") {
|
|
207
219
|
return;
|
|
208
220
|
}
|
|
209
221
|
throw error;
|
|
@@ -211,63 +223,76 @@ export async function testWithReporter(reporterName, filter = '', defaultMode =
|
|
|
211
223
|
pipeMMF(proc, mmf).then(resolve);
|
|
212
224
|
}
|
|
213
225
|
// build and run wasm
|
|
214
|
-
else if (mode ===
|
|
226
|
+
else if (mode === "wasi") {
|
|
215
227
|
let wasmFile = `${path.join(testTempDir, path.parse(file).name)}.wasm`;
|
|
216
228
|
// build
|
|
217
|
-
let buildProc = spawn(mocPath, [`-o=${wasmFile}`,
|
|
218
|
-
buildProc.addListener(
|
|
219
|
-
if (error?.code ===
|
|
229
|
+
let buildProc = spawn(mocPath, [`-o=${wasmFile}`, "-wasi-system-api", ...mocArgs], { signal });
|
|
230
|
+
buildProc.addListener("error", (error) => {
|
|
231
|
+
if (error?.code === "ABORT_ERR") {
|
|
220
232
|
return;
|
|
221
233
|
}
|
|
222
234
|
throw error;
|
|
223
235
|
});
|
|
224
|
-
pipeMMF(buildProc, mmf)
|
|
236
|
+
pipeMMF(buildProc, mmf)
|
|
237
|
+
.then(async () => {
|
|
225
238
|
if (mmf.failed > 0) {
|
|
226
239
|
return;
|
|
227
240
|
}
|
|
228
241
|
// run
|
|
229
242
|
let wasmtimeArgs = [];
|
|
230
|
-
if (config.toolchain?.wasmtime &&
|
|
243
|
+
if (config.toolchain?.wasmtime &&
|
|
244
|
+
config.toolchain?.wasmtime >= "14.0.0") {
|
|
231
245
|
wasmtimeArgs = [
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
246
|
+
"-S",
|
|
247
|
+
"preview2=n",
|
|
248
|
+
"-C",
|
|
249
|
+
"cache=n",
|
|
250
|
+
"-W",
|
|
251
|
+
"bulk-memory",
|
|
252
|
+
"-W",
|
|
253
|
+
"multi-memory",
|
|
254
|
+
"-W",
|
|
255
|
+
"memory64",
|
|
256
|
+
"-W",
|
|
257
|
+
"max-wasm-stack=4000000",
|
|
258
|
+
"-W",
|
|
259
|
+
"nan-canonicalization=y",
|
|
239
260
|
wasmFile,
|
|
240
261
|
];
|
|
241
262
|
}
|
|
242
263
|
else {
|
|
243
|
-
console.error(chalk.red(
|
|
264
|
+
console.error(chalk.red("Minimum wasmtime version is 14.0.0. Please update wasmtime to the latest version"));
|
|
244
265
|
process.exit(1);
|
|
245
266
|
}
|
|
246
267
|
let proc = spawn(wasmtimePath, wasmtimeArgs, { signal });
|
|
247
|
-
proc.addListener(
|
|
248
|
-
if (error?.code ===
|
|
268
|
+
proc.addListener("error", (error) => {
|
|
269
|
+
if (error?.code === "ABORT_ERR") {
|
|
249
270
|
return;
|
|
250
271
|
}
|
|
251
272
|
throw error;
|
|
252
273
|
});
|
|
253
274
|
await pipeMMF(proc, mmf);
|
|
254
|
-
})
|
|
275
|
+
})
|
|
276
|
+
.finally(() => {
|
|
255
277
|
fs.rmSync(wasmFile, { force: true });
|
|
256
|
-
})
|
|
278
|
+
})
|
|
279
|
+
.then(resolve);
|
|
257
280
|
}
|
|
258
281
|
// build and execute in replica
|
|
259
|
-
else if (mode ===
|
|
260
|
-
// mmf.strategy = 'print'; // because we run replica tests one-by-one
|
|
282
|
+
else if (mode === "replica") {
|
|
261
283
|
let wasmFile = `${path.join(testTempDir, path.parse(file).name)}.wasm`;
|
|
262
284
|
// build
|
|
263
|
-
let buildProc = spawn(mocPath, [`-o=${wasmFile}`, ...mocArgs], {
|
|
264
|
-
|
|
265
|
-
|
|
285
|
+
let buildProc = spawn(mocPath, [`-o=${wasmFile}`, ...mocArgs], {
|
|
286
|
+
signal,
|
|
287
|
+
});
|
|
288
|
+
buildProc.addListener("error", (error) => {
|
|
289
|
+
if (error?.code === "ABORT_ERR") {
|
|
266
290
|
return;
|
|
267
291
|
}
|
|
268
292
|
throw error;
|
|
269
293
|
});
|
|
270
|
-
pipeMMF(buildProc, mmf)
|
|
294
|
+
pipeMMF(buildProc, mmf)
|
|
295
|
+
.then(async () => {
|
|
271
296
|
if (mmf.failed > 0) {
|
|
272
297
|
return;
|
|
273
298
|
}
|
|
@@ -277,14 +302,14 @@ export async function testWithReporter(reporterName, filter = '', defaultMode =
|
|
|
277
302
|
}
|
|
278
303
|
let canisterName = path.parse(file).name;
|
|
279
304
|
let idlFactory = ({ IDL }) => {
|
|
280
|
-
return IDL.Service({
|
|
305
|
+
return IDL.Service({ runTests: IDL.Func([], [], []) });
|
|
281
306
|
};
|
|
282
307
|
let canister = await replica.deploy(canisterName, wasmFile, idlFactory, undefined, signal);
|
|
283
308
|
if (signal?.aborted || !canister) {
|
|
284
309
|
return;
|
|
285
310
|
}
|
|
286
311
|
pipeStdoutToMMF(canister.stream, mmf);
|
|
287
|
-
let actor = await replica.getActor(canisterName);
|
|
312
|
+
let actor = (await replica.getActor(canisterName));
|
|
288
313
|
try {
|
|
289
314
|
if (globalThis.mopsReplicaTestRunning) {
|
|
290
315
|
await new Promise((resolve) => {
|
|
@@ -293,7 +318,7 @@ export async function testWithReporter(reporterName, filter = '', defaultMode =
|
|
|
293
318
|
resolve();
|
|
294
319
|
clearInterval(timerId);
|
|
295
320
|
}
|
|
296
|
-
}, Math.random() * 1000 | 0);
|
|
321
|
+
}, (Math.random() * 1000) | 0);
|
|
297
322
|
});
|
|
298
323
|
}
|
|
299
324
|
if (signal?.aborted) {
|
|
@@ -309,10 +334,12 @@ export async function testWithReporter(reporterName, filter = '', defaultMode =
|
|
|
309
334
|
pipeStderrToMMF(stderrStream, mmf, path.dirname(file));
|
|
310
335
|
stderrStream.write(e.message);
|
|
311
336
|
}
|
|
312
|
-
})
|
|
337
|
+
})
|
|
338
|
+
.finally(async () => {
|
|
313
339
|
globalThis.mopsReplicaTestRunning = false;
|
|
314
340
|
fs.rmSync(wasmFile, { force: true });
|
|
315
|
-
})
|
|
341
|
+
})
|
|
342
|
+
.then(resolve);
|
|
316
343
|
}
|
|
317
344
|
});
|
|
318
345
|
if (signal?.aborted) {
|
|
@@ -320,8 +347,10 @@ export async function testWithReporter(reporterName, filter = '', defaultMode =
|
|
|
320
347
|
}
|
|
321
348
|
reporter.addRun(file, mmf, promise, mode);
|
|
322
349
|
await promise;
|
|
323
|
-
}
|
|
324
|
-
|
|
350
|
+
};
|
|
351
|
+
await parallel(os.cpus().length, filesWithMode.filter(({ mode }) => mode !== "replica"), runTestFile);
|
|
352
|
+
await parallel(1, filesWithMode.filter(({ mode }) => mode === "replica"), runTestFile);
|
|
353
|
+
if (hasReplicaTests && !watch) {
|
|
325
354
|
await replica.stop();
|
|
326
355
|
fs.rmSync(testTempDir, { recursive: true, force: true });
|
|
327
356
|
}
|
|
@@ -330,62 +359,3 @@ export async function testWithReporter(reporterName, filter = '', defaultMode =
|
|
|
330
359
|
}
|
|
331
360
|
return reporter.done();
|
|
332
361
|
}
|
|
333
|
-
function pipeStdoutToMMF(stdout, mmf) {
|
|
334
|
-
stdout.on('data', (data) => {
|
|
335
|
-
for (let line of data.toString().split('\n')) {
|
|
336
|
-
line = line.trim();
|
|
337
|
-
if (line) {
|
|
338
|
-
mmf.parseLine(line);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
function pipeStderrToMMF(stderr, mmf, dir = '') {
|
|
344
|
-
stderr.on('data', (data) => {
|
|
345
|
-
let text = data.toString().trim();
|
|
346
|
-
let failedLine = '';
|
|
347
|
-
text = text.replace(/([\w+._/-]+):(\d+).(\d+)(-\d+.\d+)/g, (_m0, m1, m2, m3) => {
|
|
348
|
-
// change absolute file path to relative
|
|
349
|
-
// change :line:col-line:col to :line:col to work in vscode
|
|
350
|
-
let res = `${absToRel(m1)}:${m2}:${m3}`;
|
|
351
|
-
let file = path.join(dir, m1);
|
|
352
|
-
if (!fs.existsSync(file)) {
|
|
353
|
-
return res;
|
|
354
|
-
}
|
|
355
|
-
// show failed line
|
|
356
|
-
let content = fs.readFileSync(file);
|
|
357
|
-
let lines = content.toString().split('\n') || [];
|
|
358
|
-
failedLine += chalk.dim('\n ...');
|
|
359
|
-
let lineBefore = lines[+m2 - 2];
|
|
360
|
-
if (lineBefore) {
|
|
361
|
-
failedLine += chalk.dim(`\n ${+m2 - 1}\t| ${lineBefore.replaceAll('\t', ' ')}`);
|
|
362
|
-
}
|
|
363
|
-
failedLine += `\n${chalk.redBright `->`} ${m2}\t| ${lines[+m2 - 1]?.replaceAll('\t', ' ')}`;
|
|
364
|
-
if (lines.length > +m2) {
|
|
365
|
-
failedLine += chalk.dim(`\n ${+m2 + 1}\t| ${lines[+m2]?.replaceAll('\t', ' ')}`);
|
|
366
|
-
}
|
|
367
|
-
failedLine += chalk.dim('\n ...');
|
|
368
|
-
return res;
|
|
369
|
-
});
|
|
370
|
-
if (failedLine) {
|
|
371
|
-
text += failedLine;
|
|
372
|
-
}
|
|
373
|
-
mmf.fail(text);
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
function pipeMMF(proc, mmf) {
|
|
377
|
-
return new Promise((resolve) => {
|
|
378
|
-
pipeStdoutToMMF(proc.stdout, mmf);
|
|
379
|
-
pipeStderrToMMF(proc.stderr, mmf);
|
|
380
|
-
// exit
|
|
381
|
-
proc.on('close', (code) => {
|
|
382
|
-
if (code === 0) {
|
|
383
|
-
mmf.strategy !== 'print' && mmf.pass();
|
|
384
|
-
}
|
|
385
|
-
else if (code !== 1) {
|
|
386
|
-
mmf.fail(`unknown exit code: ${code}`);
|
|
387
|
-
}
|
|
388
|
-
resolve();
|
|
389
|
-
});
|
|
390
|
-
});
|
|
391
|
-
}
|
|
@@ -1 +1,7 @@
|
|
|
1
|
+
import { ChildProcessWithoutNullStreams } from "node:child_process";
|
|
2
|
+
import { Readable } from "node:stream";
|
|
3
|
+
import { MMF1 } from "./mmf1.js";
|
|
1
4
|
export declare function absToRel(p: string): string;
|
|
5
|
+
export declare function pipeStdoutToMMF(stdout: Readable, mmf: MMF1): void;
|
|
6
|
+
export declare function pipeStderrToMMF(stderr: Readable, mmf: MMF1, dir?: string): void;
|
|
7
|
+
export declare function pipeMMF(proc: ChildProcessWithoutNullStreams, mmf: MMF1): Promise<void>;
|
|
@@ -1,6 +1,67 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { getRootDir } from "../../mops.js";
|
|
3
5
|
export function absToRel(p) {
|
|
4
6
|
let rootDir = getRootDir();
|
|
5
7
|
return path.relative(rootDir, path.resolve(p));
|
|
6
8
|
}
|
|
9
|
+
export function pipeStdoutToMMF(stdout, mmf) {
|
|
10
|
+
stdout.on("data", (data) => {
|
|
11
|
+
for (let line of data.toString().split("\n")) {
|
|
12
|
+
line = line.trim();
|
|
13
|
+
if (line) {
|
|
14
|
+
mmf.parseLine(line);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export function pipeStderrToMMF(stderr, mmf, dir = "") {
|
|
20
|
+
stderr.on("data", (data) => {
|
|
21
|
+
let text = data.toString().trim();
|
|
22
|
+
let failedLine = "";
|
|
23
|
+
text = text.replace(/([\w+._/-]+):(\d+).(\d+)(-\d+.\d+)/g, (_m0, m1, m2, m3) => {
|
|
24
|
+
// change absolute file path to relative
|
|
25
|
+
// change :line:col-line:col to :line:col to work in vscode
|
|
26
|
+
let res = `${absToRel(m1)}:${m2}:${m3}`;
|
|
27
|
+
let file = path.join(dir, m1);
|
|
28
|
+
if (!fs.existsSync(file)) {
|
|
29
|
+
return res;
|
|
30
|
+
}
|
|
31
|
+
// show failed line
|
|
32
|
+
let content = fs.readFileSync(file);
|
|
33
|
+
let lines = content.toString().split("\n") || [];
|
|
34
|
+
failedLine += chalk.dim("\n ...");
|
|
35
|
+
let lineBefore = lines[+m2 - 2];
|
|
36
|
+
if (lineBefore) {
|
|
37
|
+
failedLine += chalk.dim(`\n ${+m2 - 1}\t| ${lineBefore.replaceAll("\t", " ")}`);
|
|
38
|
+
}
|
|
39
|
+
failedLine += `\n${chalk.redBright `->`} ${m2}\t| ${lines[+m2 - 1]?.replaceAll("\t", " ")}`;
|
|
40
|
+
if (lines.length > +m2) {
|
|
41
|
+
failedLine += chalk.dim(`\n ${+m2 + 1}\t| ${lines[+m2]?.replaceAll("\t", " ")}`);
|
|
42
|
+
}
|
|
43
|
+
failedLine += chalk.dim("\n ...");
|
|
44
|
+
return res;
|
|
45
|
+
});
|
|
46
|
+
if (failedLine) {
|
|
47
|
+
text += failedLine;
|
|
48
|
+
}
|
|
49
|
+
mmf.fail(text);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
export function pipeMMF(proc, mmf) {
|
|
53
|
+
return new Promise((resolve) => {
|
|
54
|
+
pipeStdoutToMMF(proc.stdout, mmf);
|
|
55
|
+
pipeStderrToMMF(proc.stderr, mmf);
|
|
56
|
+
// exit
|
|
57
|
+
proc.on("close", (code) => {
|
|
58
|
+
if (code === 0) {
|
|
59
|
+
mmf.strategy !== "print" && mmf.pass();
|
|
60
|
+
}
|
|
61
|
+
else if (code !== 1) {
|
|
62
|
+
mmf.fail(`unknown exit code: ${code}`);
|
|
63
|
+
}
|
|
64
|
+
resolve();
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|