ic-mops 0.30.0 → 0.31.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.
Files changed (59) hide show
  1. package/commands/add.ts +12 -3
  2. package/commands/install.ts +2 -2
  3. package/commands/update.ts +30 -2
  4. package/dist/commands/add.js +11 -3
  5. package/dist/commands/install.js +2 -2
  6. package/dist/commands/update.js +27 -2
  7. package/dist/mops.d.ts +4 -2
  8. package/dist/mops.js +18 -4
  9. package/dist/package.json +1 -1
  10. package/dist/vessel.js +10 -10
  11. package/mops.ts +19 -5
  12. package/package.json +1 -1
  13. package/vessel.ts +10 -10
  14. package/dist/bench/$USER_BENCH_FILE.mo +0 -45
  15. package/dist/bench/bench-canister.mo +0 -57
  16. package/dist/commands/bench/$USER_BENCH_FILE.mo +0 -45
  17. package/dist/commands/bench/bench/$USER_BENCH_FILE.mo +0 -45
  18. package/dist/commands/bench/bench/bench-canister.mo +0 -57
  19. package/dist/commands/bench/bench-canister.mo +0 -85
  20. package/dist/commands/bench/declarations/bench/bench.did.d.ts +0 -6
  21. package/dist/commands/bench/declarations/bench/bench.did.js +0 -22
  22. package/dist/commands/bench/declarations/bench/index.d.ts +0 -2
  23. package/dist/commands/bench/declarations/bench/index.js +0 -30
  24. package/dist/commands/bench/declarations/main/index.d.ts +0 -2
  25. package/dist/commands/bench/declarations/main/index.js +0 -30
  26. package/dist/commands/bench/declarations/main/main.did.d.ts +0 -6
  27. package/dist/commands/bench/declarations/main/main.did.js +0 -242
  28. package/dist/commands/bench/declarations/storage/index.d.ts +0 -4
  29. package/dist/commands/bench/declarations/storage/index.js +0 -26
  30. package/dist/commands/bench/declarations/storage/storage.did.d.ts +0 -6
  31. package/dist/commands/bench/declarations/storage/storage.did.js +0 -34
  32. package/dist/commands/bench/user-bench.mo +0 -14
  33. package/dist/commands/bench.d.ts +0 -10
  34. package/dist/commands/bench.js +0 -214
  35. package/dist/commands/mmf1.d.ts +0 -21
  36. package/dist/commands/mmf1.js +0 -93
  37. package/dist/commands/test/reporter-files.d.ts +0 -10
  38. package/dist/commands/test/reporter-files.js +0 -48
  39. package/dist/commands/test/reporter-verbose.d.ts +0 -10
  40. package/dist/commands/test/reporter-verbose.js +0 -56
  41. package/dist/commands/test.d.ts +0 -4
  42. package/dist/commands/test.js +0 -186
  43. package/dist/declarations/bench/bench.did +0 -24
  44. package/dist/declarations/bench/bench.did.d.ts +0 -24
  45. package/dist/declarations/bench/bench.did.js +0 -24
  46. package/dist/declarations/bench/index.d.ts +0 -50
  47. package/dist/declarations/bench/index.js +0 -41
  48. package/dist/helpers/get-dfx-version.d.ts +0 -1
  49. package/dist/helpers/get-dfx-version.js +0 -9
  50. package/dist/helpers/get-moc-path.d.ts +0 -1
  51. package/dist/helpers/get-moc-path.js +0 -11
  52. package/dist/helpers/get-moc-version.d.ts +0 -1
  53. package/dist/helpers/get-moc-version.js +0 -7
  54. package/dist/out/cli.d.ts +0 -2
  55. package/dist/out/cli.js +0 -114581
  56. package/dist/parse-changelog.d.ts +0 -1
  57. package/dist/parse-changelog.js +0 -1435
  58. package/dist/test.d.ts +0 -1
  59. package/dist/test.js +0 -1411
@@ -1,214 +0,0 @@
1
- import { execSync } from 'node:child_process';
2
- import path from 'node:path';
3
- import fs from 'node:fs';
4
- // import os from 'node:os';
5
- import chalk from 'chalk';
6
- import { globSync } from 'glob';
7
- import { markdownTable } from 'markdown-table';
8
- import logUpdate from 'log-update';
9
- import { getRootDir } from '../mops.js';
10
- import { parallel } from '../parallel.js';
11
- import { createActor } from '../declarations/bench/index.js';
12
- import { absToRel } from './test/utils.js';
13
- import { getMocVersion } from '../helpers/get-moc-version.js';
14
- import { getDfxVersion } from '../helpers/get-dfx-version.js';
15
- let ignore = [
16
- '**/node_modules/**',
17
- '**/.mops/**',
18
- '**/.vessel/**',
19
- '**/.git/**',
20
- ];
21
- let globConfig = {
22
- nocase: true,
23
- ignore: ignore,
24
- };
25
- export async function bench(filter = '', options = {}) {
26
- let rootDir = getRootDir();
27
- let globStr = '**/bench?(mark)/**/*.bench.mo';
28
- if (filter) {
29
- globStr = `**/bench?(mark)/**/*${filter}*.mo`;
30
- }
31
- let files = globSync(path.join(rootDir, globStr), globConfig);
32
- if (!files.length) {
33
- if (filter) {
34
- console.log(`No benchmark files found for filter '${filter}'`);
35
- return false;
36
- }
37
- console.log('No *.bench.mo files found');
38
- console.log('Put your benchmark files in \'bench\' directory in *.bench.mo files');
39
- return false;
40
- }
41
- files.sort();
42
- let benchDir = `${getRootDir()}/.mops/.bench/`;
43
- fs.rmSync(benchDir, { recursive: true, force: true });
44
- fs.mkdirSync(benchDir, { recursive: true });
45
- console.log('Benchmark files:');
46
- for (let file of files) {
47
- console.log(chalk.gray(`• ${absToRel(file)}`));
48
- }
49
- console.log('');
50
- console.log('='.repeat(50));
51
- console.log('Starting dfx replica...');
52
- startDfx(options.verbose);
53
- let resultsByName = new Map();
54
- // await parallel(os.cpus().length, files, async (file: string) => {
55
- await parallel(1, files, async (file) => {
56
- console.log('\n' + '—'.repeat(50));
57
- console.log(`\nRunning ${chalk.gray(absToRel(file))}...`);
58
- console.log('');
59
- try {
60
- let { schema, results } = await runBenchFile(file, options);
61
- resultsByName.set(schema.name || absToRel(file), results);
62
- }
63
- catch (err) {
64
- console.error('Unexpected error. Stopping dfx replica...');
65
- stopDfx(options.verbose);
66
- throw err;
67
- }
68
- });
69
- if (options.save) {
70
- console.log('Saving results to mops.bench.json...');
71
- let json = {
72
- version: 1,
73
- moc: options.moc || getMocVersion(),
74
- dfx: options.dfx || getDfxVersion(),
75
- gc: options.gc || 'incremental',
76
- results: {},
77
- };
78
- resultsByName.forEach((results, name) => {
79
- json.results[name] = Array.from(results.entries());
80
- });
81
- fs.writeFileSync(path.join(rootDir, 'mops.bench.json'), JSON.stringify(json, (_, val) => {
82
- if (typeof val === 'bigint') {
83
- return Number(val);
84
- }
85
- else {
86
- return val;
87
- }
88
- }, 2));
89
- }
90
- console.log('Stopping dfx replica...');
91
- stopDfx(options.verbose);
92
- fs.rmSync(benchDir, { recursive: true, force: true });
93
- return true;
94
- }
95
- function dfxJson(canisterName) {
96
- return {
97
- version: 1,
98
- canisters: {
99
- [canisterName]: {
100
- type: 'motoko',
101
- main: 'canister.mo',
102
- args: '--force-gc --incremental-gc',
103
- }
104
- },
105
- defaults: {
106
- build: {
107
- packtool: 'mops sources',
108
- },
109
- },
110
- networks: {
111
- local: {
112
- type: 'ephemeral',
113
- bind: '127.0.0.1:4947',
114
- },
115
- },
116
- };
117
- }
118
- function startDfx(verbose = false) {
119
- stopDfx(verbose);
120
- let dir = path.join(getRootDir(), '.mops/.bench');
121
- fs.writeFileSync(path.join(dir, 'dfx.json'), JSON.stringify(dfxJson(''), null, 2));
122
- execSync('dfx start --background --clean', { cwd: dir, stdio: ['inherit', verbose ? 'inherit' : 'ignore', 'inherit'] });
123
- }
124
- function stopDfx(verbose = false) {
125
- let dir = path.join(getRootDir(), '.mops/.bench');
126
- execSync('dfx stop', { cwd: dir, stdio: ['pipe', verbose ? 'inherit' : 'ignore', 'pipe'] });
127
- }
128
- async function runBenchFile(file, options = {}) {
129
- let rootDir = getRootDir();
130
- let tempDir = path.join(rootDir, '.mops/.bench/', path.parse(file).name);
131
- fs.mkdirSync(tempDir, { recursive: true });
132
- let canisterName = Date.now().toString(36);
133
- // prepare temp files
134
- fs.writeFileSync(path.join(tempDir, 'dfx.json'), JSON.stringify(dfxJson(canisterName), null, 2));
135
- fs.cpSync(new URL('./bench/bench-canister.mo', import.meta.url), path.join(tempDir, 'canister.mo'));
136
- fs.cpSync(file, path.join(tempDir, 'user-bench.mo'));
137
- // deploy canister
138
- execSync(`dfx deploy ${canisterName} --mode reinstall --yes --identity anonymous`, { cwd: tempDir, stdio: options.verbose ? 'pipe' : ['pipe', 'ignore', 'pipe'] });
139
- let canisterId = execSync(`dfx canister id ${canisterName}`, { cwd: tempDir }).toString().trim();
140
- let actor = await createActor(canisterId, {
141
- agentOptions: {
142
- host: 'http://127.0.0.1:4947',
143
- },
144
- });
145
- let schema = await actor.init();
146
- // load previous results
147
- let prevResults;
148
- if (options.compare) {
149
- let prevResultsJson = JSON.parse(fs.readFileSync(path.join(rootDir, 'mops.bench.json')).toString());
150
- if (prevResultsJson.results[schema.name]) {
151
- prevResults = new Map(prevResultsJson.results[schema.name]);
152
- }
153
- else {
154
- console.log(chalk.yellow(`No previous results found for benchmark with name "${schema.name}"`));
155
- }
156
- }
157
- let results = new Map();
158
- let formatNumber = (n) => {
159
- return n.toLocaleString('en-US').replaceAll(',', '_');
160
- };
161
- let getTable = (prop) => {
162
- let resArr = [['', ...schema.cols]];
163
- for (let [_rowIndex, row] of schema.rows.entries()) {
164
- let curRow = [row];
165
- for (let [_colIndex, col] of schema.cols.entries()) {
166
- let res = results.get(`${row}:${col}`);
167
- if (res) {
168
- // compare with previous results
169
- let diff = '';
170
- if (options.compare && prevResults) {
171
- let prevRes = prevResults.get(`${row}:${col}`);
172
- if (prevRes) {
173
- let percent = (Number(res[prop]) - Number(prevRes[prop])) / Number(prevRes[prop]) * 100;
174
- let sign = percent > 0 ? '+' : '';
175
- let percentText = percent == 0 ? '0%' : sign + percent.toFixed(2) + '%';
176
- // diff = ' (' + (percent > 0 ? chalk.red(percentText) : chalk.green(percentText)) + ')'; // alignment is broken
177
- diff = ' (' + percentText + ')';
178
- }
179
- else {
180
- diff = chalk.yellow(' (no previous results)');
181
- }
182
- }
183
- // add to table
184
- curRow.push(formatNumber(res[prop]) + diff);
185
- }
186
- else {
187
- curRow.push('');
188
- }
189
- }
190
- resArr.push(curRow);
191
- }
192
- return markdownTable(resArr, { align: ['l', ...'r'.repeat(schema.cols.length)] });
193
- };
194
- let printResults = () => {
195
- logUpdate(`
196
- \n${chalk.bold(schema.name)}
197
- ${schema.description ? '\n' + chalk.gray(schema.description) : ''}
198
- \n\n${chalk.blue('Instructions')}\n\n${getTable('instructions')}
199
- \n\n${chalk.blue('Heap')}\n\n${getTable('rts_heap_size')}
200
- `);
201
- };
202
- printResults();
203
- // run all cells
204
- for (let [rowIndex, row] of schema.rows.entries()) {
205
- for (let [colIndex, col] of schema.cols.entries()) {
206
- // let res = await actor.runCellQuery(BigInt(rowIndex), BigInt(colIndex));
207
- let res = await actor.runCellUpdate(BigInt(rowIndex), BigInt(colIndex));
208
- results.set(`${row}:${col}`, res);
209
- printResults();
210
- }
211
- }
212
- logUpdate.done();
213
- return { schema, results };
214
- }
@@ -1,21 +0,0 @@
1
- type Strategy = 'store' | 'print';
2
- export declare class MMF1 {
3
- stack: string[];
4
- currSuite: string;
5
- failed: number;
6
- passed: number;
7
- skipped: number;
8
- srategy: Strategy;
9
- output: string[];
10
- constructor(srategy: Strategy);
11
- _log(...args: string[]): void;
12
- flush(): void;
13
- parseLine(line: string): void;
14
- _testStart(name: string): void;
15
- _testEnd(name: string): void;
16
- _testSkip(name: string): void;
17
- _status(name: string, status: string): void;
18
- fail(stderr: string): void;
19
- pass(): void;
20
- }
21
- export {};
@@ -1,93 +0,0 @@
1
- // mops message format v1
2
- // mops:1:start
3
- // mops:1:end
4
- // mops:1:skip
5
- import chalk from 'chalk';
6
- export class MMF1 {
7
- constructor(srategy) {
8
- this.stack = [];
9
- this.currSuite = '';
10
- this.failed = 0;
11
- this.passed = 0;
12
- this.skipped = 0;
13
- this.output = [];
14
- this.srategy = srategy;
15
- }
16
- _log(...args) {
17
- if (this.srategy === 'store') {
18
- this.output.push(args.join(' '));
19
- }
20
- else if (this.srategy === 'print') {
21
- console.log(...args);
22
- }
23
- }
24
- flush() {
25
- for (let out of this.output) {
26
- console.log(out);
27
- }
28
- this.output = [];
29
- }
30
- parseLine(line) {
31
- if (line.startsWith('mops:1:start ')) {
32
- this._testStart(line.split('mops:1:start ')[1] || '');
33
- }
34
- else if (line.startsWith('mops:1:end ')) {
35
- this._testEnd(line.split('mops:1:end ')[1] || '');
36
- }
37
- else if (line.startsWith('mops:1:skip ')) {
38
- this._testSkip(line.split('mops:1:skip ')[1] || '');
39
- }
40
- else {
41
- this._log(' '.repeat(this.stack.length * 2), chalk.gray('stdout'), line);
42
- }
43
- }
44
- _testStart(name) {
45
- let suite = this.stack[this.stack.length - 1];
46
- if (suite) {
47
- if (this.currSuite !== suite) {
48
- this.currSuite = suite;
49
- this._log(' '.repeat((this.stack.length - 1) * 2), (chalk.gray('•')) + '', suite);
50
- }
51
- }
52
- this.stack.push(name);
53
- }
54
- _testEnd(name) {
55
- if (name !== this.stack.pop()) {
56
- throw 'mmf1._testEnd: start and end test mismatch';
57
- }
58
- this._status(name, 'pass');
59
- }
60
- _testSkip(name) {
61
- this._status(name, 'skip');
62
- }
63
- _status(name, status) {
64
- if (status === 'pass') {
65
- // do not print suite at the end
66
- if (name === this.currSuite) {
67
- return;
68
- }
69
- this.passed++;
70
- this._log(' '.repeat(this.stack.length * 2), chalk.green('✓'), name);
71
- }
72
- else if (status === 'fail') {
73
- this.failed++;
74
- this._log(' '.repeat(this.stack.length * 2), chalk.red('✖'), name);
75
- }
76
- else if (status === 'skip') {
77
- this.skipped++;
78
- this._log(' '.repeat(this.stack.length * 2), chalk.yellow('−'), name);
79
- }
80
- }
81
- fail(stderr) {
82
- let name = this.stack.pop() || '';
83
- this._status(name, 'fail');
84
- this._log(' '.repeat(this.stack.length * 2), chalk.red('FAIL'), stderr);
85
- }
86
- pass() {
87
- let name = this.stack.pop();
88
- if (name) {
89
- this._status(name, 'pass');
90
- }
91
- this._log(' '.repeat(this.stack.length * 2), chalk.green('PASS'));
92
- }
93
- }
@@ -1,10 +0,0 @@
1
- import { MMF1 } from './mmf1.js';
2
- export declare class FilesReporter {
3
- #private;
4
- passed: number;
5
- failed: number;
6
- skipped: number;
7
- addFiles(files: string[]): void;
8
- addRun(file: string, mmf: MMF1, state: Promise<void>, wasiMode: boolean): void;
9
- done(): boolean;
10
- }
@@ -1,48 +0,0 @@
1
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
- };
6
- var _FilesReporter_startTime;
7
- import chalk from 'chalk';
8
- import { absToRel } from './utils.js';
9
- export class FilesReporter {
10
- constructor() {
11
- this.passed = 0;
12
- this.failed = 0;
13
- this.skipped = 0;
14
- _FilesReporter_startTime.set(this, Date.now());
15
- }
16
- addFiles(files) {
17
- console.log(`Test files: ${files.length}`);
18
- console.log('='.repeat(50));
19
- }
20
- addRun(file, mmf, state, wasiMode) {
21
- state.then(() => {
22
- this.passed += mmf.passed;
23
- this.failed += mmf.failed;
24
- this.skipped += mmf.skipped;
25
- if (this.failed) {
26
- mmf.flush();
27
- }
28
- else {
29
- console.log(`${chalk.green('✓')} ${absToRel(file)} ${wasiMode ? chalk.gray('(wasi)') : ''}`);
30
- }
31
- });
32
- }
33
- done() {
34
- console.log('='.repeat(50));
35
- if (this.failed) {
36
- console.log(chalk.redBright('Tests failed'));
37
- }
38
- else {
39
- console.log(chalk.greenBright('Tests passed'));
40
- }
41
- console.log(`Done in ${chalk.gray(((Date.now() - __classPrivateFieldGet(this, _FilesReporter_startTime, "f")) / 1000).toFixed(2) + 's')}`
42
- + `, passed ${chalk.greenBright(this.passed)}`
43
- + (this.skipped ? `, skipped ${chalk[this.skipped ? 'yellowBright' : 'gray'](this.skipped)}` : '')
44
- + (this.failed ? `, failed ${chalk[this.failed ? 'redBright' : 'gray'](this.failed)}` : ''));
45
- return this.failed === 0;
46
- }
47
- }
48
- _FilesReporter_startTime = new WeakMap();
@@ -1,10 +0,0 @@
1
- import { MMF1 } from './mmf1.js';
2
- export declare class VerboseReporter {
3
- #private;
4
- passed: number;
5
- failed: number;
6
- skipped: number;
7
- addFiles(files: string[]): void;
8
- addRun(file: string, mmf: MMF1, state: Promise<void>, wasiMode: boolean): void;
9
- done(): boolean;
10
- }
@@ -1,56 +0,0 @@
1
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
- };
6
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
7
- if (kind === "m") throw new TypeError("Private method is not writable");
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
- };
12
- var _VerboseReporter_startTime, _VerboseReporter_curFileIndex;
13
- import chalk from 'chalk';
14
- import { absToRel } from './utils.js';
15
- export class VerboseReporter {
16
- constructor() {
17
- this.passed = 0;
18
- this.failed = 0;
19
- this.skipped = 0;
20
- _VerboseReporter_startTime.set(this, Date.now());
21
- _VerboseReporter_curFileIndex.set(this, 0);
22
- }
23
- addFiles(files) {
24
- console.log('Test files:');
25
- for (let file of files) {
26
- console.log(chalk.gray(`• ${absToRel(file)}`));
27
- }
28
- console.log('='.repeat(50));
29
- }
30
- addRun(file, mmf, state, wasiMode) {
31
- state.then(() => {
32
- var _a, _b;
33
- this.passed += mmf.passed;
34
- this.failed += mmf.failed;
35
- this.skipped += mmf.skipped;
36
- (__classPrivateFieldSet(this, _VerboseReporter_curFileIndex, (_b = __classPrivateFieldGet(this, _VerboseReporter_curFileIndex, "f"), _a = _b++, _b), "f"), _a) && console.log('-'.repeat(50));
37
- console.log(`Running ${chalk.gray(absToRel(file))} ${wasiMode ? chalk.gray('(wasi)') : ''}`);
38
- mmf.flush();
39
- });
40
- }
41
- done() {
42
- console.log('='.repeat(50));
43
- if (this.failed) {
44
- console.log(chalk.redBright('Tests failed'));
45
- }
46
- else {
47
- console.log(chalk.greenBright('Tests passed'));
48
- }
49
- console.log(`Done in ${chalk.gray(((Date.now() - __classPrivateFieldGet(this, _VerboseReporter_startTime, "f")) / 1000).toFixed(2) + 's')}`
50
- + `, passed ${chalk.greenBright(this.passed)}`
51
- + (this.skipped ? `, skipped ${chalk[this.skipped ? 'yellowBright' : 'gray'](this.skipped)}` : '')
52
- + (this.failed ? `, failed ${chalk[this.failed ? 'redBright' : 'gray'](this.failed)}` : ''));
53
- return this.failed === 0;
54
- }
55
- }
56
- _VerboseReporter_startTime = new WeakMap(), _VerboseReporter_curFileIndex = new WeakMap();
@@ -1,4 +0,0 @@
1
- export declare function test(filter?: string, { watch }?: {
2
- watch?: boolean | undefined;
3
- }): Promise<void>;
4
- export declare function runAll(filter?: string): Promise<boolean | undefined>;
@@ -1,186 +0,0 @@
1
- import { spawn, execSync } from 'node:child_process';
2
- import path from 'node:path';
3
- import fs from 'node:fs';
4
- import os from 'node:os';
5
- import chalk from 'chalk';
6
- import { globSync } from 'glob';
7
- import chokidar from 'chokidar';
8
- import debounce from 'debounce';
9
- import { MMF1 } from './mmf1.js';
10
- import { sources } from './sources.js';
11
- import { getRootDir } from '../mops.js';
12
- import { parallel } from '../parallel.js';
13
- import { absToRel } from './test/utils.js';
14
- import { VerboseReporter } from './test/reporter-verbose.js';
15
- let ignore = [
16
- '**/node_modules/**',
17
- '**/.mops/**',
18
- '**/.vessel/**',
19
- '**/.git/**',
20
- ];
21
- let globConfig = {
22
- nocase: true,
23
- ignore: ignore,
24
- };
25
- export async function test(filter = '', { watch = false } = {}) {
26
- let rootDir = getRootDir();
27
- if (watch) {
28
- // todo: run only changed for *.test.mo?
29
- // todo: run all for *.mo?
30
- let run = debounce(async () => {
31
- console.clear();
32
- process.stdout.write('\x1Bc');
33
- await runAll(filter);
34
- console.log('-'.repeat(50));
35
- console.log('Waiting for file changes...');
36
- console.log(chalk.gray((`Press ${chalk.gray('Ctrl+C')} to exit.`)));
37
- }, 200);
38
- let watcher = chokidar.watch([
39
- path.join(rootDir, '**/*.mo'),
40
- path.join(rootDir, 'mops.toml'),
41
- ], {
42
- ignored: ignore,
43
- ignoreInitial: true,
44
- });
45
- watcher.on('all', () => {
46
- run();
47
- });
48
- run();
49
- }
50
- else {
51
- let passed = await runAll(filter);
52
- if (!passed) {
53
- process.exit(1);
54
- }
55
- }
56
- }
57
- let mocPath = process.env.DFX_MOC_PATH;
58
- export async function runAll(filter = '') {
59
- let reporter = new VerboseReporter;
60
- let rootDir = getRootDir();
61
- let files = [];
62
- let libFiles = globSync('**/test?(s)/lib.mo', globConfig);
63
- if (libFiles[0]) {
64
- files = [libFiles[0]];
65
- }
66
- else {
67
- let globStr = '**/test?(s)/**/*.test.mo';
68
- if (filter) {
69
- globStr = `**/test?(s)/**/*${filter}*.mo`;
70
- }
71
- files = globSync(path.join(rootDir, globStr), globConfig);
72
- }
73
- if (!files.length) {
74
- if (filter) {
75
- console.log(`No test files found for filter '${filter}'`);
76
- return;
77
- }
78
- console.log('No test files found');
79
- console.log('Put your tests in \'test\' directory in *.test.mo files');
80
- return;
81
- }
82
- reporter.addFiles(files);
83
- // console.log('Test files:');
84
- // for (let file of files) {
85
- // console.log(chalk.gray(`• ${absToRel(file)}`));
86
- // }
87
- // console.log('='.repeat(50));
88
- // let failed = 0;
89
- // let passed = 0;
90
- // let skipped = 0;
91
- let sourcesArr = await sources();
92
- if (!mocPath) {
93
- mocPath = execSync('dfx cache show').toString().trim() + '/moc';
94
- }
95
- let wasmDir = `${getRootDir()}/.mops/.test/`;
96
- fs.mkdirSync(wasmDir, { recursive: true });
97
- await parallel(os.cpus().length, files, async (file) => {
98
- let mmf = new MMF1('store');
99
- let wasiMode = fs.readFileSync(file, 'utf8').startsWith('// @testmode wasi');
100
- let promise = new Promise((resolve) => {
101
- if (!mocPath) {
102
- mocPath = 'moc';
103
- }
104
- let mocArgs = ['--hide-warnings', '--error-detail=2', ...sourcesArr.join(' ').split(' '), file].filter(x => x);
105
- // build and run wasm
106
- if (wasiMode) {
107
- let wasmFile = `${path.join(wasmDir, path.parse(file).name)}.wasm`;
108
- // build
109
- let buildProc = spawn(mocPath, [`-o=${wasmFile}`, '-wasi-system-api', ...mocArgs]);
110
- pipeMMF(buildProc, mmf).then(async () => {
111
- if (mmf.failed > 0) {
112
- return;
113
- }
114
- // run
115
- let proc = spawn('wasmtime', [wasmFile]);
116
- await pipeMMF(proc, mmf);
117
- }).finally(() => {
118
- fs.rmSync(wasmFile, { force: true });
119
- }).then(resolve);
120
- }
121
- // interpret
122
- else {
123
- let proc = spawn(mocPath, ['-r', '-ref-system-api', ...mocArgs]);
124
- pipeMMF(proc, mmf).then(resolve);
125
- }
126
- });
127
- reporter.addRun(file, mmf, promise, wasiMode);
128
- await promise;
129
- });
130
- fs.rmSync(wasmDir, { recursive: true, force: true });
131
- return reporter.done();
132
- }
133
- function pipeMMF(proc, mmf) {
134
- return new Promise((resolve) => {
135
- // stdout
136
- proc.stdout.on('data', (data) => {
137
- for (let line of data.toString().split('\n')) {
138
- line = line.trim();
139
- if (line) {
140
- mmf.parseLine(line);
141
- }
142
- }
143
- });
144
- // stderr
145
- proc.stderr.on('data', (data) => {
146
- let text = data.toString().trim();
147
- let failedLine = '';
148
- text = text.replace(/([\w+._/-]+):(\d+).(\d+)(-\d+.\d+)/g, (_m0, m1, m2, m3) => {
149
- // change absolute file path to relative
150
- // change :line:col-line:col to :line:col to work in vscode
151
- let res = `${absToRel(m1)}:${m2}:${m3}`;
152
- if (!fs.existsSync(m1)) {
153
- return res;
154
- }
155
- // show failed line
156
- let content = fs.readFileSync(m1);
157
- let lines = content.toString().split('\n') || [];
158
- failedLine += chalk.dim `\n ...`;
159
- let lineBefore = lines[+m2 - 2];
160
- if (lineBefore) {
161
- failedLine += chalk.dim `\n ${+m2 - 1}\t| ${lineBefore.replaceAll('\t', ' ')}`;
162
- }
163
- failedLine += `\n${chalk.redBright `->`} ${m2}\t| ${lines[+m2 - 1]?.replaceAll('\t', ' ')}`;
164
- if (lines.length > +m2) {
165
- failedLine += chalk.dim `\n ${+m2 + 1}\t| ${lines[+m2]?.replaceAll('\t', ' ')}`;
166
- }
167
- failedLine += chalk.dim `\n ...`;
168
- return res;
169
- });
170
- if (failedLine) {
171
- text += failedLine;
172
- }
173
- mmf.fail(text);
174
- });
175
- // exit
176
- proc.on('close', (code) => {
177
- if (code === 0) {
178
- mmf.pass();
179
- }
180
- else if (code !== 1) {
181
- mmf.fail(`unknown exit code: ${code}`);
182
- }
183
- resolve();
184
- });
185
- });
186
- }
@@ -1,24 +0,0 @@
1
- type anon_class_10_1 =
2
- service {
3
- getStats: () -> (BenchResult) query;
4
- init: () -> (BenchSchema);
5
- runCellQuery: (nat, nat) -> (BenchResult) query;
6
- runCellUpdate: (nat, nat) -> (BenchResult);
7
- };
8
- type BenchSchema =
9
- record {
10
- cols: vec text;
11
- description: text;
12
- name: text;
13
- rows: vec text;
14
- };
15
- type BenchResult =
16
- record {
17
- instructions: int;
18
- rts_collector_instructions: int;
19
- rts_heap_size: int;
20
- rts_memory_size: int;
21
- rts_mutator_instructions: int;
22
- rts_total_allocation: int;
23
- };
24
- service : () -> anon_class_10_1