UNPKG

@synap-ac/node-dot-extra-reporter

Version:
209 lines 28 kB
import { Transform } from "node:stream"; import chalk from "chalk"; import test from "node:test"; var EventType; (function (EventType) { EventType["ENQUEUE"] = "test:enqueue"; EventType["DEQUEUE"] = "test:dequeue"; EventType["START"] = "test:start"; EventType["PASS"] = "test:pass"; EventType["FAIL"] = "test:fail"; EventType["PLAN"] = "test:plan"; EventType["WATCH_DRAINED"] = "test:watch:drained"; EventType["STDOUT"] = "test:stdout"; EventType["STDERR"] = "test:stderr"; })(EventType || (EventType = {})); class DotExtraReporter extends Transform { passedTests; skippedTests; todoTests; totalDuration; failedTests; testSuite; currentSuite; currentSuiteLineage = []; nesting = 0; constructor(options = {}) { super({ ...options, writableObjectMode: true }); this.passedTests = 0; this.skippedTests = []; this.todoTests = []; this.totalDuration = 0; this.failedTests = []; this.testSuite = {}; } handleTestStart(test) { // Add new child const newItem = { file: test.file, name: test.name, nesting: test.nesting, children: {}, }; // If nesting > current nesting then // We've moved into a nested suite so: // - Add the current suite to the lineage // - Add new item as a child of the current suite if (test.nesting === 0) { // First entry this.currentSuite = newItem; this.testSuite[`${test.file}:${test.name}`] = newItem; } else if (test.nesting > this.nesting) { this.currentSuiteLineage.push(this.currentSuite); this.currentSuite.children[test.name] = newItem; this.currentSuite = newItem; } else { // Not deeper so add to current parent, and set new item to current const parent = this.currentSuiteLineage.pop(); parent.children[test.name] = newItem; this.currentSuiteLineage.push(parent); this.currentSuite = newItem; } this.nesting = test.nesting; } handleTestResult(test, eventType) { // Update test result details this.currentSuite.passed = eventType === EventType.PASS; if (test.details) { this.currentSuite.details = test.details; } if (test.skip) { process.stdout.write(chalk.yellow("*")); this.currentSuite.skip = test.skip; } else if (test.todo) { process.stdout.write(chalk.blue("-")); this.currentSuite.todo = test.todo; } else if (this.currentSuite.passed) { process.stdout.write(chalk.green(".")); } else { process.stdout.write(chalk.red("F")); } this.nesting = test.nesting; } handleTestEnd(test) { // Suite finished, step up to parent this.currentSuite = this.currentSuiteLineage.pop(); this.nesting = test.nesting; } _transform(event, _encoding, callback) { try { const test = event.data; switch (event.type) { case EventType.START: this.handleTestStart(test); break; case EventType.PASS: case EventType.FAIL: if (test.name !== test.file) { this.handleTestResult(test, event.type); } break; case EventType.PLAN: this.handleTestEnd(test); break; case EventType.STDOUT: process.stdout.write(event.data.message ?? ""); break; case EventType.STDERR: process.stderr.write(event.data.message ?? ""); break; default: break; } callback(); } catch (error) { console.log(error); callback(error); } } processOutcomes() { Object.entries(this.testSuite).forEach(([file, suite]) => { this.buildStats(suite); // File suite doesn't have a duration so collate from all top level suites. Object.values(suite.children ?? {}).forEach((child) => { this.totalDuration += child.details?.duration_ms || 0; }); }); } buildStats(suite, prefix) { const isSuite = (obj) => obj.details?.type === "suite"; if (isSuite(suite)) { // Iterate over each child Object.values(suite.children).forEach((child) => this.buildStats(child, prefix ? `${prefix} > ${suite.name}` : suite.name)); } if (prefix) { suite.name = `${prefix} > ${suite.name}`; } if (suite.skip) { this.skippedTests.push(suite); } else if (suite.todo) { this.todoTests.push(suite); } else if (!isSuite(suite)) { if (suite.passed === false) { this.failedTests.push(suite); } else { this.passedTests++; } } } _flush() { this.processOutcomes(); if (this.skippedTests.length > 0) { console.log("\n\nSkipped:"); this.skippedTests.forEach((test, i) => { console.log(`\n${i + 1}) ${test.name}`); if (typeof test.skip === "string") { console.log(chalk.yellow(`\tSkipped: ${test.skip}`)); } else { console.log(chalk.yellow(`\t${"Skipped: No reason"}`)); } }); } if (this.todoTests.length > 0) { console.log("\n\nTodo:"); this.todoTests.forEach((test, i) => { console.log(`\n${i + 1}) ${test.name}`); if (typeof test.todo === "string") { console.log(chalk.blue(`\tTODO: ${test.todo}`)); } else { console.log(chalk.blue(`\t${"TODO: No reason"}`)); } }); } if (this.failedTests.length > 0) { console.log(chalk.red("\n✖") + " Failing tests:"); this.failedTests.forEach((test, i) => { console.log(chalk.red(`\n${i + 1}) ${test.name} (${test.details.duration_ms}ms)`)); console.log(test.details.error?.cause); }); } console.log(`\n\nℹ Tests ${this.passedTests + this.failedTests.length + this.skippedTests.length + this.todoTests.length}`); console.log(`ℹ Passed ${chalk.green(this.passedTests)}`); console.log(`ℹ Failed ${chalk.red(this.failedTests.length)}`); console.log(`ℹ Skipped ${chalk.yellow(this.skippedTests.length)}`); console.log(`ℹ Todo ${chalk.blue(this.todoTests.length)}`); console.log(`ℹ Duration ${this.totalDuration.toFixed(2)}ms`); this.passedTests = 0; this.skippedTests = []; this.todoTests = []; this.totalDuration = 0; this.failedTests = []; this.testSuite = {}; } } export default DotExtraReporter; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG90LWV4dHJhLXJlcG9ydGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2RvdC1leHRyYS1yZXBvcnRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUEwQixNQUFNLGFBQWEsQ0FBQztBQUNoRSxPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFDMUIsT0FBTyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBbUM3QixJQUFLLFNBVUo7QUFWRCxXQUFLLFNBQVM7SUFDWixxQ0FBd0IsQ0FBQTtJQUN4QixxQ0FBd0IsQ0FBQTtJQUN4QixpQ0FBb0IsQ0FBQTtJQUNwQiwrQkFBa0IsQ0FBQTtJQUNsQiwrQkFBa0IsQ0FBQTtJQUNsQiwrQkFBa0IsQ0FBQTtJQUNsQixpREFBb0MsQ0FBQTtJQUNwQyxtQ0FBc0IsQ0FBQTtJQUN0QixtQ0FBc0IsQ0FBQTtBQUN4QixDQUFDLEVBVkksU0FBUyxLQUFULFNBQVMsUUFVYjtBQU9ELE1BQU0sZ0JBQWlCLFNBQVEsU0FBUztJQUM5QixXQUFXLENBQVM7SUFFcEIsWUFBWSxDQUFTO0lBRXJCLFNBQVMsQ0FBUztJQUVsQixhQUFhLENBQVM7SUFFdEIsV0FBVyxDQUFTO0lBRXBCLFNBQVMsQ0FBWTtJQUVyQixZQUFZLENBQW9CO0lBRWhDLG1CQUFtQixHQUFZLEVBQUUsQ0FBQztJQUVsQyxPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBRXBCLFlBQVksT0FBTyxHQUFHLEVBQUU7UUFDdEIsS0FBSyxDQUFDLEVBQUUsR0FBRyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNoRCxJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQztRQUNyQixJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNwQixJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQztRQUN2QixJQUFJ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QUFDO1FBQy9ELE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFN0QsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUM7UUFDckIsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7SUFDdEIsQ0FBQztDQUNGO0FBRUQsZUFBZSxnQkFBZ0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRyYW5zZm9ybSwgdHlwZSBUcmFuc2Zvcm1DYWxsYmFjayB9IGZyb20gXCJub2RlOnN0cmVhbVwiO1xuaW1wb3J0IGNoYWxrIGZyb20gXCJjaGFsa1wiO1xuaW1wb3J0IHRlc3QgZnJvbSBcIm5vZGU6dGVzdFwiO1xuXG4vLyBVc2VmdWwgZG9jdW1lbnRhdGlvbiBoZXJlOiBodHRwczovL25vZGVqcy5vcmcvYXBpL3Rlc3QuaHRtbCNjbGFzcy10ZXN0c3N0cmVhbVxuXG4vLyBNYXAgb2YgZmlsZSBuYW1lIHRvXG50eXBlIFRlc3RTdWl0ZSA9IFJlY29yZDxzdHJpbmcsIFN1aXRlPjtcblxudHlwZSBTdWl0ZSA9IHtcbiAgZmlsZTogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIG5lc3Rpbmc6IG51bWJlcjtcbiAgY2hpbGRyZW4/OiBSZWNvcmQ8c3RyaW5nLCBUZXN0IHwgU3VpdGU+O1xuICBwYXNzZWQ/OiBib29sZWFuO1xuICBkZXRhaWxzPzogeyBkdXJhdGlvbl9tczogbnVtYmVyOyB0eXBlPzogXCJzdWl0ZVwiOyBlcnJvcj86IHsgY2F1c2U/OiBFcnJvciB9IH07XG4gIHNraXA/OiBib29sZWFuIHwgc3RyaW5nO1xuICB0b2RvPzogYm9vbGVhbiB8IHN0cmluZztcbn07XG5cbnR5cGUgVGVzdCA9IHtcbiAgZmlsZTogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIG5lc3Rpbmc6IG51bWJlcjtcbiAgbWVzc2FnZT86IHN0cmluZztcbiAgZGV0YWlsczoge1xuICAgIGR1cmF0aW9uX21zOiBudW1iZXI7XG4gICAgdHlwZT86IFwic3VpdGVcIjtcbiAgICBlcnJvcj86IHtcbiAgICAgIGNhdXNlOiBFcnJvcjtcbiAgICB9O1xuICB9O1xuICBza2lwPzogYm9vbGVhbiB8IHN0cmluZztcbiAgdG9kbz86IGJvb2xlYW4gfCBzdHJpbmc7XG4gIHBhc3NlZD86IGJvb2xlYW47XG59O1xuXG5lbnVtIEV2ZW50VHlwZSB7XG4gIEVOUVVFVUUgPSBcInRlc3Q6ZW5xdWV1ZVwiLFxuICBERVFVRVVFID0gXCJ0ZXN0OmRlcXVldWVcIixcbiAgU1RBUlQgPSBcInRlc3Q6c3RhcnRcIixcbiAgUEFTUyA9IFwidGVzdDpwYXNzXCIsXG4gIEZBSUwgPSBcInRlc3Q6ZmFpbFwiLFxuICBQTEFOID0gXCJ0ZXN0OnBsYW5cIixcbiAgV0FUQ0hfRFJBSU5FRCA9IFwidGVzdDp3YXRjaDpkcmFpbmVkXCIsXG4gIFNURE9VVCA9IFwidGVzdDpzdGRvdXRcIixcbiAgU1RERVJSID0gXCJ0ZXN0OnN0ZGVyclwiLFxufVxuXG50eXBlIEV2ZW50ID0ge1xuICB0eXBlOiBFdmVudFR5cGU7XG4gIGRhdGE6IFRlc3Q7XG59O1xuXG5jbGFzcyBEb3RFeHRyYVJlcG9ydGVyIGV4dGVuZHMgVHJhbnNmb3JtIHtcbiAgcHJpdmF0ZSBwYXNzZWRUZXN0czogbnVtYmVyO1xuXG4gIHByaXZhdGUgc2tpcHBlZFRlc3RzOiBUZXN0W107XG5cbiAgcHJpdmF0ZSB0b2RvVGVzdHM6IFRlc3RbXTtcblxuICBwcml2YXRlIHRvdGFsRHVyYXRpb246IG51bWJlcjtcblxuICBwcml2YXRlIGZhaWxlZFRlc3RzOiBUZXN0W107XG5cbiAgcHJpdmF0ZSB0ZXN0U3VpdGU6IFRlc3RTdWl0ZTtcblxuICBwcml2YXRlIGN1cnJlbnRTdWl0ZTogU3VpdGUgfCB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSBjdXJyZW50U3VpdGVMaW5lYWdlOiBTdWl0ZVtdID0gW107XG5cbiAgcHJpdmF0ZSBuZXN0aW5nID0gMDtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pIHtcbiAgICBzdXBlcih7IC4uLm9wdGlvbnMsIHdyaXRhYmxlT2JqZWN0TW9kZTogdHJ1ZSB9KTtcbiAgICB0aGlzLnBhc3NlZFRlc3RzID0gMDtcbiAgICB0aGlzLnNraXBwZWRUZXN0cyA9IFtdO1xuICAgIHRoaXMudG9kb1Rlc3RzID0gW107XG4gICAgdGhpcy50b3RhbER1cmF0aW9uID0gMDtcbiAgICB0aGlzLmZhaWxlZFRlc3RzID0gW107XG4gICAgdGhpcy50ZXN0U3VpdGUgPSB7fTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlVGVzdFN0YXJ0KHRlc3Q6IFRlc3QpIHtcbiAgICAvLyBBZGQgbmV3IGNoaWxkXG4gICAgY29uc3QgbmV3SXRlbSA9IHtcbiAgICAgIGZpbGU6IHRlc3QuZmlsZSxcbiAgICAgIG5hbWU6IHRlc3QubmFtZSxcbiAgICAgIG5lc3Rpbmc6IHRlc3QubmVzdGluZyxcbiAgICAgIGNoaWxkcmVuOiB7fSxcbiAgICB9O1xuXG4gICAgLy8gSWYgbmVzdGluZyA+IGN1cnJlbnQgbmVzdGluZyB0aGVuXG4gICAgLy8gV2UndmUgbW92ZWQgaW50byBhIG5lc3RlZCBzdWl0ZSBzbzpcbiAgICAvLyAtIEFkZCB0aGUgY3VycmVudCBzdWl0ZSB0byB0aGUgbGluZWFnZVxuICAgIC8vIC0gQWRkIG5ldyBpdGVtIGFzIGEgY2hpbGQgb2YgdGhlIGN1cnJlbnQgc3VpdGVcbiAgICBpZiAodGVzdC5uZXN0aW5nID09PSAwKSB7XG4gICAgICAvLyBGaXJzdCBlbnRyeVxuICAgICAgdGhpcy5jdXJyZW50U3VpdGUgPSBuZXdJdGVtO1xuICAgICAgdGhpcy50ZXN0U3VpdGVbYCR7dGVzdC5maWxlfToke3Rlc3QubmFtZX1gXSA9IG5ld0l0ZW07XG4gICAgfSBlbHNlIGlmICh0ZXN0Lm5lc3RpbmcgPiB0aGlzLm5lc3RpbmcpIHtcbiAgICAgIHRoaXMuY3VycmVudFN1aXRlTGluZWFnZS5wdXNoKHRoaXMuY3VycmVudFN1aXRlISk7XG4gICAgICB0aGlzLmN1cnJlbnRTdWl0ZSEuY2hpbGRyZW4hW3Rlc3QubmFtZV0gPSBuZXdJdGVtO1xuXG4gICAgICB0aGlzLmN1cnJlbnRTdWl0ZSA9IG5ld0l0ZW07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vdCBkZWVwZXIgc28gYWRkIHRvIGN1cnJlbnQgcGFyZW50LCBhbmQgc2V0IG5ldyBpdGVtIHRvIGN1cnJlbnRcbiAgICAgIGNvbnN0IHBhcmVudCA9IHRoaXMuY3VycmVudFN1aXRlTGluZWFnZS5wb3AoKTtcbiAgICAgIHBhcmVudCEuY2hpbGRyZW4hW3Rlc3QubmFtZV0gPSBuZXdJdGVtO1xuICAgICAgdGhpcy5jdXJyZW50U3VpdGVMaW5lYWdlLnB1c2gocGFyZW50ISk7XG4gICAgICB0aGlzLmN1cnJlbnRTdWl0ZSA9IG5ld0l0ZW07XG4gICAgfVxuICAgIHRoaXMubmVzdGluZyA9IHRlc3QubmVzdGluZztcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlVGVzdFJlc3VsdCh0ZXN0OiBUZXN0LCBldmVudFR5cGU6IEV2ZW50VHlwZSkge1xuICAgIC8vIFVwZGF0ZSB0ZXN0IHJlc3VsdCBkZXRhaWxzXG4gICAgdGhpcy5jdXJyZW50U3VpdGUhLnBhc3NlZCA9IGV2ZW50VHlwZSA9PT0gRXZlbnRUeXBlLlBBU1M7XG5cbiAgICBpZiAodGVzdC5kZXRhaWxzKSB7XG4gICAgICB0aGlzLmN1cnJlbnRTdWl0ZSEuZGV0YWlscyA9IHRlc3QuZGV0YWlscztcbiAgICB9XG4gICAgaWYgKHRlc3Quc2tpcCkge1xuICAgICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoY2hhbGsueWVsbG93KFwiKlwiKSk7XG4gICAgICB0aGlzLmN1cnJlbnRTdWl0ZSEuc2tpcCA9IHRlc3Quc2tpcDtcbiAgICB9IGVsc2UgaWYgKHRlc3QudG9kbykge1xuICAgICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoY2hhbGsuYmx1ZShcIi1cIikpO1xuICAgICAgdGhpcy5jdXJyZW50U3VpdGUhLnRvZG8gPSB0ZXN0LnRvZG87XG4gICAgfSBlbHNlIGlmICh0aGlzLmN1cnJlbnRTdWl0ZSEucGFzc2VkKSB7XG4gICAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShjaGFsay5ncmVlbihcIi5cIikpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShjaGFsay5yZWQoXCJGXCIpKTtcbiAgICB9XG4gICAgdGhpcy5uZXN0aW5nID0gdGVzdC5uZXN0aW5nO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVUZXN0RW5kKHRlc3Q6IFRlc3QpIHtcbiAgICAvLyBTdWl0ZSBmaW5pc2hlZCwgc3RlcCB1cCB0byBwYXJlbnRcbiAgICB0aGlzLmN1cnJlbnRTdWl0ZSA9IHRoaXMuY3VycmVudFN1aXRlTGluZWFnZS5wb3AoKTtcbiAgICB0aGlzLm5lc3RpbmcgPSB0ZXN0Lm5lc3Rpbmc7XG4gIH1cblxuICBwdWJsaWMgb3ZlcnJpZGUgX3RyYW5zZm9ybShcbiAgICBldmVudDogRXZlbnQsXG4gICAgX2VuY29kaW5nOiBCdWZmZXJFbmNvZGluZyxcbiAgICBjYWxsYmFjazogVHJhbnNmb3JtQ2FsbGJhY2tcbiAgKTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRlc3QgPSBldmVudC5kYXRhIGFzIFRlc3Q7XG5cbiAgICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xuICAgICAgICBjYXNlIEV2ZW50VHlwZS5TVEFSVDpcbiAgICAgICAgICB0aGlzLmhhbmRsZVRlc3RTdGFydCh0ZXN0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBFdmVudFR5cGUuUEFTUzpcbiAgICAgICAgY2FzZSBFdmVudFR5cGUuRkFJTDpcbiAgICAgICAgICBpZiAodGVzdC5uYW1lICE9PSB0ZXN0LmZpbGUpIHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlVGVzdFJlc3VsdCh0ZXN0LCBldmVudC50eXBlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgRXZlbnRUeXBlLlBMQU46XG4gICAgICAgICAgdGhpcy5oYW5kbGVUZXN0RW5kKHRlc3QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIEV2ZW50VHlwZS5TVERPVVQ6XG4gICAgICAgICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoZXZlbnQuZGF0YS5tZXNzYWdlID8/IFwiXCIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIEV2ZW50VHlwZS5TVERFUlI6XG4gICAgICAgICAgcHJvY2Vzcy5zdGRlcnIud3JpdGUoZXZlbnQuZGF0YS5tZXNzYWdlID8/IFwiXCIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYWxsYmFjaygpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICBjYWxsYmFjayhlcnJvciBhcyBFcnJvcik7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHByb2Nlc3NPdXRjb21lcygpIHtcbiAgICBPYmplY3QuZW50cmllcyh0aGlzLnRlc3RTdWl0ZSkuZm9yRWFjaCgoW2ZpbGUsIHN1aXRlXSkgPT4ge1xuICAgICAgdGhpcy5idWlsZFN0YXRzKHN1aXRlKTtcbiAgICAgIC8vIEZpbGUgc3VpdGUgZG9lc24ndCBoYXZlIGEgZHVyYXRpb24gc28gY29sbGF0ZSBmcm9tIGFsbCB0b3AgbGV2ZWwgc3VpdGVzLlxuICAgICAgT2JqZWN0LnZhbHVlcyhzdWl0ZS5jaGlsZHJlbiA/PyB7fSkuZm9yRWFjaCgoY2hpbGQpID0+IHtcbiAgICAgICAgdGhpcy50b3RhbER1cmF0aW9uICs9IGNoaWxkLmRldGFpbHM/LmR1cmF0aW9uX21zIHx8IDA7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRTdGF0cyhzdWl0ZTogU3VpdGUgfCBUZXN0LCBwcmVmaXg/OiBzdHJpbmcpIHtcbiAgICBjb25zdCBpc1N1aXRlID0gKG9iajogU3VpdGUgfCBUZXN0KTogb2JqIGlzIFN1aXRlID0+XG4gICAgICBvYmouZGV0YWlscz8udHlwZSA9PT0gXCJzdWl0ZVwiO1xuXG4gICAgaWYgKGlzU3VpdGUoc3VpdGUpKSB7XG4gICAgICAvLyBJdGVyYXRlIG92ZXIgZWFjaCBjaGlsZFxuICAgICAgT2JqZWN0LnZhbHVlcyhzdWl0ZS5jaGlsZHJlbiEpLmZvckVhY2goKGNoaWxkKSA9PlxuICAgICAgICB0aGlzLmJ1aWxkU3RhdHMoXG4gICAgICAgICAgY2hpbGQsXG4gICAgICAgICAgcHJlZml4ID8gYCR7cHJlZml4fSA+ICR7c3VpdGUubmFtZX1gIDogc3VpdGUubmFtZVxuICAgICAgICApXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChwcmVmaXgpIHtcbiAgICAgIHN1aXRlLm5hbWUgPSBgJHtwcmVmaXh9ID4gJHtzdWl0ZS5uYW1lfWA7XG4gICAgfVxuICAgIGlmIChzdWl0ZS5za2lwKSB7XG4gICAgICB0aGlzLnNraXBwZWRUZXN0cy5wdXNoKHN1aXRlIGFzIFRlc3QpO1xuICAgIH0gZWxzZSBpZiAoc3VpdGUudG9kbykge1xuICAgICAgdGhpcy50b2RvVGVzdHMucHVzaChzdWl0ZSBhcyBUZXN0KTtcbiAgICB9IGVsc2UgaWYgKCFpc1N1aXRlKHN1aXRlKSkge1xuICAgICAgaWYgKHN1aXRlLnBhc3NlZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5mYWlsZWRUZXN0cy5wdXNoKHN1aXRlIGFzIFRlc3QpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5wYXNzZWRUZXN0cysrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBvdmVycmlkZSBfZmx1c2goKSB7XG4gICAgdGhpcy5wcm9jZXNzT3V0Y29tZXMoKTtcblxuICAgIGlmICh0aGlzLnNraXBwZWRUZXN0cy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zb2xlLmxvZyhcIlxcblxcblNraXBwZWQ6XCIpO1xuICAgICAgdGhpcy5za2lwcGVkVGVzdHMuZm9yRWFjaCgodGVzdCwgaSkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhgXFxuJHtpICsgMX0pICR7dGVzdC5uYW1lfWApO1xuICAgICAgICBpZiAodHlwZW9mIHRlc3Quc2tpcCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdyhgXFx0U2tpcHBlZDogJHt0ZXN0LnNraXB9YCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLnllbGxvdyhgXFx0JHtcIlNraXBwZWQ6IE5vIHJlYXNvblwifWApKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudG9kb1Rlc3RzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnNvbGUubG9nKFwiXFxuXFxuVG9kbzpcIik7XG4gICAgICB0aGlzLnRvZG9UZXN0cy5mb3JFYWNoKCh0ZXN0LCBpKSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBcXG4ke2kgKyAxfSkgJHt0ZXN0Lm5hbWV9YCk7XG4gICAgICAgIGlmICh0eXBlb2YgdGVzdC50b2RvID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coY2hhbGsuYmx1ZShgXFx0VE9ETzogJHt0ZXN0LnRvZG99YCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmJsdWUoYFxcdCR7XCJUT0RPOiBObyByZWFzb25cIn1gKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmZhaWxlZFRlc3RzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnNvbGUubG9nKGNoYWxrLnJlZChcIlxcbuKcllwiKSArIFwiIEZhaWxpbmcgdGVzdHM6XCIpO1xuICAgICAgdGhpcy5mYWlsZWRUZXN0cy5mb3JFYWNoKCh0ZXN0LCBpKSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgIGNoYWxrLnJlZChgXFxuJHtpICsgMX0pICR7dGVzdC5uYW1lfSAoJHt0ZXN0LmRldGFpbHMuZHVyYXRpb25fbXN9bXMpYClcbiAgICAgICAgKTtcbiAgICAgICAgY29uc29sZS5sb2codGVzdC5kZXRhaWxzLmVycm9yPy5jYXVzZSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGBcXG5cXG7ihLkgVGVzdHMgICAgJHtcbiAgICAgICAgdGhpcy5wYXNzZWRUZXN0cyArXG4gICAgICAgIHRoaXMuZmFpbGVkVGVzdHMubGVuZ3RoICtcbiAgICAgICAgdGhpcy5za2lwcGVkVGVzdHMubGVuZ3RoICtcbiAgICAgICAgdGhpcy50b2RvVGVzdHMubGVuZ3RoXG4gICAgICB9YFxuICAgICk7XG4gICAgY29uc29sZS5sb2coYOKEuSBQYXNzZWQgICAke2NoYWxrLmdyZWVuKHRoaXMucGFzc2VkVGVzdHMpfWApO1xuICAgIGNvbnNvbGUubG9nKGDihLkgRmFpbGVkICAgJHtjaGFsay5yZWQodGhpcy5mYWlsZWRUZXN0cy5sZW5ndGgpfWApO1xuICAgIGNvbnNvbGUubG9nKGDihLkgU2tpcHBlZCAgJHtjaGFsay55ZWxsb3codGhpcy5za2lwcGVkVGVzdHMubGVuZ3RoKX1gKTtcbiAgICBjb25zb2xlLmxvZyhg4oS5IFRvZG8gICAgICR7Y2hhbGsuYmx1ZSh0aGlzLnRvZG9UZXN0cy5sZW5ndGgpfWApO1xuICAgIGNvbnNvbGUubG9nKGDihLkgRHVyYXRpb24gJHt0aGlzLnRvdGFsRHVyYXRpb24udG9GaXhlZCgyKX1tc2ApO1xuXG4gICAgdGhpcy5wYXNzZWRUZXN0cyA9IDA7XG4gICAgdGhpcy5za2lwcGVkVGVzdHMgPSBbXTtcbiAgICB0aGlzLnRvZG9UZXN0cyA9IFtdO1xuICAgIHRoaXMudG90YWxEdXJhdGlvbiA9IDA7XG4gICAgdGhpcy5mYWlsZWRUZXN0cyA9IFtdO1xuICAgIHRoaXMudGVzdFN1aXRlID0ge307XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRG90RXh0cmFSZXBvcnRlcjtcbiJdfQ==