velocious 1.0.652 → 1.0.654
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/README.md +14 -1
- package/build/database/query/model-class-query.js +3 -1
- package/build/database/query/where-hash.js +12 -1
- package/build/database/query/where-in.js +48 -0
- package/build/database/query/where-model-class-hash.js +34 -1
- package/build/environment-handlers/node/cli/commands/test.js +2 -1
- package/build/src/database/query/model-class-query.js +5 -2
- package/build/src/database/query/where-hash.d.ts.map +1 -1
- package/build/src/database/query/where-hash.js +14 -2
- package/build/src/database/query/where-in.d.ts +22 -0
- package/build/src/database/query/where-in.d.ts.map +1 -0
- package/build/src/database/query/where-in.js +40 -0
- package/build/src/database/query/where-model-class-hash.d.ts +11 -0
- package/build/src/database/query/where-model-class-hash.d.ts.map +1 -1
- package/build/src/database/query/where-model-class-hash.js +33 -2
- package/build/src/environment-handlers/node/cli/commands/test.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/test.js +4 -2
- package/build/src/testing/test-runner.d.ts +23 -0
- package/build/src/testing/test-runner.d.ts.map +1 -1
- package/build/src/testing/test-runner.js +29 -2
- package/build/src/testing/velocious-runner-reporter.d.ts +7 -0
- package/build/src/testing/velocious-runner-reporter.d.ts.map +1 -1
- package/build/src/testing/velocious-runner-reporter.js +54 -12
- package/build/testing/test-runner.js +33 -1
- package/build/testing/velocious-runner-reporter.js +52 -11
- package/package.json +4 -4
- package/scripts/browser-test-session.js +21 -23
- package/src/database/query/model-class-query.js +3 -1
- package/src/database/query/where-hash.js +12 -1
- package/src/database/query/where-in.js +48 -0
- package/src/database/query/where-model-class-hash.js +34 -1
- package/src/environment-handlers/node/cli/commands/test.js +2 -1
- package/src/testing/test-runner.js +33 -1
- package/src/testing/velocious-runner-reporter.js +52 -11
|
@@ -56,6 +56,13 @@ export default class VelociousRunnerReporter {
|
|
|
56
56
|
testData: import("./test-runner.js").TestData;
|
|
57
57
|
testDescription: string;
|
|
58
58
|
}): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Prints complete primary and secondary stacks once, including cyclic cause graphs.
|
|
61
|
+
* @param {unknown} error - Thrown value at the reporting boundary.
|
|
62
|
+
* @param {Set<Error>} [reported] - Error identities already printed.
|
|
63
|
+
* @returns {void}
|
|
64
|
+
*/
|
|
65
|
+
printErrorCauses(error: unknown, reported?: Set<Error>): void;
|
|
59
66
|
/**
|
|
60
67
|
* Emits one legacy event and awaits listeners in registration order.
|
|
61
68
|
* @param {string} eventName - Event name.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"velocious-runner-reporter.d.ts","sourceRoot":"","sources":["../../../src/testing/velocious-runner-reporter.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"velocious-runner-reporter.d.ts","sourceRoot":"","sources":["../../../src/testing/velocious-runner-reporter.js"],"names":[],"mappings":"AAOI,YAA+D,sBAAsB,GAA3E,OAAO,2BAA2B,EAAE,eAAe,CAAwB;AACrF,YAA+D,sBAAsB,GAA3E,OAAO,2BAA2B,EAAE,eAAe,CAAwB;AAoBzF,2EAA2E;AAC3E,qBAAa,wBAAyB,SAAQ,KAAK;CAAG;AAEtD,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAQnC,UAAU;IACf,iGAAiG;IAC5F,qBAAqB,EADf,OAAO,CAAC,sBAAsB,EAAE,OAAO,kBAAkB,EAAE,oBAAoB,EAAE,CAAC;IAE7F,iDAAiD;IAC5C,UAAU,EADJ,sBAAsB,GAAG,SAAS;IAV/C;;;;OAIG;IACH,YAAY,EAAC,UAAU,EAAE,GAAG,QAAQ,EAAC,EAFlC;QAAiD,UAAU,EAAnD,OAAO,kBAAkB,EAAE,OAAO,CAC5C;KACoC,EAOpC;IAED;;;;OAIG;IACG,OAAO,CAAC,KAAK,EAHR,OAAO,2BAA2B,EAAE,WAG5B,GAFN,OAAO,CAAC,IAAI,CAAC,CA2CzB;IAED;;;;OAIG;IACG,kBAAkB,CAAC,KAAK,EAHnB,OAAO,2BAA2B,EAAE,WAGjB,GAFjB,OAAO,CAAC,IAAI,CAAC,CA+FzB;IAED;;;;OAIG;IACG,eAAe,CAAC,KAAK,EAHhB,OAAO,2BAA2B,EAAE,WAGpB,GAFd,OAAO,CAAC,IAAI,CAAC,CAmDzB;IAED;;;;;;;;;;;OAWG;IACG,gBAAgB,CAAC,EAAC,qBAAqB,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAC,EATlH;QAAgE,qBAAqB,EAA7E,OAAO,kBAAkB,EAAE,oBAAoB,EAAE,CACzD;QAAuB,YAAY,EAA3B,MAAM,EAAE,CAChB;QAA4C,KAAK,EAAzC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CACrC;QAAqB,WAAW,EAAxB,MAAM,CACd;QAAkD,QAAQ,EAAlD,OAAO,kBAAkB,EAAE,QAAQ,CAC3C;QAAkD,QAAQ,EAAlD,OAAO,kBAAkB,EAAE,QAAQ,CAC3C;QAAqB,eAAe,EAA5B,MAAM,CACd;KAEkH,GAFxG,OAAO,CAAC,IAAI,CAAC,CA4BzB;IAED;;;;;OAKG;IACH,gBAAgB,CAAC,KAAK,EAJX,OAIW,EAAE,QAAQ,AAH7B,CACA,EADQ,GAAG,CAAC,KAAK,CAGwB,GAF/B,IAAI,CAqBhB;IAED;;;;;OAKG;IACG,SAAS,CAAC,SAAS,EAJd,MAIc,EAAE,OAAO,EAHvB,MAGuB,GAFrB,OAAO,CAAC,IAAI,CAAC,CAIzB;CACF"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { addTrackedStackToError } from "../utils/with-tracked-stack.js";
|
|
3
|
-
import BacktraceCleaner from "../utils/backtrace-cleaner-node.js";
|
|
4
3
|
import picocolors from "picocolors";
|
|
5
4
|
import restArgsError from "../utils/rest-args-error.js";
|
|
6
5
|
import { testEvents } from "./test.js";
|
|
@@ -18,6 +17,10 @@ function errorFromPackageRecord(errorRecord) {
|
|
|
18
17
|
error.name = errorRecord.name;
|
|
19
18
|
if (errorRecord.stack)
|
|
20
19
|
error.stack = errorRecord.stack;
|
|
20
|
+
if (errorRecord.cause)
|
|
21
|
+
error.cause = errorFromPackageRecord(errorRecord.cause);
|
|
22
|
+
if (errorRecord.terminalResource)
|
|
23
|
+
Object.assign(error, { terminalResource: errorRecord.terminalResource });
|
|
21
24
|
return error;
|
|
22
25
|
}
|
|
23
26
|
/** Stops package traversal after framework-owned connection quarantine. */
|
|
@@ -59,8 +62,27 @@ export default class VelociousRunnerReporter {
|
|
|
59
62
|
await this.reportTestEvent(event);
|
|
60
63
|
return;
|
|
61
64
|
}
|
|
62
|
-
if (event.type === "run
|
|
65
|
+
if (event.type === "test:not-run") {
|
|
66
|
+
const test = this.testRunner.findTestDeclaration(event.test.fullName);
|
|
67
|
+
if (!test)
|
|
68
|
+
throw new Error(`Package not-run result did not match a declaration: ${event.test.fullName}`);
|
|
69
|
+
this.testRunner.recordNotRunTest(event.test);
|
|
70
|
+
this.testRunner.completeTestDeclaration(test);
|
|
71
|
+
console.error(`Not run: ${event.test.fullName} (terminal resource failure in ${event.test.reason.fullName})`);
|
|
72
|
+
await this.emitEvent("testNotRun", {
|
|
73
|
+
configuration: this.testRunner.getConfiguration(),
|
|
74
|
+
test: event.test,
|
|
75
|
+
testRunner: this.testRunner
|
|
76
|
+
});
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (event.type === "run:finish") {
|
|
63
80
|
this.testRunner.recordPackageResult(event.result);
|
|
81
|
+
for (const failure of event.result.errors) {
|
|
82
|
+
console.error(`Suite ${failure.phase} failed: ${failure.suite}`);
|
|
83
|
+
this.printErrorCauses(errorFromPackageRecord(failure.error));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
64
86
|
}
|
|
65
87
|
/**
|
|
66
88
|
* Projects attempt failure/retry events while retaining the raw thrown value.
|
|
@@ -83,7 +105,7 @@ export default class VelociousRunnerReporter {
|
|
|
83
105
|
const failed = outcome?.failed ?? Boolean(attempt.error);
|
|
84
106
|
const error = outcome?.error;
|
|
85
107
|
const retriesUsed = Math.min(attempt.attemptNumber, retryCount);
|
|
86
|
-
const willRetry = failed && !outcome?.abortRemainingTests && attempt.attemptNumber <= retryCount;
|
|
108
|
+
const willRetry = failed && !event.terminalFailure && !outcome?.abortRemainingTests && attempt.attemptNumber <= retryCount;
|
|
87
109
|
const { descriptions, testDescription } = this.testRunner.testMetadata(test);
|
|
88
110
|
const compatibility = this.testRunner.testData(test);
|
|
89
111
|
if (failed) {
|
|
@@ -221,14 +243,7 @@ export default class VelociousRunnerReporter {
|
|
|
221
243
|
const consoleOutput = testRunner.buildConsoleOutput(attemptConsoleOutputs);
|
|
222
244
|
if (error instanceof Error) {
|
|
223
245
|
console.error(picocolors.red(`${leftPadding} Test failed: ${error.message}`));
|
|
224
|
-
|
|
225
|
-
const backtraceCleaner = new BacktraceCleaner(error);
|
|
226
|
-
const cleanedStack = backtraceCleaner.getCleanedStack();
|
|
227
|
-
const stackLines = cleanedStack?.split("\n");
|
|
228
|
-
if (stackLines) {
|
|
229
|
-
for (const stackLine of stackLines)
|
|
230
|
-
console.error(picocolors.red(`${leftPadding} ${stackLine}`));
|
|
231
|
-
}
|
|
246
|
+
this.printErrorCauses(error);
|
|
232
247
|
}
|
|
233
248
|
else {
|
|
234
249
|
console.error(picocolors.red(`${leftPadding} Test failed with a ${typeof error}: ${String(error)}`));
|
|
@@ -246,6 +261,33 @@ export default class VelociousRunnerReporter {
|
|
|
246
261
|
});
|
|
247
262
|
testRunner.printRerunCommand({ descriptions, testDescription, testData, leftPadding });
|
|
248
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* Prints complete primary and secondary stacks once, including cyclic cause graphs.
|
|
266
|
+
* @param {unknown} error - Thrown value at the reporting boundary.
|
|
267
|
+
* @param {Set<Error>} [reported] - Error identities already printed.
|
|
268
|
+
* @returns {void}
|
|
269
|
+
*/
|
|
270
|
+
printErrorCauses(error, reported = new Set()) {
|
|
271
|
+
if (!(error instanceof Error)) {
|
|
272
|
+
console.error(String(error));
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (reported.has(error))
|
|
276
|
+
return;
|
|
277
|
+
reported.add(error);
|
|
278
|
+
addTrackedStackToError(error);
|
|
279
|
+
console.error(error.stack || `${error.name}: ${error.message}`);
|
|
280
|
+
if (error.cause !== undefined) {
|
|
281
|
+
console.error("Caused by:");
|
|
282
|
+
this.printErrorCauses(error.cause, reported);
|
|
283
|
+
}
|
|
284
|
+
if (error instanceof AggregateError) {
|
|
285
|
+
for (const secondary of error.errors) {
|
|
286
|
+
console.error("Related failure:");
|
|
287
|
+
this.printErrorCauses(secondary, reported);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
249
291
|
/**
|
|
250
292
|
* Emits one legacy event and awaits listeners in registration order.
|
|
251
293
|
* @param {string} eventName - Event name.
|
|
@@ -257,4 +299,4 @@ export default class VelociousRunnerReporter {
|
|
|
257
299
|
await listener(payload);
|
|
258
300
|
}
|
|
259
301
|
}
|
|
260
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVsb2Npb3VzLXJ1bm5lci1yZXBvcnRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0aW5nL3ZlbG9jaW91cy1ydW5uZXItcmVwb3J0ZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFBO0FBQ3ZFLE9BQU8sZ0JBQWdCLE1BQU0sb0NBQW9DLENBQUE7QUFDakUsT0FBTyxVQUFVLE1BQU0sWUFBWSxDQUFBO0FBQ25DLE9BQU8sYUFBYSxNQUFNLDZCQUE2QixDQUFBO0FBQ3ZELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFFdEMsNEZBQTRGO0FBQzVGLDRGQUE0RjtBQUU1Rjs7OztHQUlHO0FBQ0gsU0FBUyxzQkFBc0IsQ0FBQyxXQUFXO0lBQ3pDLE1BQU0sS0FBSyxHQUFHLFdBQVcsQ0FBQyxNQUFNO1FBQzlCLENBQUMsQ0FBQyxJQUFJLGNBQWMsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxPQUFPLENBQUM7UUFDekYsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUVsQyxLQUFLLENBQUMsSUFBSSxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUE7SUFDN0IsSUFBSSxXQUFXLENBQUMsS0FBSztRQUFFLEtBQUssQ0FBQyxLQUFLLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQTtJQUV0RCxPQUFPLEtBQUssQ0FBQTtBQUNkLENBQUM7QUFFRCwyRUFBMkU7QUFDM0UsTUFBTSxPQUFPLHdCQUF5QixTQUFRLEtBQUs7Q0FBRztBQUV0RCxNQUFNLENBQUMsT0FBTyxPQUFPLHVCQUF1QjtJQUMxQzs7OztPQUlHO0lBQ0gsWUFBWSxFQUFDLFVBQVUsRUFBRSxHQUFHLFFBQVEsRUFBQztRQUNuQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDdkIsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUE7UUFDNUIsaUdBQWlHO1FBQ2pHLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFBO1FBQzFDLGlEQUFpRDtRQUNqRCxJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQTtJQUM3QixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSztRQUNqQixJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtZQUNyRSxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDcEIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO2dCQUM5RCxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsTUFBTSxRQUFRLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQTtZQUM5RixDQUFDO1lBQ0QsT0FBTTtRQUNSLENBQUM7UUFFRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssZ0JBQWdCLEVBQUUsQ0FBQztZQUNwQyxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUNwQyxPQUFNO1FBQ1IsQ0FBQztRQUVELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxhQUFhLEVBQUUsQ0FBQztZQUNqQyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDakMsT0FBTTtRQUNSLENBQUM7UUFFRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssWUFBWTtZQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQ3BGLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEtBQUs7UUFDNUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUVuRixJQUFJLENBQUMsSUFBSTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsdURBQXVELEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFBO1FBRW5HLHFFQUFxRTtRQUNyRSxNQUFNLE9BQU8sR0FBRyxvRUFBb0UsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUNwRyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFBO1FBQzNFLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUE7UUFFeEUsSUFBSSxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDMUIscUJBQXFCLENBQUMsSUFBSSxDQUFDLEVBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxhQUFhLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLEVBQUMsQ0FBQyxDQUFBO1lBQzNHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLHFCQUFxQixDQUFDLENBQUE7UUFDN0QsQ0FBQztRQUVELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ25ELE1BQU0sTUFBTSxHQUFHLE9BQU8sRUFBRSxNQUFNLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUN4RCxNQUFNLEtBQUssR0FBRyxPQUFPLEVBQUUsS0FBSyxDQUFBO1FBQzVCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxVQUFVLENBQUMsQ0FBQTtRQUMvRCxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLEVBQUUsbUJBQW1CLElBQUksT0FBTyxDQUFDLGFBQWEsSUFBSSxVQUFVLENBQUE7UUFDaEcsTUFBTSxFQUFDLFlBQVksRUFBRSxlQUFlLEVBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUMxRSxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUVwRCxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLG1CQUFtQixFQUFFO2dCQUN4QyxhQUFhLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRTtnQkFDakQsWUFBWTtnQkFDWixLQUFLO2dCQUNMLGFBQWEsRUFBRSxPQUFPLENBQUMsYUFBYTtnQkFDcEMsV0FBVyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0JBQzlELFdBQVc7Z0JBQ1gsVUFBVTtnQkFDVixRQUFRLEVBQUUsYUFBYSxDQUFDLFFBQVE7Z0JBQ2hDLFFBQVEsRUFBRSxhQUFhLENBQUMsUUFBUTtnQkFDaEMsZUFBZTtnQkFDZixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7Z0JBQzNCLFNBQVM7YUFDVixDQUFDLENBQUE7UUFDSixDQUFDO1FBRUQsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNkLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsZUFBZSxXQUFXLElBQUksVUFBVSxrQkFBa0IsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO1lBQ3RMLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUU7Z0JBQ25DLGFBQWEsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLGdCQUFnQixFQUFFO2dCQUNqRCxZQUFZO2dCQUNaLEtBQUs7Z0JBQ0wsV0FBVyxFQUFFLE9BQU8sQ0FBQyxhQUFhLEdBQUcsQ0FBQztnQkFDdEMsV0FBVztnQkFDWCxVQUFVO2dCQUNWLFFBQVEsRUFBRSxhQUFhLENBQUMsUUFBUTtnQkFDaEMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxRQUFRO2dCQUNoQyxlQUFlO2dCQUNmLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTthQUM1QixDQUFDLENBQUE7UUFDSixDQUFDO1FBRUQsSUFBSSxPQUFPLENBQUMsYUFBYSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzlCLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEVBQUU7Z0JBQ2xDLGFBQWEsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLGdCQUFnQixFQUFFO2dCQUNqRCxZQUFZO2dCQUNaLEtBQUs7Z0JBQ0wsYUFBYSxFQUFFLE9BQU8sQ0FBQyxhQUFhO2dCQUNwQyxXQUFXO2dCQUNYLFVBQVU7Z0JBQ1YsUUFBUSxFQUFFLGFBQWEsQ0FBQyxRQUFRO2dCQUNoQyxRQUFRLEVBQUUsYUFBYSxDQUFDLFFBQVE7Z0JBQ2hDLGVBQWU7Z0JBQ2YsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO2FBQzVCLENBQUMsQ0FBQTtRQUNKLENBQUM7UUFFRCxJQUFJLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxDQUFDO1lBQ2pDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFBO1lBRW5ELElBQUksQ0FBQyxVQUFVLENBQUMsa0JBQWtCLENBQUM7Z0JBQ2pDLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTtnQkFDOUIsUUFBUSxFQUFFLGFBQWEsQ0FBQyxRQUFRLENBQUMsUUFBUSxJQUFJLFdBQVc7Z0JBQ3hELGVBQWUsRUFBRSxRQUFRLENBQUMsZUFBZTtnQkFDekMsSUFBSSxFQUFFLGFBQWEsQ0FBQyxRQUFRLENBQUMsSUFBSSxJQUFJLENBQUM7YUFDdkMsQ0FBQyxDQUFBO1lBQ0YsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUM7Z0JBQzFCLHFCQUFxQjtnQkFDckIsWUFBWTtnQkFDWixLQUFLO2dCQUNMLFdBQVcsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO2dCQUNoRCxRQUFRLEVBQUUsYUFBYSxDQUFDLFFBQVE7Z0JBQ2hDLFFBQVEsRUFBRSxhQUFhLENBQUMsUUFBUTtnQkFDaEMsZUFBZTthQUNoQixDQUFDLENBQUE7WUFDRixJQUFJLENBQUMsVUFBVSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxDQUFBO1lBQzdDLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFBO1lBQzNCLE1BQU0sSUFBSSx3QkFBd0IsQ0FBQyw0REFBNEQsQ0FBQyxDQUFBO1FBQ2xHLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxlQUFlLENBQUMsS0FBSztRQUN6QixxRUFBcUU7UUFDckUsTUFBTSxpQkFBaUIsR0FBRyw2REFBNkQsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNwRyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsbUJBQW1CLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUE7UUFFL0YsSUFBSSxDQUFDLElBQUk7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHNEQUFzRCxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFBO1FBRTlHLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ25ELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ3BELE1BQU0sVUFBVSxHQUFHLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQTtRQUV2RyxJQUFJLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDMUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQztnQkFDakMsVUFBVTtnQkFDVixRQUFRLEVBQUUsYUFBYSxDQUFDLFFBQVEsQ0FBQyxRQUFRLElBQUksV0FBVztnQkFDeEQsZUFBZSxFQUFFLFFBQVEsQ0FBQyxlQUFlO2dCQUN6QyxJQUFJLEVBQUUsYUFBYSxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQzthQUN2QyxDQUFDLENBQUE7UUFDSixDQUFDO1FBRUQsSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDMUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxvQkFBb0IsRUFBRSxDQUFBO1FBQ3hDLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxZQUFZLEdBQUcsaUJBQWlCLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBQ3RELE1BQU0sT0FBTyxHQUFHLFlBQVk7Z0JBQzFCLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLGFBQWEsQ0FBQztnQkFDbEUsQ0FBQyxDQUFDLFNBQVMsQ0FBQTtZQUNiLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLENBQUE7WUFDakUsTUFBTSxLQUFLLEdBQUcsT0FBTyxFQUFFLE1BQU07Z0JBQzNCLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSztnQkFDZixDQUFDLENBQUMsWUFBWSxDQUFDLE1BQU07b0JBQ25CLENBQUMsQ0FBQyxZQUFZLENBQUMsS0FBSztvQkFDcEIsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLEtBQUs7d0JBQ3ZCLENBQUMsQ0FBQyxzQkFBc0IsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUM7d0JBQ2pELENBQUMsQ0FBQyxTQUFTLENBQUE7WUFFakIsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUM7Z0JBQzFCLHFCQUFxQixFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtnQkFDakUsWUFBWSxFQUFFLFFBQVEsQ0FBQyxZQUFZO2dCQUNuQyxLQUFLO2dCQUNMLFdBQVcsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztnQkFDekQsUUFBUSxFQUFFLGFBQWEsQ0FBQyxRQUFRO2dCQUNoQyxRQUFRLEVBQUUsYUFBYSxDQUFDLFFBQVE7Z0JBQ2hDLGVBQWUsRUFBRSxRQUFRLENBQUMsZUFBZTthQUMxQyxDQUFDLENBQUE7UUFDSixDQUFDO1FBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUM3QyxJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQTtJQUM3QixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDSCxLQUFLLENBQUMsZ0JBQWdCLENBQUMsRUFBQyxxQkFBcUIsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBQztRQUNuSCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFBO1FBQ2xDLE1BQU0sYUFBYSxHQUFHLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFBO1FBRTFFLElBQUksS0FBSyxZQUFZLEtBQUssRUFBRSxDQUFDO1lBQzNCLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFdBQVcsa0JBQWtCLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUE7WUFDOUUsc0JBQXNCLENBQUMsS0FBSyxDQUFDLENBQUE7WUFFN0IsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFBO1lBQ3BELE1BQU0sWUFBWSxHQUFHLGdCQUFnQixDQUFDLGVBQWUsRUFBRSxDQUFBO1lBQ3ZELE1BQU0sVUFBVSxHQUFHLFlBQVksRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUE7WUFFNUMsSUFBSSxVQUFVLEVBQUUsQ0FBQztnQkFDZixLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVU7b0JBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsV0FBVyxLQUFLLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQTtZQUNuRyxDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxXQUFXLHdCQUF3QixPQUFPLEtBQUssS0FBSyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUE7UUFDdkcsQ0FBQztRQUVELFVBQVUsQ0FBQyx3QkFBd0IsQ0FBQyxFQUFDLGFBQWEsRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFBO1FBQ2pFLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFDLFlBQVksRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxlQUFlLEVBQUMsQ0FBQyxDQUFBO1FBRTVGLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUU7WUFDakMsYUFBYSxFQUFFLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRTtZQUM1QyxZQUFZO1lBQ1osS0FBSztZQUNMLFFBQVE7WUFDUixRQUFRO1lBQ1IsZUFBZTtZQUNmLFVBQVU7U0FDWCxDQUFDLENBQUE7UUFFRixVQUFVLENBQUMsaUJBQWlCLENBQUMsRUFBQyxZQUFZLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFBO0lBQ3RGLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLE9BQU87UUFDaEMsS0FBSyxNQUFNLFFBQVEsSUFBSSxVQUFVLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQztZQUFFLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ2pGLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgeyBhZGRUcmFja2VkU3RhY2tUb0Vycm9yIH0gZnJvbSBcIi4uL3V0aWxzL3dpdGgtdHJhY2tlZC1zdGFjay5qc1wiXG5pbXBvcnQgQmFja3RyYWNlQ2xlYW5lciBmcm9tIFwiLi4vdXRpbHMvYmFja3RyYWNlLWNsZWFuZXItbm9kZS5qc1wiXG5pbXBvcnQgcGljb2NvbG9ycyBmcm9tIFwicGljb2NvbG9yc1wiXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcbmltcG9ydCB7IHRlc3RFdmVudHMgfSBmcm9tIFwiLi90ZXN0LmpzXCJcblxuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCJAdmVsb2Npb3VzL3Rlc3RpbmcvcnVubmVyXCIpLlRlc3REZWNsYXJhdGlvbn0gUGFja2FnZVRlc3REZWNsYXJhdGlvbiAqL1xuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCJAdmVsb2Npb3VzL3Rlc3RpbmcvcnVubmVyXCIpLlRlc3RFcnJvclJlY29yZH0gUGFja2FnZVRlc3RFcnJvclJlY29yZCAqL1xuXG4vKipcbiAqIFJlc3RvcmVzIHRoZSBFcnJvciBzaGFwZSBzZXJpYWxpemVkIGJ5IHRoZSBwYWNrYWdlIHJ1bm5lci5cbiAqIEBwYXJhbSB7UGFja2FnZVRlc3RFcnJvclJlY29yZH0gZXJyb3JSZWNvcmQgLSBTZXJpYWxpemVkIHBhY2thZ2UgZmFpbHVyZS5cbiAqIEByZXR1cm5zIHtFcnJvcn0gLSBFcnJvciBjb21wYXRpYmxlIHdpdGggVmVsb2Npb3VzJ3MgbGVnYWN5IHJlcG9ydGVyIGNvbnRyYWN0LlxuICovXG5mdW5jdGlvbiBlcnJvckZyb21QYWNrYWdlUmVjb3JkKGVycm9yUmVjb3JkKSB7XG4gIGNvbnN0IGVycm9yID0gZXJyb3JSZWNvcmQuZXJyb3JzXG4gICAgPyBuZXcgQWdncmVnYXRlRXJyb3IoZXJyb3JSZWNvcmQuZXJyb3JzLm1hcChlcnJvckZyb21QYWNrYWdlUmVjb3JkKSwgZXJyb3JSZWNvcmQubWVzc2FnZSlcbiAgICA6IG5ldyBFcnJvcihlcnJvclJlY29yZC5tZXNzYWdlKVxuXG4gIGVycm9yLm5hbWUgPSBlcnJvclJlY29yZC5uYW1lXG4gIGlmIChlcnJvclJlY29yZC5zdGFjaykgZXJyb3Iuc3RhY2sgPSBlcnJvclJlY29yZC5zdGFja1xuXG4gIHJldHVybiBlcnJvclxufVxuXG4vKiogU3RvcHMgcGFja2FnZSB0cmF2ZXJzYWwgYWZ0ZXIgZnJhbWV3b3JrLW93bmVkIGNvbm5lY3Rpb24gcXVhcmFudGluZS4gKi9cbmV4cG9ydCBjbGFzcyBBYm9ydFJlbWFpbmluZ1Rlc3RzRXJyb3IgZXh0ZW5kcyBFcnJvciB7fVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNSdW5uZXJSZXBvcnRlciB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSBsZWdhY3kgZXZlbnQgYW5kIHJlc3VsdCBwcm9qZWN0aW9uIGFkYXB0ZXIuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQ29uc3RydWN0b3IgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuZGVmYXVsdH0gYXJncy50ZXN0UnVubmVyIC0gT3duaW5nIFZlbG9jaW91cyBydW5uZXIuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7dGVzdFJ1bm5lciwgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcbiAgICB0aGlzLnRlc3RSdW5uZXIgPSB0ZXN0UnVubmVyXG4gICAgLyoqIEB0eXBlIHtXZWFrTWFwPFBhY2thZ2VUZXN0RGVjbGFyYXRpb24sIGltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQXR0ZW1wdENvbnNvbGVPdXRwdXRbXT59ICovXG4gICAgdGhpcy5hdHRlbXB0Q29uc29sZU91dHB1dHMgPSBuZXcgV2Vha01hcCgpXG4gICAgLyoqIEB0eXBlIHtQYWNrYWdlVGVzdERlY2xhcmF0aW9uIHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuYWN0aXZlVGVzdCA9IHVuZGVmaW5lZFxuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zbGF0ZXMgb25lIGF3YWl0ZWQgcGFja2FnZSBydW5uZXIgZXZlbnQgaW50byB0aGUgbGVnYWN5IGNvbnRyYWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIkB2ZWxvY2lvdXMvdGVzdGluZy9ydW5uZXJcIikuUnVubmVyRXZlbnR9IGV2ZW50IC0gU3RydWN0dXJlZCBwYWNrYWdlIGV2ZW50LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBsZWdhY3kgbGlzdGVuZXJzIGZpbmlzaC5cbiAgICovXG4gIGFzeW5jIG9uRXZlbnQoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJ0ZXN0OnN0YXJ0XCIpIHtcbiAgICAgIHRoaXMuYWN0aXZlVGVzdCA9IHRoaXMudGVzdFJ1bm5lci5maW5kVGVzdERlY2xhcmF0aW9uKGV2ZW50LmZ1bGxOYW1lKVxuICAgICAgaWYgKHRoaXMuYWN0aXZlVGVzdCkge1xuICAgICAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMudGVzdFJ1bm5lci50ZXN0TWV0YWRhdGEodGhpcy5hY3RpdmVUZXN0KVxuICAgICAgICBjb25zb2xlLmxvZyhgJHtcIiBcIi5yZXBlYXQobWV0YWRhdGEuZGVzY3JpcHRpb25zLmxlbmd0aCAqIDIpfWl0ICR7bWV0YWRhdGEudGVzdERlc2NyaXB0aW9ufWApXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJhdHRlbXB0OmZpbmlzaFwiKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlcG9ydEF0dGVtcHRFdmVudChldmVudClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChldmVudC50eXBlID09PSBcInRlc3Q6ZmluaXNoXCIpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVwb3J0VGVzdEV2ZW50KGV2ZW50KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKGV2ZW50LnR5cGUgPT09IFwicnVuOmZpbmlzaFwiKSB0aGlzLnRlc3RSdW5uZXIucmVjb3JkUGFja2FnZVJlc3VsdChldmVudC5yZXN1bHQpXG4gIH1cblxuICAvKipcbiAgICogUHJvamVjdHMgYXR0ZW1wdCBmYWlsdXJlL3JldHJ5IGV2ZW50cyB3aGlsZSByZXRhaW5pbmcgdGhlIHJhdyB0aHJvd24gdmFsdWUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiKS5SdW5uZXJFdmVudH0gZXZlbnQgLSBBdHRlbXB0IGV2ZW50LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBsaXN0ZW5lcnMgZmluaXNoLlxuICAgKi9cbiAgYXN5bmMgcmVwb3J0QXR0ZW1wdEV2ZW50KGV2ZW50KSB7XG4gICAgY29uc3QgdGVzdCA9IHRoaXMuYWN0aXZlVGVzdCB8fCB0aGlzLnRlc3RSdW5uZXIuZmluZFRlc3REZWNsYXJhdGlvbihldmVudC5mdWxsTmFtZSlcblxuICAgIGlmICghdGVzdCkgdGhyb3cgbmV3IEVycm9yKGBQYWNrYWdlIHJ1bm5lciBhdHRlbXB0IGRpZCBub3QgbWF0Y2ggYSBkZWNsYXJhdGlvbjogJHtldmVudC5mdWxsTmFtZX1gKVxuXG4gICAgLy8gTmFycm93cyB0aGUgc3RydWN0dXJlZCBldmVudCBwYXlsb2FkIGZvciB0aGlzIGV2ZW50IGRpc2NyaW1pbmF0b3IuXG4gICAgY29uc3QgYXR0ZW1wdCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiKS5UZXN0QXR0ZW1wdFJlc3VsdH0gKi8gKGV2ZW50LmF0dGVtcHQpXG4gICAgY29uc3Qgb3V0Y29tZSA9IHRoaXMudGVzdFJ1bm5lci5hdHRlbXB0T3V0Y29tZSh0ZXN0LCBhdHRlbXB0LmF0dGVtcHROdW1iZXIpXG4gICAgY29uc3QgYXR0ZW1wdENvbnNvbGVPdXRwdXRzID0gdGhpcy5hdHRlbXB0Q29uc29sZU91dHB1dHMuZ2V0KHRlc3QpIHx8IFtdXG5cbiAgICBpZiAoYXR0ZW1wdC5jb25zb2xlT3V0cHV0KSB7XG4gICAgICBhdHRlbXB0Q29uc29sZU91dHB1dHMucHVzaCh7YXR0ZW1wdE51bWJlcjogYXR0ZW1wdC5hdHRlbXB0TnVtYmVyLCBvdXRwdXQ6IGF0dGVtcHQuY29uc29sZU91dHB1dC50cmltRW5kKCl9KVxuICAgICAgdGhpcy5hdHRlbXB0Q29uc29sZU91dHB1dHMuc2V0KHRlc3QsIGF0dGVtcHRDb25zb2xlT3V0cHV0cylcbiAgICB9XG5cbiAgICBjb25zdCByZXRyeUNvdW50ID0gdGhpcy50ZXN0UnVubmVyLnJldHJ5Q291bnQodGVzdClcbiAgICBjb25zdCBmYWlsZWQgPSBvdXRjb21lPy5mYWlsZWQgPz8gQm9vbGVhbihhdHRlbXB0LmVycm9yKVxuICAgIGNvbnN0IGVycm9yID0gb3V0Y29tZT8uZXJyb3JcbiAgICBjb25zdCByZXRyaWVzVXNlZCA9IE1hdGgubWluKGF0dGVtcHQuYXR0ZW1wdE51bWJlciwgcmV0cnlDb3VudClcbiAgICBjb25zdCB3aWxsUmV0cnkgPSBmYWlsZWQgJiYgIW91dGNvbWU/LmFib3J0UmVtYWluaW5nVGVzdHMgJiYgYXR0ZW1wdC5hdHRlbXB0TnVtYmVyIDw9IHJldHJ5Q291bnRcbiAgICBjb25zdCB7ZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb259ID0gdGhpcy50ZXN0UnVubmVyLnRlc3RNZXRhZGF0YSh0ZXN0KVxuICAgIGNvbnN0IGNvbXBhdGliaWxpdHkgPSB0aGlzLnRlc3RSdW5uZXIudGVzdERhdGEodGVzdClcblxuICAgIGlmIChmYWlsZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdEF0dGVtcHRGYWlsZWRcIiwge1xuICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLnRlc3RSdW5uZXIuZ2V0Q29uZmlndXJhdGlvbigpLFxuICAgICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBhdHRlbXB0TnVtYmVyOiBhdHRlbXB0LmF0dGVtcHROdW1iZXIsXG4gICAgICAgIG5leHRBdHRlbXB0OiB3aWxsUmV0cnkgPyBhdHRlbXB0LmF0dGVtcHROdW1iZXIgKyAxIDogdW5kZWZpbmVkLFxuICAgICAgICByZXRyaWVzVXNlZCxcbiAgICAgICAgcmV0cnlDb3VudCxcbiAgICAgICAgdGVzdEFyZ3M6IGNvbXBhdGliaWxpdHkudGVzdEFyZ3MsXG4gICAgICAgIHRlc3REYXRhOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLFxuICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgIHRlc3RSdW5uZXI6IHRoaXMudGVzdFJ1bm5lcixcbiAgICAgICAgd2lsbFJldHJ5XG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmICh3aWxsUmV0cnkpIHtcbiAgICAgIGNvbnNvbGUud2FybihwaWNvY29sb3JzLnJlZChgJHtcIiBcIi5yZXBlYXQoZGVzY3JpcHRpb25zLmxlbmd0aCAqIDIpfSAgUmV0cnlpbmcgKCR7cmV0cmllc1VzZWR9LyR7cmV0cnlDb3VudH0pIGFmdGVyIGVycm9yOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gKSlcbiAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdFJldHJ5aW5nXCIsIHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy50ZXN0UnVubmVyLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgbmV4dEF0dGVtcHQ6IGF0dGVtcHQuYXR0ZW1wdE51bWJlciArIDEsXG4gICAgICAgIHJldHJpZXNVc2VkLFxuICAgICAgICByZXRyeUNvdW50LFxuICAgICAgICB0ZXN0QXJnczogY29tcGF0aWJpbGl0eS50ZXN0QXJncyxcbiAgICAgICAgdGVzdERhdGE6IGNvbXBhdGliaWxpdHkudGVzdERhdGEsXG4gICAgICAgIHRlc3REZXNjcmlwdGlvbixcbiAgICAgICAgdGVzdFJ1bm5lcjogdGhpcy50ZXN0UnVubmVyXG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmIChhdHRlbXB0LmF0dGVtcHROdW1iZXIgPiAxKSB7XG4gICAgICBhd2FpdCB0aGlzLmVtaXRFdmVudChcInRlc3RSZXRyaWVkXCIsIHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy50ZXN0UnVubmVyLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgYXR0ZW1wdE51bWJlcjogYXR0ZW1wdC5hdHRlbXB0TnVtYmVyLFxuICAgICAgICByZXRyaWVzVXNlZCxcbiAgICAgICAgcmV0cnlDb3VudCxcbiAgICAgICAgdGVzdEFyZ3M6IGNvbXBhdGliaWxpdHkudGVzdEFyZ3MsXG4gICAgICAgIHRlc3REYXRhOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLFxuICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgIHRlc3RSdW5uZXI6IHRoaXMudGVzdFJ1bm5lclxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAob3V0Y29tZT8uYWJvcnRSZW1haW5pbmdUZXN0cykge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnRlc3RSdW5uZXIudGVzdE1ldGFkYXRhKHRlc3QpXG5cbiAgICAgIHRoaXMudGVzdFJ1bm5lci5yZWNvcmRUZXN0RHVyYXRpb24oe1xuICAgICAgICBkdXJhdGlvbk1zOiBhdHRlbXB0LmR1cmF0aW9uTXMsXG4gICAgICAgIGZpbGVQYXRoOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLmZpbGVQYXRoID8/IFwiPHVua25vd24+XCIsXG4gICAgICAgIGZ1bGxEZXNjcmlwdGlvbjogbWV0YWRhdGEuZnVsbERlc2NyaXB0aW9uLFxuICAgICAgICBsaW5lOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLmxpbmUgPz8gMFxuICAgICAgfSlcbiAgICAgIGF3YWl0IHRoaXMucmVwb3J0RmFpbGVkVGVzdCh7XG4gICAgICAgIGF0dGVtcHRDb25zb2xlT3V0cHV0cyxcbiAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgbGVmdFBhZGRpbmc6IFwiIFwiLnJlcGVhdChkZXNjcmlwdGlvbnMubGVuZ3RoICogMiksXG4gICAgICAgIHRlc3RBcmdzOiBjb21wYXRpYmlsaXR5LnRlc3RBcmdzLFxuICAgICAgICB0ZXN0RGF0YTogY29tcGF0aWJpbGl0eS50ZXN0RGF0YSxcbiAgICAgICAgdGVzdERlc2NyaXB0aW9uXG4gICAgICB9KVxuICAgICAgdGhpcy50ZXN0UnVubmVyLmNvbXBsZXRlVGVzdERlY2xhcmF0aW9uKHRlc3QpXG4gICAgICB0aGlzLmFjdGl2ZVRlc3QgPSB1bmRlZmluZWRcbiAgICAgIHRocm93IG5ldyBBYm9ydFJlbWFpbmluZ1Rlc3RzRXJyb3IoXCJWZWxvY2lvdXMgcXVhcmFudGluZWQgYW4gYXR0ZW1wdC1vd25lZCBkYXRhYmFzZSBjb25uZWN0aW9uXCIpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFByb2plY3RzIGZpbmFsIHBhY2thZ2UgcmVzdWx0IGFjY291bnRpbmcgYW5kIGZhaWx1cmVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIkB2ZWxvY2lvdXMvdGVzdGluZy9ydW5uZXJcIikuUnVubmVyRXZlbnR9IGV2ZW50IC0gVGVzdCByZXN1bHQgZXZlbnQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIGxpc3RlbmVycyBmaW5pc2guXG4gICAqL1xuICBhc3luYyByZXBvcnRUZXN0RXZlbnQoZXZlbnQpIHtcbiAgICAvLyBOYXJyb3dzIHRoZSBzdHJ1Y3R1cmVkIGV2ZW50IHBheWxvYWQgZm9yIHRoaXMgZXZlbnQgZGlzY3JpbWluYXRvci5cbiAgICBjb25zdCBwYWNrYWdlVGVzdFJlc3VsdCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiKS5UZXN0UmVzdWx0fSAqLyAoZXZlbnQudGVzdClcbiAgICBjb25zdCB0ZXN0ID0gdGhpcy5hY3RpdmVUZXN0IHx8IHRoaXMudGVzdFJ1bm5lci5maW5kVGVzdERlY2xhcmF0aW9uKHBhY2thZ2VUZXN0UmVzdWx0LmZ1bGxOYW1lKVxuXG4gICAgaWYgKCF0ZXN0KSB0aHJvdyBuZXcgRXJyb3IoYFBhY2thZ2UgcnVubmVyIHJlc3VsdCBkaWQgbm90IG1hdGNoIGEgZGVjbGFyYXRpb246ICR7cGFja2FnZVRlc3RSZXN1bHQuZnVsbE5hbWV9YClcblxuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy50ZXN0UnVubmVyLnRlc3RNZXRhZGF0YSh0ZXN0KVxuICAgIGNvbnN0IGNvbXBhdGliaWxpdHkgPSB0aGlzLnRlc3RSdW5uZXIudGVzdERhdGEodGVzdClcbiAgICBjb25zdCBkdXJhdGlvbk1zID0gcGFja2FnZVRlc3RSZXN1bHQuYXR0ZW1wdHMucmVkdWNlKCh0b3RhbCwgYXR0ZW1wdCkgPT4gdG90YWwgKyBhdHRlbXB0LmR1cmF0aW9uTXMsIDApXG5cbiAgICBpZiAocGFja2FnZVRlc3RSZXN1bHQuYXR0ZW1wdHMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy50ZXN0UnVubmVyLnJlY29yZFRlc3REdXJhdGlvbih7XG4gICAgICAgIGR1cmF0aW9uTXMsXG4gICAgICAgIGZpbGVQYXRoOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLmZpbGVQYXRoID8/IFwiPHVua25vd24+XCIsXG4gICAgICAgIGZ1bGxEZXNjcmlwdGlvbjogbWV0YWRhdGEuZnVsbERlc2NyaXB0aW9uLFxuICAgICAgICBsaW5lOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLmxpbmUgPz8gMFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAocGFja2FnZVRlc3RSZXN1bHQuc3RhdHVzID09PSBcInBhc3NlZFwiKSB7XG4gICAgICB0aGlzLnRlc3RSdW5uZXIucmVjb3JkU3VjY2Vzc2Z1bFRlc3QoKVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBmaW5hbEF0dGVtcHQgPSBwYWNrYWdlVGVzdFJlc3VsdC5hdHRlbXB0cy5hdCgtMSlcbiAgICAgIGNvbnN0IG91dGNvbWUgPSBmaW5hbEF0dGVtcHRcbiAgICAgICAgPyB0aGlzLnRlc3RSdW5uZXIuYXR0ZW1wdE91dGNvbWUodGVzdCwgZmluYWxBdHRlbXB0LmF0dGVtcHROdW1iZXIpXG4gICAgICAgIDogdW5kZWZpbmVkXG4gICAgICBjb25zdCBzZXR1cEZhaWx1cmUgPSB0aGlzLnRlc3RSdW5uZXIuc2V0dXBGYWlsdXJlT3V0Y29tZUZvcih0ZXN0KVxuICAgICAgY29uc3QgZXJyb3IgPSBvdXRjb21lPy5mYWlsZWRcbiAgICAgICAgPyBvdXRjb21lLmVycm9yXG4gICAgICAgIDogc2V0dXBGYWlsdXJlLmZhaWxlZFxuICAgICAgICAgID8gc2V0dXBGYWlsdXJlLmVycm9yXG4gICAgICAgICAgOiBwYWNrYWdlVGVzdFJlc3VsdC5lcnJvclxuICAgICAgICAgICAgPyBlcnJvckZyb21QYWNrYWdlUmVjb3JkKHBhY2thZ2VUZXN0UmVzdWx0LmVycm9yKVxuICAgICAgICAgICAgOiB1bmRlZmluZWRcblxuICAgICAgYXdhaXQgdGhpcy5yZXBvcnRGYWlsZWRUZXN0KHtcbiAgICAgICAgYXR0ZW1wdENvbnNvbGVPdXRwdXRzOiB0aGlzLmF0dGVtcHRDb25zb2xlT3V0cHV0cy5nZXQodGVzdCkgfHwgW10sXG4gICAgICAgIGRlc2NyaXB0aW9uczogbWV0YWRhdGEuZGVzY3JpcHRpb25zLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgbGVmdFBhZGRpbmc6IFwiIFwiLnJlcGVhdChtZXRhZGF0YS5kZXNjcmlwdGlvbnMubGVuZ3RoICogMiksXG4gICAgICAgIHRlc3RBcmdzOiBjb21wYXRpYmlsaXR5LnRlc3RBcmdzLFxuICAgICAgICB0ZXN0RGF0YTogY29tcGF0aWJpbGl0eS50ZXN0RGF0YSxcbiAgICAgICAgdGVzdERlc2NyaXB0aW9uOiBtZXRhZGF0YS50ZXN0RGVzY3JpcHRpb25cbiAgICAgIH0pXG4gICAgfVxuXG4gICAgdGhpcy50ZXN0UnVubmVyLmNvbXBsZXRlVGVzdERlY2xhcmF0aW9uKHRlc3QpXG4gICAgdGhpcy5hY3RpdmVUZXN0ID0gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogUmVjb3JkcyBhbmQgZW1pdHMgb25lIGZpbmFsIGZhaWxlZCB0ZXN0IHJlc3VsdC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBGaW5hbCBmYWlsdXJlIG1ldGFkYXRhLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQXR0ZW1wdENvbnNvbGVPdXRwdXRbXX0gYXJncy5hdHRlbXB0Q29uc29sZU91dHB1dHMgLSBDYXB0dXJlZCBvdXRwdXQgYWNyb3NzIGF0dGVtcHRzLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLmRlc2NyaXB0aW9ucyAtIFBhcmVudCBkZXNjcmlwdGlvbiBzdGFjay5cbiAgICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gYXJncy5lcnJvciAtIFJhdyBmaW5hbCBmYWlsdXJlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5sZWZ0UGFkZGluZyAtIENvbnNvbGUgaW5kZW50YXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5UZXN0QXJnc30gYXJncy50ZXN0QXJncyAtIFN0YWJsZSB0ZXN0IGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3Rlc3QtcnVubmVyLmpzXCIpLlRlc3REYXRhfSBhcmdzLnRlc3REYXRhIC0gVGVzdCByZWdpc3RyYXRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLnRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIHRoZSBmaW5hbC1mYWlsdXJlIGxpc3RlbmVyIGNvbXBsZXRlcy5cbiAgICovXG4gIGFzeW5jIHJlcG9ydEZhaWxlZFRlc3Qoe2F0dGVtcHRDb25zb2xlT3V0cHV0cywgZGVzY3JpcHRpb25zLCBlcnJvciwgbGVmdFBhZGRpbmcsIHRlc3RBcmdzLCB0ZXN0RGF0YSwgdGVzdERlc2NyaXB0aW9ufSkge1xuICAgIGNvbnN0IHRlc3RSdW5uZXIgPSB0aGlzLnRlc3RSdW5uZXJcbiAgICBjb25zdCBjb25zb2xlT3V0cHV0ID0gdGVzdFJ1bm5lci5idWlsZENvbnNvbGVPdXRwdXQoYXR0ZW1wdENvbnNvbGVPdXRwdXRzKVxuXG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IocGljb2NvbG9ycy5yZWQoYCR7bGVmdFBhZGRpbmd9ICBUZXN0IGZhaWxlZDogJHtlcnJvci5tZXNzYWdlfWApKVxuICAgICAgYWRkVHJhY2tlZFN0YWNrVG9FcnJvcihlcnJvcilcblxuICAgICAgY29uc3QgYmFja3RyYWNlQ2xlYW5lciA9IG5ldyBCYWNrdHJhY2VDbGVhbmVyKGVycm9yKVxuICAgICAgY29uc3QgY2xlYW5lZFN0YWNrID0gYmFja3RyYWNlQ2xlYW5lci5nZXRDbGVhbmVkU3RhY2soKVxuICAgICAgY29uc3Qgc3RhY2tMaW5lcyA9IGNsZWFuZWRTdGFjaz8uc3BsaXQoXCJcXG5cIilcblxuICAgICAgaWYgKHN0YWNrTGluZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBzdGFja0xpbmUgb2Ygc3RhY2tMaW5lcykgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gICR7c3RhY2tMaW5lfWApKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGAke2xlZnRQYWRkaW5nfSAgVGVzdCBmYWlsZWQgd2l0aCBhICR7dHlwZW9mIGVycm9yfTogJHtTdHJpbmcoZXJyb3IpfWApKVxuICAgIH1cblxuICAgIHRlc3RSdW5uZXIucHJpbnRGYWlsZWRDb25zb2xlT3V0cHV0KHtjb25zb2xlT3V0cHV0LCBsZWZ0UGFkZGluZ30pXG4gICAgdGVzdFJ1bm5lci5yZWNvcmRGYWlsZWRUZXN0KHtkZXNjcmlwdGlvbnMsIGVycm9yLCBjb25zb2xlT3V0cHV0LCB0ZXN0RGF0YSwgdGVzdERlc2NyaXB0aW9ufSlcblxuICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdEZhaWxlZFwiLCB7XG4gICAgICBjb25maWd1cmF0aW9uOiB0ZXN0UnVubmVyLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgIGRlc2NyaXB0aW9ucyxcbiAgICAgIGVycm9yLFxuICAgICAgdGVzdEFyZ3MsXG4gICAgICB0ZXN0RGF0YSxcbiAgICAgIHRlc3REZXNjcmlwdGlvbixcbiAgICAgIHRlc3RSdW5uZXJcbiAgICB9KVxuXG4gICAgdGVzdFJ1bm5lci5wcmludFJlcnVuQ29tbWFuZCh7ZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24sIHRlc3REYXRhLCBsZWZ0UGFkZGluZ30pXG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgb25lIGxlZ2FjeSBldmVudCBhbmQgYXdhaXRzIGxpc3RlbmVycyBpbiByZWdpc3RyYXRpb24gb3JkZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgLSBFdmVudCBuYW1lLlxuICAgKiBAcGFyYW0ge29iamVjdH0gcGF5bG9hZCAtIEV2ZW50IHBheWxvYWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gYWxsIGxpc3RlbmVycyBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGVtaXRFdmVudChldmVudE5hbWUsIHBheWxvYWQpIHtcbiAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIHRlc3RFdmVudHMubGlzdGVuZXJzKGV2ZW50TmFtZSkpIGF3YWl0IGxpc3RlbmVyKHBheWxvYWQpXG4gIH1cbn1cbiJdfQ==
|
|
302
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVsb2Npb3VzLXJ1bm5lci1yZXBvcnRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0aW5nL3ZlbG9jaW91cy1ydW5uZXItcmVwb3J0ZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFBO0FBQ3ZFLE9BQU8sVUFBVSxNQUFNLFlBQVksQ0FBQTtBQUNuQyxPQUFPLGFBQWEsTUFBTSw2QkFBNkIsQ0FBQTtBQUN2RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBRXRDLDRGQUE0RjtBQUM1Riw0RkFBNEY7QUFFNUY7Ozs7R0FJRztBQUNILFNBQVMsc0JBQXNCLENBQUMsV0FBVztJQUN6QyxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsTUFBTTtRQUM5QixDQUFDLENBQUMsSUFBSSxjQUFjLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsRUFBRSxXQUFXLENBQUMsT0FBTyxDQUFDO1FBQ3pGLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUE7SUFFbEMsS0FBSyxDQUFDLElBQUksR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFBO0lBQzdCLElBQUksV0FBVyxDQUFDLEtBQUs7UUFBRSxLQUFLLENBQUMsS0FBSyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUE7SUFDdEQsSUFBSSxXQUFXLENBQUMsS0FBSztRQUFFLEtBQUssQ0FBQyxLQUFLLEdBQUcsc0JBQXNCLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzlFLElBQUksV0FBVyxDQUFDLGdCQUFnQjtRQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLEVBQUMsZ0JBQWdCLEVBQUUsV0FBVyxDQUFDLGdCQUFnQixFQUFDLENBQUMsQ0FBQTtJQUV4RyxPQUFPLEtB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LFVBQVUsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDO1lBQUUsTUFBTSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDakYsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7IGFkZFRyYWNrZWRTdGFja1RvRXJyb3IgfSBmcm9tIFwiLi4vdXRpbHMvd2l0aC10cmFja2VkLXN0YWNrLmpzXCJcbmltcG9ydCBwaWNvY29sb3JzIGZyb20gXCJwaWNvY29sb3JzXCJcbmltcG9ydCByZXN0QXJnc0Vycm9yIGZyb20gXCIuLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuaW1wb3J0IHsgdGVzdEV2ZW50cyB9IGZyb20gXCIuL3Rlc3QuanNcIlxuXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIkB2ZWxvY2lvdXMvdGVzdGluZy9ydW5uZXJcIikuVGVzdERlY2xhcmF0aW9ufSBQYWNrYWdlVGVzdERlY2xhcmF0aW9uICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIkB2ZWxvY2lvdXMvdGVzdGluZy9ydW5uZXJcIikuVGVzdEVycm9yUmVjb3JkfSBQYWNrYWdlVGVzdEVycm9yUmVjb3JkICovXG5cbi8qKlxuICogUmVzdG9yZXMgdGhlIEVycm9yIHNoYXBlIHNlcmlhbGl6ZWQgYnkgdGhlIHBhY2thZ2UgcnVubmVyLlxuICogQHBhcmFtIHtQYWNrYWdlVGVzdEVycm9yUmVjb3JkfSBlcnJvclJlY29yZCAtIFNlcmlhbGl6ZWQgcGFja2FnZSBmYWlsdXJlLlxuICogQHJldHVybnMge0Vycm9yfSAtIEVycm9yIGNvbXBhdGlibGUgd2l0aCBWZWxvY2lvdXMncyBsZWdhY3kgcmVwb3J0ZXIgY29udHJhY3QuXG4gKi9cbmZ1bmN0aW9uIGVycm9yRnJvbVBhY2thZ2VSZWNvcmQoZXJyb3JSZWNvcmQpIHtcbiAgY29uc3QgZXJyb3IgPSBlcnJvclJlY29yZC5lcnJvcnNcbiAgICA/IG5ldyBBZ2dyZWdhdGVFcnJvcihlcnJvclJlY29yZC5lcnJvcnMubWFwKGVycm9yRnJvbVBhY2thZ2VSZWNvcmQpLCBlcnJvclJlY29yZC5tZXNzYWdlKVxuICAgIDogbmV3IEVycm9yKGVycm9yUmVjb3JkLm1lc3NhZ2UpXG5cbiAgZXJyb3IubmFtZSA9IGVycm9yUmVjb3JkLm5hbWVcbiAgaWYgKGVycm9yUmVjb3JkLnN0YWNrKSBlcnJvci5zdGFjayA9IGVycm9yUmVjb3JkLnN0YWNrXG4gIGlmIChlcnJvclJlY29yZC5jYXVzZSkgZXJyb3IuY2F1c2UgPSBlcnJvckZyb21QYWNrYWdlUmVjb3JkKGVycm9yUmVjb3JkLmNhdXNlKVxuICBpZiAoZXJyb3JSZWNvcmQudGVybWluYWxSZXNvdXJjZSkgT2JqZWN0LmFzc2lnbihlcnJvciwge3Rlcm1pbmFsUmVzb3VyY2U6IGVycm9yUmVjb3JkLnRlcm1pbmFsUmVzb3VyY2V9KVxuXG4gIHJldHVybiBlcnJvclxufVxuXG4vKiogU3RvcHMgcGFja2FnZSB0cmF2ZXJzYWwgYWZ0ZXIgZnJhbWV3b3JrLW93bmVkIGNvbm5lY3Rpb24gcXVhcmFudGluZS4gKi9cbmV4cG9ydCBjbGFzcyBBYm9ydFJlbWFpbmluZ1Rlc3RzRXJyb3IgZXh0ZW5kcyBFcnJvciB7fVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNSdW5uZXJSZXBvcnRlciB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSBsZWdhY3kgZXZlbnQgYW5kIHJlc3VsdCBwcm9qZWN0aW9uIGFkYXB0ZXIuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQ29uc3RydWN0b3IgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuZGVmYXVsdH0gYXJncy50ZXN0UnVubmVyIC0gT3duaW5nIFZlbG9jaW91cyBydW5uZXIuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7dGVzdFJ1bm5lciwgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcbiAgICB0aGlzLnRlc3RSdW5uZXIgPSB0ZXN0UnVubmVyXG4gICAgLyoqIEB0eXBlIHtXZWFrTWFwPFBhY2thZ2VUZXN0RGVjbGFyYXRpb24sIGltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQXR0ZW1wdENvbnNvbGVPdXRwdXRbXT59ICovXG4gICAgdGhpcy5hdHRlbXB0Q29uc29sZU91dHB1dHMgPSBuZXcgV2Vha01hcCgpXG4gICAgLyoqIEB0eXBlIHtQYWNrYWdlVGVzdERlY2xhcmF0aW9uIHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuYWN0aXZlVGVzdCA9IHVuZGVmaW5lZFxuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zbGF0ZXMgb25lIGF3YWl0ZWQgcGFja2FnZSBydW5uZXIgZXZlbnQgaW50byB0aGUgbGVnYWN5IGNvbnRyYWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIkB2ZWxvY2lvdXMvdGVzdGluZy9ydW5uZXJcIikuUnVubmVyRXZlbnR9IGV2ZW50IC0gU3RydWN0dXJlZCBwYWNrYWdlIGV2ZW50LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBsZWdhY3kgbGlzdGVuZXJzIGZpbmlzaC5cbiAgICovXG4gIGFzeW5jIG9uRXZlbnQoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJ0ZXN0OnN0YXJ0XCIpIHtcbiAgICAgIHRoaXMuYWN0aXZlVGVzdCA9IHRoaXMudGVzdFJ1bm5lci5maW5kVGVzdERlY2xhcmF0aW9uKGV2ZW50LmZ1bGxOYW1lKVxuICAgICAgaWYgKHRoaXMuYWN0aXZlVGVzdCkge1xuICAgICAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMudGVzdFJ1bm5lci50ZXN0TWV0YWRhdGEodGhpcy5hY3RpdmVUZXN0KVxuICAgICAgICBjb25zb2xlLmxvZyhgJHtcIiBcIi5yZXBlYXQobWV0YWRhdGEuZGVzY3JpcHRpb25zLmxlbmd0aCAqIDIpfWl0ICR7bWV0YWRhdGEudGVzdERlc2NyaXB0aW9ufWApXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJhdHRlbXB0OmZpbmlzaFwiKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlcG9ydEF0dGVtcHRFdmVudChldmVudClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChldmVudC50eXBlID09PSBcInRlc3Q6ZmluaXNoXCIpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVwb3J0VGVzdEV2ZW50KGV2ZW50KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKGV2ZW50LnR5cGUgPT09IFwidGVzdDpub3QtcnVuXCIpIHtcbiAgICAgIGNvbnN0IHRlc3QgPSB0aGlzLnRlc3RSdW5uZXIuZmluZFRlc3REZWNsYXJhdGlvbihldmVudC50ZXN0LmZ1bGxOYW1lKVxuICAgICAgaWYgKCF0ZXN0KSB0aHJvdyBuZXcgRXJyb3IoYFBhY2thZ2Ugbm90LXJ1biByZXN1bHQgZGlkIG5vdCBtYXRjaCBhIGRlY2xhcmF0aW9uOiAke2V2ZW50LnRlc3QuZnVsbE5hbWV9YClcbiAgICAgIHRoaXMudGVzdFJ1bm5lci5yZWNvcmROb3RSdW5UZXN0KGV2ZW50LnRlc3QpXG4gICAgICB0aGlzLnRlc3RSdW5uZXIuY29tcGxldGVUZXN0RGVjbGFyYXRpb24odGVzdClcbiAgICAgIGNvbnNvbGUuZXJyb3IoYE5vdCBydW46ICR7ZXZlbnQudGVzdC5mdWxsTmFtZX0gKHRlcm1pbmFsIHJlc291cmNlIGZhaWx1cmUgaW4gJHtldmVudC50ZXN0LnJlYXNvbi5mdWxsTmFtZX0pYClcbiAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdE5vdFJ1blwiLCB7XG4gICAgICAgIGNvbmZpZ3VyYXRpb246IHRoaXMudGVzdFJ1bm5lci5nZXRDb25maWd1cmF0aW9uKCksXG4gICAgICAgIHRlc3Q6IGV2ZW50LnRlc3QsXG4gICAgICAgIHRlc3RSdW5uZXI6IHRoaXMudGVzdFJ1bm5lclxuICAgICAgfSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChldmVudC50eXBlID09PSBcInJ1bjpmaW5pc2hcIikge1xuICAgICAgdGhpcy50ZXN0UnVubmVyLnJlY29yZFBhY2thZ2VSZXN1bHQoZXZlbnQucmVzdWx0KVxuICAgICAgZm9yIChjb25zdCBmYWlsdXJlIG9mIGV2ZW50LnJlc3VsdC5lcnJvcnMpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgU3VpdGUgJHtmYWlsdXJlLnBoYXNlfSBmYWlsZWQ6ICR7ZmFpbHVyZS5zdWl0ZX1gKVxuICAgICAgICB0aGlzLnByaW50RXJyb3JDYXVzZXMoZXJyb3JGcm9tUGFja2FnZVJlY29yZChmYWlsdXJlLmVycm9yKSlcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHJvamVjdHMgYXR0ZW1wdCBmYWlsdXJlL3JldHJ5IGV2ZW50cyB3aGlsZSByZXRhaW5pbmcgdGhlIHJhdyB0aHJvd24gdmFsdWUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiKS5SdW5uZXJFdmVudH0gZXZlbnQgLSBBdHRlbXB0IGV2ZW50LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBsaXN0ZW5lcnMgZmluaXNoLlxuICAgKi9cbiAgYXN5bmMgcmVwb3J0QXR0ZW1wdEV2ZW50KGV2ZW50KSB7XG4gICAgY29uc3QgdGVzdCA9IHRoaXMuYWN0aXZlVGVzdCB8fCB0aGlzLnRlc3RSdW5uZXIuZmluZFRlc3REZWNsYXJhdGlvbihldmVudC5mdWxsTmFtZSlcblxuICAgIGlmICghdGVzdCkgdGhyb3cgbmV3IEVycm9yKGBQYWNrYWdlIHJ1bm5lciBhdHRlbXB0IGRpZCBub3QgbWF0Y2ggYSBkZWNsYXJhdGlvbjogJHtldmVudC5mdWxsTmFtZX1gKVxuXG4gICAgLy8gTmFycm93cyB0aGUgc3RydWN0dXJlZCBldmVudCBwYXlsb2FkIGZvciB0aGlzIGV2ZW50IGRpc2NyaW1pbmF0b3IuXG4gICAgY29uc3QgYXR0ZW1wdCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiKS5UZXN0QXR0ZW1wdFJlc3VsdH0gKi8gKGV2ZW50LmF0dGVtcHQpXG4gICAgY29uc3Qgb3V0Y29tZSA9IHRoaXMudGVzdFJ1bm5lci5hdHRlbXB0T3V0Y29tZSh0ZXN0LCBhdHRlbXB0LmF0dGVtcHROdW1iZXIpXG4gICAgY29uc3QgYXR0ZW1wdENvbnNvbGVPdXRwdXRzID0gdGhpcy5hdHRlbXB0Q29uc29sZU91dHB1dHMuZ2V0KHRlc3QpIHx8IFtdXG5cbiAgICBpZiAoYXR0ZW1wdC5jb25zb2xlT3V0cHV0KSB7XG4gICAgICBhdHRlbXB0Q29uc29sZU91dHB1dHMucHVzaCh7YXR0ZW1wdE51bWJlcjogYXR0ZW1wdC5hdHRlbXB0TnVtYmVyLCBvdXRwdXQ6IGF0dGVtcHQuY29uc29sZU91dHB1dC50cmltRW5kKCl9KVxuICAgICAgdGhpcy5hdHRlbXB0Q29uc29sZU91dHB1dHMuc2V0KHRlc3QsIGF0dGVtcHRDb25zb2xlT3V0cHV0cylcbiAgICB9XG5cbiAgICBjb25zdCByZXRyeUNvdW50ID0gdGhpcy50ZXN0UnVubmVyLnJldHJ5Q291bnQodGVzdClcbiAgICBjb25zdCBmYWlsZWQgPSBvdXRjb21lPy5mYWlsZWQgPz8gQm9vbGVhbihhdHRlbXB0LmVycm9yKVxuICAgIGNvbnN0IGVycm9yID0gb3V0Y29tZT8uZXJyb3JcbiAgICBjb25zdCByZXRyaWVzVXNlZCA9IE1hdGgubWluKGF0dGVtcHQuYXR0ZW1wdE51bWJlciwgcmV0cnlDb3VudClcbiAgICBjb25zdCB3aWxsUmV0cnkgPSBmYWlsZWQgJiYgIWV2ZW50LnRlcm1pbmFsRmFpbHVyZSAmJiAhb3V0Y29tZT8uYWJvcnRSZW1haW5pbmdUZXN0cyAmJiBhdHRlbXB0LmF0dGVtcHROdW1iZXIgPD0gcmV0cnlDb3VudFxuICAgIGNvbnN0IHtkZXNjcmlwdGlvbnMsIHRlc3REZXNjcmlwdGlvbn0gPSB0aGlzLnRlc3RSdW5uZXIudGVzdE1ldGFkYXRhKHRlc3QpXG4gICAgY29uc3QgY29tcGF0aWJpbGl0eSA9IHRoaXMudGVzdFJ1bm5lci50ZXN0RGF0YSh0ZXN0KVxuXG4gICAgaWYgKGZhaWxlZCkge1xuICAgICAgYXdhaXQgdGhpcy5lbWl0RXZlbnQoXCJ0ZXN0QXR0ZW1wdEZhaWxlZFwiLCB7XG4gICAgICAgIGNvbmZpZ3VyYXRpb246IHRoaXMudGVzdFJ1bm5lci5nZXRDb25maWd1cmF0aW9uKCksXG4gICAgICAgIGRlc2NyaXB0aW9ucyxcbiAgICAgICAgZXJyb3IsXG4gICAgICAgIGF0dGVtcHROdW1iZXI6IGF0dGVtcHQuYXR0ZW1wdE51bWJlcixcbiAgICAgICAgbmV4dEF0dGVtcHQ6IHdpbGxSZXRyeSA/IGF0dGVtcHQuYXR0ZW1wdE51bWJlciArIDEgOiB1bmRlZmluZWQsXG4gICAgICAgIHJldHJpZXNVc2VkLFxuICAgICAgICByZXRyeUNvdW50LFxuICAgICAgICB0ZXN0QXJnczogY29tcGF0aWJpbGl0eS50ZXN0QXJncyxcbiAgICAgICAgdGVzdERhdGE6IGNvbXBhdGliaWxpdHkudGVzdERhdGEsXG4gICAgICAgIHRlc3REZXNjcmlwdGlvbixcbiAgICAgICAgdGVzdFJ1bm5lcjogdGhpcy50ZXN0UnVubmVyLFxuICAgICAgICB3aWxsUmV0cnlcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgaWYgKHdpbGxSZXRyeSkge1xuICAgICAgY29uc29sZS53YXJuKHBpY29jb2xvcnMucmVkKGAke1wiIFwiLnJlcGVhdChkZXNjcmlwdGlvbnMubGVuZ3RoICogMil9ICBSZXRyeWluZyAoJHtyZXRyaWVzVXNlZH0vJHtyZXRyeUNvdW50fSkgYWZ0ZXIgZXJyb3I6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWApKVxuICAgICAgYXdhaXQgdGhpcy5lbWl0RXZlbnQoXCJ0ZXN0UmV0cnlpbmdcIiwge1xuICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLnRlc3RSdW5uZXIuZ2V0Q29uZmlndXJhdGlvbigpLFxuICAgICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBuZXh0QXR0ZW1wdDogYXR0ZW1wdC5hdHRlbXB0TnVtYmVyICsgMSxcbiAgICAgICAgcmV0cmllc1VzZWQsXG4gICAgICAgIHJldHJ5Q291bnQsXG4gICAgICAgIHRlc3RBcmdzOiBjb21wYXRpYmlsaXR5LnRlc3RBcmdzLFxuICAgICAgICB0ZXN0RGF0YTogY29tcGF0aWJpbGl0eS50ZXN0RGF0YSxcbiAgICAgICAgdGVzdERlc2NyaXB0aW9uLFxuICAgICAgICB0ZXN0UnVubmVyOiB0aGlzLnRlc3RSdW5uZXJcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgaWYgKGF0dGVtcHQuYXR0ZW1wdE51bWJlciA+IDEpIHtcbiAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdFJldHJpZWRcIiwge1xuICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLnRlc3RSdW5uZXIuZ2V0Q29uZmlndXJhdGlvbigpLFxuICAgICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBhdHRlbXB0TnVtYmVyOiBhdHRlbXB0LmF0dGVtcHROdW1iZXIsXG4gICAgICAgIHJldHJpZXNVc2VkLFxuICAgICAgICByZXRyeUNvdW50LFxuICAgICAgICB0ZXN0QXJnczogY29tcGF0aWJpbGl0eS50ZXN0QXJncyxcbiAgICAgICAgdGVzdERhdGE6IGNvbXBhdGliaWxpdHkudGVzdERhdGEsXG4gICAgICAgIHRlc3REZXNjcmlwdGlvbixcbiAgICAgICAgdGVzdFJ1bm5lcjogdGhpcy50ZXN0UnVubmVyXG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmIChvdXRjb21lPy5hYm9ydFJlbWFpbmluZ1Rlc3RzKSB7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMudGVzdFJ1bm5lci50ZXN0TWV0YWRhdGEodGVzdClcblxuICAgICAgdGhpcy50ZXN0UnVubmVyLnJlY29yZFRlc3REdXJhdGlvbih7XG4gICAgICAgIGR1cmF0aW9uTXM6IGF0dGVtcHQuZHVyYXRpb25NcyxcbiAgICAgICAgZmlsZVBhdGg6IGNvbXBhdGliaWxpdHkudGVzdERhdGEuZmlsZVBhdGggPz8gXCI8dW5rbm93bj5cIixcbiAgICAgICAgZnVsbERlc2NyaXB0aW9uOiBtZXRhZGF0YS5mdWxsRGVzY3JpcHRpb24sXG4gICAgICAgIGxpbmU6IGNvbXBhdGliaWxpdHkudGVzdERhdGEubGluZSA/PyAwXG4gICAgICB9KVxuICAgICAgYXdhaXQgdGhpcy5yZXBvcnRGYWlsZWRUZXN0KHtcbiAgICAgICAgYXR0ZW1wdENvbnNvbGVPdXRwdXRzLFxuICAgICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBsZWZ0UGFkZGluZzogXCIgXCIucmVwZWF0KGRlc2NyaXB0aW9ucy5sZW5ndGggKiAyKSxcbiAgICAgICAgdGVzdEFyZ3M6IGNvbXBhdGliaWxpdHkudGVzdEFyZ3MsXG4gICAgICAgIHRlc3REYXRhOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLFxuICAgICAgICB0ZXN0RGVzY3JpcHRpb25cbiAgICAgIH0pXG4gICAgICB0aGlzLnRlc3RSdW5uZXIuY29tcGxldGVUZXN0RGVjbGFyYXRpb24odGVzdClcbiAgICAgIHRoaXMuYWN0aXZlVGVzdCA9IHVuZGVmaW5lZFxuICAgICAgdGhyb3cgbmV3IEFib3J0UmVtYWluaW5nVGVzdHNFcnJvcihcIlZlbG9jaW91cyBxdWFyYW50aW5lZCBhbiBhdHRlbXB0LW93bmVkIGRhdGFiYXNlIGNvbm5lY3Rpb25cIilcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHJvamVjdHMgZmluYWwgcGFja2FnZSByZXN1bHQgYWNjb3VudGluZyBhbmQgZmFpbHVyZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiKS5SdW5uZXJFdmVudH0gZXZlbnQgLSBUZXN0IHJlc3VsdCBldmVudC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgbGlzdGVuZXJzIGZpbmlzaC5cbiAgICovXG4gIGFzeW5jIHJlcG9ydFRlc3RFdmVudChldmVudCkge1xuICAgIC8vIE5hcnJvd3MgdGhlIHN0cnVjdHVyZWQgZXZlbnQgcGF5bG9hZCBmb3IgdGhpcyBldmVudCBkaXNjcmltaW5hdG9yLlxuICAgIGNvbnN0IHBhY2thZ2VUZXN0UmVzdWx0ID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJAdmVsb2Npb3VzL3Rlc3RpbmcvcnVubmVyXCIpLlRlc3RSZXN1bHR9ICovIChldmVudC50ZXN0KVxuICAgIGNvbnN0IHRlc3QgPSB0aGlzLmFjdGl2ZVRlc3QgfHwgdGhpcy50ZXN0UnVubmVyLmZpbmRUZXN0RGVjbGFyYXRpb24ocGFja2FnZVRlc3RSZXN1bHQuZnVsbE5hbWUpXG5cbiAgICBpZiAoIXRlc3QpIHRocm93IG5ldyBFcnJvcihgUGFja2FnZSBydW5uZXIgcmVzdWx0IGRpZCBub3QgbWF0Y2ggYSBkZWNsYXJhdGlvbjogJHtwYWNrYWdlVGVzdFJlc3VsdC5mdWxsTmFtZX1gKVxuXG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnRlc3RSdW5uZXIudGVzdE1ldGFkYXRhKHRlc3QpXG4gICAgY29uc3QgY29tcGF0aWJpbGl0eSA9IHRoaXMudGVzdFJ1bm5lci50ZXN0RGF0YSh0ZXN0KVxuICAgIGNvbnN0IGR1cmF0aW9uTXMgPSBwYWNrYWdlVGVzdFJlc3VsdC5hdHRlbXB0cy5yZWR1Y2UoKHRvdGFsLCBhdHRlbXB0KSA9PiB0b3RhbCArIGF0dGVtcHQuZHVyYXRpb25NcywgMClcblxuICAgIGlmIChwYWNrYWdlVGVzdFJlc3VsdC5hdHRlbXB0cy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnRlc3RSdW5uZXIucmVjb3JkVGVzdER1cmF0aW9uKHtcbiAgICAgICAgZHVyYXRpb25NcyxcbiAgICAgICAgZmlsZVBhdGg6IGNvbXBhdGliaWxpdHkudGVzdERhdGEuZmlsZVBhdGggPz8gXCI8dW5rbm93bj5cIixcbiAgICAgICAgZnVsbERlc2NyaXB0aW9uOiBtZXRhZGF0YS5mdWxsRGVzY3JpcHRpb24sXG4gICAgICAgIGxpbmU6IGNvbXBhdGliaWxpdHkudGVzdERhdGEubGluZSA/PyAwXG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmIChwYWNrYWdlVGVzdFJlc3VsdC5zdGF0dXMgPT09IFwicGFzc2VkXCIpIHtcbiAgICAgIHRoaXMudGVzdFJ1bm5lci5yZWNvcmRTdWNjZXNzZnVsVGVzdCgpXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGZpbmFsQXR0ZW1wdCA9IHBhY2thZ2VUZXN0UmVzdWx0LmF0dGVtcHRzLmF0KC0xKVxuICAgICAgY29uc3Qgb3V0Y29tZSA9IGZpbmFsQXR0ZW1wdFxuICAgICAgICA/IHRoaXMudGVzdFJ1bm5lci5hdHRlbXB0T3V0Y29tZSh0ZXN0LCBmaW5hbEF0dGVtcHQuYXR0ZW1wdE51bWJlcilcbiAgICAgICAgOiB1bmRlZmluZWRcbiAgICAgIGNvbnN0IHNldHVwRmFpbHVyZSA9IHRoaXMudGVzdFJ1bm5lci5zZXR1cEZhaWx1cmVPdXRjb21lRm9yKHRlc3QpXG4gICAgICBjb25zdCBlcnJvciA9IG91dGNvbWU/LmZhaWxlZFxuICAgICAgICA/IG91dGNvbWUuZXJyb3JcbiAgICAgICAgOiBzZXR1cEZhaWx1cmUuZmFpbGVkXG4gICAgICAgICAgPyBzZXR1cEZhaWx1cmUuZXJyb3JcbiAgICAgICAgICA6IHBhY2thZ2VUZXN0UmVzdWx0LmVycm9yXG4gICAgICAgICAgICA/IGVycm9yRnJvbVBhY2thZ2VSZWNvcmQocGFja2FnZVRlc3RSZXN1bHQuZXJyb3IpXG4gICAgICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgICBhd2FpdCB0aGlzLnJlcG9ydEZhaWxlZFRlc3Qoe1xuICAgICAgICBhdHRlbXB0Q29uc29sZU91dHB1dHM6IHRoaXMuYXR0ZW1wdENvbnNvbGVPdXRwdXRzLmdldCh0ZXN0KSB8fCBbXSxcbiAgICAgICAgZGVzY3JpcHRpb25zOiBtZXRhZGF0YS5kZXNjcmlwdGlvbnMsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBsZWZ0UGFkZGluZzogXCIgXCIucmVwZWF0KG1ldGFkYXRhLmRlc2NyaXB0aW9ucy5sZW5ndGggKiAyKSxcbiAgICAgICAgdGVzdEFyZ3M6IGNvbXBhdGliaWxpdHkudGVzdEFyZ3MsXG4gICAgICAgIHRlc3REYXRhOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLFxuICAgICAgICB0ZXN0RGVzY3JpcHRpb246IG1ldGFkYXRhLnRlc3REZXNjcmlwdGlvblxuICAgICAgfSlcbiAgICB9XG5cbiAgICB0aGlzLnRlc3RSdW5uZXIuY29tcGxldGVUZXN0RGVjbGFyYXRpb24odGVzdClcbiAgICB0aGlzLmFjdGl2ZVRlc3QgPSB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmRzIGFuZCBlbWl0cyBvbmUgZmluYWwgZmFpbGVkIHRlc3QgcmVzdWx0LlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEZpbmFsIGZhaWx1cmUgbWV0YWRhdGEuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5BdHRlbXB0Q29uc29sZU91dHB1dFtdfSBhcmdzLmF0dGVtcHRDb25zb2xlT3V0cHV0cyAtIENhcHR1cmVkIG91dHB1dCBhY3Jvc3MgYXR0ZW1wdHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MuZGVzY3JpcHRpb25zIC0gUGFyZW50IGRlc2NyaXB0aW9uIHN0YWNrLlxuICAgKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBhcmdzLmVycm9yIC0gUmF3IGZpbmFsIGZhaWx1cmUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmxlZnRQYWRkaW5nIC0gQ29uc29sZSBpbmRlbnRhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3Rlc3QtcnVubmVyLmpzXCIpLlRlc3RBcmdzfSBhcmdzLnRlc3RBcmdzIC0gU3RhYmxlIHRlc3QgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuVGVzdERhdGF9IGFyZ3MudGVzdERhdGEgLSBUZXN0IHJlZ2lzdHJhdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MudGVzdERlc2NyaXB0aW9uIC0gVGVzdCBkZXNjcmlwdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgdGhlIGZpbmFsLWZhaWx1cmUgbGlzdGVuZXIgY29tcGxldGVzLlxuICAgKi9cbiAgYXN5bmMgcmVwb3J0RmFpbGVkVGVzdCh7YXR0ZW1wdENvbnNvbGVPdXRwdXRzLCBkZXNjcmlwdGlvbnMsIGVycm9yLCBsZWZ0UGFkZGluZywgdGVzdEFyZ3MsIHRlc3REYXRhLCB0ZXN0RGVzY3JpcHRpb259KSB7XG4gICAgY29uc3QgdGVzdFJ1bm5lciA9IHRoaXMudGVzdFJ1bm5lclxuICAgIGNvbnN0IGNvbnNvbGVPdXRwdXQgPSB0ZXN0UnVubmVyLmJ1aWxkQ29uc29sZU91dHB1dChhdHRlbXB0Q29uc29sZU91dHB1dHMpXG5cbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gIFRlc3QgZmFpbGVkOiAke2Vycm9yLm1lc3NhZ2V9YCkpXG4gICAgICB0aGlzLnByaW50RXJyb3JDYXVzZXMoZXJyb3IpXG5cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gIFRlc3QgZmFpbGVkIHdpdGggYSAke3R5cGVvZiBlcnJvcn06ICR7U3RyaW5nKGVycm9yKX1gKSlcbiAgICB9XG5cbiAgICB0ZXN0UnVubmVyLnByaW50RmFpbGVkQ29uc29sZU91dHB1dCh7Y29uc29sZU91dHB1dCwgbGVmdFBhZGRpbmd9KVxuICAgIHRlc3RSdW5uZXIucmVjb3JkRmFpbGVkVGVzdCh7ZGVzY3JpcHRpb25zLCBlcnJvciwgY29uc29sZU91dHB1dCwgdGVzdERhdGEsIHRlc3REZXNjcmlwdGlvbn0pXG5cbiAgICBhd2FpdCB0aGlzLmVtaXRFdmVudChcInRlc3RGYWlsZWRcIiwge1xuICAgICAgY29uZmlndXJhdGlvbjogdGVzdFJ1bm5lci5nZXRDb25maWd1cmF0aW9uKCksXG4gICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICBlcnJvcixcbiAgICAgIHRlc3RBcmdzLFxuICAgICAgdGVzdERhdGEsXG4gICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICB0ZXN0UnVubmVyXG4gICAgfSlcblxuICAgIHRlc3RSdW5uZXIucHJpbnRSZXJ1bkNvbW1hbmQoe2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uLCB0ZXN0RGF0YSwgbGVmdFBhZGRpbmd9KVxuICB9XG5cbiAgLyoqXG4gICAqIFByaW50cyBjb21wbGV0ZSBwcmltYXJ5IGFuZCBzZWNvbmRhcnkgc3RhY2tzIG9uY2UsIGluY2x1ZGluZyBjeWNsaWMgY2F1c2UgZ3JhcGhzLlxuICAgKiBAcGFyYW0ge3Vua25vd259IGVycm9yIC0gVGhyb3duIHZhbHVlIGF0IHRoZSByZXBvcnRpbmcgYm91bmRhcnkuXG4gICAqIEBwYXJhbSB7U2V0PEVycm9yPn0gW3JlcG9ydGVkXSAtIEVycm9yIGlkZW50aXRpZXMgYWxyZWFkeSBwcmludGVkLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHByaW50RXJyb3JDYXVzZXMoZXJyb3IsIHJlcG9ydGVkID0gbmV3IFNldCgpKSB7XG4gICAgaWYgKCEoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoU3RyaW5nKGVycm9yKSlcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBpZiAocmVwb3J0ZWQuaGFzKGVycm9yKSkgcmV0dXJuXG4gICAgcmVwb3J0ZWQuYWRkKGVycm9yKVxuICAgIGFkZFRyYWNrZWRTdGFja1RvRXJyb3IoZXJyb3IpXG4gICAgY29uc29sZS5lcnJvcihlcnJvci5zdGFjayB8fCBgJHtlcnJvci5uYW1lfTogJHtlcnJvci5tZXNzYWdlfWApXG4gICAgaWYgKGVycm9yLmNhdXNlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJDYXVzZWQgYnk6XCIpXG4gICAgICB0aGlzLnByaW50RXJyb3JDYXVzZXMoZXJyb3IuY2F1c2UsIHJlcG9ydGVkKVxuICAgIH1cbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBBZ2dyZWdhdGVFcnJvcikge1xuICAgICAgZm9yIChjb25zdCBzZWNvbmRhcnkgb2YgZXJyb3IuZXJyb3JzKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJSZWxhdGVkIGZhaWx1cmU6XCIpXG4gICAgICAgIHRoaXMucHJpbnRFcnJvckNhdXNlcyhzZWNvbmRhcnksIHJlcG9ydGVkKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyBvbmUgbGVnYWN5IGV2ZW50IGFuZCBhd2FpdHMgbGlzdGVuZXJzIGluIHJlZ2lzdHJhdGlvbiBvcmRlci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSAtIEV2ZW50IG5hbWUuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBwYXlsb2FkIC0gRXZlbnQgcGF5bG9hZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBhbGwgbGlzdGVuZXJzIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgZW1pdEV2ZW50KGV2ZW50TmFtZSwgcGF5bG9hZCkge1xuICAgIGZvciAoY29uc3QgbGlzdGVuZXIgb2YgdGVzdEV2ZW50cy5saXN0ZW5lcnMoZXZlbnROYW1lKSkgYXdhaXQgbGlzdGVuZXIocGF5bG9hZClcbiAgfVxufVxuIl19
|
|
@@ -142,6 +142,8 @@ import VelociousTestArguments from "./velocious-test-arguments.js"
|
|
|
142
142
|
* @property {import("../database/pool/base.js").TestSharedConnectionRegistration | undefined} sharedRegistration - Physical-key shared registration once published.
|
|
143
143
|
*/
|
|
144
144
|
|
|
145
|
+
const testingPackageDirectory = path.dirname(fileURLToPath(import.meta.resolve("@velocious/testing/package.json")))
|
|
146
|
+
|
|
145
147
|
/**
|
|
146
148
|
* Runs to file slug.
|
|
147
149
|
* @param {string} value - Value to sanitize.
|
|
@@ -197,6 +199,8 @@ export default class TestRunner {
|
|
|
197
199
|
this._successfulTests = 0
|
|
198
200
|
this._testsCount = 0
|
|
199
201
|
this._failedTestDetails = []
|
|
202
|
+
/** @type {import("@velocious/testing/runner").NonRunTestResult[]} */
|
|
203
|
+
this._notRunTestDetails = []
|
|
200
204
|
/** @type {{fullDescription: string, filePath: string, line: number} | null} */
|
|
201
205
|
this._lastTestContext = null
|
|
202
206
|
/** @type {Array<{fullDescription: string, filePath: string, line: number, durationMs: number}>} */
|
|
@@ -1007,6 +1011,25 @@ export default class TestRunner {
|
|
|
1007
1011
|
return this._failedTests
|
|
1008
1012
|
}
|
|
1009
1013
|
|
|
1014
|
+
/**
|
|
1015
|
+
* Counts selected tests blocked by a terminal resource.
|
|
1016
|
+
* @returns {number} - Selected tests not executed because a shared resource failed.
|
|
1017
|
+
*/
|
|
1018
|
+
getNotRunTests() { return this._notRunTestDetails.length }
|
|
1019
|
+
|
|
1020
|
+
/**
|
|
1021
|
+
* Returns runtime non-run attribution.
|
|
1022
|
+
* @returns {import("@velocious/testing/runner").NonRunTestResult[]} - Runtime non-run details with the originating failure.
|
|
1023
|
+
*/
|
|
1024
|
+
getNotRunTestDetails() { return this._notRunTestDetails }
|
|
1025
|
+
|
|
1026
|
+
/**
|
|
1027
|
+
* Records a selected test that did not execute.
|
|
1028
|
+
* @param {import("@velocious/testing/runner").NonRunTestResult} result - Terminal-resource non-run record.
|
|
1029
|
+
* @returns {void}
|
|
1030
|
+
*/
|
|
1031
|
+
recordNotRunTest(result) { this._notRunTestDetails.push(result) }
|
|
1032
|
+
|
|
1010
1033
|
/**
|
|
1011
1034
|
* Runs get failed test details.
|
|
1012
1035
|
* @returns {FailedTestDetail[]} - Failed test details.
|
|
@@ -1087,6 +1110,14 @@ export default class TestRunner {
|
|
|
1087
1110
|
return this._packageResult?.tests.length ?? this._testDurations.length
|
|
1088
1111
|
}
|
|
1089
1112
|
|
|
1113
|
+
/**
|
|
1114
|
+
* Distinguishes an empty selection from a failure before selected cases execute.
|
|
1115
|
+
* @returns {boolean} - Whether selection matched no declarations.
|
|
1116
|
+
*/
|
|
1117
|
+
hasNoMatches() {
|
|
1118
|
+
return this._packageResult?.noMatches === true
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1090
1121
|
/**
|
|
1091
1122
|
* Returns the tests recorded during the run, slowest first.
|
|
1092
1123
|
* @param {number} [limit] - Maximum number of tests to return (0 returns all).
|
|
@@ -1105,6 +1136,7 @@ export default class TestRunner {
|
|
|
1105
1136
|
async prepare() {
|
|
1106
1137
|
this.anyTestsFocussed = false
|
|
1107
1138
|
this._failedTests = 0
|
|
1139
|
+
this._notRunTestDetails = []
|
|
1108
1140
|
this._successfulTests = 0
|
|
1109
1141
|
this._testsCount = 0
|
|
1110
1142
|
this._abortRemainingTests = false
|
|
@@ -1177,7 +1209,7 @@ export default class TestRunner {
|
|
|
1177
1209
|
|
|
1178
1210
|
if (portablePath.endsWith("/src/testing/test-runner.js")) continue
|
|
1179
1211
|
if (portablePath.endsWith("/src/testing/test.js")) continue
|
|
1180
|
-
if (
|
|
1212
|
+
if (resolvedFilePath.startsWith(`${testingPackageDirectory}${path.sep}`)) continue
|
|
1181
1213
|
|
|
1182
1214
|
return {filePath: resolvedFilePath, line: Number(match[2])}
|
|
1183
1215
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
import { addTrackedStackToError } from "../utils/with-tracked-stack.js"
|
|
4
|
-
import BacktraceCleaner from "../utils/backtrace-cleaner-node.js"
|
|
5
4
|
import picocolors from "picocolors"
|
|
6
5
|
import restArgsError from "../utils/rest-args-error.js"
|
|
7
6
|
import { testEvents } from "./test.js"
|
|
@@ -21,6 +20,8 @@ function errorFromPackageRecord(errorRecord) {
|
|
|
21
20
|
|
|
22
21
|
error.name = errorRecord.name
|
|
23
22
|
if (errorRecord.stack) error.stack = errorRecord.stack
|
|
23
|
+
if (errorRecord.cause) error.cause = errorFromPackageRecord(errorRecord.cause)
|
|
24
|
+
if (errorRecord.terminalResource) Object.assign(error, {terminalResource: errorRecord.terminalResource})
|
|
24
25
|
|
|
25
26
|
return error
|
|
26
27
|
}
|
|
@@ -68,7 +69,27 @@ export default class VelociousRunnerReporter {
|
|
|
68
69
|
return
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
if (event.type === "run
|
|
72
|
+
if (event.type === "test:not-run") {
|
|
73
|
+
const test = this.testRunner.findTestDeclaration(event.test.fullName)
|
|
74
|
+
if (!test) throw new Error(`Package not-run result did not match a declaration: ${event.test.fullName}`)
|
|
75
|
+
this.testRunner.recordNotRunTest(event.test)
|
|
76
|
+
this.testRunner.completeTestDeclaration(test)
|
|
77
|
+
console.error(`Not run: ${event.test.fullName} (terminal resource failure in ${event.test.reason.fullName})`)
|
|
78
|
+
await this.emitEvent("testNotRun", {
|
|
79
|
+
configuration: this.testRunner.getConfiguration(),
|
|
80
|
+
test: event.test,
|
|
81
|
+
testRunner: this.testRunner
|
|
82
|
+
})
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (event.type === "run:finish") {
|
|
87
|
+
this.testRunner.recordPackageResult(event.result)
|
|
88
|
+
for (const failure of event.result.errors) {
|
|
89
|
+
console.error(`Suite ${failure.phase} failed: ${failure.suite}`)
|
|
90
|
+
this.printErrorCauses(errorFromPackageRecord(failure.error))
|
|
91
|
+
}
|
|
92
|
+
}
|
|
72
93
|
}
|
|
73
94
|
|
|
74
95
|
/**
|
|
@@ -95,7 +116,7 @@ export default class VelociousRunnerReporter {
|
|
|
95
116
|
const failed = outcome?.failed ?? Boolean(attempt.error)
|
|
96
117
|
const error = outcome?.error
|
|
97
118
|
const retriesUsed = Math.min(attempt.attemptNumber, retryCount)
|
|
98
|
-
const willRetry = failed && !outcome?.abortRemainingTests && attempt.attemptNumber <= retryCount
|
|
119
|
+
const willRetry = failed && !event.terminalFailure && !outcome?.abortRemainingTests && attempt.attemptNumber <= retryCount
|
|
99
120
|
const {descriptions, testDescription} = this.testRunner.testMetadata(test)
|
|
100
121
|
const compatibility = this.testRunner.testData(test)
|
|
101
122
|
|
|
@@ -245,15 +266,8 @@ export default class VelociousRunnerReporter {
|
|
|
245
266
|
|
|
246
267
|
if (error instanceof Error) {
|
|
247
268
|
console.error(picocolors.red(`${leftPadding} Test failed: ${error.message}`))
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
const backtraceCleaner = new BacktraceCleaner(error)
|
|
251
|
-
const cleanedStack = backtraceCleaner.getCleanedStack()
|
|
252
|
-
const stackLines = cleanedStack?.split("\n")
|
|
269
|
+
this.printErrorCauses(error)
|
|
253
270
|
|
|
254
|
-
if (stackLines) {
|
|
255
|
-
for (const stackLine of stackLines) console.error(picocolors.red(`${leftPadding} ${stackLine}`))
|
|
256
|
-
}
|
|
257
271
|
} else {
|
|
258
272
|
console.error(picocolors.red(`${leftPadding} Test failed with a ${typeof error}: ${String(error)}`))
|
|
259
273
|
}
|
|
@@ -274,6 +288,33 @@ export default class VelociousRunnerReporter {
|
|
|
274
288
|
testRunner.printRerunCommand({descriptions, testDescription, testData, leftPadding})
|
|
275
289
|
}
|
|
276
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Prints complete primary and secondary stacks once, including cyclic cause graphs.
|
|
293
|
+
* @param {unknown} error - Thrown value at the reporting boundary.
|
|
294
|
+
* @param {Set<Error>} [reported] - Error identities already printed.
|
|
295
|
+
* @returns {void}
|
|
296
|
+
*/
|
|
297
|
+
printErrorCauses(error, reported = new Set()) {
|
|
298
|
+
if (!(error instanceof Error)) {
|
|
299
|
+
console.error(String(error))
|
|
300
|
+
return
|
|
301
|
+
}
|
|
302
|
+
if (reported.has(error)) return
|
|
303
|
+
reported.add(error)
|
|
304
|
+
addTrackedStackToError(error)
|
|
305
|
+
console.error(error.stack || `${error.name}: ${error.message}`)
|
|
306
|
+
if (error.cause !== undefined) {
|
|
307
|
+
console.error("Caused by:")
|
|
308
|
+
this.printErrorCauses(error.cause, reported)
|
|
309
|
+
}
|
|
310
|
+
if (error instanceof AggregateError) {
|
|
311
|
+
for (const secondary of error.errors) {
|
|
312
|
+
console.error("Related failure:")
|
|
313
|
+
this.printErrorCauses(secondary, reported)
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
277
318
|
/**
|
|
278
319
|
* Emits one legacy event and awaits listeners in registration order.
|
|
279
320
|
* @param {string} eventName - Event name.
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"velocious": "build/bin/velocious.js"
|
|
4
4
|
},
|
|
5
5
|
"name": "velocious",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.654",
|
|
7
7
|
"main": "build/index.js",
|
|
8
8
|
"types": "build/index.d.ts",
|
|
9
9
|
"files": [
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"ws": "^8.21.3"
|
|
92
92
|
},
|
|
93
93
|
"peerDependencies": {
|
|
94
|
-
"@velocious/testing": "0.0.
|
|
94
|
+
"@velocious/testing": "^0.0.12",
|
|
95
95
|
"react": ">=18",
|
|
96
96
|
"smtp-connection": "^4.0.2",
|
|
97
97
|
"sqlite": "^5.1.1",
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
"@types/react-dom": "^19.2.3",
|
|
122
122
|
"@types/strftime": "^0.9.8",
|
|
123
123
|
"@types/ws": "^8.18.1",
|
|
124
|
-
"@velocious/testing": "0.0.
|
|
124
|
+
"@velocious/testing": "0.0.12",
|
|
125
125
|
"chokidar-cli": "^3.0.0",
|
|
126
126
|
"cpy-cli": "^7.0.0",
|
|
127
127
|
"esbuild": "^0.28.0",
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
"selenium-webdriver": "^4.39.0",
|
|
143
143
|
"sqlite": "^5.1.1",
|
|
144
144
|
"sqlite3": "^6.0.1",
|
|
145
|
-
"system-testing": "^1.0.
|
|
145
|
+
"system-testing": "^1.0.137",
|
|
146
146
|
"tedious": "^20.0.0",
|
|
147
147
|
"typescript": "^7.0.2",
|
|
148
148
|
"uniqunize": "^1.0.3"
|
|
@@ -7,6 +7,7 @@ import { createRequire } from "node:module"
|
|
|
7
7
|
import path from "node:path"
|
|
8
8
|
import { promisify } from "node:util"
|
|
9
9
|
import timeout from "awaitery/build/timeout.js"
|
|
10
|
+
import { resolveChromeRuntime } from "system-testing/build/chrome-runtime-manager.js"
|
|
10
11
|
import SystemTest from "system-testing/build/system-test.js"
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -33,13 +34,12 @@ import SystemTest from "system-testing/build/system-test.js"
|
|
|
33
34
|
/**
|
|
34
35
|
* @typedef {object} BrowserTestSystemTestConfig
|
|
35
36
|
* @property {boolean} debug - Whether SystemTest should emit debug output.
|
|
36
|
-
* @property {{type: "selenium", options: {chromeArguments: string[], chromeBinaryPath: string}}} driver - Selenium driver config.
|
|
37
|
+
* @property {{type: "selenium", options: {chromeArguments: string[], chromeBinaryPath: string, chromedriverPath: string}}} driver - Selenium driver config.
|
|
37
38
|
* @property {string} httpHost - HTTP host for the browser-test app.
|
|
38
39
|
* @property {number} httpPort - HTTP port for the browser-test app.
|
|
39
40
|
*/
|
|
40
41
|
|
|
41
42
|
const require = createRequire(import.meta.url)
|
|
42
|
-
const { binaryPaths } = require("selenium-webdriver/common/seleniumManager.js")
|
|
43
43
|
const { CancellationError, waitForServer } = require("selenium-webdriver/http/util.js")
|
|
44
44
|
const { findFreePort } = require("selenium-webdriver/net/portprober.js")
|
|
45
45
|
const execFileAsync = promisify(execFile)
|
|
@@ -97,30 +97,24 @@ async function assertExecutable(executablePath, description) {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
|
-
* Resolves, validates, and persists the exact Chrome
|
|
100
|
+
* Resolves, validates, and persists the exact Chrome-for-Testing runtime pair.
|
|
101
101
|
* @param {object} [args] - Prewarm options.
|
|
102
|
-
* @param {() => {browserPath?: string, driverPath?: string}} [args.binaryPathsResolver] - Selenium path resolver.
|
|
103
102
|
* @param {string} [args.manifestPath] - Runtime manifest path.
|
|
103
|
+
* @param {() => Promise<{chromeBinaryPath: string, chromedriverPath: string} | undefined>} [args.runtimeResolver] - System-testing runtime resolver.
|
|
104
104
|
* @param {(executablePath: string) => Promise<string>} [args.versionReader] - Executable version reader.
|
|
105
105
|
* @returns {Promise<BrowserTestChromeRuntime>} - Prewarmed runtime.
|
|
106
106
|
*/
|
|
107
107
|
export async function prewarmBrowserTestChromeRuntime({
|
|
108
|
-
binaryPathsResolver = () => binaryPaths([
|
|
109
|
-
"--browser",
|
|
110
|
-
"chrome",
|
|
111
|
-
"--language-binding",
|
|
112
|
-
"javascript",
|
|
113
|
-
"--output",
|
|
114
|
-
"json",
|
|
115
|
-
"--avoid-browser-download"
|
|
116
|
-
]),
|
|
117
108
|
manifestPath = defaultManifestPath(),
|
|
109
|
+
runtimeResolver = resolveChromeRuntime,
|
|
118
110
|
versionReader = readExecutableVersion
|
|
119
111
|
} = {}) {
|
|
120
|
-
const
|
|
112
|
+
const chromeRuntime = await runtimeResolver()
|
|
113
|
+
const browserPath = chromeRuntime?.chromeBinaryPath
|
|
114
|
+
const driverPath = chromeRuntime?.chromedriverPath
|
|
121
115
|
|
|
122
|
-
if (!browserPath) throw new Error("
|
|
123
|
-
if (!driverPath) throw new Error("
|
|
116
|
+
if (!browserPath) throw new Error("System-testing did not resolve a Chrome executable")
|
|
117
|
+
if (!driverPath) throw new Error("System-testing did not resolve a ChromeDriver executable")
|
|
124
118
|
|
|
125
119
|
await assertExecutable(browserPath, "Chrome")
|
|
126
120
|
await assertExecutable(driverPath, "ChromeDriver")
|
|
@@ -143,7 +137,7 @@ export async function prewarmBrowserTestChromeRuntime({
|
|
|
143
137
|
const browserVersion = parseExecutableVersion(browserVersionOutput, "Chrome")
|
|
144
138
|
const driverVersion = parseExecutableVersion(driverVersionOutput, "ChromeDriver")
|
|
145
139
|
|
|
146
|
-
if (browserVersion
|
|
140
|
+
if (browserVersion !== driverVersion) {
|
|
147
141
|
throw new Error(`Chrome ${browserVersion} is incompatible with ChromeDriver ${driverVersion}`)
|
|
148
142
|
}
|
|
149
143
|
|
|
@@ -218,14 +212,14 @@ function browserTestChromeArguments() {
|
|
|
218
212
|
|
|
219
213
|
/**
|
|
220
214
|
* Builds the SystemTest factory used by BrowserTestSession so the Selenium builder path
|
|
221
|
-
* receives the pinned Chrome
|
|
215
|
+
* receives the pinned Chrome runtime and the required headless container Chrome arguments.
|
|
222
216
|
* @param {object} [args] - Factory options.
|
|
223
217
|
* @param {string[]} [args.chromeArguments] - Chrome launch arguments.
|
|
224
218
|
* @param {boolean} [args.debug] - Whether SystemTest should emit debug output.
|
|
225
219
|
* @param {string} [args.httpHost] - HTTP host for the browser-test app.
|
|
226
220
|
* @param {number} [args.httpPort] - HTTP port for the browser-test app.
|
|
227
221
|
* @param {(config: BrowserTestSystemTestConfig) => BrowserTestSystemTest} [args.systemTestCurrent] - SystemTest factory.
|
|
228
|
-
* @returns {(args: {browserPath: string, remoteUrl: string}) => BrowserTestSystemTest} - SystemTest factory.
|
|
222
|
+
* @returns {(args: {browserPath: string, driverPath: string, remoteUrl: string}) => BrowserTestSystemTest} - SystemTest factory.
|
|
229
223
|
*/
|
|
230
224
|
export function buildBrowserTestSystemTestFactory({
|
|
231
225
|
chromeArguments = browserTestChromeArguments(),
|
|
@@ -234,11 +228,11 @@ export function buildBrowserTestSystemTestFactory({
|
|
|
234
228
|
httpPort = 1984,
|
|
235
229
|
systemTestCurrent = SystemTest.current
|
|
236
230
|
} = {}) {
|
|
237
|
-
return ({browserPath}) => systemTestCurrent({
|
|
231
|
+
return ({browserPath, driverPath}) => systemTestCurrent({
|
|
238
232
|
debug,
|
|
239
233
|
driver: {
|
|
240
234
|
type: "selenium",
|
|
241
|
-
options: {chromeArguments, chromeBinaryPath: browserPath}
|
|
235
|
+
options: {chromeArguments, chromeBinaryPath: browserPath, chromedriverPath: driverPath}
|
|
242
236
|
},
|
|
243
237
|
httpHost,
|
|
244
238
|
httpPort
|
|
@@ -428,7 +422,7 @@ export class BrowserTestSession {
|
|
|
428
422
|
* @param {(runtime: BrowserTestChromeRuntime) => Promise<BrowserTestChromeDriverService>} [args.chromeDriverServiceFactory] - Driver service factory.
|
|
429
423
|
* @param {(phase: string) => Promise<string>} [args.processSnapshot] - Process snapshot callback.
|
|
430
424
|
* @param {BrowserTestChromeRuntime} args.runtime - Chrome runtime.
|
|
431
|
-
* @param {(args: {browserPath: string, remoteUrl: string}) => BrowserTestSystemTest} args.systemTestFactory - SystemTest factory.
|
|
425
|
+
* @param {(args: {browserPath: string, driverPath: string, remoteUrl: string}) => BrowserTestSystemTest} args.systemTestFactory - SystemTest factory.
|
|
432
426
|
*/
|
|
433
427
|
constructor({
|
|
434
428
|
chromeDriverServiceFactory = async (runtime) => new ManagedChromeDriverProcess(runtime),
|
|
@@ -463,7 +457,11 @@ export class BrowserTestSession {
|
|
|
463
457
|
this.startupPhase = "starting ChromeDriver service"
|
|
464
458
|
this.remoteUrl = await this.chromeDriverService.start()
|
|
465
459
|
process.env.SELENIUM_REMOTE_URL = this.remoteUrl
|
|
466
|
-
this.systemTest = this.systemTestFactory({
|
|
460
|
+
this.systemTest = this.systemTestFactory({
|
|
461
|
+
browserPath: this.runtime.browserPath,
|
|
462
|
+
driverPath: this.runtime.driverPath,
|
|
463
|
+
remoteUrl: this.remoteUrl
|
|
464
|
+
})
|
|
467
465
|
this.startupPhase = "creating Selenium WebDriver session"
|
|
468
466
|
await this.systemTest.start()
|
|
469
467
|
|
|
@@ -1468,7 +1468,9 @@ function splitWhereHash({hash, modelClass}) {
|
|
|
1468
1468
|
const isNested = isPlainObject(value)
|
|
1469
1469
|
const relationship = getRelationshipByName(modelClass, key)
|
|
1470
1470
|
|
|
1471
|
-
if (isNested) {
|
|
1471
|
+
if (isNested && !relationship && resolveColumnName(modelClass, key)) {
|
|
1472
|
+
resolvedHash[key] = value
|
|
1473
|
+
} else if (isNested) {
|
|
1472
1474
|
if (relationship) {
|
|
1473
1475
|
const rawTargetModelClass = relationship.getTargetModelClass()
|
|
1474
1476
|
if (!rawTargetModelClass) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
import WhereBase from "./where-base.js"
|
|
4
|
+
import WhereIn from "./where-in.js"
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* VelociousDatabaseQueryWhereHash class.
|
|
@@ -50,7 +51,17 @@ export default class VelociousDatabaseQueryWhereHash extends WhereBase {
|
|
|
50
51
|
if (index > 0) sql += " AND "
|
|
51
52
|
sql += "1=0"
|
|
52
53
|
} else if (!Array.isArray(whereValue) && whereValue !== null && typeof whereValue == "object") {
|
|
53
|
-
|
|
54
|
+
if (tableName && "in" in whereValue) {
|
|
55
|
+
if (index > 0) sql += " AND "
|
|
56
|
+
|
|
57
|
+
sql += WhereIn.toSql({
|
|
58
|
+
columnSql: `${options.quoteTableName(tableName)}.${options.quoteColumnName(whereKey)}`,
|
|
59
|
+
options,
|
|
60
|
+
values: WhereIn.values(whereValue)
|
|
61
|
+
})
|
|
62
|
+
} else {
|
|
63
|
+
sql += this._whereSQLFromHash(whereValue, whereKey, index)
|
|
64
|
+
}
|
|
54
65
|
} else {
|
|
55
66
|
if (index > 0) sql += " AND "
|
|
56
67
|
|