@w-lfpup/jackrabbit 0.2.0 → 0.3.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/.github/workflows/browsers.json +45 -0
- package/.github/workflows/browsers.macos.json +51 -0
- package/.github/workflows/browsers.windows.json +19 -0
- package/.github/workflows/tests.yml +24 -0
- package/README.md +41 -1
- package/browser/dist/logger.js +43 -0
- package/browser/dist/mod.js +26 -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 +161 -0
- package/nodejs/dist/mod.js +31 -0
- package/nodejs/dist/results.js +139 -0
- package/nodejs/dist/results_str.js +147 -0
- package/nodejs/dist/runner.js +17 -0
- package/nodejs/src/logger.ts +193 -0
- package/nodejs/src/mod.ts +37 -0
- package/nodejs/src/results_str.ts +234 -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 -13
- package/tests/dist/test_error.test.d.ts +9 -0
- package/tests/dist/test_error.test.js +27 -0
- package/tests/dist/test_errors.test.d.ts +9 -0
- package/tests/dist/test_errors.test.js +27 -0
- package/tests/dist/test_logger.d.ts +3 -2
- package/tests/dist/test_logger.js +5 -1
- 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 +1 -1
- package/webdriver/dist/config.js +57 -0
- package/webdriver/dist/eventbus.js +18 -0
- package/webdriver/dist/listeners.js +21 -0
- package/webdriver/dist/logger.js +203 -0
- package/webdriver/dist/mod.js +36 -0
- package/webdriver/dist/results_str.js +167 -0
- package/webdriver/dist/routes.js +172 -0
- package/webdriver/dist/routes2.js +163 -0
- package/webdriver/dist/test_hangar.js +20 -0
- package/webdriver/dist/webdriver.js +273 -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 +43 -0
- package/webdriver/src/results.ts +56 -0
- package/webdriver/src/results_str.ts +222 -0
- package/webdriver/src/routes.ts +211 -0
- package/webdriver/src/test_hangar.ts +25 -0
- package/webdriver/src/webdriver.ts +372 -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/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
- /package/{cli/dist/cli_types.js → webdriver/dist/results.js} +0 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { getResultsAsString } from "./results_str.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 results() {
|
|
25
|
+
return getResultsAsString(this.#results);
|
|
26
|
+
}
|
|
27
|
+
log(action) {
|
|
28
|
+
if ("start_run" === action.type) {
|
|
29
|
+
this.#results.startTime = action.time;
|
|
30
|
+
this.#results.expectedCollections = action.expected_collection_count;
|
|
31
|
+
}
|
|
32
|
+
if ("end_run" === action.type) {
|
|
33
|
+
this.#results.endTime = action.time;
|
|
34
|
+
}
|
|
35
|
+
if ("run_error" === action.type) {
|
|
36
|
+
this.#results.errors += 1;
|
|
37
|
+
this.#results.errorLogs.push(action);
|
|
38
|
+
}
|
|
39
|
+
if ("start_collection" === action.type) {
|
|
40
|
+
this.#results.collections[action.collection_id] = {
|
|
41
|
+
completedModules: 0,
|
|
42
|
+
completedTests: 0,
|
|
43
|
+
errorLogs: [],
|
|
44
|
+
errors: 0,
|
|
45
|
+
expectedModules: action.expected_module_count,
|
|
46
|
+
expectedTests: 0,
|
|
47
|
+
fails: 0,
|
|
48
|
+
loggerAction: action,
|
|
49
|
+
modules: [],
|
|
50
|
+
};
|
|
51
|
+
this.#results.expectedModules += action.expected_module_count;
|
|
52
|
+
}
|
|
53
|
+
if ("end_collection" === action.type) {
|
|
54
|
+
let collection = this.#results.collections[action.collection_id];
|
|
55
|
+
if (!collection)
|
|
56
|
+
return;
|
|
57
|
+
this.#results.completedCollections += 1;
|
|
58
|
+
}
|
|
59
|
+
if ("collection_error" === action.type) {
|
|
60
|
+
let collection = this.#results.collections[action.collection_id];
|
|
61
|
+
if (!collection)
|
|
62
|
+
return;
|
|
63
|
+
this.#results.errors += 1;
|
|
64
|
+
collection.errors += 1;
|
|
65
|
+
collection.errorLogs.push(action);
|
|
66
|
+
}
|
|
67
|
+
if ("start_module" === action.type) {
|
|
68
|
+
let collection = this.#results.collections[action.collection_id];
|
|
69
|
+
if (!collection)
|
|
70
|
+
return;
|
|
71
|
+
collection.modules[action.module_id] = {
|
|
72
|
+
completedTests: 0,
|
|
73
|
+
errorLogs: [],
|
|
74
|
+
errors: 0,
|
|
75
|
+
expectedTests: action.expected_test_count,
|
|
76
|
+
fails: 0,
|
|
77
|
+
loggerAction: action,
|
|
78
|
+
testResults: [],
|
|
79
|
+
};
|
|
80
|
+
collection.expectedTests += action.expected_test_count;
|
|
81
|
+
this.#results.expectedTests += action.expected_test_count;
|
|
82
|
+
}
|
|
83
|
+
if ("end_module" === action.type) {
|
|
84
|
+
let collection = this.#results.collections[action.collection_id];
|
|
85
|
+
if (!collection)
|
|
86
|
+
return;
|
|
87
|
+
let module = collection.modules[action.module_id];
|
|
88
|
+
if (!module)
|
|
89
|
+
return;
|
|
90
|
+
this.#results.completedModules += 1;
|
|
91
|
+
collection.completedModules += 1;
|
|
92
|
+
}
|
|
93
|
+
if ("module_error" === action.type) {
|
|
94
|
+
let collection = this.#results.collections[action.collection_id];
|
|
95
|
+
if (!collection)
|
|
96
|
+
return;
|
|
97
|
+
let module = collection.modules[action.module_id];
|
|
98
|
+
if (!module)
|
|
99
|
+
return;
|
|
100
|
+
this.#results.errors += 1;
|
|
101
|
+
collection.errors += 1;
|
|
102
|
+
module.errors += 1;
|
|
103
|
+
module.errorLogs.push(action);
|
|
104
|
+
}
|
|
105
|
+
if ("start_test" === action.type) {
|
|
106
|
+
let collection = this.#results.collections[action.collection_id];
|
|
107
|
+
if (!collection)
|
|
108
|
+
return;
|
|
109
|
+
let module = collection.modules[action.module_id];
|
|
110
|
+
if (!module)
|
|
111
|
+
return;
|
|
112
|
+
module.testResults[action.test_id] = {
|
|
113
|
+
loggerStartAction: action,
|
|
114
|
+
loggerEndAction: undefined,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
if ("end_test" === action.type) {
|
|
118
|
+
endTest(this.#results, action);
|
|
119
|
+
}
|
|
120
|
+
if ("test_error" === action.type) {
|
|
121
|
+
let collection = this.#results.collections[action.collection_id];
|
|
122
|
+
if (!collection)
|
|
123
|
+
return;
|
|
124
|
+
let module = collection.modules[action.module_id];
|
|
125
|
+
if (!module)
|
|
126
|
+
return;
|
|
127
|
+
let testResult = module.testResults[action.test_id];
|
|
128
|
+
if (!testResult)
|
|
129
|
+
return;
|
|
130
|
+
testResult.loggerEndAction = action;
|
|
131
|
+
this.#results.errors += 1;
|
|
132
|
+
collection.errors += 1;
|
|
133
|
+
module.errors += 1;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function endTest(runResults, loggerAction) {
|
|
138
|
+
let collection = runResults.collections[loggerAction.collection_id];
|
|
139
|
+
if (!collection)
|
|
140
|
+
return;
|
|
141
|
+
let module = collection.modules[loggerAction.module_id];
|
|
142
|
+
if (!module)
|
|
143
|
+
return;
|
|
144
|
+
let testResult = module.testResults[loggerAction.test_id];
|
|
145
|
+
if (!testResult)
|
|
146
|
+
return;
|
|
147
|
+
testResult.loggerEndAction = loggerAction;
|
|
148
|
+
runResults.completedTests += 1;
|
|
149
|
+
collection.completedTests += 1;
|
|
150
|
+
module.completedTests += 1;
|
|
151
|
+
let { assertions } = loggerAction;
|
|
152
|
+
const isAssertionArray = Array.isArray(assertions) && assertions.length;
|
|
153
|
+
// might be worth just sticking with language standard "none" like "" or 0 or false
|
|
154
|
+
const isAssertion = !Array.isArray(assertions) && undefined !== assertions;
|
|
155
|
+
if (isAssertion || isAssertionArray) {
|
|
156
|
+
runResults.fails += 1;
|
|
157
|
+
collection.fails += 1;
|
|
158
|
+
module.fails += 1;
|
|
159
|
+
}
|
|
160
|
+
runResults.testTime += Math.max(0, loggerAction.end_time - loggerAction.start_time);
|
|
161
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
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 ? process.exit(1) : process.exit(0);
|
|
@@ -0,0 +1,139 @@
|
|
|
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
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
function logCollectionResult(output, collection) {
|
|
45
|
+
if (!collection)
|
|
46
|
+
return true;
|
|
47
|
+
let { loggerAction } = collection;
|
|
48
|
+
if ("start_collection" !== loggerAction.type)
|
|
49
|
+
return true;
|
|
50
|
+
output.push(`${SPACE}${loggerAction.collection_url}`);
|
|
51
|
+
if (!collection.fails &&
|
|
52
|
+
!collection.errors &&
|
|
53
|
+
collection.expectedTests === collection.completedTests &&
|
|
54
|
+
collection.expectedModules === collection.completedModules) {
|
|
55
|
+
output.push(`${collection.expectedTests} tests
|
|
56
|
+
${loggerAction.expected_module_count} modules`);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
for (let errorAction of collection.errorLogs) {
|
|
60
|
+
if ("collection_error" !== errorAction.type)
|
|
61
|
+
continue;
|
|
62
|
+
output.push(`[collection_error] ${errorAction.error}`);
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
function logModuleResult(output, module) {
|
|
67
|
+
if (!module)
|
|
68
|
+
return true;
|
|
69
|
+
let { loggerAction } = module;
|
|
70
|
+
if ("start_module" !== loggerAction.type)
|
|
71
|
+
return true;
|
|
72
|
+
output.push(`${SPACE}${loggerAction.module_name}`);
|
|
73
|
+
if (!module.fails &&
|
|
74
|
+
!module.errors &&
|
|
75
|
+
module.expectedTests === module.completedTests) {
|
|
76
|
+
output.push(`${SPACE.repeat(2)}${module.expectedTests} tests`);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
for (let errorAction of module.errorLogs) {
|
|
80
|
+
if ("collection_error" !== errorAction.type)
|
|
81
|
+
continue;
|
|
82
|
+
output.push(`${SPACE}[module_error] ${errorAction.error}`);
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
function logTest(output, test) {
|
|
87
|
+
if (!test)
|
|
88
|
+
return;
|
|
89
|
+
let { loggerStartAction, loggerEndAction } = test;
|
|
90
|
+
if ("start_test" !== loggerStartAction.type)
|
|
91
|
+
return;
|
|
92
|
+
if ("test_error" === loggerEndAction?.type) {
|
|
93
|
+
let { test_name } = loggerStartAction;
|
|
94
|
+
output.push(`${SPACE.repeat(2)}${test_name}
|
|
95
|
+
${SPACE.repeat(3)}[error] ${loggerEndAction.error}`);
|
|
96
|
+
}
|
|
97
|
+
if ("end_test" === loggerEndAction?.type) {
|
|
98
|
+
let { assertions } = loggerEndAction;
|
|
99
|
+
const isAssertionArray = Array.isArray(assertions) && assertions.length;
|
|
100
|
+
const isAssertion = !Array.isArray(assertions) &&
|
|
101
|
+
undefined !== assertions &&
|
|
102
|
+
null !== assertions;
|
|
103
|
+
if (isAssertion || isAssertionArray) {
|
|
104
|
+
let { test_name } = loggerStartAction;
|
|
105
|
+
output.push(`${SPACE.repeat(2)}${test_name}`);
|
|
106
|
+
}
|
|
107
|
+
if (isAssertion) {
|
|
108
|
+
output.push(`${SPACE.repeat(3)}- ${assertions}`);
|
|
109
|
+
}
|
|
110
|
+
if (isAssertionArray) {
|
|
111
|
+
for (const assertion of assertions) {
|
|
112
|
+
output.push(`${SPACE.repeat(3)}- ${assertion}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function logSummary(output, runResults) {
|
|
118
|
+
let status_with_color = runResults.fails
|
|
119
|
+
? yellow("\u{2717} failed")
|
|
120
|
+
: blue("\u{2714} passed");
|
|
121
|
+
if (runResults.errors) {
|
|
122
|
+
status_with_color = gray("\u{2717} errored");
|
|
123
|
+
}
|
|
124
|
+
let totalTime = runResults.endTime - runResults.startTime;
|
|
125
|
+
output.push(`
|
|
126
|
+
${status_with_color}
|
|
127
|
+
duration: ${runResults.testTime.toFixed(4)} mS
|
|
128
|
+
total: ${totalTime.toFixed(4)} mS
|
|
129
|
+
`);
|
|
130
|
+
}
|
|
131
|
+
function blue(text) {
|
|
132
|
+
return `\x1b[44m\x1b[97m${text}\x1b[0m`;
|
|
133
|
+
}
|
|
134
|
+
function yellow(text) {
|
|
135
|
+
return `\x1b[43m\x1b[97m${text}\x1b[0m`;
|
|
136
|
+
}
|
|
137
|
+
function gray(text) {
|
|
138
|
+
return `\x1b[100m\x1b[97m${text}\x1b[0m`;
|
|
139
|
+
}
|
|
@@ -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(`${SPACE}${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(`${collection.expectedTests} tests
|
|
61
|
+
${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(`[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}[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,193 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
LoggerAction,
|
|
3
|
+
LoggerInterface,
|
|
4
|
+
EndTest,
|
|
5
|
+
} from "../../core/dist/mod.js";
|
|
6
|
+
import type { RunResults } from "./results_str.js";
|
|
7
|
+
|
|
8
|
+
import { getResultsAsString } from "./results_str.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() {
|
|
28
|
+
return this.#results.fails !== 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get errored() {
|
|
32
|
+
return this.#results.errors !== 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
get results(): string {
|
|
36
|
+
return getResultsAsString(this.#results);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
log(action: LoggerAction) {
|
|
40
|
+
if ("start_run" === action.type) {
|
|
41
|
+
this.#results.startTime = action.time;
|
|
42
|
+
this.#results.expectedCollections = action.expected_collection_count;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if ("end_run" === action.type) {
|
|
46
|
+
this.#results.endTime = action.time;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if ("run_error" === action.type) {
|
|
50
|
+
this.#results.errors += 1;
|
|
51
|
+
this.#results.errorLogs.push(action);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if ("start_collection" === action.type) {
|
|
55
|
+
this.#results.collections[action.collection_id] = {
|
|
56
|
+
completedModules: 0,
|
|
57
|
+
completedTests: 0,
|
|
58
|
+
errorLogs: [],
|
|
59
|
+
errors: 0,
|
|
60
|
+
expectedModules: action.expected_module_count,
|
|
61
|
+
expectedTests: 0,
|
|
62
|
+
fails: 0,
|
|
63
|
+
loggerAction: action,
|
|
64
|
+
modules: [],
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
this.#results.expectedModules += action.expected_module_count;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if ("end_collection" === action.type) {
|
|
71
|
+
let collection = this.#results.collections[action.collection_id];
|
|
72
|
+
if (!collection) return;
|
|
73
|
+
|
|
74
|
+
this.#results.completedCollections += 1;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if ("collection_error" === action.type) {
|
|
78
|
+
let collection = this.#results.collections[action.collection_id];
|
|
79
|
+
if (!collection) return;
|
|
80
|
+
|
|
81
|
+
this.#results.errors += 1;
|
|
82
|
+
collection.errors += 1;
|
|
83
|
+
|
|
84
|
+
collection.errorLogs.push(action);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if ("start_module" === action.type) {
|
|
88
|
+
let collection = this.#results.collections[action.collection_id];
|
|
89
|
+
if (!collection) return;
|
|
90
|
+
|
|
91
|
+
collection.modules[action.module_id] = {
|
|
92
|
+
completedTests: 0,
|
|
93
|
+
errorLogs: [],
|
|
94
|
+
errors: 0,
|
|
95
|
+
expectedTests: action.expected_test_count,
|
|
96
|
+
fails: 0,
|
|
97
|
+
loggerAction: action,
|
|
98
|
+
testResults: [],
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
collection.expectedTests += action.expected_test_count;
|
|
102
|
+
this.#results.expectedTests += action.expected_test_count;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if ("end_module" === action.type) {
|
|
106
|
+
let collection = this.#results.collections[action.collection_id];
|
|
107
|
+
if (!collection) return;
|
|
108
|
+
|
|
109
|
+
let module = collection.modules[action.module_id];
|
|
110
|
+
if (!module) return;
|
|
111
|
+
|
|
112
|
+
this.#results.completedModules += 1;
|
|
113
|
+
collection.completedModules += 1;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if ("module_error" === action.type) {
|
|
117
|
+
let collection = this.#results.collections[action.collection_id];
|
|
118
|
+
if (!collection) return;
|
|
119
|
+
|
|
120
|
+
let module = collection.modules[action.module_id];
|
|
121
|
+
if (!module) return;
|
|
122
|
+
|
|
123
|
+
this.#results.errors += 1;
|
|
124
|
+
collection.errors += 1;
|
|
125
|
+
module.errors += 1;
|
|
126
|
+
module.errorLogs.push(action);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if ("start_test" === action.type) {
|
|
130
|
+
let collection = this.#results.collections[action.collection_id];
|
|
131
|
+
if (!collection) return;
|
|
132
|
+
|
|
133
|
+
let module = collection.modules[action.module_id];
|
|
134
|
+
if (!module) return;
|
|
135
|
+
|
|
136
|
+
module.testResults[action.test_id] = {
|
|
137
|
+
loggerStartAction: action,
|
|
138
|
+
loggerEndAction: undefined,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if ("end_test" === action.type) {
|
|
143
|
+
endTest(this.#results, action);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if ("test_error" === action.type) {
|
|
147
|
+
let collection = this.#results.collections[action.collection_id];
|
|
148
|
+
if (!collection) return;
|
|
149
|
+
|
|
150
|
+
let module = collection.modules[action.module_id];
|
|
151
|
+
if (!module) return;
|
|
152
|
+
|
|
153
|
+
let testResult = module.testResults[action.test_id];
|
|
154
|
+
if (!testResult) return;
|
|
155
|
+
|
|
156
|
+
testResult.loggerEndAction = action;
|
|
157
|
+
this.#results.errors += 1;
|
|
158
|
+
collection.errors += 1;
|
|
159
|
+
module.errors += 1;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function endTest(runResults: RunResults, loggerAction: EndTest) {
|
|
165
|
+
let collection = runResults.collections[loggerAction.collection_id];
|
|
166
|
+
if (!collection) return;
|
|
167
|
+
|
|
168
|
+
let module = collection.modules[loggerAction.module_id];
|
|
169
|
+
if (!module) return;
|
|
170
|
+
|
|
171
|
+
let testResult = module.testResults[loggerAction.test_id];
|
|
172
|
+
if (!testResult) return;
|
|
173
|
+
|
|
174
|
+
testResult.loggerEndAction = loggerAction;
|
|
175
|
+
runResults.completedTests += 1;
|
|
176
|
+
collection.completedTests += 1;
|
|
177
|
+
module.completedTests += 1;
|
|
178
|
+
|
|
179
|
+
let { assertions } = loggerAction;
|
|
180
|
+
const isAssertionArray = Array.isArray(assertions) && assertions.length;
|
|
181
|
+
// might be worth just sticking with language standard "none" like "" or 0 or false
|
|
182
|
+
const isAssertion = !Array.isArray(assertions) && undefined !== assertions;
|
|
183
|
+
if (isAssertion || isAssertionArray) {
|
|
184
|
+
runResults.fails += 1;
|
|
185
|
+
collection.fails += 1;
|
|
186
|
+
module.fails += 1;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
runResults.testTime += Math.max(
|
|
190
|
+
0,
|
|
191
|
+
loggerAction.end_time - loggerAction.start_time,
|
|
192
|
+
);
|
|
193
|
+
}
|