ic-mops 0.16.0 → 0.17.1
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/commands/mmf1.js +29 -7
- package/commands/test.js +54 -46
- package/package.json +1 -1
- package/templates/mops-test.yml +3 -6
package/commands/mmf1.js
CHANGED
|
@@ -10,6 +10,28 @@ export class MMF1 {
|
|
|
10
10
|
failed = 0;
|
|
11
11
|
passed = 0;
|
|
12
12
|
skipped = 0;
|
|
13
|
+
srategy; // 'store' | 'print'
|
|
14
|
+
output = [];
|
|
15
|
+
|
|
16
|
+
constructor(srategy) {
|
|
17
|
+
this.srategy = srategy;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
_log(...args) {
|
|
21
|
+
if (this.srategy === 'store') {
|
|
22
|
+
this.output.push(args.join(' '));
|
|
23
|
+
}
|
|
24
|
+
else if (this.srategy === 'print') {
|
|
25
|
+
console.log(...args);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
flush() {
|
|
30
|
+
for (let out of this.output) {
|
|
31
|
+
console.log(out);
|
|
32
|
+
}
|
|
33
|
+
this.store = [];
|
|
34
|
+
}
|
|
13
35
|
|
|
14
36
|
parseLine(line) {
|
|
15
37
|
if (line.startsWith('mops:1:start ')) {
|
|
@@ -22,7 +44,7 @@ export class MMF1 {
|
|
|
22
44
|
this._testSkip(line.split('mops:1:skip ')[1]);
|
|
23
45
|
}
|
|
24
46
|
else {
|
|
25
|
-
|
|
47
|
+
this._log(' '.repeat(this.stack.length * 2), chalk.gray('stdout'), line);
|
|
26
48
|
}
|
|
27
49
|
}
|
|
28
50
|
|
|
@@ -31,7 +53,7 @@ export class MMF1 {
|
|
|
31
53
|
let suite = this.stack[this.stack.length - 1];
|
|
32
54
|
if (this.currSuite !== suite) {
|
|
33
55
|
this.currSuite = suite;
|
|
34
|
-
|
|
56
|
+
this._log(' '.repeat((this.stack.length - 1) * 2), (chalk.gray('•')) + '', suite);
|
|
35
57
|
}
|
|
36
58
|
}
|
|
37
59
|
this.stack.push(name);
|
|
@@ -55,22 +77,22 @@ export class MMF1 {
|
|
|
55
77
|
return;
|
|
56
78
|
}
|
|
57
79
|
this.passed++;
|
|
58
|
-
|
|
80
|
+
this._log(' '.repeat(this.stack.length * 2), chalk.green('✓'), name);
|
|
59
81
|
}
|
|
60
82
|
else if (status === 'fail') {
|
|
61
83
|
this.failed++;
|
|
62
|
-
|
|
84
|
+
this._log(' '.repeat(this.stack.length * 2), chalk.red('×'), name);
|
|
63
85
|
}
|
|
64
86
|
else if (status === 'skip') {
|
|
65
87
|
this.skipped++;
|
|
66
|
-
|
|
88
|
+
this._log(' '.repeat(this.stack.length * 2), chalk.yellow('−'), name);
|
|
67
89
|
}
|
|
68
90
|
}
|
|
69
91
|
|
|
70
92
|
fail(stderr) {
|
|
71
93
|
let name = this.stack.pop() || '';
|
|
72
94
|
this._status(name, 'fail');
|
|
73
|
-
|
|
95
|
+
this._log(' '.repeat(this.stack.length * 2), chalk.red('FAIL'), stderr);
|
|
74
96
|
}
|
|
75
97
|
|
|
76
98
|
pass() {
|
|
@@ -78,6 +100,6 @@ export class MMF1 {
|
|
|
78
100
|
if (name) {
|
|
79
101
|
this._status(name, 'pass');
|
|
80
102
|
}
|
|
81
|
-
|
|
103
|
+
this._log(' '.repeat(this.stack.length * 2), chalk.green('PASS'));
|
|
82
104
|
}
|
|
83
105
|
}
|
package/commands/test.js
CHANGED
|
@@ -5,9 +5,12 @@ import chokidar from 'chokidar';
|
|
|
5
5
|
import debounce from 'debounce';
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import fs from 'fs';
|
|
8
|
+
import os from 'os';
|
|
9
|
+
|
|
8
10
|
import {MMF1} from './mmf1.js';
|
|
9
11
|
import {sources} from './sources.js';
|
|
10
12
|
import {getRootDir} from '../mops.js';
|
|
13
|
+
import {parallel} from '../parallel.js';
|
|
11
14
|
|
|
12
15
|
let ignore = [
|
|
13
16
|
'**/node_modules/**',
|
|
@@ -99,46 +102,51 @@ export async function runAll(filter = '') {
|
|
|
99
102
|
let wasmDir = `${getRootDir()}/.mops/.test/`;
|
|
100
103
|
fs.mkdirSync(wasmDir, {recursive: true});
|
|
101
104
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
105
|
+
let promises = [];
|
|
106
|
+
|
|
107
|
+
await parallel(os.cpus().length, files, async (file) => {
|
|
108
|
+
let mmf = new MMF1('store');
|
|
109
|
+
|
|
110
|
+
let wasiMode = fs.readFileSync(file, 'utf8').startsWith('// @testmode wasi');
|
|
111
|
+
|
|
112
|
+
let mocArgs = ['--hide-warnings', '--error-detail=2', ...sourcesArr.join(' ').split(' '), file].filter(x => x);
|
|
113
|
+
|
|
114
|
+
// build and run wasm
|
|
115
|
+
if (wasiMode) {
|
|
116
|
+
let wasmFile = `${path.join(wasmDir, path.parse(file).name)}.wasm`;
|
|
117
|
+
|
|
118
|
+
// build
|
|
119
|
+
let buildProc = spawn(mocPath, [`-o=${wasmFile}`, '-wasi-system-api', ...mocArgs]);
|
|
120
|
+
await pipeMMF(buildProc, mmf).then(async () => {
|
|
121
|
+
if (mmf.failed > 0) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// run
|
|
125
|
+
let proc = spawn('wasmtime', [wasmFile]);
|
|
126
|
+
await pipeMMF(proc, mmf);
|
|
127
|
+
}).finally(() => {
|
|
128
|
+
fs.rmSync(wasmFile);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// interpret
|
|
132
|
+
else {
|
|
133
|
+
let proc = spawn(mocPath, ['-r', '-ref-system-api', ...mocArgs]);
|
|
134
|
+
await pipeMMF(proc, mmf);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
passed += mmf.passed;
|
|
138
|
+
failed += mmf.failed;
|
|
139
|
+
skipped += mmf.skipped;
|
|
140
|
+
|
|
141
|
+
promises.push([file, mmf]);
|
|
142
|
+
});
|
|
138
143
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
let i = 0;
|
|
145
|
+
for (let [file, mmf] of promises) {
|
|
146
|
+
i++ && console.log('-'.repeat(50));
|
|
147
|
+
let wasiMode = fs.readFileSync(file, 'utf8').startsWith('// @testmode wasi');
|
|
148
|
+
console.log(`Running ${chalk.gray(file)} ${wasiMode ? chalk.gray('(wasi)') : ''}`);
|
|
149
|
+
mmf.flush();
|
|
142
150
|
}
|
|
143
151
|
|
|
144
152
|
fs.rmSync(wasmDir, {recursive: true, force: true});
|
|
@@ -165,14 +173,14 @@ function absToRel(p) {
|
|
|
165
173
|
return path.relative(rootDir, path.resolve(p));
|
|
166
174
|
}
|
|
167
175
|
|
|
168
|
-
function pipeMMF(proc,
|
|
176
|
+
function pipeMMF(proc, mmf) {
|
|
169
177
|
return new Promise((resolve) => {
|
|
170
178
|
// stdout
|
|
171
179
|
proc.stdout.on('data', (data) => {
|
|
172
180
|
for (let line of data.toString().split('\n')) {
|
|
173
181
|
line = line.trim();
|
|
174
182
|
if (line) {
|
|
175
|
-
|
|
183
|
+
mmf.parseLine(line);
|
|
176
184
|
}
|
|
177
185
|
}
|
|
178
186
|
});
|
|
@@ -183,18 +191,18 @@ function pipeMMF(proc, mmf1) {
|
|
|
183
191
|
// change absolute file path to relative
|
|
184
192
|
// change :line:col-line:col to :line:col to work in vscode
|
|
185
193
|
text = text.replace(/([\w+._/-]+):(\d+).(\d+)(-\d+.\d+)/g, (m0, m1, m2, m3) => `${absToRel(m1)}:${m2}:${m3}`);
|
|
186
|
-
|
|
194
|
+
mmf.fail(text);
|
|
187
195
|
});
|
|
188
196
|
|
|
189
197
|
// exit
|
|
190
|
-
proc.on('
|
|
198
|
+
proc.on('close', (code) => {
|
|
191
199
|
if (code === 0) {
|
|
192
|
-
|
|
200
|
+
mmf.pass();
|
|
193
201
|
}
|
|
194
202
|
else if (code !== 1) {
|
|
195
|
-
|
|
203
|
+
mmf.fail(`unknown exit code: ${code}`);
|
|
196
204
|
}
|
|
197
|
-
resolve();
|
|
205
|
+
resolve(mmf);
|
|
198
206
|
});
|
|
199
207
|
});
|
|
200
208
|
}
|
package/package.json
CHANGED
package/templates/mops-test.yml
CHANGED
|
@@ -16,15 +16,12 @@ jobs:
|
|
|
16
16
|
- uses: actions/setup-node@v3
|
|
17
17
|
with:
|
|
18
18
|
node-version: 18
|
|
19
|
-
- uses: aviate-labs/setup-dfx@v0.2.5
|
|
20
|
-
with:
|
|
21
|
-
dfx-version: 0.14.1
|
|
22
19
|
|
|
23
|
-
- name: install
|
|
24
|
-
run:
|
|
20
|
+
- name: install moc
|
|
21
|
+
run: npx mocv use 0.9.3
|
|
25
22
|
|
|
26
23
|
- name: install mops
|
|
27
|
-
run: npm i ic-mops -g
|
|
24
|
+
run: npm i ic-mops -g
|
|
28
25
|
|
|
29
26
|
- name: install mops packages
|
|
30
27
|
run: mops install
|