@decaf-ts/utils 0.9.5 → 0.10.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/lib/esm/index.d.ts +1 -1
- package/lib/esm/index.js +1 -1
- package/lib/esm/tests/Consumer.d.ts +39 -0
- package/lib/esm/tests/Consumer.js +250 -0
- package/lib/esm/tests/Consumer.js.map +1 -0
- package/lib/esm/tests/ProducerChildProcess.d.ts +17 -0
- package/lib/esm/tests/ProducerChildProcess.js +49 -0
- package/lib/esm/tests/ProducerChildProcess.js.map +1 -0
- package/lib/esm/tests/TestReporter.d.ts +193 -0
- package/lib/esm/tests/TestReporter.js +260 -0
- package/lib/esm/tests/TestReporter.js.map +1 -0
- package/lib/esm/tests/index.d.ts +2 -0
- package/lib/esm/tests/index.js +3 -0
- package/lib/esm/tests/index.js.map +1 -0
- package/lib/esm/utils/tests.d.ts +1 -193
- package/lib/esm/utils/tests.js +1 -259
- package/lib/esm/utils/tests.js.map +1 -1
- package/lib/index.cjs +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/tests/Consumer.cjs +256 -0
- package/lib/tests/Consumer.d.ts +39 -0
- package/lib/tests/Consumer.js.map +1 -0
- package/lib/tests/ProducerChildProcess.cjs +49 -0
- package/lib/tests/ProducerChildProcess.d.ts +17 -0
- package/lib/tests/ProducerChildProcess.js.map +1 -0
- package/lib/tests/TestReporter.cjs +300 -0
- package/lib/tests/TestReporter.d.ts +193 -0
- package/lib/tests/TestReporter.js.map +1 -0
- package/lib/tests/index.cjs +19 -0
- package/lib/tests/index.d.ts +2 -0
- package/lib/tests/index.js.map +1 -0
- package/lib/utils/tests.cjs +3 -285
- package/lib/utils/tests.d.ts +1 -193
- package/lib/utils/tests.js.map +1 -1
- package/package.json +11 -3
package/lib/esm/utils/tests.js
CHANGED
|
@@ -1,260 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
import { installIfNotAvailable } from "./fs.js";
|
|
4
|
-
/**
|
|
5
|
-
* @description Environment variable key for Jest HTML reporters temporary directory path
|
|
6
|
-
* @summary Constant defining the environment variable key for Jest HTML reporters
|
|
7
|
-
* @const JestReportersTempPathEnvKey
|
|
8
|
-
* @memberOf module:utils
|
|
9
|
-
*/
|
|
10
|
-
export const JestReportersTempPathEnvKey = "JEST_HTML_REPORTERS_TEMP_DIR_PATH";
|
|
11
|
-
/**
|
|
12
|
-
* @description Array of dependencies required by the test reporter
|
|
13
|
-
* @summary List of npm packages needed for reporting functionality
|
|
14
|
-
* @const dependencies
|
|
15
|
-
* @memberOf module:utils
|
|
16
|
-
*/
|
|
17
|
-
const dependencies = ["jest-html-reporters", "json2md", "chartjs-node-canvas"];
|
|
18
|
-
/**
|
|
19
|
-
* @description Normalizes imports to handle both CommonJS and ESModule formats
|
|
20
|
-
* @summary Utility function to handle module import differences between formats
|
|
21
|
-
* @template T - Type of the imported module
|
|
22
|
-
* @param {Promise<T>} importPromise - Promise returned by dynamic import
|
|
23
|
-
* @return {Promise<T>} Normalized module
|
|
24
|
-
* @function normalizeImport
|
|
25
|
-
* @memberOf module:utils
|
|
26
|
-
*/
|
|
27
|
-
async function normalizeImport(importPromise) {
|
|
28
|
-
// CommonJS's `module.exports` is wrapped as `default` in ESModule.
|
|
29
|
-
return importPromise.then((m) => (m.default || m));
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* @description Test reporting utility class for managing test results and evidence
|
|
33
|
-
* @summary A comprehensive test reporter that handles various types of test artifacts including messages,
|
|
34
|
-
* attachments, data, images, tables, and graphs. It provides methods to report and store test evidence
|
|
35
|
-
* in different formats and manages dependencies for reporting functionality.
|
|
36
|
-
*
|
|
37
|
-
* @template T - Type of data being reported
|
|
38
|
-
* @param {string} [testCase="tests"] - Name of the test case
|
|
39
|
-
* @param {string} [basePath] - Base path for storing test reports
|
|
40
|
-
* @class
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* ```typescript
|
|
44
|
-
* const reporter = new TestReporter('login-test');
|
|
45
|
-
*
|
|
46
|
-
* // Report test messages
|
|
47
|
-
* await reporter.reportMessage('Test Started', 'Login flow initiated');
|
|
48
|
-
*
|
|
49
|
-
* // Report test data
|
|
50
|
-
* await reporter.reportData('user-credentials', { username: 'test' }, 'json');
|
|
51
|
-
*
|
|
52
|
-
* // Report test results table
|
|
53
|
-
* await reporter.reportTable('test-results', {
|
|
54
|
-
* headers: ['Step', 'Status'],
|
|
55
|
-
* rows: [
|
|
56
|
-
* { Step: 'Login', Status: 'Pass' },
|
|
57
|
-
* { Step: 'Validation', Status: 'Pass' }
|
|
58
|
-
* ]
|
|
59
|
-
* });
|
|
60
|
-
*
|
|
61
|
-
* // Report test evidence
|
|
62
|
-
* await reporter.reportAttachment('Screenshot', screenshotBuffer);
|
|
63
|
-
* ```
|
|
64
|
-
*
|
|
65
|
-
* @mermaid
|
|
66
|
-
* sequenceDiagram
|
|
67
|
-
* participant Client
|
|
68
|
-
* participant TestReporter
|
|
69
|
-
* participant FileSystem
|
|
70
|
-
* participant Dependencies
|
|
71
|
-
*
|
|
72
|
-
* Client->>TestReporter: new TestReporter(testCase, basePath)
|
|
73
|
-
* TestReporter->>FileSystem: Create report directory
|
|
74
|
-
*
|
|
75
|
-
* alt Report Message
|
|
76
|
-
* Client->>TestReporter: reportMessage(title, message)
|
|
77
|
-
* TestReporter->>Dependencies: Import helpers
|
|
78
|
-
* TestReporter->>FileSystem: Store message
|
|
79
|
-
* else Report Data
|
|
80
|
-
* Client->>TestReporter: reportData(reference, data, type)
|
|
81
|
-
* TestReporter->>Dependencies: Process data
|
|
82
|
-
* TestReporter->>FileSystem: Store formatted data
|
|
83
|
-
* else Report Table
|
|
84
|
-
* Client->>TestReporter: reportTable(reference, tableDef)
|
|
85
|
-
* TestReporter->>Dependencies: Convert to MD format
|
|
86
|
-
* TestReporter->>FileSystem: Store table
|
|
87
|
-
* end
|
|
88
|
-
*/
|
|
89
|
-
export class TestReporter {
|
|
90
|
-
constructor(testCase = "tests", basePath = path.join(process.cwd(), "workdocs", "reports", "evidences")) {
|
|
91
|
-
this.testCase = testCase;
|
|
92
|
-
this.basePath = basePath;
|
|
93
|
-
this.basePath = path.join(basePath, this.testCase);
|
|
94
|
-
if (!fs.existsSync(this.basePath)) {
|
|
95
|
-
fs.mkdirSync(basePath, { recursive: true });
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* @description Imports required helper functions
|
|
100
|
-
* @summary Ensures all necessary dependencies are available and imports helper functions
|
|
101
|
-
* @return {Promise<void>} Promise that resolves when helpers are imported
|
|
102
|
-
*/
|
|
103
|
-
async importHelpers() {
|
|
104
|
-
this.deps = await installIfNotAvailable([dependencies[0]], this.deps);
|
|
105
|
-
// if (!process.env[JestReportersTempPathEnvKey])
|
|
106
|
-
// process.env[JestReportersTempPathEnvKey] = './workdocs/reports';
|
|
107
|
-
const { addMsg, addAttach } = await normalizeImport(import(`${dependencies[0]}/helper`));
|
|
108
|
-
TestReporter.addMsgFunction = addMsg;
|
|
109
|
-
TestReporter.addAttachFunction = addAttach;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* @description Reports a message to the test report
|
|
113
|
-
* @summary Adds a formatted message to the test report with an optional title
|
|
114
|
-
* @param {string} title - Title of the message
|
|
115
|
-
* @param {string | object} message - Content of the message
|
|
116
|
-
* @return {Promise<void>} Promise that resolves when the message is reported
|
|
117
|
-
*/
|
|
118
|
-
async reportMessage(title, message) {
|
|
119
|
-
if (!TestReporter.addMsgFunction)
|
|
120
|
-
await this.importHelpers();
|
|
121
|
-
const msg = `${title}${message ? `\n${message}` : ""}`;
|
|
122
|
-
await TestReporter.addMsgFunction({ message: msg });
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* @description Reports an attachment to the test report
|
|
126
|
-
* @summary Adds a formatted message to the test report with an optional title
|
|
127
|
-
* @param {string} title - Title of the message
|
|
128
|
-
* @param {string | Buffer} attachment - Content of the message
|
|
129
|
-
* @return {Promise<void>} Promise that resolves when the message is reported
|
|
130
|
-
*/
|
|
131
|
-
async reportAttachment(title, attachment) {
|
|
132
|
-
if (!TestReporter.addAttachFunction)
|
|
133
|
-
await this.importHelpers();
|
|
134
|
-
await TestReporter.addAttachFunction({
|
|
135
|
-
attach: attachment,
|
|
136
|
-
description: title,
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* @description Reports data with specified type
|
|
141
|
-
* @summary Processes and stores data in the test report with formatting
|
|
142
|
-
* @param {string} reference - Reference identifier for the data
|
|
143
|
-
* @param {string | number | object} data - Data to be reported
|
|
144
|
-
* @param {PayloadType} type - Type of the payload
|
|
145
|
-
* @param {boolean} [trim=false] - Whether to trim the data
|
|
146
|
-
* @return {Promise<void>} Promise that resolves when data is reported
|
|
147
|
-
*/
|
|
148
|
-
async report(reference, data, type, trim = false) {
|
|
149
|
-
try {
|
|
150
|
-
let attachFunction = this.reportMessage.bind(this);
|
|
151
|
-
let extension = ".txt";
|
|
152
|
-
switch (type) {
|
|
153
|
-
case "image":
|
|
154
|
-
data = Buffer.from(data);
|
|
155
|
-
extension = ".png";
|
|
156
|
-
attachFunction = this.reportAttachment.bind(this);
|
|
157
|
-
break;
|
|
158
|
-
case "json":
|
|
159
|
-
if (trim) {
|
|
160
|
-
if (data.request)
|
|
161
|
-
delete data["request"];
|
|
162
|
-
if (data.config)
|
|
163
|
-
delete data["config"];
|
|
164
|
-
}
|
|
165
|
-
data = JSON.stringify(data, null, 2);
|
|
166
|
-
extension = ".json";
|
|
167
|
-
break;
|
|
168
|
-
case "md":
|
|
169
|
-
extension = ".md";
|
|
170
|
-
break;
|
|
171
|
-
case "text":
|
|
172
|
-
extension = ".txt";
|
|
173
|
-
break;
|
|
174
|
-
default:
|
|
175
|
-
console.log(`Unsupported type ${type}. assuming text`);
|
|
176
|
-
}
|
|
177
|
-
reference = reference.includes("\n")
|
|
178
|
-
? reference
|
|
179
|
-
: `${reference}${extension}`;
|
|
180
|
-
await attachFunction(reference, data);
|
|
181
|
-
}
|
|
182
|
-
catch (e) {
|
|
183
|
-
throw new Error(`Could not store attach artifact ${reference} under to test report ${this.testCase} - ${e}`);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* @description Reports data with a specified type
|
|
188
|
-
* @summary Wrapper method for reporting various types of data
|
|
189
|
-
* @param {string} reference - Reference identifier for the data
|
|
190
|
-
* @param {string | number | object} data - Data to be reported
|
|
191
|
-
* @param {PayloadType} [type="json"] - Type of the payload
|
|
192
|
-
* @param {boolean} [trim=false] - Whether to trim the data
|
|
193
|
-
* @return {Promise<void>} Promise that resolves when data is reported
|
|
194
|
-
*/
|
|
195
|
-
async reportData(reference, data, type = "json", trim = false) {
|
|
196
|
-
return this.report(reference, data, type, trim);
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* @description Reports a JSON object
|
|
200
|
-
* @summary Convenience method for reporting JSON objects
|
|
201
|
-
* @param {string} reference - Reference identifier for the object
|
|
202
|
-
* @param {object} json - JSON object to be reported
|
|
203
|
-
* @param {boolean} [trim=false] - Whether to trim the object
|
|
204
|
-
* @return {Promise<void>} Promise that resolves when object is reported
|
|
205
|
-
*/
|
|
206
|
-
async reportObject(reference, json, trim = false) {
|
|
207
|
-
return this.report(reference, json, "json", trim);
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* @description Reports a table in markdown format
|
|
211
|
-
* @summary Converts and stores a table definition in markdown format
|
|
212
|
-
* @param {string} reference - Reference identifier for the table
|
|
213
|
-
* @param {MdTableDefinition} tableDef - Table definition object
|
|
214
|
-
* @return {Promise<void>} Promise that resolves when table is reported
|
|
215
|
-
*/
|
|
216
|
-
async reportTable(reference, tableDef) {
|
|
217
|
-
this.deps = await installIfNotAvailable([dependencies[1]], this.deps);
|
|
218
|
-
let txt;
|
|
219
|
-
try {
|
|
220
|
-
const json2md = await normalizeImport(import(`${dependencies[1]}`));
|
|
221
|
-
txt = json2md(tableDef);
|
|
222
|
-
}
|
|
223
|
-
catch (e) {
|
|
224
|
-
throw new Error(`Could not convert JSON to Markdown - ${e}`);
|
|
225
|
-
}
|
|
226
|
-
return this.report(reference, txt, "md");
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* @description Reports a graph using Chart.js
|
|
230
|
-
* @summary Generates and stores a graph visualization
|
|
231
|
-
* @param {string} reference - Reference identifier for the graph
|
|
232
|
-
* @param {any} config - Chart.js configuration object
|
|
233
|
-
* @return {Promise<void>} Promise that resolves when graph is reported
|
|
234
|
-
*/
|
|
235
|
-
async reportGraph(reference, config) {
|
|
236
|
-
this.deps = await installIfNotAvailable([dependencies[2]], this.deps);
|
|
237
|
-
const { ChartJSNodeCanvas } = await normalizeImport(import(dependencies[2]));
|
|
238
|
-
const width = 600; //px
|
|
239
|
-
const height = 800; //px
|
|
240
|
-
const backgroundColour = "white"; // Uses https://www.w3schools.com/tags/canvas_fillstyle.asp
|
|
241
|
-
const chartJSNodeCanvas = new ChartJSNodeCanvas({
|
|
242
|
-
width,
|
|
243
|
-
height,
|
|
244
|
-
backgroundColour,
|
|
245
|
-
});
|
|
246
|
-
const image = await chartJSNodeCanvas.renderToBuffer(config);
|
|
247
|
-
return await this.reportImage(reference, image);
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* @description Reports an image to the test report
|
|
251
|
-
* @summary Stores an image buffer in the test report
|
|
252
|
-
* @param {string} reference - Reference identifier for the image
|
|
253
|
-
* @param {Buffer} buffer - Image data buffer
|
|
254
|
-
* @return {Promise<void>} Promise that resolves when image is reported
|
|
255
|
-
*/
|
|
256
|
-
async reportImage(reference, buffer) {
|
|
257
|
-
return this.report(reference, buffer, "image");
|
|
258
|
-
}
|
|
259
|
-
}
|
|
1
|
+
export * from "./../tests/index.js";
|
|
260
2
|
//# sourceMappingURL=tests.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tests.js","sourceRoot":"","sources":["../../../src/utils/tests.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"tests.js","sourceRoot":"","sources":["../../../src/utils/tests.ts"],"names":[],"mappings":"AAAA,oCAAyB"}
|
package/lib/index.cjs
CHANGED
|
@@ -43,7 +43,7 @@ __exportStar(require("./writers/index.cjs"), exports);
|
|
|
43
43
|
* @const VERSION
|
|
44
44
|
* @memberOf module:utils
|
|
45
45
|
*/
|
|
46
|
-
exports.VERSION = "0.9.
|
|
46
|
+
exports.VERSION = "0.9.6";
|
|
47
47
|
/**
|
|
48
48
|
* @description Represents the current version of the module.
|
|
49
49
|
* @summary Stores the version for the @decaf-ts/utils package. The build replaces
|
package/lib/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export * from "./writers";
|
|
|
26
26
|
* @const VERSION
|
|
27
27
|
* @memberOf module:utils
|
|
28
28
|
*/
|
|
29
|
-
export declare const VERSION = "0.9.
|
|
29
|
+
export declare const VERSION = "0.9.6";
|
|
30
30
|
/**
|
|
31
31
|
* @description Represents the current version of the module.
|
|
32
32
|
* @summary Stores the version for the @decaf-ts/utils package. The build replaces
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConsumerRunner = exports.reportingComparer = exports.defaultComparer = void 0;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const logging_1 = require("@decaf-ts/logging");
|
|
7
|
+
const TestReporter_1 = require("./TestReporter.cjs");
|
|
8
|
+
const parseData = (data) => {
|
|
9
|
+
const [timestamp, , child, action] = data.split(" - ");
|
|
10
|
+
return {
|
|
11
|
+
timestamp: parseInt(timestamp, 10),
|
|
12
|
+
child,
|
|
13
|
+
action,
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
const defaultComparer = async (consumerData, producerData) => {
|
|
17
|
+
const sortedConsumerData = Object.keys(consumerData)
|
|
18
|
+
.reduce((accum, key) => {
|
|
19
|
+
const identifier = Number(key);
|
|
20
|
+
const entries = consumerData[identifier] ?? [];
|
|
21
|
+
accum.push(...entries.map((entry) => parseData(entry)));
|
|
22
|
+
return accum;
|
|
23
|
+
}, [])
|
|
24
|
+
.sort((a, b) => a.timestamp - b.timestamp);
|
|
25
|
+
const sortedProducerData = Object.keys(producerData)
|
|
26
|
+
.reduce((accum, key) => {
|
|
27
|
+
const identifier = Number(key);
|
|
28
|
+
const entries = producerData[identifier] ?? [];
|
|
29
|
+
accum.push(...entries.map((entry) => parseData(entry)));
|
|
30
|
+
return accum;
|
|
31
|
+
}, [])
|
|
32
|
+
.sort((a, b) => a.timestamp - b.timestamp);
|
|
33
|
+
if (sortedProducerData.length !== sortedConsumerData.length) {
|
|
34
|
+
throw new Error("Producer data and consumer data does not match in length");
|
|
35
|
+
}
|
|
36
|
+
let counter = -1;
|
|
37
|
+
const isMatching = sortedProducerData.every((producer, index) => {
|
|
38
|
+
counter = index;
|
|
39
|
+
const consumer = sortedConsumerData[index];
|
|
40
|
+
return (producer.child === consumer.child && producer.action === consumer.action);
|
|
41
|
+
});
|
|
42
|
+
if (!isMatching) {
|
|
43
|
+
const errorLines = [
|
|
44
|
+
`Producer data and consumer data do not sort the same way as of record ${counter}:`,
|
|
45
|
+
" | CONSUMER | PRODUCER |",
|
|
46
|
+
" | id | action | timestamp | id | action | timestamp |",
|
|
47
|
+
];
|
|
48
|
+
sortedProducerData.forEach((producer, index) => {
|
|
49
|
+
if (index < counter || index > counter + 15) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const consumer = sortedConsumerData[index];
|
|
53
|
+
errorLines.push(` ${index < 10 ? `0${index}` : index}| ${consumer.child} | ${consumer.action} | ${consumer.timestamp} | ${producer.child} | ${producer.action} | ${producer.timestamp} |`);
|
|
54
|
+
});
|
|
55
|
+
throw new Error(errorLines.join("\n"));
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
consumer: sortedConsumerData,
|
|
59
|
+
producer: sortedProducerData,
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
exports.defaultComparer = defaultComparer;
|
|
63
|
+
const formatTimestamp = (value) => new Date(value).toISOString();
|
|
64
|
+
const reportingComparer = async (consumerData, producerData, options) => {
|
|
65
|
+
const reporter = options?.reporter ??
|
|
66
|
+
new TestReporter_1.TestReporter(options?.testCase ?? "consumer-producer");
|
|
67
|
+
const referencePrefix = options?.referencePrefix ?? "consumer-producer";
|
|
68
|
+
try {
|
|
69
|
+
const comparison = await (0, exports.defaultComparer)(consumerData, producerData);
|
|
70
|
+
const rows = comparison.consumer.map((consumerEntry, index) => {
|
|
71
|
+
const producerEntry = comparison.producer[index];
|
|
72
|
+
return {
|
|
73
|
+
Index: `${index}`,
|
|
74
|
+
"Consumer Child": consumerEntry.child,
|
|
75
|
+
"Consumer Action": consumerEntry.action,
|
|
76
|
+
"Consumer Timestamp": formatTimestamp(consumerEntry.timestamp),
|
|
77
|
+
"Producer Child": producerEntry?.child ?? "N/A",
|
|
78
|
+
"Producer Action": producerEntry?.action ?? "N/A",
|
|
79
|
+
"Producer Timestamp": producerEntry
|
|
80
|
+
? formatTimestamp(producerEntry.timestamp)
|
|
81
|
+
: "N/A",
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
await Promise.allSettled([
|
|
85
|
+
reporter.reportMessage(`${referencePrefix}-comparison`, `Consumer and producer logs matched (${comparison.consumer.length} entries).`),
|
|
86
|
+
reporter.reportTable(`${referencePrefix}-logs`, {
|
|
87
|
+
headers: [
|
|
88
|
+
"Index",
|
|
89
|
+
"Consumer Child",
|
|
90
|
+
"Consumer Action",
|
|
91
|
+
"Consumer Timestamp",
|
|
92
|
+
"Producer Child",
|
|
93
|
+
"Producer Action",
|
|
94
|
+
"Producer Timestamp",
|
|
95
|
+
],
|
|
96
|
+
rows,
|
|
97
|
+
}),
|
|
98
|
+
]);
|
|
99
|
+
return comparison;
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
const message = error instanceof Error ? error.message : String(error ?? "Unknown error");
|
|
103
|
+
await Promise.allSettled([
|
|
104
|
+
reporter.reportMessage(`${referencePrefix}-mismatch`, message),
|
|
105
|
+
reporter.reportObject(`${referencePrefix}-consumer`, consumerData),
|
|
106
|
+
reporter.reportObject(`${referencePrefix}-producer`, producerData),
|
|
107
|
+
]);
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
exports.reportingComparer = reportingComparer;
|
|
112
|
+
class ConsumerRunner extends logging_1.LoggedClass {
|
|
113
|
+
constructor(action, consumerHandler, compareHandler) {
|
|
114
|
+
super();
|
|
115
|
+
this.forkedCache = [];
|
|
116
|
+
this.consumerResults = {};
|
|
117
|
+
this.producerResults = {};
|
|
118
|
+
this.completionTriggered = false;
|
|
119
|
+
this.action = action;
|
|
120
|
+
this.handler = consumerHandler;
|
|
121
|
+
this.comparerHandle = compareHandler ?? exports.defaultComparer;
|
|
122
|
+
this.reset();
|
|
123
|
+
}
|
|
124
|
+
reset() {
|
|
125
|
+
this.forkedCache = [];
|
|
126
|
+
this.consumerResults = {};
|
|
127
|
+
this.producerResults = {};
|
|
128
|
+
this.completionTriggered = false;
|
|
129
|
+
}
|
|
130
|
+
store(identifier, action, timeout, times, count, random) {
|
|
131
|
+
const logParts = [
|
|
132
|
+
Date.now(),
|
|
133
|
+
"PRODUCER",
|
|
134
|
+
identifier,
|
|
135
|
+
action,
|
|
136
|
+
];
|
|
137
|
+
if (timeout) {
|
|
138
|
+
logParts.push(timeout);
|
|
139
|
+
}
|
|
140
|
+
if (times && count) {
|
|
141
|
+
logParts.push(`${count}/${times}`, random ?? false);
|
|
142
|
+
}
|
|
143
|
+
const log = logParts.join(" - ");
|
|
144
|
+
if (!this.producerResults[identifier]) {
|
|
145
|
+
this.producerResults[identifier] = [];
|
|
146
|
+
}
|
|
147
|
+
this.producerResults[identifier].push(log);
|
|
148
|
+
}
|
|
149
|
+
recordConsumer(identifier) {
|
|
150
|
+
const logParts = [
|
|
151
|
+
Date.now(),
|
|
152
|
+
"CONSUMER",
|
|
153
|
+
identifier,
|
|
154
|
+
this.action,
|
|
155
|
+
];
|
|
156
|
+
const log = logParts.join(" - ");
|
|
157
|
+
if (!this.consumerResults[identifier]) {
|
|
158
|
+
this.consumerResults[identifier] = [];
|
|
159
|
+
}
|
|
160
|
+
this.consumerResults[identifier].push(log);
|
|
161
|
+
}
|
|
162
|
+
isProducerComplete(count, times) {
|
|
163
|
+
const producerKeys = Object.keys(this.producerResults);
|
|
164
|
+
if (producerKeys.length !== count) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
return producerKeys.every((key) => this.producerResults[Number(key)]?.length === times);
|
|
168
|
+
}
|
|
169
|
+
isConsumerComplete(count, times) {
|
|
170
|
+
const consumerKeys = Object.keys(this.consumerResults);
|
|
171
|
+
if (consumerKeys.length !== count) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
return consumerKeys.every((key) => this.consumerResults[Number(key)]?.length === times);
|
|
175
|
+
}
|
|
176
|
+
terminateChildren() {
|
|
177
|
+
if (!this.forkedCache) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
this.forkedCache.forEach((forked, index) => {
|
|
181
|
+
forked.send({
|
|
182
|
+
identifier: index,
|
|
183
|
+
terminate: true,
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
this.forkedCache = undefined;
|
|
187
|
+
}
|
|
188
|
+
async run(count, timeout, times, random) {
|
|
189
|
+
this.reset();
|
|
190
|
+
const childPath = (0, node_path_1.join)(__dirname, "ProducerChildProcess.cjs");
|
|
191
|
+
return new Promise((resolve, reject) => {
|
|
192
|
+
const handleError = (error) => {
|
|
193
|
+
if (this.completionTriggered) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
this.completionTriggered = true;
|
|
197
|
+
this.terminateChildren();
|
|
198
|
+
reject(error);
|
|
199
|
+
};
|
|
200
|
+
const finalizeIfComplete = () => {
|
|
201
|
+
if (this.completionTriggered) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (!this.isProducerComplete(count, times) ||
|
|
205
|
+
!this.isConsumerComplete(count, times)) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
this.terminateChildren();
|
|
209
|
+
this.completionTriggered = true;
|
|
210
|
+
try {
|
|
211
|
+
Promise.resolve(this.comparerHandle(this.consumerResults, this.producerResults))
|
|
212
|
+
.then(resolve)
|
|
213
|
+
.catch(reject);
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
reject(error);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
const checkProducerCompletion = () => {
|
|
220
|
+
if (this.isProducerComplete(count, times)) {
|
|
221
|
+
this.terminateChildren();
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
for (let identifier = 1; identifier < count + 1; identifier += 1) {
|
|
225
|
+
const forked = (0, node_child_process_1.fork)(childPath);
|
|
226
|
+
this.forkedCache?.push(forked);
|
|
227
|
+
forked.on("error", handleError);
|
|
228
|
+
forked.on("message", async (message) => {
|
|
229
|
+
const { identifier: childId, args, action, timeout: childTimeout, times: childTimes, random: childRandom, } = message;
|
|
230
|
+
try {
|
|
231
|
+
this.store(childId, action, childTimeout, childTimes, count, childRandom);
|
|
232
|
+
checkProducerCompletion();
|
|
233
|
+
const handlerArgs = Array.isArray(args) ? args : [];
|
|
234
|
+
await Promise.resolve(this.handler(childId, ...handlerArgs));
|
|
235
|
+
this.recordConsumer(childId);
|
|
236
|
+
finalizeIfComplete();
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
handleError(error);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
this.forkedCache?.forEach((forked, index) => {
|
|
244
|
+
forked.send({
|
|
245
|
+
identifier: index,
|
|
246
|
+
action: this.action,
|
|
247
|
+
timeout,
|
|
248
|
+
times,
|
|
249
|
+
random,
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
exports.ConsumerRunner = ConsumerRunner;
|
|
256
|
+
//# sourceMappingURL=Consumer.js.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { LoggedClass } from "@decaf-ts/logging";
|
|
2
|
+
import { TestReporter } from "./TestReporter";
|
|
3
|
+
type LogStore = Record<number, string[]>;
|
|
4
|
+
export interface ParsedLog {
|
|
5
|
+
timestamp: number;
|
|
6
|
+
child: string;
|
|
7
|
+
action: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ComparerResult {
|
|
10
|
+
consumer: ParsedLog[];
|
|
11
|
+
producer: ParsedLog[];
|
|
12
|
+
}
|
|
13
|
+
type Comparer = (consumerData: LogStore, producerData: LogStore) => Promise<ComparerResult>;
|
|
14
|
+
type ConsumerHandler = (identifier: number, ...args: unknown[]) => unknown | Promise<unknown>;
|
|
15
|
+
export declare const defaultComparer: Comparer;
|
|
16
|
+
export interface ReportingComparerOptions {
|
|
17
|
+
reporter?: TestReporter;
|
|
18
|
+
testCase?: string;
|
|
19
|
+
referencePrefix?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare const reportingComparer: (consumerData: LogStore, producerData: LogStore, options?: ReportingComparerOptions) => Promise<ComparerResult>;
|
|
22
|
+
export declare class ConsumerRunner extends LoggedClass {
|
|
23
|
+
private readonly action;
|
|
24
|
+
private readonly handler;
|
|
25
|
+
private readonly comparerHandle;
|
|
26
|
+
private forkedCache;
|
|
27
|
+
private consumerResults;
|
|
28
|
+
private producerResults;
|
|
29
|
+
private completionTriggered;
|
|
30
|
+
constructor(action: string, consumerHandler: ConsumerHandler, compareHandler?: Comparer);
|
|
31
|
+
private reset;
|
|
32
|
+
private store;
|
|
33
|
+
private recordConsumer;
|
|
34
|
+
private isProducerComplete;
|
|
35
|
+
private isConsumerComplete;
|
|
36
|
+
private terminateChildren;
|
|
37
|
+
run(count: number, timeout: number | undefined, times: number, random: boolean | undefined): Promise<ComparerResult>;
|
|
38
|
+
}
|
|
39
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Consumer.js","sourceRoot":"","sources":["../../src/tests/Consumer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const result = [];
|
|
3
|
+
process.on('message', (args) => {
|
|
4
|
+
const { identifier, action, timeout, times, random, terminate } = args;
|
|
5
|
+
const tick = (count) => {
|
|
6
|
+
const logParts = [Date.now(), 'PRODUCER', identifier, action];
|
|
7
|
+
if (timeout) {
|
|
8
|
+
logParts.push(timeout);
|
|
9
|
+
}
|
|
10
|
+
if (times && count) {
|
|
11
|
+
logParts.push(`${count}/${times}`, random ?? false);
|
|
12
|
+
}
|
|
13
|
+
const log = logParts.join(' - ');
|
|
14
|
+
result.push(log);
|
|
15
|
+
const response = { identifier, action, timeout, times, random };
|
|
16
|
+
if (result.length === times) {
|
|
17
|
+
response.result = [...result];
|
|
18
|
+
}
|
|
19
|
+
process.send?.(response);
|
|
20
|
+
};
|
|
21
|
+
if (terminate) {
|
|
22
|
+
const log = [Date.now(), 'PRODUCER', identifier, action, 'Quitting!'].join(' - ');
|
|
23
|
+
console.log(log);
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
if (!timeout) {
|
|
27
|
+
tick(times);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const getTimeout = () => {
|
|
31
|
+
if (!random) {
|
|
32
|
+
return timeout;
|
|
33
|
+
}
|
|
34
|
+
return Math.floor(Math.random() * timeout);
|
|
35
|
+
};
|
|
36
|
+
let actionCount = 0;
|
|
37
|
+
const iterator = () => {
|
|
38
|
+
const currentTimeout = getTimeout();
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
actionCount += 1;
|
|
41
|
+
tick(actionCount);
|
|
42
|
+
if (actionCount < times) {
|
|
43
|
+
iterator();
|
|
44
|
+
}
|
|
45
|
+
}, currentTimeout);
|
|
46
|
+
};
|
|
47
|
+
iterator();
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=ProducerChildProcess.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type ParentMessage = {
|
|
2
|
+
identifier: number;
|
|
3
|
+
action: string;
|
|
4
|
+
timeout?: number;
|
|
5
|
+
times: number;
|
|
6
|
+
random?: boolean;
|
|
7
|
+
terminate?: boolean;
|
|
8
|
+
};
|
|
9
|
+
type ProducerResponse = {
|
|
10
|
+
identifier: number;
|
|
11
|
+
action: string;
|
|
12
|
+
timeout?: number;
|
|
13
|
+
times: number;
|
|
14
|
+
random?: boolean;
|
|
15
|
+
result?: string[];
|
|
16
|
+
};
|
|
17
|
+
declare const result: string[];
|