@w-lfpup/jackrabbit 0.2.0 → 0.3.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/.github/workflows/browsers.json +55 -0
- package/.github/workflows/browsers.macos.json +51 -0
- package/.github/workflows/browsers.windows.json +19 -0
- package/.github/workflows/tests.yml +13 -0
- package/README.md +41 -1
- package/browser/dist/logger.js +43 -0
- package/browser/dist/mod.js +25 -0
- package/browser/dist/queue.js +27 -0
- package/browser/dist/runner.js +20 -0
- package/{cli → browser}/package.json +1 -1
- package/browser/src/logger.ts +57 -0
- package/browser/src/mod.ts +30 -0
- package/browser/src/runner.ts +22 -0
- package/browser/tsconfig.json +11 -0
- package/browser/tsconfig.tsbuildinfo +1 -0
- package/browsers.json +38 -0
- package/core/dist/jackrabbit_types.d.ts +61 -27
- package/core/dist/mod.d.ts +2 -2
- package/core/dist/mod.js +1 -1
- package/core/dist/run_steps.d.ts +2 -2
- package/core/dist/run_steps.js +83 -67
- package/core/src/jackrabbit_types.ts +72 -28
- package/core/src/mod.ts +2 -8
- package/core/src/run_steps.ts +111 -80
- package/examples/hello_world/goodbye_world.ts +1 -1
- package/examples/hello_world/hello_world.ts +1 -1
- package/nodejs/dist/logger.js +164 -0
- package/nodejs/dist/mod.js +33 -0
- package/nodejs/dist/results.js +145 -0
- package/nodejs/dist/results_str.js +147 -0
- package/nodejs/dist/runner.js +17 -0
- package/nodejs/src/logger.ts +200 -0
- package/nodejs/src/mod.ts +39 -0
- package/nodejs/src/results.ts +239 -0
- package/{nodejs_cli → nodejs}/tsconfig.json +2 -1
- package/nodejs/tsconfig.tsbuildinfo +1 -0
- package/package.json +6 -4
- package/tests/dist/mod.d.ts +14 -3
- package/tests/dist/mod.js +33 -15
- package/tests/dist/test_error.test.d.ts +9 -0
- package/tests/dist/test_error.test.js +25 -0
- package/tests/dist/test_errors.test.d.ts +9 -0
- package/tests/dist/test_errors.test.js +27 -0
- package/tests/dist/test_fail.test.js +0 -2
- package/tests/dist/test_logger.d.ts +3 -2
- package/tests/dist/test_logger.js +5 -1
- package/tests/dist/test_pass.test.js +0 -2
- package/tests/src/mod.ts +31 -15
- package/tests/src/test_error.test.ts +32 -0
- package/tests/src/test_logger.ts +6 -1
- package/tests/tsconfig.tsbuildinfo +1 -1
- package/tsconfig.json +3 -2
- package/webdriver/dist/config.js +56 -0
- package/webdriver/dist/eventbus.js +18 -0
- package/webdriver/dist/listeners.js +21 -0
- package/webdriver/dist/logger.js +200 -0
- package/webdriver/dist/mod.js +35 -0
- package/webdriver/dist/results.js +190 -0
- package/webdriver/dist/results_str.js +167 -0
- package/webdriver/dist/routes.js +162 -0
- package/webdriver/dist/routes2.js +163 -0
- package/webdriver/dist/test_hangar.js +20 -0
- package/webdriver/dist/webdriver.js +272 -0
- package/webdriver/package.json +8 -0
- package/webdriver/src/config.ts +89 -0
- package/webdriver/src/eventbus.ts +104 -0
- package/webdriver/src/logger.ts +247 -0
- package/webdriver/src/mod.ts +45 -0
- package/webdriver/src/results.ts +311 -0
- package/webdriver/src/routes.ts +198 -0
- package/webdriver/src/test_hangar.ts +25 -0
- package/webdriver/src/webdriver.ts +373 -0
- package/{cli → webdriver}/tsconfig.json +1 -0
- package/webdriver/tsconfig.tsbuildinfo +1 -0
- package/cli/dist/cli.d.ts +0 -3
- package/cli/dist/cli.js +0 -8
- package/cli/dist/cli_types.d.ts +0 -7
- package/cli/dist/cli_types.js +0 -1
- package/cli/dist/config.d.ts +0 -5
- package/cli/dist/config.js +0 -6
- package/cli/dist/importer.d.ts +0 -7
- package/cli/dist/importer.js +0 -16
- package/cli/dist/logger.d.ts +0 -7
- package/cli/dist/logger.js +0 -88
- package/cli/dist/mod.d.ts +0 -6
- package/cli/dist/mod.js +0 -4
- package/cli/src/cli.ts +0 -17
- package/cli/src/cli_types.ts +0 -9
- package/cli/src/config.ts +0 -9
- package/cli/src/importer.ts +0 -25
- package/cli/src/logger.ts +0 -126
- package/cli/src/mod.ts +0 -7
- package/cli/tsconfig.tsbuildinfo +0 -1
- package/nodejs_cli/dist/mod.d.ts +0 -2
- package/nodejs_cli/dist/mod.js +0 -20
- package/nodejs_cli/src/mod.ts +0 -25
- package/nodejs_cli/tsconfig.tsbuildinfo +0 -1
- /package/{nodejs_cli → nodejs}/package.json +0 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { getResultsAsString } from "./results.js";
|
|
2
|
+
export class Logger {
|
|
3
|
+
#results = {
|
|
4
|
+
startTime: 0,
|
|
5
|
+
fails: 0,
|
|
6
|
+
errors: 0,
|
|
7
|
+
expectedTests: 0,
|
|
8
|
+
endTime: 0,
|
|
9
|
+
testTime: 0,
|
|
10
|
+
expectedModules: 0,
|
|
11
|
+
expectedCollections: 0,
|
|
12
|
+
completedModules: 0,
|
|
13
|
+
completedCollections: 0,
|
|
14
|
+
completedTests: 0,
|
|
15
|
+
errorLogs: [],
|
|
16
|
+
collections: [],
|
|
17
|
+
};
|
|
18
|
+
get failed() {
|
|
19
|
+
return this.#results.fails !== 0;
|
|
20
|
+
}
|
|
21
|
+
get errored() {
|
|
22
|
+
return this.#results.errors !== 0;
|
|
23
|
+
}
|
|
24
|
+
get completed() {
|
|
25
|
+
return (0 < this.#results.expectedTests &&
|
|
26
|
+
this.#results.expectedTests === this.#results.completedTests);
|
|
27
|
+
}
|
|
28
|
+
get results() {
|
|
29
|
+
return getResultsAsString(this.#results);
|
|
30
|
+
}
|
|
31
|
+
log(action) {
|
|
32
|
+
if ("start_run" === action.type) {
|
|
33
|
+
this.#results.startTime = action.time;
|
|
34
|
+
this.#results.expectedCollections = action.expected_collection_count;
|
|
35
|
+
}
|
|
36
|
+
if ("end_run" === action.type) {
|
|
37
|
+
this.#results.endTime = action.time;
|
|
38
|
+
}
|
|
39
|
+
if ("run_error" === action.type) {
|
|
40
|
+
this.#results.errors += 1;
|
|
41
|
+
this.#results.errorLogs.push(action);
|
|
42
|
+
}
|
|
43
|
+
if ("start_collection" === action.type) {
|
|
44
|
+
this.#results.collections[action.collection_id] = {
|
|
45
|
+
completedModules: 0,
|
|
46
|
+
completedTests: 0,
|
|
47
|
+
errorLogs: [],
|
|
48
|
+
errors: 0,
|
|
49
|
+
expectedModules: action.expected_module_count,
|
|
50
|
+
expectedTests: 0,
|
|
51
|
+
fails: 0,
|
|
52
|
+
loggerAction: action,
|
|
53
|
+
modules: [],
|
|
54
|
+
};
|
|
55
|
+
this.#results.expectedModules += action.expected_module_count;
|
|
56
|
+
}
|
|
57
|
+
if ("end_collection" === action.type) {
|
|
58
|
+
let collection = this.#results.collections[action.collection_id];
|
|
59
|
+
if (!collection)
|
|
60
|
+
return;
|
|
61
|
+
this.#results.completedCollections += 1;
|
|
62
|
+
}
|
|
63
|
+
if ("collection_error" === action.type) {
|
|
64
|
+
let collection = this.#results.collections[action.collection_id];
|
|
65
|
+
if (!collection)
|
|
66
|
+
return;
|
|
67
|
+
this.#results.errors += 1;
|
|
68
|
+
collection.errors += 1;
|
|
69
|
+
collection.errorLogs.push(action);
|
|
70
|
+
}
|
|
71
|
+
if ("start_module" === action.type) {
|
|
72
|
+
let collection = this.#results.collections[action.collection_id];
|
|
73
|
+
if (!collection)
|
|
74
|
+
return;
|
|
75
|
+
collection.modules[action.module_id] = {
|
|
76
|
+
completedTests: 0,
|
|
77
|
+
errorLogs: [],
|
|
78
|
+
errors: 0,
|
|
79
|
+
expectedTests: action.expected_test_count,
|
|
80
|
+
fails: 0,
|
|
81
|
+
loggerAction: action,
|
|
82
|
+
testResults: [],
|
|
83
|
+
};
|
|
84
|
+
collection.expectedTests += action.expected_test_count;
|
|
85
|
+
this.#results.expectedTests += action.expected_test_count;
|
|
86
|
+
}
|
|
87
|
+
if ("end_module" === action.type) {
|
|
88
|
+
let collection = this.#results.collections[action.collection_id];
|
|
89
|
+
if (!collection)
|
|
90
|
+
return;
|
|
91
|
+
let module = collection.modules[action.module_id];
|
|
92
|
+
if (!module)
|
|
93
|
+
return;
|
|
94
|
+
this.#results.completedModules += 1;
|
|
95
|
+
collection.completedModules += 1;
|
|
96
|
+
}
|
|
97
|
+
if ("module_error" === action.type) {
|
|
98
|
+
let collection = this.#results.collections[action.collection_id];
|
|
99
|
+
if (!collection)
|
|
100
|
+
return;
|
|
101
|
+
let module = collection.modules[action.module_id];
|
|
102
|
+
if (!module)
|
|
103
|
+
return;
|
|
104
|
+
this.#results.errors += 1;
|
|
105
|
+
collection.errors += 1;
|
|
106
|
+
module.errors += 1;
|
|
107
|
+
module.errorLogs.push(action);
|
|
108
|
+
}
|
|
109
|
+
if ("start_test" === action.type) {
|
|
110
|
+
let collection = this.#results.collections[action.collection_id];
|
|
111
|
+
if (!collection)
|
|
112
|
+
return;
|
|
113
|
+
let module = collection.modules[action.module_id];
|
|
114
|
+
if (!module)
|
|
115
|
+
return;
|
|
116
|
+
module.testResults[action.test_id] = {
|
|
117
|
+
loggerStartAction: action,
|
|
118
|
+
loggerEndAction: undefined,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
if ("end_test" === action.type) {
|
|
122
|
+
endTest(this.#results, action);
|
|
123
|
+
}
|
|
124
|
+
if ("test_error" === action.type) {
|
|
125
|
+
let collection = this.#results.collections[action.collection_id];
|
|
126
|
+
if (!collection)
|
|
127
|
+
return;
|
|
128
|
+
let module = collection.modules[action.module_id];
|
|
129
|
+
if (!module)
|
|
130
|
+
return;
|
|
131
|
+
let testResult = module.testResults[action.test_id];
|
|
132
|
+
if (!testResult)
|
|
133
|
+
return;
|
|
134
|
+
testResult.loggerEndAction = action;
|
|
135
|
+
this.#results.errors += 1;
|
|
136
|
+
collection.errors += 1;
|
|
137
|
+
module.errors += 1;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function endTest(runResults, loggerAction) {
|
|
142
|
+
let collection = runResults.collections[loggerAction.collection_id];
|
|
143
|
+
if (!collection)
|
|
144
|
+
return;
|
|
145
|
+
let module = collection.modules[loggerAction.module_id];
|
|
146
|
+
if (!module)
|
|
147
|
+
return;
|
|
148
|
+
let testResult = module.testResults[loggerAction.test_id];
|
|
149
|
+
if (!testResult)
|
|
150
|
+
return;
|
|
151
|
+
testResult.loggerEndAction = loggerAction;
|
|
152
|
+
runResults.completedTests += 1;
|
|
153
|
+
collection.completedTests += 1;
|
|
154
|
+
module.completedTests += 1;
|
|
155
|
+
let { assertions } = loggerAction;
|
|
156
|
+
const isAssertionArray = Array.isArray(assertions) && assertions.length;
|
|
157
|
+
const isAssertion = !Array.isArray(assertions) && undefined !== assertions;
|
|
158
|
+
if (isAssertion || isAssertionArray) {
|
|
159
|
+
runResults.fails += 1;
|
|
160
|
+
collection.fails += 1;
|
|
161
|
+
module.fails += 1;
|
|
162
|
+
}
|
|
163
|
+
runResults.testTime += Math.max(0, loggerAction.end_time - loggerAction.start_time);
|
|
164
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Logger } from "./logger.js";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import { runCollection } from "../../core/dist/mod.js";
|
|
5
|
+
let filepaths = process.argv.slice(2);
|
|
6
|
+
const logger = new Logger();
|
|
7
|
+
logger.log({
|
|
8
|
+
type: "start_run",
|
|
9
|
+
time: performance.now(),
|
|
10
|
+
expected_collection_count: filepaths.length,
|
|
11
|
+
});
|
|
12
|
+
for (const [collection_id, file] of filepaths.entries()) {
|
|
13
|
+
try {
|
|
14
|
+
let filepath = path.join(process.cwd(), file);
|
|
15
|
+
const { testModules } = await import(filepath);
|
|
16
|
+
await runCollection(logger, testModules, collection_id, filepath);
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
logger.log({
|
|
20
|
+
type: "collection_error",
|
|
21
|
+
collection_id,
|
|
22
|
+
error: e?.toString() ?? "wild horses error",
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
logger.log({
|
|
27
|
+
type: "end_run",
|
|
28
|
+
time: performance.now(),
|
|
29
|
+
});
|
|
30
|
+
console.log(logger.results);
|
|
31
|
+
logger.failed || logger.errored || !logger.completed
|
|
32
|
+
? process.exit(1)
|
|
33
|
+
: process.exit(0);
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
const SPACE = " ";
|
|
2
|
+
export function getResultsAsString(runResults) {
|
|
3
|
+
const output = [];
|
|
4
|
+
for (let errorAction of runResults.errorLogs) {
|
|
5
|
+
if ("run_error" !== errorAction.type)
|
|
6
|
+
continue;
|
|
7
|
+
output.push(`${SPACE}[session_error]\n${errorAction.error}`);
|
|
8
|
+
}
|
|
9
|
+
if (!logRunResults(output, runResults))
|
|
10
|
+
for (const collection of runResults.collections) {
|
|
11
|
+
if (logCollectionResult(output, collection))
|
|
12
|
+
continue;
|
|
13
|
+
if (collection)
|
|
14
|
+
for (const moduleResult of collection.modules) {
|
|
15
|
+
if (logModuleResult(output, moduleResult))
|
|
16
|
+
continue;
|
|
17
|
+
if (moduleResult)
|
|
18
|
+
for (const testResult of moduleResult.testResults) {
|
|
19
|
+
logTest(output, testResult);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
logSummary(output, runResults);
|
|
24
|
+
return output.join("\n");
|
|
25
|
+
}
|
|
26
|
+
function logRunResults(output, result) {
|
|
27
|
+
if (!result.fails &&
|
|
28
|
+
!result.errors &&
|
|
29
|
+
result.expectedTests === result.completedTests &&
|
|
30
|
+
result.expectedModules === result.completedModules &&
|
|
31
|
+
result.expectedCollections === result.completedCollections) {
|
|
32
|
+
output.push(`${result.completedTests} tests
|
|
33
|
+
${result.completedModules} modules
|
|
34
|
+
${result.completedCollections} collections`);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
for (let errorAction of result.errorLogs) {
|
|
38
|
+
if ("run_error" !== errorAction.type)
|
|
39
|
+
continue;
|
|
40
|
+
output.push(`[run_error] ${errorAction.error}`);
|
|
41
|
+
}
|
|
42
|
+
if (result.errorLogs.length)
|
|
43
|
+
output.push("");
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
function logCollectionResult(output, collection) {
|
|
47
|
+
if (!collection)
|
|
48
|
+
return true;
|
|
49
|
+
let { loggerAction } = collection;
|
|
50
|
+
if ("start_collection" !== loggerAction.type)
|
|
51
|
+
return true;
|
|
52
|
+
output.push(`${loggerAction.collection_url}`);
|
|
53
|
+
if (!collection.fails &&
|
|
54
|
+
!collection.errors &&
|
|
55
|
+
collection.expectedTests === collection.completedTests &&
|
|
56
|
+
collection.expectedModules === collection.completedModules) {
|
|
57
|
+
output.push(`${SPACE}${collection.expectedTests} tests
|
|
58
|
+
${SPACE}${loggerAction.expected_module_count} modules`);
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
for (let errorAction of collection.errorLogs) {
|
|
62
|
+
if ("collection_error" !== errorAction.type)
|
|
63
|
+
continue;
|
|
64
|
+
output.push(`${SPACE}[collection_error] ${errorAction.error}`);
|
|
65
|
+
}
|
|
66
|
+
if (collection.errorLogs.length)
|
|
67
|
+
output.push("");
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
function logModuleResult(output, module) {
|
|
71
|
+
if (!module)
|
|
72
|
+
return true;
|
|
73
|
+
let { loggerAction } = module;
|
|
74
|
+
if ("start_module" !== loggerAction.type)
|
|
75
|
+
return true;
|
|
76
|
+
output.push(`${SPACE}${loggerAction.module_name}`);
|
|
77
|
+
if (!module.fails &&
|
|
78
|
+
!module.errors &&
|
|
79
|
+
module.expectedTests === module.completedTests) {
|
|
80
|
+
output.push(`${SPACE.repeat(2)}${module.expectedTests} tests`);
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
for (let errorAction of module.errorLogs) {
|
|
84
|
+
if ("collection_error" !== errorAction.type)
|
|
85
|
+
continue;
|
|
86
|
+
output.push(`${SPACE.repeat(2)}[module_error] ${errorAction.error}`);
|
|
87
|
+
}
|
|
88
|
+
if (module.errorLogs.length)
|
|
89
|
+
output.push("");
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
function logTest(output, test) {
|
|
93
|
+
if (!test)
|
|
94
|
+
return;
|
|
95
|
+
let { loggerStartAction, loggerEndAction } = test;
|
|
96
|
+
if ("start_test" !== loggerStartAction.type)
|
|
97
|
+
return;
|
|
98
|
+
if ("test_error" === loggerEndAction?.type) {
|
|
99
|
+
let { test_name } = loggerStartAction;
|
|
100
|
+
output.push(`${SPACE.repeat(2)}${test_name}
|
|
101
|
+
${SPACE.repeat(3)}[error] ${loggerEndAction.error}`);
|
|
102
|
+
}
|
|
103
|
+
if ("end_test" === loggerEndAction?.type) {
|
|
104
|
+
let { assertions } = loggerEndAction;
|
|
105
|
+
const isAssertionArray = Array.isArray(assertions) && assertions.length;
|
|
106
|
+
const isAssertion = !Array.isArray(assertions) &&
|
|
107
|
+
undefined !== assertions &&
|
|
108
|
+
null !== assertions;
|
|
109
|
+
if (isAssertion || isAssertionArray) {
|
|
110
|
+
let { test_name } = loggerStartAction;
|
|
111
|
+
output.push(`${SPACE.repeat(2)}${test_name}`);
|
|
112
|
+
}
|
|
113
|
+
if (isAssertion) {
|
|
114
|
+
output.push(`${SPACE.repeat(3)}- ${assertions}`);
|
|
115
|
+
}
|
|
116
|
+
if (isAssertionArray) {
|
|
117
|
+
for (const assertion of assertions) {
|
|
118
|
+
output.push(`${SPACE.repeat(3)}- ${assertion}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function logSummary(output, runResults) {
|
|
124
|
+
let status_with_color = runResults.fails
|
|
125
|
+
? yellow("\u{2717} failed")
|
|
126
|
+
: blue("\u{2714} passed");
|
|
127
|
+
if (runResults.errors) {
|
|
128
|
+
status_with_color = gray("\u{2717} errored");
|
|
129
|
+
}
|
|
130
|
+
let totalTime = runResults.endTime - runResults.startTime;
|
|
131
|
+
output.push(`
|
|
132
|
+
${status_with_color}
|
|
133
|
+
duration: ${runResults.testTime.toFixed(4)} mS
|
|
134
|
+
total: ${totalTime.toFixed(4)} mS
|
|
135
|
+
`);
|
|
136
|
+
}
|
|
137
|
+
function blue(text) {
|
|
138
|
+
return `\x1b[44m\x1b[97m${text}\x1b[0m`;
|
|
139
|
+
}
|
|
140
|
+
function yellow(text) {
|
|
141
|
+
return `\x1b[43m\x1b[97m${text}\x1b[0m`;
|
|
142
|
+
}
|
|
143
|
+
function gray(text) {
|
|
144
|
+
return `\x1b[100m\x1b[97m${text}\x1b[0m`;
|
|
145
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
const SPACE = " ";
|
|
2
|
+
export function getResultsAsString(runResults) {
|
|
3
|
+
const output = [];
|
|
4
|
+
for (let errorAction of runResults.errorLogs) {
|
|
5
|
+
if ("run_error" !== errorAction.type)
|
|
6
|
+
continue;
|
|
7
|
+
output.push(`${SPACE}[session_error]\n${errorAction.error}`);
|
|
8
|
+
}
|
|
9
|
+
// Lots of nested loops because results a nested structure.
|
|
10
|
+
// I'd rather see composition nested in one function
|
|
11
|
+
// than have for loops spread across each function.
|
|
12
|
+
if (!logRunResults(output, runResults))
|
|
13
|
+
for (const collection of runResults.collections) {
|
|
14
|
+
if (logCollectionResult(output, collection))
|
|
15
|
+
continue;
|
|
16
|
+
if (collection)
|
|
17
|
+
for (const moduleResult of collection.modules) {
|
|
18
|
+
if (logModuleResult(output, moduleResult))
|
|
19
|
+
continue;
|
|
20
|
+
if (moduleResult)
|
|
21
|
+
for (const testResult of moduleResult.testResults) {
|
|
22
|
+
logTest(output, testResult);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
logSummary(output, runResults);
|
|
27
|
+
return output.join("\n");
|
|
28
|
+
}
|
|
29
|
+
function logRunResults(output, result) {
|
|
30
|
+
// When everything goes right :3
|
|
31
|
+
if (!result.fails &&
|
|
32
|
+
!result.errors &&
|
|
33
|
+
result.expectedTests === result.completedTests &&
|
|
34
|
+
result.expectedModules === result.completedModules &&
|
|
35
|
+
result.expectedCollections === result.completedCollections) {
|
|
36
|
+
output.push(`${result.completedTests} tests
|
|
37
|
+
${result.completedModules} modules
|
|
38
|
+
${result.completedCollections} collections`);
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
for (let errorAction of result.errorLogs) {
|
|
42
|
+
if ("run_error" !== errorAction.type)
|
|
43
|
+
continue;
|
|
44
|
+
output.push(`[run_error] ${errorAction.error}`);
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
function logCollectionResult(output, collection) {
|
|
49
|
+
if (!collection)
|
|
50
|
+
return true;
|
|
51
|
+
let { loggerAction } = collection;
|
|
52
|
+
if ("start_collection" !== loggerAction.type)
|
|
53
|
+
return true;
|
|
54
|
+
output.push(`${loggerAction.collection_url}`);
|
|
55
|
+
// when everything in the collection goes right
|
|
56
|
+
if (!collection.fails &&
|
|
57
|
+
!collection.errors &&
|
|
58
|
+
collection.expectedTests === collection.completedTests &&
|
|
59
|
+
collection.expectedModules === collection.completedModules) {
|
|
60
|
+
output.push(`${SPACE}${collection.expectedTests} tests
|
|
61
|
+
${SPACE}${loggerAction.expected_module_count} modules`);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
for (let errorAction of collection.errorLogs) {
|
|
65
|
+
if ("collection_error" !== errorAction.type)
|
|
66
|
+
continue;
|
|
67
|
+
output.push(`${SPACE}[collection_error] ${errorAction.error}`);
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
function logModuleResult(output, module) {
|
|
72
|
+
if (!module)
|
|
73
|
+
return true;
|
|
74
|
+
let { loggerAction } = module;
|
|
75
|
+
if ("start_module" !== loggerAction.type)
|
|
76
|
+
return true;
|
|
77
|
+
output.push(`${SPACE}${loggerAction.module_name}`);
|
|
78
|
+
// when everything in the module goes right
|
|
79
|
+
if (!module.fails &&
|
|
80
|
+
!module.errors &&
|
|
81
|
+
module.expectedTests === module.completedTests) {
|
|
82
|
+
output.push(`${SPACE.repeat(2)}${module.expectedTests} tests`);
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
for (let errorAction of module.errorLogs) {
|
|
86
|
+
if ("collection_error" !== errorAction.type)
|
|
87
|
+
continue;
|
|
88
|
+
output.push(`${SPACE.repeat(2)}[module_error] ${errorAction.error}`);
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
function logTest(output, test) {
|
|
93
|
+
if (!test)
|
|
94
|
+
return;
|
|
95
|
+
let { loggerStartAction, loggerEndAction } = test;
|
|
96
|
+
if ("start_test" !== loggerStartAction.type)
|
|
97
|
+
return;
|
|
98
|
+
if ("test_error" === loggerEndAction?.type) {
|
|
99
|
+
let { test_name } = loggerStartAction;
|
|
100
|
+
output.push(`${SPACE.repeat(2)}${test_name}
|
|
101
|
+
${SPACE.repeat(3)}[error] ${loggerEndAction.error}`);
|
|
102
|
+
}
|
|
103
|
+
if ("end_test" === loggerEndAction?.type) {
|
|
104
|
+
let { assertions } = loggerEndAction;
|
|
105
|
+
const isAssertionArray = Array.isArray(assertions) && assertions.length;
|
|
106
|
+
const isAssertion = !Array.isArray(assertions) &&
|
|
107
|
+
undefined !== assertions &&
|
|
108
|
+
null !== assertions;
|
|
109
|
+
if (isAssertion || isAssertionArray) {
|
|
110
|
+
let { test_name } = loggerStartAction;
|
|
111
|
+
output.push(`${SPACE.repeat(2)}${test_name}`);
|
|
112
|
+
}
|
|
113
|
+
if (isAssertion) {
|
|
114
|
+
output.push(`${SPACE.repeat(3)}- ${assertions}`);
|
|
115
|
+
}
|
|
116
|
+
if (isAssertionArray) {
|
|
117
|
+
for (const assertion of assertions) {
|
|
118
|
+
output.push(`${SPACE.repeat(3)}- ${assertion}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function logSummary(output, runResults) {
|
|
124
|
+
let status_with_color = runResults.fails
|
|
125
|
+
? yellow("\u{2717} failed")
|
|
126
|
+
: blue("\u{2714} passed");
|
|
127
|
+
if (runResults.errors) {
|
|
128
|
+
status_with_color = gray("\u{2717} errored");
|
|
129
|
+
}
|
|
130
|
+
let totalTime = runResults.endTime - runResults.startTime;
|
|
131
|
+
output.push(`
|
|
132
|
+
${status_with_color}
|
|
133
|
+
duration: ${runResults.testTime.toFixed(4)} mS
|
|
134
|
+
total: ${totalTime.toFixed(4)} mS
|
|
135
|
+
`);
|
|
136
|
+
}
|
|
137
|
+
// 39 - default foreground color
|
|
138
|
+
// 49 - default background color
|
|
139
|
+
function blue(text) {
|
|
140
|
+
return `\x1b[44m\x1b[97m${text}\x1b[0m`;
|
|
141
|
+
}
|
|
142
|
+
function yellow(text) {
|
|
143
|
+
return `\x1b[43m\x1b[97m${text}\x1b[0m`;
|
|
144
|
+
}
|
|
145
|
+
function gray(text) {
|
|
146
|
+
return `\x1b[100m\x1b[97m${text}\x1b[0m`;
|
|
147
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as path from "path";
|
|
2
|
+
import { startRun } from "../../core/dist/mod.js";
|
|
3
|
+
export async function run(logger, files) {
|
|
4
|
+
for (const file of files) {
|
|
5
|
+
let filepath = path.join(process.cwd(), file);
|
|
6
|
+
try {
|
|
7
|
+
const { testModules } = await import(filepath);
|
|
8
|
+
await startRun(logger, testModules);
|
|
9
|
+
}
|
|
10
|
+
catch (e) {
|
|
11
|
+
logger.log({
|
|
12
|
+
type: "run_error",
|
|
13
|
+
error: e?.toString() ?? "wild horses error",
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
LoggerAction,
|
|
3
|
+
LoggerInterface,
|
|
4
|
+
EndTest,
|
|
5
|
+
} from "../../core/dist/mod.js";
|
|
6
|
+
import type { RunResults } from "./results.js";
|
|
7
|
+
|
|
8
|
+
import { getResultsAsString } from "./results.js";
|
|
9
|
+
|
|
10
|
+
export class Logger implements LoggerInterface {
|
|
11
|
+
#results: RunResults = {
|
|
12
|
+
startTime: 0,
|
|
13
|
+
fails: 0,
|
|
14
|
+
errors: 0,
|
|
15
|
+
expectedTests: 0,
|
|
16
|
+
endTime: 0,
|
|
17
|
+
testTime: 0,
|
|
18
|
+
expectedModules: 0,
|
|
19
|
+
expectedCollections: 0,
|
|
20
|
+
completedModules: 0,
|
|
21
|
+
completedCollections: 0,
|
|
22
|
+
completedTests: 0,
|
|
23
|
+
errorLogs: [],
|
|
24
|
+
collections: [],
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
get failed(): boolean {
|
|
28
|
+
return this.#results.fails !== 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get errored(): boolean {
|
|
32
|
+
return this.#results.errors !== 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
get completed(): boolean {
|
|
36
|
+
return (
|
|
37
|
+
0 < this.#results.expectedTests &&
|
|
38
|
+
this.#results.expectedTests === this.#results.completedTests
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
get results(): string {
|
|
43
|
+
return getResultsAsString(this.#results);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
log(action: LoggerAction) {
|
|
47
|
+
if ("start_run" === action.type) {
|
|
48
|
+
this.#results.startTime = action.time;
|
|
49
|
+
this.#results.expectedCollections = action.expected_collection_count;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if ("end_run" === action.type) {
|
|
53
|
+
this.#results.endTime = action.time;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if ("run_error" === action.type) {
|
|
57
|
+
this.#results.errors += 1;
|
|
58
|
+
this.#results.errorLogs.push(action);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if ("start_collection" === action.type) {
|
|
62
|
+
this.#results.collections[action.collection_id] = {
|
|
63
|
+
completedModules: 0,
|
|
64
|
+
completedTests: 0,
|
|
65
|
+
errorLogs: [],
|
|
66
|
+
errors: 0,
|
|
67
|
+
expectedModules: action.expected_module_count,
|
|
68
|
+
expectedTests: 0,
|
|
69
|
+
fails: 0,
|
|
70
|
+
loggerAction: action,
|
|
71
|
+
modules: [],
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
this.#results.expectedModules += action.expected_module_count;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if ("end_collection" === action.type) {
|
|
78
|
+
let collection = this.#results.collections[action.collection_id];
|
|
79
|
+
if (!collection) return;
|
|
80
|
+
|
|
81
|
+
this.#results.completedCollections += 1;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if ("collection_error" === action.type) {
|
|
85
|
+
let collection = this.#results.collections[action.collection_id];
|
|
86
|
+
if (!collection) return;
|
|
87
|
+
|
|
88
|
+
this.#results.errors += 1;
|
|
89
|
+
collection.errors += 1;
|
|
90
|
+
|
|
91
|
+
collection.errorLogs.push(action);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if ("start_module" === action.type) {
|
|
95
|
+
let collection = this.#results.collections[action.collection_id];
|
|
96
|
+
if (!collection) return;
|
|
97
|
+
|
|
98
|
+
collection.modules[action.module_id] = {
|
|
99
|
+
completedTests: 0,
|
|
100
|
+
errorLogs: [],
|
|
101
|
+
errors: 0,
|
|
102
|
+
expectedTests: action.expected_test_count,
|
|
103
|
+
fails: 0,
|
|
104
|
+
loggerAction: action,
|
|
105
|
+
testResults: [],
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
collection.expectedTests += action.expected_test_count;
|
|
109
|
+
this.#results.expectedTests += action.expected_test_count;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if ("end_module" === action.type) {
|
|
113
|
+
let collection = this.#results.collections[action.collection_id];
|
|
114
|
+
if (!collection) return;
|
|
115
|
+
|
|
116
|
+
let module = collection.modules[action.module_id];
|
|
117
|
+
if (!module) return;
|
|
118
|
+
|
|
119
|
+
this.#results.completedModules += 1;
|
|
120
|
+
collection.completedModules += 1;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if ("module_error" === action.type) {
|
|
124
|
+
let collection = this.#results.collections[action.collection_id];
|
|
125
|
+
if (!collection) return;
|
|
126
|
+
|
|
127
|
+
let module = collection.modules[action.module_id];
|
|
128
|
+
if (!module) return;
|
|
129
|
+
|
|
130
|
+
this.#results.errors += 1;
|
|
131
|
+
collection.errors += 1;
|
|
132
|
+
module.errors += 1;
|
|
133
|
+
module.errorLogs.push(action);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if ("start_test" === action.type) {
|
|
137
|
+
let collection = this.#results.collections[action.collection_id];
|
|
138
|
+
if (!collection) return;
|
|
139
|
+
|
|
140
|
+
let module = collection.modules[action.module_id];
|
|
141
|
+
if (!module) return;
|
|
142
|
+
|
|
143
|
+
module.testResults[action.test_id] = {
|
|
144
|
+
loggerStartAction: action,
|
|
145
|
+
loggerEndAction: undefined,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if ("end_test" === action.type) {
|
|
150
|
+
endTest(this.#results, action);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if ("test_error" === action.type) {
|
|
154
|
+
let collection = this.#results.collections[action.collection_id];
|
|
155
|
+
if (!collection) return;
|
|
156
|
+
|
|
157
|
+
let module = collection.modules[action.module_id];
|
|
158
|
+
if (!module) return;
|
|
159
|
+
|
|
160
|
+
let testResult = module.testResults[action.test_id];
|
|
161
|
+
if (!testResult) return;
|
|
162
|
+
|
|
163
|
+
testResult.loggerEndAction = action;
|
|
164
|
+
this.#results.errors += 1;
|
|
165
|
+
collection.errors += 1;
|
|
166
|
+
module.errors += 1;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function endTest(runResults: RunResults, loggerAction: EndTest) {
|
|
172
|
+
let collection = runResults.collections[loggerAction.collection_id];
|
|
173
|
+
if (!collection) return;
|
|
174
|
+
|
|
175
|
+
let module = collection.modules[loggerAction.module_id];
|
|
176
|
+
if (!module) return;
|
|
177
|
+
|
|
178
|
+
let testResult = module.testResults[loggerAction.test_id];
|
|
179
|
+
if (!testResult) return;
|
|
180
|
+
|
|
181
|
+
testResult.loggerEndAction = loggerAction;
|
|
182
|
+
runResults.completedTests += 1;
|
|
183
|
+
collection.completedTests += 1;
|
|
184
|
+
module.completedTests += 1;
|
|
185
|
+
|
|
186
|
+
let { assertions } = loggerAction;
|
|
187
|
+
const isAssertionArray = Array.isArray(assertions) && assertions.length;
|
|
188
|
+
// might be worth just sticking with language standard "none" like "" or 0 or false
|
|
189
|
+
const isAssertion = !Array.isArray(assertions) && undefined !== assertions;
|
|
190
|
+
if (isAssertion || isAssertionArray) {
|
|
191
|
+
runResults.fails += 1;
|
|
192
|
+
collection.fails += 1;
|
|
193
|
+
module.fails += 1;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
runResults.testTime += Math.max(
|
|
197
|
+
0,
|
|
198
|
+
loggerAction.end_time - loggerAction.start_time,
|
|
199
|
+
);
|
|
200
|
+
}
|