@rhost/testkit 1.4.1 → 1.5.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/dist/cli/index.js +15 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +107 -19
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/lint.d.ts +2 -0
- package/dist/cli/lint.d.ts.map +1 -0
- package/dist/cli/lint.js +163 -0
- package/dist/cli/lint.js.map +1 -0
- package/dist/cli/mush-format.d.ts +2 -0
- package/dist/cli/mush-format.d.ts.map +1 -0
- package/dist/cli/mush-format.js +232 -0
- package/dist/cli/mush-format.js.map +1 -0
- package/dist/client.d.ts +43 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +78 -5
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/offline/document.d.ts +8 -0
- package/dist/offline/document.d.ts.map +1 -0
- package/dist/offline/document.js +124 -0
- package/dist/offline/document.js.map +1 -0
- package/dist/offline/expect.d.ts +27 -0
- package/dist/offline/expect.d.ts.map +1 -0
- package/dist/offline/expect.js +90 -0
- package/dist/offline/expect.js.map +1 -0
- package/dist/offline/index.d.ts +5 -0
- package/dist/offline/index.d.ts.map +1 -0
- package/dist/offline/index.js +14 -0
- package/dist/offline/index.js.map +1 -0
- package/dist/offline/mock-client.d.ts +19 -0
- package/dist/offline/mock-client.d.ts.map +1 -0
- package/dist/offline/mock-client.js +36 -0
- package/dist/offline/mock-client.js.map +1 -0
- package/dist/offline/mock-world.d.ts +30 -0
- package/dist/offline/mock-world.d.ts.map +1 -0
- package/dist/offline/mock-world.js +64 -0
- package/dist/offline/mock-world.js.map +1 -0
- package/dist/offline/reduced-expect.d.ts +38 -0
- package/dist/offline/reduced-expect.d.ts.map +1 -0
- package/dist/offline/reduced-expect.js +61 -0
- package/dist/offline/reduced-expect.js.map +1 -0
- package/dist/offline/runner.d.ts +13 -0
- package/dist/offline/runner.d.ts.map +1 -0
- package/dist/offline/runner.js +174 -0
- package/dist/offline/runner.js.map +1 -0
- package/dist/offline/types.d.ts +78 -0
- package/dist/offline/types.d.ts.map +1 -0
- package/dist/offline/types.js +3 -0
- package/dist/offline/types.js.map +1 -0
- package/dist/reporter.d.ts +3 -1
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +20 -0
- package/dist/reporter.js.map +1 -1
- package/dist/runner.d.ts +39 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +82 -15
- package/dist/runner.js.map +1 -1
- package/dist/validator/mush-format.d.ts +43 -0
- package/dist/validator/mush-format.d.ts.map +1 -0
- package/dist/validator/mush-format.js +484 -0
- package/dist/validator/mush-format.js.map +1 -0
- package/dist/validator/mush-lint.d.ts +22 -0
- package/dist/validator/mush-lint.d.ts.map +1 -0
- package/dist/validator/mush-lint.js +590 -0
- package/dist/validator/mush-lint.js.map +1 -0
- package/package.json +10 -2
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OfflineRunner = void 0;
|
|
4
|
+
const document_1 = require("./document");
|
|
5
|
+
const expect_1 = require("./expect");
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Context builder
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
function makeTestContext() {
|
|
10
|
+
return {
|
|
11
|
+
parse: (source, filename) => (0, document_1.parseDocument)(source, filename),
|
|
12
|
+
expect: (doc) => new expect_1.OfflineExpect(doc),
|
|
13
|
+
loadFile: (filePath) => (0, document_1.parseDocumentFile)(filePath),
|
|
14
|
+
loadGlob: (pattern, cwd) => (0, document_1.loadGlob)(pattern, cwd),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function makeSuiteContext(suite) {
|
|
18
|
+
function makeIt(mode) {
|
|
19
|
+
return (name, fn) => suite.children.push({ kind: 'test', name, fn, mode });
|
|
20
|
+
}
|
|
21
|
+
function makeDescribe(mode) {
|
|
22
|
+
return (name, fn) => {
|
|
23
|
+
const child = { kind: 'suite', name, children: [], beforeAll: [], afterAll: [], beforeEach: [], afterEach: [], mode };
|
|
24
|
+
suite.children.push(child);
|
|
25
|
+
fn(makeSuiteContext(child));
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const it = makeIt('normal');
|
|
29
|
+
it.skip = makeIt('skip');
|
|
30
|
+
it.only = makeIt('only');
|
|
31
|
+
const test = makeIt('normal');
|
|
32
|
+
test.skip = makeIt('skip');
|
|
33
|
+
test.only = makeIt('only');
|
|
34
|
+
const describe = makeDescribe('normal');
|
|
35
|
+
describe.skip = makeDescribe('skip');
|
|
36
|
+
describe.only = makeDescribe('only');
|
|
37
|
+
return {
|
|
38
|
+
it,
|
|
39
|
+
test,
|
|
40
|
+
describe,
|
|
41
|
+
beforeAll: fn => suite.beforeAll.push(fn),
|
|
42
|
+
afterAll: fn => suite.afterAll.push(fn),
|
|
43
|
+
beforeEach: fn => suite.beforeEach.push(fn),
|
|
44
|
+
afterEach: fn => suite.afterEach.push(fn),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// OfflineRunner
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
class OfflineRunner {
|
|
51
|
+
constructor() {
|
|
52
|
+
this.root = {
|
|
53
|
+
kind: 'suite', name: '<root>', children: [],
|
|
54
|
+
beforeAll: [], afterAll: [], beforeEach: [], afterEach: [], mode: 'normal',
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
describe(name, fn) {
|
|
58
|
+
const suite = { kind: 'suite', name, children: [], beforeAll: [], afterAll: [], beforeEach: [], afterEach: [], mode: 'normal' };
|
|
59
|
+
this.root.children.push(suite);
|
|
60
|
+
fn(makeSuiteContext(suite));
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
run(options = {}) {
|
|
64
|
+
const useJest = options.useJest ?? (typeof describe !== 'undefined' && typeof it !== 'undefined');
|
|
65
|
+
if (useJest) {
|
|
66
|
+
return this._runJest(this.root, options);
|
|
67
|
+
}
|
|
68
|
+
return this._runStandalone(this.root, options);
|
|
69
|
+
}
|
|
70
|
+
// -------------------------------------------------------------------------
|
|
71
|
+
// Jest delegation
|
|
72
|
+
// -------------------------------------------------------------------------
|
|
73
|
+
_runJest(root, _opts) {
|
|
74
|
+
// When Jest globals are present we register describe/it blocks and let
|
|
75
|
+
// Jest drive execution. Return a placeholder result — Jest owns reporting.
|
|
76
|
+
for (const child of root.children) {
|
|
77
|
+
this._registerJestNode(child);
|
|
78
|
+
}
|
|
79
|
+
return { passed: 0, failed: 0, skipped: 0, total: 0, duration: 0, failures: [] };
|
|
80
|
+
}
|
|
81
|
+
_registerJestNode(node) {
|
|
82
|
+
if (node.kind === 'test') {
|
|
83
|
+
const jestIt = node.mode === 'skip' ? it.skip : node.mode === 'only' ? it.only : it;
|
|
84
|
+
jestIt(node.name, async () => {
|
|
85
|
+
await node.fn(makeTestContext());
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
const jestDescribe = node.mode === 'skip' ? describe.skip : node.mode === 'only' ? describe.only : describe;
|
|
90
|
+
jestDescribe(node.name, () => {
|
|
91
|
+
if (node.beforeAll.length)
|
|
92
|
+
beforeAll(async () => { for (const h of node.beforeAll)
|
|
93
|
+
await h(); });
|
|
94
|
+
if (node.afterAll.length)
|
|
95
|
+
afterAll(async () => { for (const h of node.afterAll)
|
|
96
|
+
await h(); });
|
|
97
|
+
if (node.beforeEach.length)
|
|
98
|
+
beforeEach(async () => { for (const h of node.beforeEach)
|
|
99
|
+
await h(); });
|
|
100
|
+
if (node.afterEach.length)
|
|
101
|
+
afterEach(async () => { for (const h of node.afterEach)
|
|
102
|
+
await h(); });
|
|
103
|
+
for (const child of node.children)
|
|
104
|
+
this._registerJestNode(child);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// -------------------------------------------------------------------------
|
|
109
|
+
// Standalone executor
|
|
110
|
+
// -------------------------------------------------------------------------
|
|
111
|
+
_runStandalone(root, opts) {
|
|
112
|
+
const result = { passed: 0, failed: 0, skipped: 0, total: 0, duration: 0, failures: [] };
|
|
113
|
+
const start = Date.now();
|
|
114
|
+
this._execSuite(root, [], result, opts);
|
|
115
|
+
result.duration = Date.now() - start;
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
async _execSuite(suite, ancestors, result, opts) {
|
|
119
|
+
if (suite.mode === 'skip') {
|
|
120
|
+
const count = this._countTests(suite);
|
|
121
|
+
result.skipped += count;
|
|
122
|
+
result.total += count;
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const path = suite.name === '<root>' ? ancestors : [...ancestors, suite.name];
|
|
126
|
+
for (const h of suite.beforeAll)
|
|
127
|
+
await h();
|
|
128
|
+
for (const child of suite.children) {
|
|
129
|
+
if (child.kind === 'suite') {
|
|
130
|
+
await this._execSuite(child, path, result, opts);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
await this._execTest(child, path, suite, result, opts);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
for (const h of suite.afterAll)
|
|
137
|
+
await h();
|
|
138
|
+
}
|
|
139
|
+
async _execTest(node, suitePath, suite, result, opts) {
|
|
140
|
+
result.total++;
|
|
141
|
+
if (node.mode === 'skip') {
|
|
142
|
+
result.skipped++;
|
|
143
|
+
if (opts.verbose)
|
|
144
|
+
console.log(` SKIP ${[...suitePath, node.name].join(' > ')}`);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
for (const h of suite.beforeEach)
|
|
148
|
+
await h();
|
|
149
|
+
try {
|
|
150
|
+
await node.fn(makeTestContext());
|
|
151
|
+
result.passed++;
|
|
152
|
+
if (opts.verbose)
|
|
153
|
+
console.log(` PASS ${[...suitePath, node.name].join(' > ')}`);
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
result.failed++;
|
|
157
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
158
|
+
result.failures.push({ suite: suitePath.join(' > '), test: node.name, error });
|
|
159
|
+
if (opts.verbose)
|
|
160
|
+
console.error(` FAIL ${[...suitePath, node.name].join(' > ')}\n ${error.message}`);
|
|
161
|
+
}
|
|
162
|
+
for (const h of suite.afterEach)
|
|
163
|
+
await h();
|
|
164
|
+
}
|
|
165
|
+
_countTests(suite) {
|
|
166
|
+
let n = 0;
|
|
167
|
+
for (const child of suite.children) {
|
|
168
|
+
n += child.kind === 'test' ? 1 : this._countTests(child);
|
|
169
|
+
}
|
|
170
|
+
return n;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
exports.OfflineRunner = OfflineRunner;
|
|
174
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/offline/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { ValidationResult, Diagnostic } from '../validator/types';
|
|
2
|
+
import type { LintResult, LintDiag } from '../validator/mush-lint';
|
|
3
|
+
export type { ValidationResult, Diagnostic, LintResult, LintDiag };
|
|
4
|
+
export interface OfflineAttr {
|
|
5
|
+
name: string;
|
|
6
|
+
object: string;
|
|
7
|
+
value: string;
|
|
8
|
+
line: number;
|
|
9
|
+
}
|
|
10
|
+
export interface OfflineDocument {
|
|
11
|
+
source: string;
|
|
12
|
+
filename: string;
|
|
13
|
+
attrs: OfflineAttr[];
|
|
14
|
+
validationResult: ValidationResult;
|
|
15
|
+
lintResult: LintResult;
|
|
16
|
+
/** Shorthand: start an assertion chain directly on this document. */
|
|
17
|
+
readonly expect: OfflineExpectChain;
|
|
18
|
+
}
|
|
19
|
+
export interface OfflineExpectChain {
|
|
20
|
+
not: OfflineExpectChain;
|
|
21
|
+
noSyntaxErrors(): OfflineExpectChain;
|
|
22
|
+
noLintErrors(): OfflineExpectChain;
|
|
23
|
+
noLintWarnings(): OfflineExpectChain;
|
|
24
|
+
hasFunction(name: string): OfflineExpectChain;
|
|
25
|
+
hasAttribute(name: string): OfflineExpectChain;
|
|
26
|
+
attributeCount(n: number): OfflineExpectChain;
|
|
27
|
+
noUndefinedFunctions(): OfflineExpectChain;
|
|
28
|
+
noClobber(): OfflineExpectChain;
|
|
29
|
+
isPortable(): OfflineExpectChain;
|
|
30
|
+
hasDiagnostic(code: string): OfflineExpectChain;
|
|
31
|
+
maxAttributeLength(chars?: number): OfflineExpectChain;
|
|
32
|
+
}
|
|
33
|
+
export interface OfflineTestContext {
|
|
34
|
+
parse(source: string, filename?: string): OfflineDocument;
|
|
35
|
+
expect(doc: OfflineDocument): OfflineExpectChain;
|
|
36
|
+
loadFile(filePath: string): OfflineDocument;
|
|
37
|
+
loadGlob(pattern: string, cwd?: string): OfflineDocument[];
|
|
38
|
+
}
|
|
39
|
+
export interface OfflineSuiteContext {
|
|
40
|
+
it: OfflineItFn & {
|
|
41
|
+
skip: OfflineItFn;
|
|
42
|
+
only: OfflineItFn;
|
|
43
|
+
};
|
|
44
|
+
test: OfflineItFn & {
|
|
45
|
+
skip: OfflineItFn;
|
|
46
|
+
only: OfflineItFn;
|
|
47
|
+
};
|
|
48
|
+
describe: OfflineDescribeFn & {
|
|
49
|
+
skip: OfflineDescribeFn;
|
|
50
|
+
only: OfflineDescribeFn;
|
|
51
|
+
};
|
|
52
|
+
beforeAll(fn: OfflineHookFn): void;
|
|
53
|
+
afterAll(fn: OfflineHookFn): void;
|
|
54
|
+
beforeEach(fn: OfflineHookFn): void;
|
|
55
|
+
afterEach(fn: OfflineHookFn): void;
|
|
56
|
+
}
|
|
57
|
+
export type OfflineItFn = (name: string, fn: OfflineTestFn) => void;
|
|
58
|
+
export type OfflineDescribeFn = (name: string, fn: (ctx: OfflineSuiteContext) => void) => void;
|
|
59
|
+
export type OfflineTestFn = (ctx: OfflineTestContext) => void | Promise<void>;
|
|
60
|
+
export type OfflineHookFn = () => void | Promise<void>;
|
|
61
|
+
export interface OfflineRunOptions {
|
|
62
|
+
verbose?: boolean;
|
|
63
|
+
/** Delegate to Jest's describe/it when Jest globals are detected */
|
|
64
|
+
useJest?: boolean;
|
|
65
|
+
}
|
|
66
|
+
export interface OfflineRunResult {
|
|
67
|
+
passed: number;
|
|
68
|
+
failed: number;
|
|
69
|
+
skipped: number;
|
|
70
|
+
total: number;
|
|
71
|
+
duration: number;
|
|
72
|
+
failures: Array<{
|
|
73
|
+
suite: string;
|
|
74
|
+
test: string;
|
|
75
|
+
error: Error;
|
|
76
|
+
}>;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/offline/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/offline/types.ts"],"names":[],"mappings":""}
|
package/dist/reporter.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RunResult } from './runner';
|
|
1
|
+
import type { RunResult } from './runner';
|
|
2
2
|
import { SnapshotStats } from './snapshots';
|
|
3
3
|
export declare class Reporter {
|
|
4
4
|
private readonly verbose;
|
|
@@ -7,6 +7,8 @@ export declare class Reporter {
|
|
|
7
7
|
testPass(name: string, ms: number, depth: number): void;
|
|
8
8
|
testFail(name: string, ms: number, depth: number, error: Error): void;
|
|
9
9
|
testSkip(name: string, depth: number): void;
|
|
10
|
+
testOfflineSkip(name: string, depth: number, behavioralSkips: number): void;
|
|
11
|
+
offlineBanner(reason?: string): void;
|
|
10
12
|
summary(result: RunResult): void;
|
|
11
13
|
snapshotSummary(stats: SnapshotStats): void;
|
|
12
14
|
}
|
package/dist/reporter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuB5C,qBAAa,QAAQ;IACL,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,OAAO;IAE7C,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAM7C,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAMvD,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAWrE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAM3C,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAO3E,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAOpC,OAAO,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAgBhC,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;CAoB9C"}
|
package/dist/reporter.js
CHANGED
|
@@ -50,6 +50,20 @@ class Reporter {
|
|
|
50
50
|
const indent = ' '.repeat(depth + 1);
|
|
51
51
|
process.stdout.write(`${indent}${yellow('○')} ${gray(name)}\n`);
|
|
52
52
|
}
|
|
53
|
+
testOfflineSkip(name, depth, behavioralSkips) {
|
|
54
|
+
if (!this.verbose)
|
|
55
|
+
return;
|
|
56
|
+
const indent = ' '.repeat(depth + 1);
|
|
57
|
+
const skipped = behavioralSkips > 0 ? gray(` (${behavioralSkips} behavioral skipped)`) : '';
|
|
58
|
+
process.stdout.write(`${indent}${cyan('⊘')} ${name}${skipped}\n`);
|
|
59
|
+
}
|
|
60
|
+
offlineBanner(reason) {
|
|
61
|
+
if (!this.verbose)
|
|
62
|
+
return;
|
|
63
|
+
const msg = reason ? ` — ${reason}` : '';
|
|
64
|
+
process.stdout.write(`\n${cyan('⚡')} ${bold('Offline mode')}${gray(msg)}\n`);
|
|
65
|
+
process.stdout.write(`${gray(' Syntax and lint checks run. Behavioral assertions skipped.')}\n`);
|
|
66
|
+
}
|
|
53
67
|
summary(result) {
|
|
54
68
|
if (!this.verbose)
|
|
55
69
|
return;
|
|
@@ -60,8 +74,14 @@ class Reporter {
|
|
|
60
74
|
parts.push(red(`${result.failed} failed`));
|
|
61
75
|
if (result.skipped > 0)
|
|
62
76
|
parts.push(yellow(`${result.skipped} skipped`));
|
|
77
|
+
if (result.offlineSkipped > 0)
|
|
78
|
+
parts.push(cyan(`${result.offlineSkipped} syntax-checked`));
|
|
63
79
|
parts.push(`${result.total} total`);
|
|
64
80
|
process.stdout.write(`\nTests: ${parts.join(', ')} ${gray(`(${result.duration}ms)`)}\n`);
|
|
81
|
+
if (result.mode === 'offline') {
|
|
82
|
+
const skipped = result.behavioralSkipped ?? 0;
|
|
83
|
+
process.stdout.write(`${cyan('⚡')} ${gray(`Offline — ${skipped} behavioral assertion${skipped !== 1 ? 's' : ''} skipped (needs server)`)}\n`);
|
|
84
|
+
}
|
|
65
85
|
this.snapshotSummary(result.snapshots);
|
|
66
86
|
}
|
|
67
87
|
snapshotSummary(stats) {
|
package/dist/reporter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
|
package/dist/runner.d.ts
CHANGED
|
@@ -7,6 +7,12 @@ export interface RunResult {
|
|
|
7
7
|
passed: number;
|
|
8
8
|
failed: number;
|
|
9
9
|
skipped: number;
|
|
10
|
+
/** Tests that ran in offline mode (syntax-checked but behavioral assertions skipped). */
|
|
11
|
+
offlineSkipped: number;
|
|
12
|
+
/** Total behavioral assertions skipped across all offline tests. */
|
|
13
|
+
behavioralSkipped: number;
|
|
14
|
+
/** Whether this run connected to a server or ran entirely offline. */
|
|
15
|
+
mode: 'online' | 'offline';
|
|
10
16
|
total: number;
|
|
11
17
|
duration: number;
|
|
12
18
|
failures: Array<{
|
|
@@ -18,6 +24,23 @@ export interface RunResult {
|
|
|
18
24
|
}
|
|
19
25
|
export interface TestContext {
|
|
20
26
|
expect(expression: string): RhostExpect;
|
|
27
|
+
/**
|
|
28
|
+
* Evaluate N expressions in one pipelined batch and assert on each result.
|
|
29
|
+
*
|
|
30
|
+
* Pass `[expression, expected]` pairs. A string `expected` uses exact
|
|
31
|
+
* match (`.toBe`); a RegExp uses `.test()` (equivalent to `.toMatch`).
|
|
32
|
+
* All failures are collected before throwing, so you see every broken
|
|
33
|
+
* assertion at once rather than stopping at the first.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* await expectAll([
|
|
37
|
+
* [`u(${cg}/F.IS.STAT,int)`, '1'],
|
|
38
|
+
* [`u(${cg}/F.IS.STAT,INT)`, '1'],
|
|
39
|
+
* [`u(${cg}/F.IS.STAT,foo)`, '0'],
|
|
40
|
+
* [`u(${cg}/F.VALIDATE,${p},int,0)`, /minimum/],
|
|
41
|
+
* ]);
|
|
42
|
+
*/
|
|
43
|
+
expectAll(cases: Array<[string, string | RegExp]>): Promise<void>;
|
|
21
44
|
client: RhostClient;
|
|
22
45
|
world: RhostWorld;
|
|
23
46
|
/**
|
|
@@ -122,6 +145,22 @@ export interface RunnerOptions extends RhostClientOptions {
|
|
|
122
145
|
* Default: false
|
|
123
146
|
*/
|
|
124
147
|
updateSnapshots?: boolean;
|
|
148
|
+
/**
|
|
149
|
+
* Run tests in offline mode — no server connection required.
|
|
150
|
+
*
|
|
151
|
+
* In offline mode:
|
|
152
|
+
* - `world.set()` validates softcode syntax and lint rules immediately,
|
|
153
|
+
* failing the test if errors are found.
|
|
154
|
+
* - `expect(expr).toBe(...)` and all other behavioral matchers are silently
|
|
155
|
+
* skipped — they can't run without a live server.
|
|
156
|
+
* - Syntax errors in `expect()` expressions still fail the test.
|
|
157
|
+
*
|
|
158
|
+
* Also activated by the `RHOST_OFFLINE=1` environment variable.
|
|
159
|
+
*
|
|
160
|
+
* Set to `'auto'` to try connecting first and silently fall back to
|
|
161
|
+
* offline mode if the server is unreachable.
|
|
162
|
+
*/
|
|
163
|
+
offline?: boolean | 'auto';
|
|
125
164
|
}
|
|
126
165
|
/**
|
|
127
166
|
* Jest-style test runner for RhostMUSH softcode.
|
package/dist/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAmB,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/runner.js
CHANGED
|
@@ -42,6 +42,9 @@ const expect_1 = require("./expect");
|
|
|
42
42
|
const world_1 = require("./world");
|
|
43
43
|
const reporter_1 = require("./reporter");
|
|
44
44
|
const snapshots_1 = require("./snapshots");
|
|
45
|
+
const mock_client_1 = require("./offline/mock-client");
|
|
46
|
+
const mock_world_1 = require("./offline/mock-world");
|
|
47
|
+
const reduced_expect_1 = require("./offline/reduced-expect");
|
|
45
48
|
// ---------------------------------------------------------------------------
|
|
46
49
|
// RhostRunner
|
|
47
50
|
// ---------------------------------------------------------------------------
|
|
@@ -85,12 +88,38 @@ class RhostRunner {
|
|
|
85
88
|
process.env['RHOST_UPDATE_SNAPSHOTS'] === '1';
|
|
86
89
|
const snapshotFile = this.resolveSnapshotFile(options);
|
|
87
90
|
const snapshots = new snapshots_1.SnapshotManager(snapshotFile, updateMode);
|
|
88
|
-
const
|
|
89
|
-
await client.connect();
|
|
90
|
-
await client.login(options.username, options.password);
|
|
91
|
+
const offlineOpt = options.offline ?? (process.env['RHOST_OFFLINE'] === '1' ? true : undefined);
|
|
91
92
|
const reporter = new reporter_1.Reporter(verbose);
|
|
93
|
+
let isOffline = offlineOpt === true;
|
|
94
|
+
let client;
|
|
95
|
+
if (offlineOpt === 'auto') {
|
|
96
|
+
try {
|
|
97
|
+
client = new client_1.RhostClient(options);
|
|
98
|
+
await client.connect();
|
|
99
|
+
await client.login(options.username, options.password);
|
|
100
|
+
isOffline = false;
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
isOffline = true;
|
|
104
|
+
client = new mock_client_1.MockRhostClient();
|
|
105
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
106
|
+
reporter.offlineBanner(`server unreachable — ${reason}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if (isOffline) {
|
|
110
|
+
client = new mock_client_1.MockRhostClient();
|
|
111
|
+
reporter.offlineBanner();
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
client = new client_1.RhostClient(options);
|
|
115
|
+
await client.connect();
|
|
116
|
+
await client.login(options.username, options.password);
|
|
117
|
+
}
|
|
92
118
|
const result = {
|
|
93
|
-
passed: 0, failed: 0, skipped: 0,
|
|
119
|
+
passed: 0, failed: 0, skipped: 0,
|
|
120
|
+
offlineSkipped: 0, behavioralSkipped: 0,
|
|
121
|
+
mode: isOffline ? 'offline' : 'online',
|
|
122
|
+
total: 0, duration: 0,
|
|
94
123
|
failures: [],
|
|
95
124
|
snapshots: { matched: 0, written: 0, updated: 0, obsolete: 0 },
|
|
96
125
|
};
|
|
@@ -103,12 +132,13 @@ class RhostRunner {
|
|
|
103
132
|
children: this.topLevel,
|
|
104
133
|
beforeAll: [], afterAll: [], beforeEach: [], afterEach: [],
|
|
105
134
|
};
|
|
106
|
-
await this._runSuite(root, client, reporter, result, [], 0, [], snapshots);
|
|
135
|
+
await this._runSuite(root, client, reporter, result, [], 0, [], snapshots, isOffline);
|
|
107
136
|
result.duration = Date.now() - start;
|
|
108
137
|
snapshots.save();
|
|
109
138
|
result.snapshots = snapshots.stats();
|
|
110
139
|
reporter.summary(result);
|
|
111
|
-
|
|
140
|
+
if (!isOffline)
|
|
141
|
+
await client.disconnect();
|
|
112
142
|
return result;
|
|
113
143
|
}
|
|
114
144
|
// -------------------------------------------------------------------------
|
|
@@ -179,7 +209,7 @@ class RhostRunner {
|
|
|
179
209
|
// -------------------------------------------------------------------------
|
|
180
210
|
// Internal: executing the tree
|
|
181
211
|
// -------------------------------------------------------------------------
|
|
182
|
-
async _runSuite(suite, client, reporter, result, inheritedBeforeEach, depth, suitePath, snapshots) {
|
|
212
|
+
async _runSuite(suite, client, reporter, result, inheritedBeforeEach, depth, suitePath, snapshots, isOffline = false) {
|
|
183
213
|
// Skip entire suite if marked skip
|
|
184
214
|
if (suite.mode === 'skip') {
|
|
185
215
|
this._countSkipped(suite, result, reporter, depth);
|
|
@@ -194,7 +224,7 @@ class RhostRunner {
|
|
|
194
224
|
// Build the path for this suite's children
|
|
195
225
|
const childPath = suite.name ? [...suitePath, suite.name] : suitePath;
|
|
196
226
|
// Run suite-level beforeAll hooks — if one throws, count all suite tests as failures
|
|
197
|
-
const hookCtx = { client, world: new world_1.RhostWorld(client) };
|
|
227
|
+
const hookCtx = { client, world: isOffline ? new mock_world_1.OfflineWorldProxy(client) : new world_1.RhostWorld(client) };
|
|
198
228
|
for (const hook of suite.beforeAll) {
|
|
199
229
|
try {
|
|
200
230
|
await hook(hookCtx);
|
|
@@ -211,11 +241,11 @@ class RhostRunner {
|
|
|
211
241
|
const childWithMode = effectiveMode !== child.mode
|
|
212
242
|
? { ...child, mode: effectiveMode }
|
|
213
243
|
: child;
|
|
214
|
-
await this._runSuite(childWithMode, client, reporter, result, combinedBeforeEach, depth + (suite.name ? 1 : 0), childPath, snapshots);
|
|
244
|
+
await this._runSuite(childWithMode, client, reporter, result, combinedBeforeEach, depth + (suite.name ? 1 : 0), childPath, snapshots, isOffline);
|
|
215
245
|
}
|
|
216
246
|
else {
|
|
217
247
|
const skip = !activeChildren.includes(child) || child.mode === 'skip';
|
|
218
|
-
await this._runTest(child, skip, client, reporter, result, combinedBeforeEach, suite.afterEach, childPath, depth + (suite.name ? 1 : 0), snapshots);
|
|
248
|
+
await this._runTest(child, skip, client, reporter, result, combinedBeforeEach, suite.afterEach, childPath, depth + (suite.name ? 1 : 0), snapshots, isOffline);
|
|
219
249
|
}
|
|
220
250
|
}
|
|
221
251
|
// Run suite-level afterAll hooks
|
|
@@ -223,7 +253,7 @@ class RhostRunner {
|
|
|
223
253
|
await hook(hookCtx);
|
|
224
254
|
}
|
|
225
255
|
}
|
|
226
|
-
async _runTest(test, skip, client, reporter, result, beforeEachHooks, afterEachHooks, suitePath, depth, snapshots) {
|
|
256
|
+
async _runTest(test, skip, client, reporter, result, beforeEachHooks, afterEachHooks, suitePath, depth, snapshots, isOffline = false) {
|
|
227
257
|
result.total++;
|
|
228
258
|
if (skip || test.mode === 'skip') {
|
|
229
259
|
result.skipped++;
|
|
@@ -235,16 +265,46 @@ class RhostRunner {
|
|
|
235
265
|
const suiteName = suitePath[suitePath.length - 1] ?? '';
|
|
236
266
|
// Reset snapshot counter for this test
|
|
237
267
|
snapshots.resetCounter(testKey);
|
|
238
|
-
const world =
|
|
268
|
+
const world = isOffline
|
|
269
|
+
? new mock_world_1.OfflineWorldProxy(client)
|
|
270
|
+
: new world_1.RhostWorld(client);
|
|
239
271
|
const hookCtx = { client, world };
|
|
240
272
|
const snapshotCtx = {
|
|
241
273
|
manager: snapshots,
|
|
242
274
|
testName: testKey,
|
|
243
275
|
};
|
|
276
|
+
const counter = { behavioralSkips: 0 };
|
|
244
277
|
const testCtx = {
|
|
245
278
|
client,
|
|
246
279
|
world,
|
|
247
|
-
expect: (expr) =>
|
|
280
|
+
expect: (expr) => isOffline
|
|
281
|
+
? new reduced_expect_1.ReducedExpect(expr, false, snapshotCtx, counter)
|
|
282
|
+
: new expect_1.RhostExpect(client, expr, false, snapshotCtx),
|
|
283
|
+
expectAll: async (cases) => {
|
|
284
|
+
if (isOffline) {
|
|
285
|
+
for (const [expr] of cases) {
|
|
286
|
+
await new reduced_expect_1.ReducedExpect(expr, false, snapshotCtx, counter).toBe('');
|
|
287
|
+
}
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const results = await client.evalAll(cases.map(c => c[0]));
|
|
291
|
+
const failures = [];
|
|
292
|
+
for (let i = 0; i < cases.length; i++) {
|
|
293
|
+
const actual = results[i].replace(/[\r\n]+$/, '');
|
|
294
|
+
const expected = cases[i][1];
|
|
295
|
+
const pass = typeof expected === 'string'
|
|
296
|
+
? actual === expected
|
|
297
|
+
: expected.test(actual);
|
|
298
|
+
if (!pass) {
|
|
299
|
+
failures.push(` [${i}] expect(${JSON.stringify(cases[i][0])})\n` +
|
|
300
|
+
` Expected: ${expected instanceof RegExp ? expected : JSON.stringify(expected)}\n` +
|
|
301
|
+
` Received: ${JSON.stringify(actual)}`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (failures.length > 0) {
|
|
305
|
+
throw new Error(`expectAll: ${failures.length} of ${cases.length} failed:\n${failures.join('\n')}`);
|
|
306
|
+
}
|
|
307
|
+
},
|
|
248
308
|
preview: (input, opts) => client.preview(input, opts),
|
|
249
309
|
};
|
|
250
310
|
// Run inherited + suite beforeEach — if one throws, count as a test failure
|
|
@@ -269,8 +329,15 @@ class RhostRunner {
|
|
|
269
329
|
const timeoutMs = test.timeout ?? 15000;
|
|
270
330
|
await this._withTimeout(test.fn(testCtx), timeoutMs, test.name);
|
|
271
331
|
const ms = Date.now() - t0;
|
|
272
|
-
|
|
273
|
-
|
|
332
|
+
if (isOffline) {
|
|
333
|
+
result.offlineSkipped++;
|
|
334
|
+
result.behavioralSkipped += counter.behavioralSkips;
|
|
335
|
+
reporter.testOfflineSkip(test.name, depth, counter.behavioralSkips);
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
result.passed++;
|
|
339
|
+
reporter.testPass(test.name, ms, depth);
|
|
340
|
+
}
|
|
274
341
|
}
|
|
275
342
|
catch (err) {
|
|
276
343
|
const ms = Date.now() - t0;
|