jest-allure2-reporter
Version:
Idiomatic Jest reporter for Allure Framework
101 lines • 4.18 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeferredTaskQueue = void 0;
class DeferredTaskQueue {
pendingPayloads = new Map();
executingTasks = new Map();
processedPayloads = new Set();
config;
threadTailPromises = new Map();
constructor(config) {
this.config = config;
}
_getPayloadKey(payload) {
return this.config.getPayloadKey(payload);
}
/**
* Starts payload execution, chaining it in its thread and tracking its promise.
* @param payload Payload to execute.
* @param threadName Thread for this payload.
*/
_startExecutionAndTrack(payload, threadName) {
const payloadKey = this._getPayloadKey(payload);
if (this.executingTasks.has(payloadKey)) {
return;
}
const predecessorPromiseInThread = this.threadTailPromises.get(threadName) || Promise.resolve();
const taskExecutor = () => this.config.execute(payload);
// Chain the current task to the predecessor in the same thread.
// If predecessorPromiseInThread rejects, taskExecutor will not run.
const executionChainPromise = predecessorPromiseInThread.then(taskExecutor);
// This finalPromise is what gets stored and returned. It includes cleanup.
const finalPromise = executionChainPromise.then(() => {
this.processedPayloads.add(payloadKey);
this.executingTasks.delete(payloadKey);
}, () => {
this.executingTasks.delete(payloadKey);
});
this.executingTasks.set(payloadKey, finalPromise);
// This task's promise becomes the new tail for this thread.
this.threadTailPromises.set(threadName, finalPromise);
}
/**
* Adds a payload to the queue.
* If a payload for the same thread was pending, it starts. The new payload becomes pending.
* Does not await started tasks.
* @param payload Payload to enqueue.
*/
enqueue(payload) {
const key = this._getPayloadKey(payload);
if (this.processedPayloads.has(key)) {
// Payload with this key has already been processed, ignore it.
return;
}
const threadName = this.config.getThreadName(payload);
const previousPayload = this.pendingPayloads.get(threadName);
// Set the new payload as the currently pending one for this thread.
this.pendingPayloads.set(threadName, payload);
if (previousPayload !== undefined) {
// A new payload has superseded `previousPayload` for this thread.
// Execute `previousPayload` now. It will be chained correctly by _startExecutionAndTrack.
this._startExecutionAndTrack(previousPayload, threadName);
}
}
/**
* Starts pending payloads.
* If threadName is given, starts tasks for that thread only. Otherwise, starts all pending.
* Does not await task completion.
* @param threadName Optional. Specific thread to start.
*/
startPending(threadName) {
const payloadsToStart = [];
if (threadName) {
const payload = this.pendingPayloads.get(threadName);
if (payload) {
payloadsToStart.push({ payload, threadName });
this.pendingPayloads.delete(threadName);
}
}
else {
for (const [tName, payload] of this.pendingPayloads) {
payloadsToStart.push({ payload, threadName: tName });
}
this.pendingPayloads.clear();
}
for (const { payload, threadName: tn } of payloadsToStart) {
this._startExecutionAndTrack(payload, tn);
}
}
/**
* Waits for all currently executing tasks to complete.
* Does not start new tasks. Resolves when all tasks finish (or rejects if any task fails).
*/
async awaitCompletion() {
if (this.executingTasks.size > 0) {
const promises = [...this.executingTasks.values()];
await Promise.all(promises);
}
}
}
exports.DeferredTaskQueue = DeferredTaskQueue;
//# sourceMappingURL=DeferredTaskQueue.js.map