ic-mops 2.2.0 → 2.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 (82) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/RELEASE.md +9 -1
  3. package/bundle/cli.tgz +0 -0
  4. package/cli.ts +25 -2
  5. package/commands/build.ts +2 -10
  6. package/commands/check-stable.ts +177 -0
  7. package/commands/check.ts +53 -6
  8. package/commands/toolchain/index.ts +4 -0
  9. package/dist/cli.js +22 -2
  10. package/dist/commands/build.js +2 -5
  11. package/dist/commands/check-stable.d.ts +14 -0
  12. package/dist/commands/check-stable.js +95 -0
  13. package/dist/commands/check.js +41 -6
  14. package/dist/commands/toolchain/index.js +3 -0
  15. package/dist/helpers/resolve-canisters.d.ts +7 -0
  16. package/dist/helpers/resolve-canisters.js +31 -0
  17. package/dist/mops.js +0 -4
  18. package/dist/package.json +6 -7
  19. package/dist/tests/check-fix.test.js +17 -0
  20. package/dist/tests/check-stable.test.d.ts +1 -0
  21. package/dist/tests/check-stable.test.js +51 -0
  22. package/dist/tests/check.test.js +54 -1
  23. package/dist/tests/moc-args.test.js +3 -3
  24. package/dist/tests/toolchain.test.js +11 -0
  25. package/dist/types.d.ts +5 -1
  26. package/helpers/resolve-canisters.ts +52 -0
  27. package/mops.ts +0 -6
  28. package/package.json +8 -9
  29. package/tests/README.md +16 -0
  30. package/tests/__snapshots__/check-fix.test.ts.snap +16 -10
  31. package/tests/__snapshots__/check-stable.test.ts.snap +29 -0
  32. package/tests/__snapshots__/check.test.ts.snap +26 -16
  33. package/tests/build/no-dfx/mops.toml +3 -0
  34. package/tests/build/no-dfx/src/Main.mo +1 -1
  35. package/tests/check/canisters/Ok.mo +5 -0
  36. package/tests/check/canisters/mops.toml +8 -0
  37. package/tests/check/canisters-error/Error.mo +7 -0
  38. package/tests/check/canisters-error/mops.toml +8 -0
  39. package/tests/check/canisters-moc-args/Warning.mo +5 -0
  40. package/tests/check/canisters-moc-args/mops.toml +8 -0
  41. package/tests/check/deployed-compatible/main.mo +4 -0
  42. package/tests/check/deployed-compatible/mops.toml +11 -0
  43. package/tests/check/deployed-compatible/old.mo +3 -0
  44. package/tests/check/deployed-compile-error/Error.mo +7 -0
  45. package/tests/check/deployed-compile-error/mops.toml +11 -0
  46. package/tests/check/deployed-compile-error/old.mo +3 -0
  47. package/tests/check/deployed-missing-error/Ok.mo +5 -0
  48. package/tests/check/deployed-missing-error/mops.toml +11 -0
  49. package/tests/check/deployed-missing-skip/Ok.mo +5 -0
  50. package/tests/check/deployed-missing-skip/mops.toml +12 -0
  51. package/tests/check/error/Error.mo +1 -1
  52. package/tests/check/error/mops.toml +5 -2
  53. package/tests/check/fix/M0223.mo +1 -1
  54. package/tests/check/fix/M0236.mo +1 -1
  55. package/tests/check/fix/M0237.mo +1 -1
  56. package/tests/check/fix/Ok.mo +1 -1
  57. package/tests/check/fix/fix-with-error.mo +9 -0
  58. package/tests/check/fix/fix-with-warning.mo +8 -0
  59. package/tests/check/fix/mops.toml +3 -0
  60. package/tests/check/fix/transitive-main.mo +1 -1
  61. package/tests/check/moc-args/Warning.mo +1 -1
  62. package/tests/check/moc-args/mops.toml +4 -1
  63. package/tests/check/success/Ok.mo +1 -1
  64. package/tests/check/success/Warning.mo +1 -1
  65. package/tests/check/success/mops.toml +5 -2
  66. package/tests/check-fix.test.ts +25 -0
  67. package/tests/check-stable/compatible/mops.toml +8 -0
  68. package/tests/check-stable/compatible/new.mo +4 -0
  69. package/tests/check-stable/compatible/old.mo +3 -0
  70. package/tests/check-stable/incompatible/mops.toml +8 -0
  71. package/tests/check-stable/incompatible/new.mo +3 -0
  72. package/tests/check-stable/incompatible/old.mo +4 -0
  73. package/tests/check-stable/subdirectory/.old/src/main.mo +3 -0
  74. package/tests/check-stable/subdirectory/mops.toml +8 -0
  75. package/tests/check-stable/subdirectory/src/main.mo +4 -0
  76. package/tests/check-stable.test.ts +56 -0
  77. package/tests/check.test.ts +63 -1
  78. package/tests/moc-args.test.ts +3 -3
  79. package/tests/toolchain-local-subpath/bin/moc +2 -0
  80. package/tests/toolchain-local-subpath/mops.toml +2 -0
  81. package/tests/toolchain.test.ts +13 -0
  82. package/types.ts +5 -1
@@ -3,9 +3,10 @@
3
3
  exports[`check [moc] args are passed to moc 1`] = `
4
4
  {
5
5
  "exitCode": 1,
6
- "stderr": "Warning.mo:3.9-3.15: warning [M0194], unused identifier unused (delete or rename to wildcard \`_\` or \`_unused\`)
6
+ "stderr": "Warning.mo:3.9-3.15: warning [M0194], unused identifier: \`unused\`
7
+ help: if this is intentional, prefix it with an underscore: \`_unused\`
7
8
  ✗ Check failed for file Warning.mo (exit code: 1)",
8
- "stdout": "moc < 1.3.0: some diagnostic hints may be missing",
9
+ "stdout": "",
9
10
  }
10
11
  `;
11
12
 
@@ -18,7 +19,7 @@ cannot produce expected type
18
19
  ()
19
20
  Error.mo:7.1-7.21: type error [M0057], unbound variable thisshouldnotcompile
20
21
  ✗ Check failed for file Error.mo (exit code: 1)",
21
- "stdout": "moc < 1.3.0: some diagnostic hints may be missing",
22
+ "stdout": "",
22
23
  }
23
24
  `;
24
25
 
@@ -27,7 +28,15 @@ exports[`check error 2`] = `
27
28
  "exitCode": 1,
28
29
  "stderr": "Ok.mo: No such file or directory
29
30
  ✗ Check failed for file Ok.mo (exit code: 1)",
30
- "stdout": "moc < 1.3.0: some diagnostic hints may be missing",
31
+ "stdout": "",
32
+ }
33
+ `;
34
+
35
+ exports[`check no args falls back to [canisters] entrypoints 1`] = `
36
+ {
37
+ "exitCode": 0,
38
+ "stderr": "",
39
+ "stdout": "✓ Ok.mo",
31
40
  }
32
41
  `;
33
42
 
@@ -35,8 +44,7 @@ exports[`check ok 1`] = `
35
44
  {
36
45
  "exitCode": 0,
37
46
  "stderr": "",
38
- "stdout": "moc < 1.3.0: some diagnostic hints may be missing
39
- ✓ Ok.mo",
47
+ "stdout": " Ok.mo",
40
48
  }
41
49
  `;
42
50
 
@@ -44,9 +52,9 @@ exports[`check ok 2`] = `
44
52
  {
45
53
  "exitCode": 0,
46
54
  "stderr": "",
47
- "stdout": "moc < 1.3.0: some diagnostic hints may be missing
55
+ "stdout": "check Using --all-libs for richer diagnostics
48
56
  check Running moc:
49
- moc-wrapper ["Ok.mo","--check","--package","core",".mops/core@2.0.0/src"]
57
+ <CACHE>moc-wrapper ["Ok.mo","--check","--all-libs","--default-persistent-actors"]
50
58
  ✓ Ok.mo",
51
59
  }
52
60
  `;
@@ -54,19 +62,20 @@ moc-wrapper ["Ok.mo","--check","--package","core",".mops/core@2.0.0/src"]
54
62
  exports[`check warning 1`] = `
55
63
  {
56
64
  "exitCode": 0,
57
- "stderr": "Warning.mo:3.9-3.15: warning [M0194], unused identifier unused (delete or rename to wildcard \`_\` or \`_unused\`)",
58
- "stdout": "moc < 1.3.0: some diagnostic hints may be missing
59
- ✓ Warning.mo",
65
+ "stderr": "Warning.mo:3.9-3.15: warning [M0194], unused identifier: \`unused\`
66
+ help: if this is intentional, prefix it with an underscore: \`_unused\`",
67
+ "stdout": "✓ Warning.mo",
60
68
  }
61
69
  `;
62
70
 
63
71
  exports[`check warning verbose 1`] = `
64
72
  {
65
73
  "exitCode": 0,
66
- "stderr": "Warning.mo:3.9-3.15: warning [M0194], unused identifier unused (delete or rename to wildcard \`_\` or \`_unused\`)",
67
- "stdout": "moc < 1.3.0: some diagnostic hints may be missing
74
+ "stderr": "Warning.mo:3.9-3.15: warning [M0194], unused identifier: \`unused\`
75
+ help: if this is intentional, prefix it with an underscore: \`_unused\`",
76
+ "stdout": "check Using --all-libs for richer diagnostics
68
77
  check Running moc:
69
- moc-wrapper ["Warning.mo","--check","--package","core",".mops/core@2.0.0/src"]
78
+ <CACHE>moc-wrapper ["Warning.mo","--check","--all-libs","--default-persistent-actors"]
70
79
  ✓ Warning.mo",
71
80
  }
72
81
  `;
@@ -74,8 +83,9 @@ moc-wrapper ["Warning.mo","--check","--package","core",".mops/core@2.0.0/src"]
74
83
  exports[`check warning with -Werror flag 1`] = `
75
84
  {
76
85
  "exitCode": 1,
77
- "stderr": "Warning.mo:3.9-3.15: warning [M0194], unused identifier unused (delete or rename to wildcard \`_\` or \`_unused\`)
86
+ "stderr": "Warning.mo:3.9-3.15: warning [M0194], unused identifier: \`unused\`
87
+ help: if this is intentional, prefix it with an underscore: \`_unused\`
78
88
  ✗ Check failed for file Warning.mo (exit code: 1)",
79
- "stdout": "moc < 1.3.0: some diagnostic hints may be missing",
89
+ "stdout": "",
80
90
  }
81
91
  `;
@@ -1,5 +1,8 @@
1
1
  [toolchain]
2
2
  moc = "1.3.0"
3
3
 
4
+ [moc]
5
+ args = ["--default-persistent-actors"]
6
+
4
7
  [canisters.main]
5
8
  main = "src/Main.mo"
@@ -1,4 +1,4 @@
1
- persistent actor {
1
+ actor {
2
2
  public func greet(name : Text) : async Text {
3
3
  "Hello, " # name # "!";
4
4
  };
@@ -0,0 +1,5 @@
1
+ actor {
2
+ public func hello() : async Text {
3
+ "Hello, World!";
4
+ };
5
+ };
@@ -0,0 +1,8 @@
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
4
+ [moc]
5
+ args = ["--default-persistent-actors"]
6
+
7
+ [canisters.backend]
8
+ main = "Ok.mo"
@@ -0,0 +1,7 @@
1
+ actor {
2
+ public func hello() : async Text {
3
+ "Hello, World!";
4
+ };
5
+ };
6
+
7
+ thisshouldnotcompile;
@@ -0,0 +1,8 @@
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
4
+ [moc]
5
+ args = ["--default-persistent-actors"]
6
+
7
+ [canisters.backend]
8
+ main = "Error.mo"
@@ -0,0 +1,5 @@
1
+ actor {
2
+ public func example() : async () {
3
+ let unused = 123;
4
+ };
5
+ };
@@ -0,0 +1,8 @@
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
4
+ [moc]
5
+ args = ["--default-persistent-actors", "-Werror"]
6
+
7
+ [canisters.backend]
8
+ main = "Warning.mo"
@@ -0,0 +1,4 @@
1
+ actor {
2
+ var counter : Nat = 0;
3
+ var name : Text = "";
4
+ };
@@ -0,0 +1,11 @@
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
4
+ [moc]
5
+ args = ["--default-persistent-actors"]
6
+
7
+ [canisters.backend]
8
+ main = "main.mo"
9
+
10
+ [canisters.backend.check-stable]
11
+ path = "old.mo"
@@ -0,0 +1,3 @@
1
+ actor {
2
+ var counter : Nat = 0;
3
+ };
@@ -0,0 +1,7 @@
1
+ actor {
2
+ public func hello() : async Text {
3
+ "Hello, World!";
4
+ };
5
+ };
6
+
7
+ thisshouldnotcompile;
@@ -0,0 +1,11 @@
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
4
+ [moc]
5
+ args = ["--default-persistent-actors"]
6
+
7
+ [canisters.backend]
8
+ main = "Error.mo"
9
+
10
+ [canisters.backend.check-stable]
11
+ path = "old.mo"
@@ -0,0 +1,3 @@
1
+ actor {
2
+ var counter : Nat = 0;
3
+ };
@@ -0,0 +1,5 @@
1
+ actor {
2
+ public func hello() : async Text {
3
+ "Hello, World!";
4
+ };
5
+ };
@@ -0,0 +1,11 @@
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
4
+ [moc]
5
+ args = ["--default-persistent-actors"]
6
+
7
+ [canisters.backend]
8
+ main = "Ok.mo"
9
+
10
+ [canisters.backend.check-stable]
11
+ path = "nonexistent.mo"
@@ -0,0 +1,5 @@
1
+ actor {
2
+ public func hello() : async Text {
3
+ "Hello, World!";
4
+ };
5
+ };
@@ -0,0 +1,12 @@
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
4
+ [moc]
5
+ args = ["--default-persistent-actors"]
6
+
7
+ [canisters.backend]
8
+ main = "Ok.mo"
9
+
10
+ [canisters.backend.check-stable]
11
+ path = "nonexistent.mo"
12
+ skipIfMissing = true
@@ -1,4 +1,4 @@
1
- persistent actor {
1
+ actor {
2
2
  public func hello() : async Text {
3
3
  "Hello, World!";
4
4
  };
@@ -1,2 +1,5 @@
1
- [dependencies]
2
- core = "2.0.0"
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
4
+ [moc]
5
+ args = ["--default-persistent-actors"]
@@ -1,7 +1,7 @@
1
1
  // M0223: Redundant type instantiation
2
2
  // The type annotation is not needed when it can be inferred
3
3
 
4
- persistent actor {
4
+ actor {
5
5
  public func testM0223() : async () {
6
6
  func identity<T>(x : T) : T = x;
7
7
  let varArray : [var Nat] = [var 1];
@@ -3,7 +3,7 @@
3
3
  import List "mo:core/List";
4
4
  import Nat "mo:core/Nat";
5
5
 
6
- persistent actor {
6
+ actor {
7
7
  public func testM0236() : async () {
8
8
  let list = List.fromArray<Nat>([1, 2, 3]);
9
9
  List.sortInPlace(list);
@@ -3,7 +3,7 @@
3
3
  import List "mo:core/List";
4
4
  import Nat "mo:core/Nat";
5
5
 
6
- persistent actor {
6
+ actor {
7
7
  public func testM0237() : async () {
8
8
  let list = List.fromArray<Nat>([3, 2, 1]);
9
9
  list.sortInPlace(Nat.compare);
@@ -1,5 +1,5 @@
1
1
  // Clean file — no fixable warnings
2
- persistent actor {
2
+ actor {
3
3
  public func example() : async () {
4
4
  let _x : ?Text = null;
5
5
  ();
@@ -0,0 +1,9 @@
1
+ actor {
2
+ public func test() : async () {
3
+ func identity<T>(x : T) : T = x;
4
+ let nat = identity<Nat>(1);
5
+ ignore nat;
6
+ };
7
+ };
8
+
9
+ thisshouldnotcompile;
@@ -0,0 +1,8 @@
1
+ actor {
2
+ public func test() : async () {
3
+ func identity<T>(x : T) : T = x;
4
+ let unused = 123;
5
+ let nat = identity<Nat>(1);
6
+ ignore nat;
7
+ };
8
+ };
@@ -3,3 +3,6 @@ core = "2.0.0"
3
3
 
4
4
  [toolchain]
5
5
  moc = "1.3.0"
6
+
7
+ [moc]
8
+ args = ["--default-persistent-actors"]
@@ -1,6 +1,6 @@
1
1
  import Lib "./transitive-lib";
2
2
 
3
- persistent actor {
3
+ actor {
4
4
  public func run() : async () {
5
5
  func identity<T>(x : T) : T = x;
6
6
  let _ = identity<Nat>(1);
@@ -1,4 +1,4 @@
1
- persistent actor {
1
+ actor {
2
2
  public func example() : async () {
3
3
  let unused = 123;
4
4
  };
@@ -1,2 +1,5 @@
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
1
4
  [moc]
2
- args = ["-Werror"]
5
+ args = ["--default-persistent-actors", "-Werror"]
@@ -1,4 +1,4 @@
1
- persistent actor {
1
+ actor {
2
2
  public func hello() : async Text {
3
3
  "Hello, World!";
4
4
  };
@@ -1,4 +1,4 @@
1
- persistent actor {
1
+ actor {
2
2
  public func example() : async () {
3
3
  let unused = 123;
4
4
  };
@@ -1,2 +1,5 @@
1
- [dependencies]
2
- core = "2.0.0"
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
4
+ [moc]
5
+ args = ["--default-persistent-actors"]
@@ -131,4 +131,29 @@ describe("check --fix", () => {
131
131
  expect(result.stdout).toContain("Attempting to fix files");
132
132
  expect(result.stdout).toContain("No fixes were needed");
133
133
  });
134
+
135
+ test("fix with remaining warnings", async () => {
136
+ const runFilePath = copyFixture("fix-with-warning.mo");
137
+ const result = await cli(
138
+ ["check", runFilePath, "--fix", "--", warningFlags],
139
+ { cwd: fixDir },
140
+ );
141
+ expect(result.exitCode).toBe(0);
142
+ expect(result.stdout).toContain("1 fix applied");
143
+ expect(result.stdout).toMatch(/✓/);
144
+ expect(result.stderr).toMatch(/warning \[M0194\]/);
145
+ expect(result.stderr).toMatch(/unused identifier/);
146
+ });
147
+
148
+ test("fix with remaining errors", async () => {
149
+ const runFilePath = copyFixture("fix-with-error.mo");
150
+ const result = await cli(
151
+ ["check", runFilePath, "--fix", "--", warningFlags],
152
+ { cwd: fixDir },
153
+ );
154
+ expect(result.exitCode).toBe(1);
155
+ expect(result.stdout).toContain("1 fix applied");
156
+ expect(result.stderr).toMatch(/error/i);
157
+ expect(result.stdout).not.toMatch(/✓ run/);
158
+ });
134
159
  });
@@ -0,0 +1,8 @@
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
4
+ [moc]
5
+ args = ["--default-persistent-actors"]
6
+
7
+ [canisters.backend]
8
+ main = "new.mo"
@@ -0,0 +1,4 @@
1
+ actor {
2
+ var counter : Nat = 0;
3
+ var name : Text = "";
4
+ };
@@ -0,0 +1,3 @@
1
+ actor {
2
+ var counter : Nat = 0;
3
+ };
@@ -0,0 +1,8 @@
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
4
+ [moc]
5
+ args = ["--default-persistent-actors"]
6
+
7
+ [canisters.backend]
8
+ main = "new.mo"
@@ -0,0 +1,3 @@
1
+ actor {
2
+ var counter : Text = "";
3
+ };
@@ -0,0 +1,4 @@
1
+ actor {
2
+ var counter : Nat = 0;
3
+ var name : Text = "";
4
+ };
@@ -0,0 +1,3 @@
1
+ actor {
2
+ var counter : Nat = 0;
3
+ };
@@ -0,0 +1,8 @@
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
4
+ [moc]
5
+ args = ["--default-persistent-actors"]
6
+
7
+ [canisters.backend]
8
+ main = "src/main.mo"
@@ -0,0 +1,4 @@
1
+ actor {
2
+ var counter : Nat = 0;
3
+ var name : Text = "";
4
+ };
@@ -0,0 +1,56 @@
1
+ import { describe, expect, test } from "@jest/globals";
2
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import path from "path";
5
+ import { cli, cliSnapshot } from "./helpers";
6
+
7
+ describe("check-stable", () => {
8
+ test("compatible upgrade from .mo file", async () => {
9
+ const cwd = path.join(import.meta.dirname, "check-stable/compatible");
10
+ await cliSnapshot(["check-stable", "old.mo"], { cwd }, 0);
11
+ });
12
+
13
+ test("incompatible upgrade from .mo file", async () => {
14
+ const cwd = path.join(import.meta.dirname, "check-stable/incompatible");
15
+ const result = await cliSnapshot(["check-stable", "old.mo"], { cwd }, 1);
16
+ expect(result.stderr).toMatch(/compatibility/i);
17
+ });
18
+
19
+ test("compatible upgrade with verbose", async () => {
20
+ const cwd = path.join(import.meta.dirname, "check-stable/compatible");
21
+ const result = await cli(["check-stable", "old.mo", "--verbose"], { cwd });
22
+ expect(result.exitCode).toBe(0);
23
+ expect(result.stdout).toMatch(/Generating stable types for old\.mo/);
24
+ expect(result.stdout).toMatch(/Generating stable types for new\.mo/);
25
+ expect(result.stdout).toMatch(/--stable-compatible/);
26
+ expect(result.stdout).toMatch(/Stable compatibility check passed/);
27
+ });
28
+
29
+ test("old file in subdirectory (.old/src/ pattern)", async () => {
30
+ const cwd = path.join(import.meta.dirname, "check-stable/subdirectory");
31
+ const result = await cli(["check-stable", ".old/src/main.mo"], { cwd });
32
+ expect(result.exitCode).toBe(0);
33
+ expect(result.stdout).toMatch(/Stable compatibility check passed/);
34
+ });
35
+
36
+ test("compatible upgrade from .most file", async () => {
37
+ const cwd = path.join(import.meta.dirname, "check-stable/compatible");
38
+ const tempDir = await mkdtemp(path.join(tmpdir(), "mops-test-most-"));
39
+ try {
40
+ const mostPath = path.join(tempDir, "old.most");
41
+ await writeFile(mostPath, "actor {\n stable var counter : Nat\n};\n");
42
+ const result = await cli(["check-stable", mostPath], { cwd });
43
+ expect(result.exitCode).toBe(0);
44
+ expect(result.stdout).toMatch(/Stable compatibility check passed/);
45
+ } finally {
46
+ await rm(tempDir, { recursive: true, force: true });
47
+ }
48
+ });
49
+
50
+ test("errors when old file does not exist", async () => {
51
+ const cwd = path.join(import.meta.dirname, "check-stable/compatible");
52
+ const result = await cli(["check-stable", "nonexistent.mo"], { cwd });
53
+ expect(result.exitCode).toBe(1);
54
+ expect(result.stderr).toMatch(/File not found/);
55
+ });
56
+ });
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, test } from "@jest/globals";
2
2
  import path from "path";
3
- import { cliSnapshot } from "./helpers";
3
+ import { cli, cliSnapshot } from "./helpers";
4
4
 
5
5
  describe("check", () => {
6
6
  test("ok", async () => {
@@ -48,4 +48,66 @@ describe("check", () => {
48
48
  const cwd = path.join(import.meta.dirname, "check/moc-args");
49
49
  await cliSnapshot(["check", "Warning.mo"], { cwd }, 1);
50
50
  });
51
+
52
+ test("no args falls back to [canisters] entrypoints", async () => {
53
+ const cwd = path.join(import.meta.dirname, "check/canisters");
54
+ await cliSnapshot(["check"], { cwd }, 0);
55
+ });
56
+
57
+ test("[moc] args applied when using canister fallback", async () => {
58
+ const cwd = path.join(import.meta.dirname, "check/canisters-moc-args");
59
+ const result = await cli(["check"], { cwd });
60
+ expect(result.exitCode).toBe(1);
61
+ expect(result.stderr).toMatch(/warning \[M0194\]/);
62
+ });
63
+
64
+ test("canister entrypoint with errors", async () => {
65
+ const cwd = path.join(import.meta.dirname, "check/canisters-error");
66
+ const result = await cli(["check"], { cwd });
67
+ expect(result.exitCode).toBe(1);
68
+ expect(result.stderr).toMatch(/error/i);
69
+ });
70
+
71
+ test("--fix with canister fallback", async () => {
72
+ const cwd = path.join(import.meta.dirname, "check/canisters");
73
+ const result = await cli(["check", "--fix"], { cwd });
74
+ expect(result.exitCode).toBe(0);
75
+ });
76
+
77
+ test("deployed: runs stable check when deployed file exists", async () => {
78
+ const cwd = path.join(import.meta.dirname, "check/deployed-compatible");
79
+ const result = await cli(["check"], { cwd });
80
+ expect(result.exitCode).toBe(0);
81
+ expect(result.stdout).toMatch(/Stable compatibility check passed/);
82
+ });
83
+
84
+ test("deployed: silently skips when file missing and skipIfMissing", async () => {
85
+ const cwd = path.join(import.meta.dirname, "check/deployed-missing-skip");
86
+ const result = await cli(["check"], { cwd });
87
+ expect(result.exitCode).toBe(0);
88
+ expect(result.stdout).not.toMatch(/stable/i);
89
+ });
90
+
91
+ test("deployed: errors when file missing without deployedSkipIfFileMissing", async () => {
92
+ const cwd = path.join(import.meta.dirname, "check/deployed-missing-error");
93
+ const result = await cli(["check"], { cwd });
94
+ expect(result.exitCode).toBe(1);
95
+ expect(result.stderr).toMatch(/Deployed file not found/);
96
+ expect(result.stderr).toMatch(/skipIfMissing/);
97
+ });
98
+
99
+ test("--fix runs stable check after fixing", async () => {
100
+ const cwd = path.join(import.meta.dirname, "check/deployed-compatible");
101
+ const result = await cli(["check", "--fix"], { cwd });
102
+ expect(result.exitCode).toBe(0);
103
+ expect(result.stdout).toMatch(/Stable compatibility check passed/);
104
+ });
105
+
106
+ test("stable check is skipped when type-checking fails", async () => {
107
+ const cwd = path.join(import.meta.dirname, "check/deployed-compile-error");
108
+ const result = await cli(["check"], { cwd });
109
+ expect(result.exitCode).toBe(1);
110
+ expect(result.stderr).toMatch(/error/i);
111
+ expect(result.stdout).not.toMatch(/Stable compatibility/);
112
+ });
51
113
  });
@@ -7,13 +7,13 @@ describe("moc-args", () => {
7
7
  const cwd = path.join(import.meta.dirname, "check/moc-args");
8
8
  const result = await cli(["moc-args"], { cwd });
9
9
  expect(result.exitCode).toBe(0);
10
- expect(result.stdout).toBe("-Werror");
10
+ expect(result.stdout).toBe("--default-persistent-actors\n-Werror");
11
11
  });
12
12
 
13
- test("prints nothing when no [moc] config", async () => {
13
+ test("prints only global args when no extra [moc] args", async () => {
14
14
  const cwd = path.join(import.meta.dirname, "check/success");
15
15
  const result = await cli(["moc-args"], { cwd });
16
16
  expect(result.exitCode).toBe(0);
17
- expect(result.stdout).toBe("");
17
+ expect(result.stdout).toBe("--default-persistent-actors");
18
18
  });
19
19
  });
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ echo "Mock moc binary"
@@ -0,0 +1,2 @@
1
+ [toolchain]
2
+ moc = "./bin/moc"