ic-mops 2.0.0 → 2.1.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 (197) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/RELEASE.md +179 -0
  3. package/bundle/cli.tgz +0 -0
  4. package/check-requirements.ts +3 -8
  5. package/cli.ts +79 -11
  6. package/commands/bench/bench-canister.mo +17 -6
  7. package/commands/bench.ts +2 -13
  8. package/commands/build.ts +42 -17
  9. package/commands/check.ts +117 -0
  10. package/commands/format.ts +3 -18
  11. package/commands/lint.ts +92 -0
  12. package/commands/sync.ts +2 -8
  13. package/commands/test/test.ts +7 -19
  14. package/commands/toolchain/index.ts +21 -8
  15. package/commands/toolchain/lintoko.ts +54 -0
  16. package/commands/toolchain/toolchain-utils.ts +2 -0
  17. package/constants.ts +23 -0
  18. package/dist/check-requirements.js +3 -8
  19. package/dist/cli.js +60 -10
  20. package/dist/commands/bench/bench-canister.mo +17 -6
  21. package/dist/commands/bench.js +2 -11
  22. package/dist/commands/build.js +38 -16
  23. package/dist/commands/check.d.ts +6 -0
  24. package/dist/commands/check.js +78 -0
  25. package/dist/commands/format.js +3 -16
  26. package/dist/commands/lint.d.ts +7 -0
  27. package/dist/commands/lint.js +69 -0
  28. package/dist/commands/sync.js +2 -7
  29. package/dist/commands/test/test.js +7 -17
  30. package/dist/commands/toolchain/index.d.ts +2 -2
  31. package/dist/commands/toolchain/index.js +18 -7
  32. package/dist/commands/toolchain/lintoko.d.ts +8 -0
  33. package/dist/commands/toolchain/lintoko.js +36 -0
  34. package/dist/commands/toolchain/toolchain-utils.d.ts +1 -0
  35. package/dist/commands/toolchain/toolchain-utils.js +1 -0
  36. package/dist/constants.d.ts +15 -0
  37. package/dist/constants.js +21 -0
  38. package/dist/environments/nodejs/cli.js +6 -1
  39. package/dist/helpers/autofix-motoko.d.ts +26 -0
  40. package/dist/helpers/autofix-motoko.js +105 -0
  41. package/dist/helpers/get-moc-version.d.ts +2 -0
  42. package/dist/helpers/get-moc-version.js +10 -1
  43. package/dist/mops.js +2 -1
  44. package/dist/package.json +4 -3
  45. package/dist/tests/build-no-dfx.test.d.ts +1 -0
  46. package/dist/tests/build-no-dfx.test.js +9 -0
  47. package/dist/tests/build.test.d.ts +1 -0
  48. package/dist/tests/build.test.js +18 -0
  49. package/dist/tests/check-candid.test.d.ts +1 -0
  50. package/dist/tests/check-candid.test.js +20 -0
  51. package/dist/tests/check-fix.test.d.ts +1 -0
  52. package/dist/tests/check-fix.test.js +73 -0
  53. package/dist/tests/check.test.d.ts +1 -0
  54. package/dist/tests/check.test.js +33 -0
  55. package/dist/tests/cli.test.js +4 -57
  56. package/dist/tests/helpers.d.ts +22 -0
  57. package/dist/tests/helpers.js +43 -0
  58. package/dist/tests/lint.test.d.ts +1 -0
  59. package/dist/tests/lint.test.js +15 -0
  60. package/dist/tests/toolchain.test.d.ts +1 -0
  61. package/dist/tests/toolchain.test.js +11 -0
  62. package/dist/types.d.ts +6 -1
  63. package/dist/wasm/pkg/nodejs/wasm.d.ts +3 -0
  64. package/dist/wasm/pkg/nodejs/wasm.js +323 -17
  65. package/dist/wasm/pkg/nodejs/wasm_bg.wasm +0 -0
  66. package/dist/wasm/pkg/nodejs/wasm_bg.wasm.d.ts +6 -1
  67. package/dist/wasm/pkg/web/wasm.d.ts +10 -1
  68. package/dist/wasm/pkg/web/wasm.js +300 -21
  69. package/dist/wasm/pkg/web/wasm_bg.wasm +0 -0
  70. package/dist/wasm/pkg/web/wasm_bg.wasm.d.ts +6 -1
  71. package/dist/wasm.d.ts +6 -1
  72. package/environments/nodejs/cli.ts +7 -1
  73. package/helpers/autofix-motoko.ts +170 -0
  74. package/helpers/get-moc-version.ts +12 -1
  75. package/mops.ts +2 -1
  76. package/package.json +4 -3
  77. package/tests/__snapshots__/build-no-dfx.test.ts.snap +11 -0
  78. package/tests/__snapshots__/build.test.ts.snap +77 -0
  79. package/tests/__snapshots__/check-candid.test.ts.snap +73 -0
  80. package/tests/__snapshots__/check-fix.test.ts.snap +242 -0
  81. package/tests/__snapshots__/check.test.ts.snap +72 -0
  82. package/tests/__snapshots__/lint.test.ts.snap +78 -0
  83. package/tests/build/error/src/Bar.mo +2 -2
  84. package/tests/build/no-dfx/mops.toml +5 -0
  85. package/tests/build/no-dfx/src/Main.mo +5 -0
  86. package/tests/build/success/candid/bar.did +1 -0
  87. package/tests/build/success/mops.toml +8 -3
  88. package/tests/build-no-dfx.test.ts +10 -0
  89. package/tests/build.test.ts +24 -0
  90. package/tests/check/error/Error.mo +7 -0
  91. package/tests/check/error/mops.toml +2 -0
  92. package/tests/check/fix/M0223.mo +11 -0
  93. package/tests/check/fix/M0236.mo +11 -0
  94. package/tests/check/fix/M0237.mo +11 -0
  95. package/tests/check/fix/Ok.mo +7 -0
  96. package/tests/check/fix/edit-suggestions.mo +143 -0
  97. package/tests/check/fix/mops.toml +5 -0
  98. package/tests/check/fix/transitive-lib.mo +9 -0
  99. package/tests/check/fix/transitive-main.mo +9 -0
  100. package/tests/check/success/Ok.mo +5 -0
  101. package/tests/check/success/Warning.mo +5 -0
  102. package/tests/check/success/mops.toml +2 -0
  103. package/tests/check-candid.test.ts +22 -0
  104. package/tests/check-fix.test.ts +111 -0
  105. package/tests/check.test.ts +46 -0
  106. package/tests/cli.test.ts +4 -74
  107. package/tests/helpers.ts +58 -0
  108. package/tests/lint/lints/no-bool-switch.toml +9 -0
  109. package/tests/lint/mops.toml +4 -0
  110. package/tests/lint/src/NoBoolSwitch.mo +8 -0
  111. package/tests/lint/src/Ok.mo +5 -0
  112. package/tests/lint.test.ts +17 -0
  113. package/tests/toolchain/mock +2 -0
  114. package/tests/toolchain/mops.toml +2 -0
  115. package/tests/toolchain.test.ts +12 -0
  116. package/types.ts +6 -1
  117. package/wasm/Cargo.lock +101 -54
  118. package/wasm/Cargo.toml +2 -5
  119. package/wasm/pkg/nodejs/wasm.d.ts +3 -0
  120. package/wasm/pkg/nodejs/wasm.js +323 -17
  121. package/wasm/pkg/nodejs/wasm_bg.wasm +0 -0
  122. package/wasm/pkg/nodejs/wasm_bg.wasm.d.ts +6 -1
  123. package/wasm/pkg/web/wasm.d.ts +10 -1
  124. package/wasm/pkg/web/wasm.js +300 -21
  125. package/wasm/pkg/web/wasm_bg.wasm +0 -0
  126. package/wasm/pkg/web/wasm_bg.wasm.d.ts +6 -1
  127. package/wasm/src/lib.rs +10 -5
  128. package/wasm/src/utils.rs +15 -0
  129. package/wasm/src/wasm_utils.rs +79 -0
  130. package/wasm.ts +10 -1
  131. package/.DS_Store +0 -0
  132. package/bundle/bench/bench-canister.mo +0 -121
  133. package/bundle/bench/user-bench.mo +0 -10
  134. package/bundle/bin/moc-wrapper.sh +0 -40
  135. package/bundle/bin/mops.js +0 -3
  136. package/bundle/cli.js +0 -2144
  137. package/bundle/declarations/bench/bench.did +0 -30
  138. package/bundle/declarations/bench/bench.did.d.ts +0 -33
  139. package/bundle/declarations/bench/bench.did.js +0 -30
  140. package/bundle/declarations/bench/index.d.ts +0 -50
  141. package/bundle/declarations/bench/index.js +0 -40
  142. package/bundle/declarations/main/index.d.ts +0 -50
  143. package/bundle/declarations/main/index.js +0 -40
  144. package/bundle/declarations/main/main.did +0 -428
  145. package/bundle/declarations/main/main.did.d.ts +0 -348
  146. package/bundle/declarations/main/main.did.js +0 -406
  147. package/bundle/declarations/storage/index.d.ts +0 -50
  148. package/bundle/declarations/storage/index.js +0 -30
  149. package/bundle/declarations/storage/storage.did +0 -46
  150. package/bundle/declarations/storage/storage.did.d.ts +0 -40
  151. package/bundle/declarations/storage/storage.did.js +0 -38
  152. package/bundle/package.json +0 -36
  153. package/bundle/templates/README.md +0 -13
  154. package/bundle/templates/licenses/Apache-2.0 +0 -202
  155. package/bundle/templates/licenses/Apache-2.0-NOTICE +0 -13
  156. package/bundle/templates/licenses/MIT +0 -21
  157. package/bundle/templates/mops-publish.yml +0 -17
  158. package/bundle/templates/mops-test.yml +0 -24
  159. package/bundle/templates/src/lib.mo +0 -15
  160. package/bundle/templates/test/lib.test.mo +0 -4
  161. package/bundle/wasm_bg.wasm +0 -0
  162. package/bundle/xhr-sync-worker.js +0 -59
  163. package/dist/wasm/pkg/bundler/package.json +0 -20
  164. package/dist/wasm/pkg/bundler/wasm.d.ts +0 -3
  165. package/dist/wasm/pkg/bundler/wasm.js +0 -5
  166. package/dist/wasm/pkg/bundler/wasm_bg.js +0 -93
  167. package/dist/wasm/pkg/bundler/wasm_bg.wasm +0 -0
  168. package/dist/wasm/pkg/bundler/wasm_bg.wasm.d.ts +0 -8
  169. package/tests/__snapshots__/cli.test.ts.snap +0 -202
  170. package/tests/build/success/.dfx/local/canister_ids.json +0 -17
  171. package/tests/build/success/.dfx/local/canisters/bar/bar.did +0 -3
  172. package/tests/build/success/.dfx/local/canisters/bar/bar.most +0 -4
  173. package/tests/build/success/.dfx/local/canisters/bar/bar.wasm +0 -0
  174. package/tests/build/success/.dfx/local/canisters/bar/constructor.did +0 -3
  175. package/tests/build/success/.dfx/local/canisters/bar/index.js +0 -42
  176. package/tests/build/success/.dfx/local/canisters/bar/init_args.txt +0 -1
  177. package/tests/build/success/.dfx/local/canisters/bar/service.did +0 -3
  178. package/tests/build/success/.dfx/local/canisters/bar/service.did.d.ts +0 -7
  179. package/tests/build/success/.dfx/local/canisters/bar/service.did.js +0 -4
  180. package/tests/build/success/.dfx/local/canisters/foo/constructor.did +0 -3
  181. package/tests/build/success/.dfx/local/canisters/foo/foo.did +0 -3
  182. package/tests/build/success/.dfx/local/canisters/foo/foo.most +0 -4
  183. package/tests/build/success/.dfx/local/canisters/foo/foo.wasm +0 -0
  184. package/tests/build/success/.dfx/local/canisters/foo/index.js +0 -42
  185. package/tests/build/success/.dfx/local/canisters/foo/init_args.txt +0 -1
  186. package/tests/build/success/.dfx/local/canisters/foo/service.did +0 -3
  187. package/tests/build/success/.dfx/local/canisters/foo/service.did.d.ts +0 -7
  188. package/tests/build/success/.dfx/local/canisters/foo/service.did.js +0 -4
  189. package/tests/build/success/.dfx/local/lsp/ucwa4-rx777-77774-qaada-cai.did +0 -3
  190. package/tests/build/success/.dfx/local/lsp/ulvla-h7777-77774-qaacq-cai.did +0 -3
  191. package/tests/build/success/.dfx/local/network-id +0 -4
  192. package/wasm/pkg/bundler/package.json +0 -20
  193. package/wasm/pkg/bundler/wasm.d.ts +0 -3
  194. package/wasm/pkg/bundler/wasm.js +0 -5
  195. package/wasm/pkg/bundler/wasm_bg.js +0 -93
  196. package/wasm/pkg/bundler/wasm_bg.wasm +0 -0
  197. package/wasm/pkg/bundler/wasm_bg.wasm.d.ts +0 -8
@@ -0,0 +1,77 @@
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
+
3
+ exports[`build error 1`] = `
4
+ {
5
+ "exitCode": 0,
6
+ "stderr": "",
7
+ "stdout": "build canister foo
8
+ moc-wrapper ["-c","--idl","-o",".mops/.build/foo.wasm","src/Foo.mo","--package","core",".mops/core@1.0.0/src","--release","--public-metadata","candid:service","--public-metadata","candid:args"]
9
+ Adding metadata to .mops/.build/foo.wasm
10
+
11
+ ✓ Built 1 canister successfully",
12
+ }
13
+ `;
14
+
15
+ exports[`build error 2`] = `
16
+ {
17
+ "exitCode": 1,
18
+ "stderr": "Candid compatibility check failed for canister bar",
19
+ "stdout": "build canister bar",
20
+ }
21
+ `;
22
+
23
+ exports[`build error 3`] = `
24
+ {
25
+ "exitCode": 1,
26
+ "stderr": "Candid compatibility check failed for canister bar",
27
+ "stdout": "build canister foo
28
+ build canister bar",
29
+ }
30
+ `;
31
+
32
+ exports[`build ok 1`] = `
33
+ {
34
+ "exitCode": 0,
35
+ "stderr": "",
36
+ "stdout": "build canister foo
37
+ moc-wrapper ["-c","--idl","-o",".mops/.build/foo.wasm","src/Foo.mo","--package","core",".mops/core@1.0.0/src","--release","--public-metadata","candid:service","--public-metadata","candid:args"]
38
+ Adding metadata to .mops/.build/foo.wasm
39
+ build canister bar
40
+ moc-wrapper ["-c","--idl","-o",".mops/.build/bar.wasm","src/Bar.mo","--package","core",".mops/core@1.0.0/src","--release","--incremental-gc","--public-metadata","candid:service","--public-metadata","candid:args"]
41
+ Candid compatibility check passed for canister bar
42
+ Adding metadata to .mops/.build/bar.wasm
43
+
44
+ ✓ Built 2 canisters successfully",
45
+ }
46
+ `;
47
+
48
+ exports[`build ok 2`] = `
49
+ {
50
+ "exitCode": 0,
51
+ "stderr": "",
52
+ "stdout": "build canister foo
53
+
54
+ ✓ Built 1 canister successfully",
55
+ }
56
+ `;
57
+
58
+ exports[`build ok 3`] = `
59
+ {
60
+ "exitCode": 0,
61
+ "stderr": "",
62
+ "stdout": "build canister bar
63
+
64
+ ✓ Built 1 canister successfully",
65
+ }
66
+ `;
67
+
68
+ exports[`build ok 4`] = `
69
+ {
70
+ "exitCode": 0,
71
+ "stderr": "",
72
+ "stdout": "build canister foo
73
+ build canister bar
74
+
75
+ ✓ Built 2 canisters successfully",
76
+ }
77
+ `;
@@ -0,0 +1,73 @@
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
+
3
+ exports[`check-candid error 1`] = `
4
+ {
5
+ "exitCode": 1,
6
+ "stderr": "✖ Candid compatibility check failed",
7
+ "stdout": "",
8
+ }
9
+ `;
10
+
11
+ exports[`check-candid error 2`] = `
12
+ {
13
+ "exitCode": 1,
14
+ "stderr": "✖ Candid compatibility check failed",
15
+ "stdout": "",
16
+ }
17
+ `;
18
+
19
+ exports[`check-candid error 3`] = `
20
+ {
21
+ "exitCode": 1,
22
+ "stderr": "✖ Candid compatibility check failed",
23
+ "stdout": "",
24
+ }
25
+ `;
26
+
27
+ exports[`check-candid error 4`] = `
28
+ {
29
+ "exitCode": 1,
30
+ "stderr": "✖ Candid compatibility check failed",
31
+ "stdout": "",
32
+ }
33
+ `;
34
+
35
+ exports[`check-candid ok 1`] = `
36
+ {
37
+ "exitCode": 0,
38
+ "stderr": "",
39
+ "stdout": "✓ Candid compatibility check passed",
40
+ }
41
+ `;
42
+
43
+ exports[`check-candid ok 2`] = `
44
+ {
45
+ "exitCode": 0,
46
+ "stderr": "",
47
+ "stdout": "✓ Candid compatibility check passed",
48
+ }
49
+ `;
50
+
51
+ exports[`check-candid ok 3`] = `
52
+ {
53
+ "exitCode": 0,
54
+ "stderr": "",
55
+ "stdout": "✓ Candid compatibility check passed",
56
+ }
57
+ `;
58
+
59
+ exports[`check-candid ok 4`] = `
60
+ {
61
+ "exitCode": 0,
62
+ "stderr": "",
63
+ "stdout": "✓ Candid compatibility check passed",
64
+ }
65
+ `;
66
+
67
+ exports[`check-candid ok 5`] = `
68
+ {
69
+ "exitCode": 0,
70
+ "stderr": "",
71
+ "stdout": "✓ Candid compatibility check passed",
72
+ }
73
+ `;
@@ -0,0 +1,242 @@
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
+
3
+ exports[`check --fix M0223 1`] = `
4
+ "// M0223: Redundant type instantiation
5
+ // The type annotation is not needed when it can be inferred
6
+
7
+ persistent actor {
8
+ public func testM0223() : async () {
9
+ func identity<T>(x : T) : T = x;
10
+ let varArray : [var Nat] = [var 1];
11
+ let nat = identity(1);
12
+ varArray[0] := nat;
13
+ };
14
+ };
15
+ "
16
+ `;
17
+
18
+ exports[`check --fix M0223: fix output 1`] = `
19
+ "Fixed run/M0223.mo (1 fix: M0223)
20
+
21
+ ✓ 1 fix applied to 1 file"
22
+ `;
23
+
24
+ exports[`check --fix M0236 1`] = `
25
+ "// M0236: Suggested to use dot notation
26
+ // Function calls can be rewritten using dot notation
27
+ import List "mo:core/List";
28
+ import Nat "mo:core/Nat";
29
+
30
+ persistent actor {
31
+ public func testM0236() : async () {
32
+ let list = List.fromArray<Nat>([1, 2, 3]);
33
+ list.sortInPlace();
34
+ };
35
+ };
36
+ "
37
+ `;
38
+
39
+ exports[`check --fix M0236: fix output 1`] = `
40
+ "Fixed run/M0236.mo (2 fixes: M0236)
41
+
42
+ ✓ 2 fixes applied to 1 file"
43
+ `;
44
+
45
+ exports[`check --fix M0237 1`] = `
46
+ "// M0237: Redundant explicit implicit argument
47
+ // Some arguments can be inferred and don't need to be specified
48
+ import List "mo:core/List";
49
+ import Nat "mo:core/Nat";
50
+
51
+ persistent actor {
52
+ public func testM0237() : async () {
53
+ let list = List.fromArray<Nat>([3, 2, 1]);
54
+ list.sortInPlace();
55
+ };
56
+ };
57
+ "
58
+ `;
59
+
60
+ exports[`check --fix M0237: fix output 1`] = `
61
+ "Fixed run/M0237.mo (1 fix: M0237)
62
+
63
+ ✓ 1 fix applied to 1 file"
64
+ `;
65
+
66
+ exports[`check --fix edit-suggestions 1`] = `
67
+ "import Map "mo:core/Map";
68
+ import Nat "mo:core/Nat";
69
+ import Text "mo:core/Text";
70
+ import { type Order } "mo:core/Order";
71
+
72
+ // --- M0223: redundant type instantiation ---
73
+
74
+ do {
75
+ func inferred<T>(x : T) : T = x;
76
+ let n1 = inferred(1);
77
+ ignore n1;
78
+ };
79
+
80
+ // --- M0236: contextual dot notation ---
81
+
82
+ do {
83
+ let m = Map.empty<Nat, Text>();
84
+ // single arg
85
+ ignore m.size(); // warn M0236
86
+
87
+ // multi arg with implicit -> M0236 + M0237
88
+ ignore m.get(1); // warn M0236 + M0237
89
+
90
+ // complex receiver
91
+ ignore Map.empty<Nat, Text>().size(
92
+
93
+ ); // warn M0236
94
+
95
+ // multiline call -> M0236 + M0237
96
+ m.add(
97
+ 1,
98
+ "John",
99
+ ); // warn M0236 + M0237
100
+ };
101
+
102
+ // --- M0237: implicit argument removal ---
103
+
104
+ do {
105
+ let m = Map.empty<Nat, Text>();
106
+
107
+ // single line
108
+ ignore m.get(1); // warn M0237
109
+
110
+ // multiline
111
+ ignore m.get(
112
+ 1,
113
+ ); // warn M0237
114
+ };
115
+
116
+ // --- M0237: complex implicit patterns ---
117
+
118
+ module Impl {
119
+ // implicit in the middle: f(self, implicit, key)
120
+ public func get<K, V>(
121
+ self : [(K, V)],
122
+ _cmp : (implicit : (compare : (K, K) -> Order)),
123
+ key : K,
124
+ ) : ?V { ignore self; ignore key; null };
125
+
126
+ // two adjacent implicits: f(self, implicit1, implicit2, key, value)
127
+ public func put<K, V>(
128
+ self : [(K, V)],
129
+ _cmpK : (implicit : (compare : (K, K) -> Order)),
130
+ _cmpV : (implicit : (compare : (V, V) -> Order)),
131
+ key : K,
132
+ value : V,
133
+ ) : [(K, V)] { ignore key; ignore value; self };
134
+
135
+ // implicit at the end
136
+ public func find<K, V>(
137
+ self : [(K, V)],
138
+ key : K,
139
+ _cmp : (implicit : (compare : (K, K) -> Order)),
140
+ ) : ?V { ignore self; ignore key; null };
141
+ public func sort1<K, V>(
142
+ self : [(K, V)],
143
+ _cmp : (implicit : (compare : (K, K) -> Order)),
144
+ ) : [(K, V)] { self };
145
+ public func sort2<K, V>(
146
+ notSelf : [(K, V)],
147
+ _cmp : (implicit : (compare : (K, K) -> Order)),
148
+ ) : [(K, V)] { notSelf };
149
+
150
+ // all implicits: f(implicit1, implicit2)
151
+ public func make<K, V>(
152
+ _cmpK : (implicit : (compare : (K, K) -> Order)),
153
+ _cmpV : (implicit : (compare : (V, V) -> Order)),
154
+ ) : [(K, V)] { [] };
155
+
156
+ // non-adjacent implicits: f(self, implicit1, key, implicit2, value)
157
+ public func update<K, V>(
158
+ self : [(K, V)],
159
+ _cmpK : (implicit : (compare : (K, K) -> Order)),
160
+ key : K,
161
+ _cmpV : (implicit : (compare : (V, V) -> Order)),
162
+ value : V,
163
+ ) : [(K, V)] { ignore key; ignore value; self };
164
+ };
165
+
166
+ do {
167
+ let data : [(Nat, Text)] = [];
168
+
169
+ // implicit in the middle -> M0236 + M0237
170
+ ignore data.get(1);
171
+
172
+ // two adjacent implicits -> M0236 + M0237 x2
173
+ ignore data.put(1, "a");
174
+
175
+ // implicit at the end -> M0236 + M0237
176
+ ignore data.find(1, );
177
+ ignore data.sort1(); // -> M0236 + M0237
178
+ ignore Impl.sort2(data, ); // no dot suggestion (notSelf), M0237 only
179
+
180
+ // all implicits -> M0237 x2
181
+ let _ = Impl.make<Nat, Text>();
182
+
183
+ // non-adjacent implicits -> M0236 + M0237 x2
184
+ ignore data.update(1, "a");
185
+
186
+ // multiline: two adjacent implicits -> M0236 + M0237 x2
187
+ ignore data.put(
188
+ 1,
189
+ "a",
190
+ );
191
+ };
192
+
193
+ // --- Mix: M0223 + M0236 + M0237 ---
194
+
195
+ do {
196
+ // NB: Must use \`let _ = ...\` to get the 'redundant type instantiation' error
197
+ let _ = Map.empty<Nat, Text>().insert(
198
+ 1,
199
+ "John",
200
+ ); // warn M0223 + M0236 + M0237
201
+ };
202
+ "
203
+ `;
204
+
205
+ exports[`check --fix edit-suggestions: fix output 1`] = `
206
+ "Fixed run/edit-suggestions.mo (41 fixes: M0223, M0236, M0237)
207
+
208
+ ✓ 41 fixes applied to 1 file"
209
+ `;
210
+
211
+ exports[`check --fix transitive imports: fix output 1`] = `
212
+ "Fixed run/transitive-lib.mo (2 fixes: M0236)
213
+ Fixed run/transitive-main.mo (1 fix: M0223)
214
+
215
+ ✓ 3 fixes applied to 2 files"
216
+ `;
217
+
218
+ exports[`check --fix transitive imports: lib file 1`] = `
219
+ "import List "mo:core/List";
220
+ import Nat "mo:core/Nat";
221
+
222
+ module {
223
+ public func test() {
224
+ let list = List.fromArray<Nat>([3, 2, 1]);
225
+ list.sortInPlace();
226
+ };
227
+ };
228
+ "
229
+ `;
230
+
231
+ exports[`check --fix transitive imports: main file 1`] = `
232
+ "import Lib "./transitive-lib";
233
+
234
+ persistent actor {
235
+ public func run() : async () {
236
+ func identity<T>(x : T) : T = x;
237
+ let _ = identity(1);
238
+ Lib.test();
239
+ };
240
+ };
241
+ "
242
+ `;
@@ -0,0 +1,72 @@
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
+
3
+ exports[`check error 1`] = `
4
+ {
5
+ "exitCode": 1,
6
+ "stderr": "Error.mo:1.1-5.2: type error [M0096], expression of type
7
+ actor {hello : shared () -> async Text}
8
+ cannot produce expected type
9
+ ()
10
+ Error.mo:7.1-7.21: type error [M0057], unbound variable thisshouldnotcompile
11
+ ✗ Check failed for file Error.mo (exit code: 1)",
12
+ "stdout": "moc < 1.3.0: some diagnostic hints may be missing",
13
+ }
14
+ `;
15
+
16
+ exports[`check error 2`] = `
17
+ {
18
+ "exitCode": 1,
19
+ "stderr": "Ok.mo: No such file or directory
20
+ ✗ Check failed for file Ok.mo (exit code: 1)",
21
+ "stdout": "moc < 1.3.0: some diagnostic hints may be missing",
22
+ }
23
+ `;
24
+
25
+ exports[`check ok 1`] = `
26
+ {
27
+ "exitCode": 0,
28
+ "stderr": "",
29
+ "stdout": "moc < 1.3.0: some diagnostic hints may be missing
30
+ ✓ Ok.mo",
31
+ }
32
+ `;
33
+
34
+ exports[`check ok 2`] = `
35
+ {
36
+ "exitCode": 0,
37
+ "stderr": "",
38
+ "stdout": "moc < 1.3.0: some diagnostic hints may be missing
39
+ check Running moc:
40
+ moc-wrapper ["Ok.mo","--check","--package","core",".mops/core@2.0.0/src"]
41
+ ✓ Ok.mo",
42
+ }
43
+ `;
44
+
45
+ exports[`check warning 1`] = `
46
+ {
47
+ "exitCode": 0,
48
+ "stderr": "Warning.mo:3.9-3.15: warning [M0194], unused identifier unused (delete or rename to wildcard \`_\` or \`_unused\`)",
49
+ "stdout": "moc < 1.3.0: some diagnostic hints may be missing
50
+ ✓ Warning.mo",
51
+ }
52
+ `;
53
+
54
+ exports[`check warning verbose 1`] = `
55
+ {
56
+ "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
+ check Running moc:
60
+ moc-wrapper ["Warning.mo","--check","--package","core",".mops/core@2.0.0/src"]
61
+ ✓ Warning.mo",
62
+ }
63
+ `;
64
+
65
+ exports[`check warning with -Werror flag 1`] = `
66
+ {
67
+ "exitCode": 1,
68
+ "stderr": "Warning.mo:3.9-3.15: warning [M0194], unused identifier unused (delete or rename to wildcard \`_\` or \`_unused\`)
69
+ ✗ Check failed for file Warning.mo (exit code: 1)",
70
+ "stdout": "moc < 1.3.0: some diagnostic hints may be missing",
71
+ }
72
+ `;
@@ -0,0 +1,78 @@
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
+
3
+ exports[`lint error 1`] = `
4
+ {
5
+ "exitCode": 1,
6
+ "stderr": " × [ERROR]: no-bool-switch
7
+ ╭─[<TEST_DIR>/lint/src/NoBoolSwitch.mo:3:5]
8
+ 2 │ public func boolSwitch(b : Bool) : Bool {
9
+ 3 │ ╭─▶ switch (b) {
10
+ 4 │ │ case false { false };
11
+ 5 │ │ case true { true };
12
+ 6 │ ├─▶ };
13
+ · ╰──── Don't switch on boolean values, use if instead
14
+ 7 │ };
15
+ ╰────
16
+
17
+ Error: Found 1 errors
18
+ Lint failed with exit code 1",
19
+ "stdout": "lint Running lintoko:
20
+ <CACHE>/lintoko/0.7.0/lintoko
21
+ ["--verbose","--rules","lints","<TEST_DIR>/lint/src/Ok.mo","<TEST_DIR>/lint/src/NoBoolSwitch.mo"]
22
+ DEBUG file input: <TEST_DIR>/lint/src/Ok.mo
23
+ DEBUG file input: <TEST_DIR>/lint/src/NoBoolSwitch.mo
24
+ DEBUG Loading rules from: lints
25
+ DEBUG Parsing extra rule at: lints/no-bool-switch.toml
26
+ DEBUG Linting file: <TEST_DIR>/lint/src/NoBoolSwitch.mo
27
+ DEBUG Linting file: <TEST_DIR>/lint/src/Ok.mo",
28
+ }
29
+ `;
30
+
31
+ exports[`lint error 2`] = `
32
+ {
33
+ "exitCode": 1,
34
+ "stderr": " × [ERROR]: no-bool-switch
35
+ ╭─[<TEST_DIR>/lint/src/NoBoolSwitch.mo:3:5]
36
+ 2 │ public func boolSwitch(b : Bool) : Bool {
37
+ 3 │ ╭─▶ switch (b) {
38
+ 4 │ │ case false { false };
39
+ 5 │ │ case true { true };
40
+ 6 │ ├─▶ };
41
+ · ╰──── Don't switch on boolean values, use if instead
42
+ 7 │ };
43
+ ╰────
44
+
45
+ Error: Found 1 errors
46
+ Lint failed with exit code 1",
47
+ "stdout": "lint Running lintoko:
48
+ <CACHE>/lintoko/0.7.0/lintoko
49
+ ["--verbose","--rules","lints","<TEST_DIR>/lint/src/NoBoolSwitch.mo"]
50
+ DEBUG file input: <TEST_DIR>/lint/src/NoBoolSwitch.mo
51
+ DEBUG Loading rules from: lints
52
+ DEBUG Parsing extra rule at: lints/no-bool-switch.toml
53
+ DEBUG Linting file: <TEST_DIR>/lint/src/NoBoolSwitch.mo",
54
+ }
55
+ `;
56
+
57
+ exports[`lint error 3`] = `
58
+ {
59
+ "exitCode": 1,
60
+ "stderr": "No files found for filter 'DoesNotExist'",
61
+ "stdout": "",
62
+ }
63
+ `;
64
+
65
+ exports[`lint ok 1`] = `
66
+ {
67
+ "exitCode": 0,
68
+ "stderr": "",
69
+ "stdout": "lint Running lintoko:
70
+ <CACHE>/lintoko/0.7.0/lintoko
71
+ ["--verbose","--rules","lints","<TEST_DIR>/lint/src/Ok.mo"]
72
+ DEBUG file input: <TEST_DIR>/lint/src/Ok.mo
73
+ DEBUG Loading rules from: lints
74
+ DEBUG Parsing extra rule at: lints/no-bool-switch.toml
75
+ DEBUG Linting file: <TEST_DIR>/lint/src/Ok.mo
76
+ ✓ Lint succeeded",
77
+ }
78
+ `;
@@ -1,5 +1,5 @@
1
- persistent actor {
1
+ persistent actor class (message : Text) {
2
2
  public func call() : async Text {
3
- "Hello";
3
+ message;
4
4
  };
5
5
  };
@@ -0,0 +1,5 @@
1
+ [toolchain]
2
+ moc = "1.3.0"
3
+
4
+ [canisters.main]
5
+ main = "src/Main.mo"
@@ -0,0 +1,5 @@
1
+ persistent actor {
2
+ public func greet(name : Text) : async Text {
3
+ "Hello, " # name # "!";
4
+ };
5
+ };
@@ -1,3 +1,4 @@
1
+ // Custom Candid file
1
2
  service : {
2
3
  call: () -> (text);
3
4
  }
@@ -1,9 +1,14 @@
1
1
  [dependencies]
2
2
  core = "1.0.0"
3
3
 
4
- [canisters]
5
- foo = "src/Foo.mo"
6
- bar = { main = "src/Bar.mo", args = ["--incremental-gc"], candid = "candid/bar.did" }
4
+ [canisters.foo]
5
+ main = "src/Foo.mo"
6
+
7
+ [canisters.bar]
8
+ main = "src/Bar.mo"
9
+ args = ["--incremental-gc"]
10
+ candid = "candid/bar.did"
11
+ initArg = "(\"Custom text\")"
7
12
 
8
13
  [build]
9
14
  args = ["--release"]
@@ -0,0 +1,10 @@
1
+ import { describe, test } from "@jest/globals";
2
+ import path from "path";
3
+ import { cliSnapshot } from "./helpers";
4
+
5
+ describe("build without dfx", () => {
6
+ test("builds using mops toolchain moc", async () => {
7
+ const cwd = path.join(import.meta.dirname, "build/no-dfx");
8
+ await cliSnapshot(["build"], { cwd }, 0);
9
+ }, 120_000);
10
+ });
@@ -0,0 +1,24 @@
1
+ import { describe, expect, test } from "@jest/globals";
2
+ import path from "path";
3
+ import { cliSnapshot } from "./helpers";
4
+
5
+ describe("build", () => {
6
+ test("ok", async () => {
7
+ const cwd = path.join(import.meta.dirname, "build/success");
8
+ await cliSnapshot(["build", "--verbose"], { cwd }, 0);
9
+ await cliSnapshot(["build", "foo"], { cwd }, 0);
10
+ await cliSnapshot(["build", "bar"], { cwd }, 0);
11
+ await cliSnapshot(["build", "foo", "bar"], { cwd }, 0);
12
+ });
13
+
14
+ test("error", async () => {
15
+ const cwd = path.join(import.meta.dirname, "build/error");
16
+ await cliSnapshot(["build", "foo", "--verbose"], { cwd }, 0);
17
+ expect((await cliSnapshot(["build", "bar"], { cwd }, 1)).stderr).toMatch(
18
+ "Candid compatibility check failed for canister bar",
19
+ );
20
+ expect(
21
+ (await cliSnapshot(["build", "foo", "bar"], { cwd }, 1)).stderr,
22
+ ).toMatch("Candid compatibility check failed for canister bar");
23
+ });
24
+ });
@@ -0,0 +1,7 @@
1
+ persistent actor {
2
+ public func hello() : async Text {
3
+ "Hello, World!";
4
+ };
5
+ };
6
+
7
+ thisshouldnotcompile;
@@ -0,0 +1,2 @@
1
+ [dependencies]
2
+ core = "2.0.0"
@@ -0,0 +1,11 @@
1
+ // M0223: Redundant type instantiation
2
+ // The type annotation is not needed when it can be inferred
3
+
4
+ persistent actor {
5
+ public func testM0223() : async () {
6
+ func identity<T>(x : T) : T = x;
7
+ let varArray : [var Nat] = [var 1];
8
+ let nat = identity<Nat>(1);
9
+ varArray[0] := nat;
10
+ };
11
+ };
@@ -0,0 +1,11 @@
1
+ // M0236: Suggested to use dot notation
2
+ // Function calls can be rewritten using dot notation
3
+ import List "mo:core/List";
4
+ import Nat "mo:core/Nat";
5
+
6
+ persistent actor {
7
+ public func testM0236() : async () {
8
+ let list = List.fromArray<Nat>([1, 2, 3]);
9
+ List.sortInPlace(list);
10
+ };
11
+ };
@@ -0,0 +1,11 @@
1
+ // M0237: Redundant explicit implicit argument
2
+ // Some arguments can be inferred and don't need to be specified
3
+ import List "mo:core/List";
4
+ import Nat "mo:core/Nat";
5
+
6
+ persistent actor {
7
+ public func testM0237() : async () {
8
+ let list = List.fromArray<Nat>([3, 2, 1]);
9
+ list.sortInPlace(Nat.compare);
10
+ };
11
+ };
@@ -0,0 +1,7 @@
1
+ // Clean file — no fixable warnings
2
+ persistent actor {
3
+ public func example() : async () {
4
+ let _x : ?Text = null;
5
+ ();
6
+ };
7
+ };