velocious 1.0.648 → 1.0.650
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 +12 -0
- package/build/cli/commands/db/base-command.js +6 -4
- package/build/cli/commands/db/create.js +1 -1
- package/build/database/drivers/base.js +1 -0
- package/build/database/drivers/mssql/index.js +12 -4
- package/build/database/query/model-class-query.js +8 -1
- package/build/database/query/query-data.js +3 -4
- package/build/database/query/select-base.js +9 -0
- package/build/database/query/select-plain.js +24 -0
- package/build/database/query/where-model-class-hash.js +1 -1
- package/build/database/record/index.js +16 -5
- package/build/src/cli/commands/db/base-command.d.ts +4 -2
- package/build/src/cli/commands/db/base-command.d.ts.map +1 -1
- package/build/src/cli/commands/db/base-command.js +7 -5
- package/build/src/cli/commands/db/create.js +2 -2
- package/build/src/database/drivers/base.d.ts +4 -0
- package/build/src/database/drivers/base.d.ts.map +1 -1
- package/build/src/database/drivers/base.js +2 -1
- package/build/src/database/drivers/mssql/index.d.ts +2 -1
- package/build/src/database/drivers/mssql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/index.js +13 -5
- package/build/src/database/query/model-class-query.d.ts.map +1 -1
- package/build/src/database/query/model-class-query.js +8 -2
- package/build/src/database/query/query-data.js +4 -5
- package/build/src/database/query/select-base.d.ts +8 -0
- package/build/src/database/query/select-base.d.ts.map +1 -1
- package/build/src/database/query/select-base.js +9 -1
- package/build/src/database/query/select-plain.d.ts +10 -0
- package/build/src/database/query/select-plain.d.ts.map +1 -1
- package/build/src/database/query/select-plain.js +21 -1
- package/build/src/database/query/where-model-class-hash.js +2 -2
- package/build/src/database/record/index.d.ts +14 -4
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +17 -6
- package/build/src/testing/shared-transaction-proxy-driver.d.ts.map +1 -1
- package/build/src/testing/shared-transaction-proxy-driver.js +7 -1
- package/build/src/testing/test-runner.d.ts +8 -3
- package/build/src/testing/test-runner.d.ts.map +1 -1
- package/build/src/testing/test-runner.js +6 -5
- package/build/src/testing/velocious-runner-reporter.d.ts +1 -1
- package/build/src/testing/velocious-runner-reporter.d.ts.map +1 -1
- package/build/src/testing/velocious-runner-reporter.js +22 -2
- package/build/src/testing/velocious-suite-hook-executor.d.ts.map +1 -1
- package/build/src/testing/velocious-suite-hook-executor.js +5 -2
- package/build/testing/shared-transaction-proxy-driver.js +6 -0
- package/build/testing/test-runner.js +6 -4
- package/build/testing/velocious-runner-reporter.js +23 -1
- package/build/testing/velocious-suite-hook-executor.js +4 -1
- package/package.json +1 -1
- package/src/cli/commands/db/base-command.js +6 -4
- package/src/cli/commands/db/create.js +1 -1
- package/src/database/drivers/base.js +1 -0
- package/src/database/drivers/mssql/index.js +12 -4
- package/src/database/query/model-class-query.js +8 -1
- package/src/database/query/query-data.js +3 -4
- package/src/database/query/select-base.js +9 -0
- package/src/database/query/select-plain.js +24 -0
- package/src/database/query/where-model-class-hash.js +1 -1
- package/src/database/record/index.js +16 -5
- package/src/testing/shared-transaction-proxy-driver.js +6 -0
- package/src/testing/test-runner.js +6 -4
- package/src/testing/velocious-runner-reporter.js +23 -1
- package/src/testing/velocious-suite-hook-executor.js +4 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type PackageTestDeclaration = import("@velocious/testing/runner").TestDeclaration;
|
|
2
|
-
|
|
2
|
+
export type PackageTestErrorRecord = import("@velocious/testing/runner").TestErrorRecord;
|
|
3
3
|
/** Stops package traversal after framework-owned connection quarantine. */
|
|
4
4
|
export declare class AbortRemainingTestsError extends Error {
|
|
5
5
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"velocious-runner-reporter.d.ts","sourceRoot":"","sources":["../../../src/testing/velocious-runner-reporter.js"],"names":[],"mappings":"AAQI,YAA+D,sBAAsB,GAA3E,OAAO,2BAA2B,EAAE,eAAe,CAAwB;
|
|
1
|
+
{"version":3,"file":"velocious-runner-reporter.d.ts","sourceRoot":"","sources":["../../../src/testing/velocious-runner-reporter.js"],"names":[],"mappings":"AAQI,YAA+D,sBAAsB,GAA3E,OAAO,2BAA2B,EAAE,eAAe,CAAwB;AACrF,YAA+D,sBAAsB,GAA3E,OAAO,2BAA2B,EAAE,eAAe,CAAwB;AAkBzF,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,CAuBzB;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,CAmCzB;IAED;;;;;OAKG;IACG,SAAS,CAAC,SAAS,EAJd,MAIc,EAAE,OAAO,EAHvB,MAGuB,GAFrB,OAAO,CAAC,IAAI,CAAC,CAIzB;CACF"}
|
|
@@ -5,6 +5,21 @@ import picocolors from "picocolors";
|
|
|
5
5
|
import restArgsError from "../utils/rest-args-error.js";
|
|
6
6
|
import { testEvents } from "./test.js";
|
|
7
7
|
/** @typedef {import("@velocious/testing/runner").TestDeclaration} PackageTestDeclaration */
|
|
8
|
+
/** @typedef {import("@velocious/testing/runner").TestErrorRecord} PackageTestErrorRecord */
|
|
9
|
+
/**
|
|
10
|
+
* Restores the Error shape serialized by the package runner.
|
|
11
|
+
* @param {PackageTestErrorRecord} errorRecord - Serialized package failure.
|
|
12
|
+
* @returns {Error} - Error compatible with Velocious's legacy reporter contract.
|
|
13
|
+
*/
|
|
14
|
+
function errorFromPackageRecord(errorRecord) {
|
|
15
|
+
const error = errorRecord.errors
|
|
16
|
+
? new AggregateError(errorRecord.errors.map(errorFromPackageRecord), errorRecord.message)
|
|
17
|
+
: new Error(errorRecord.message);
|
|
18
|
+
error.name = errorRecord.name;
|
|
19
|
+
if (errorRecord.stack)
|
|
20
|
+
error.stack = errorRecord.stack;
|
|
21
|
+
return error;
|
|
22
|
+
}
|
|
8
23
|
/** Stops package traversal after framework-owned connection quarantine. */
|
|
9
24
|
export class AbortRemainingTestsError extends Error {
|
|
10
25
|
}
|
|
@@ -168,9 +183,14 @@ export default class VelociousRunnerReporter {
|
|
|
168
183
|
const outcome = finalAttempt
|
|
169
184
|
? this.testRunner.attemptOutcome(test, finalAttempt.attemptNumber)
|
|
170
185
|
: undefined;
|
|
186
|
+
const setupFailure = this.testRunner.setupFailureOutcomeFor(test);
|
|
171
187
|
const error = outcome?.failed
|
|
172
188
|
? outcome.error
|
|
173
|
-
:
|
|
189
|
+
: setupFailure.failed
|
|
190
|
+
? setupFailure.error
|
|
191
|
+
: packageTestResult.error
|
|
192
|
+
? errorFromPackageRecord(packageTestResult.error)
|
|
193
|
+
: undefined;
|
|
174
194
|
await this.reportFailedTest({
|
|
175
195
|
attemptConsoleOutputs: this.attemptConsoleOutputs.get(test) || [],
|
|
176
196
|
descriptions: metadata.descriptions,
|
|
@@ -237,4 +257,4 @@ export default class VelociousRunnerReporter {
|
|
|
237
257
|
await listener(payload);
|
|
238
258
|
}
|
|
239
259
|
}
|
|
240
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVsb2Npb3VzLXJ1bm5lci1yZXBvcnRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0aW5nL3ZlbG9jaW91cy1ydW5uZXItcmVwb3J0ZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFBO0FBQ3ZFLE9BQU8sZ0JBQWdCLE1BQU0sb0NBQW9DLENBQUE7QUFDakUsT0FBTyxVQUFVLE1BQU0sWUFBWSxDQUFBO0FBQ25DLE9BQU8sYUFBYSxNQUFNLDZCQUE2QixDQUFBO0FBQ3ZELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFFdEMsNEZBQTRGO0FBRTVGLDJFQUEyRTtBQUMzRSxNQUFNLE9BQU8sd0JBQXlCLFNBQVEsS0FBSztDQUFHO0FBRXRELE1BQU0sQ0FBQyxPQUFPLE9BQU8sdUJBQXVCO0lBQzFDOzs7O09BSUc7SUFDSCxZQUFZLEVBQUMsVUFBVSxFQUFFLEdBQUcsUUFBUSxFQUFDO1FBQ25DLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUN2QixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQTtRQUM1QixpR0FBaUc7UUFDakcsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7UUFDMUMsaURBQWlEO1FBQ2pELElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFBO0lBQzdCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLO1FBQ2pCLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxZQUFZLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1lBQ3JFLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUNw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QUF3QixPQUFPLEtBQUssS0FBSyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUE7UUFDdkcsQ0FBQztRQUVELFVBQVUsQ0FBQyx3QkFBd0IsQ0FBQyxFQUFDLGFBQWEsRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFBO1FBQ2pFLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFDLFlBQVksRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxlQUFlLEVBQUMsQ0FBQyxDQUFBO1FBRTVGLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUU7WUFDakMsYUFBYSxFQUFFLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRTtZQUM1QyxZQUFZO1lBQ1osS0FBSztZQUNMLFFBQVE7WUFDUixRQUFRO1lBQ1IsZUFBZTtZQUNmLFVBQVU7U0FDWCxDQUFDLENBQUE7UUFFRixVQUFVLENBQUMsaUJBQWlCLENBQUMsRUFBQyxZQUFZLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFBO0lBQ3RGLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLE9BQU87UUFDaEMsS0FBSyxNQUFNLFFBQVEsSUFBSSxVQUFVLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQztZQUFFLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ2pGLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgeyBhZGRUcmFja2VkU3RhY2tUb0Vycm9yIH0gZnJvbSBcIi4uL3V0aWxzL3dpdGgtdHJhY2tlZC1zdGFjay5qc1wiXG5pbXBvcnQgQmFja3RyYWNlQ2xlYW5lciBmcm9tIFwiLi4vdXRpbHMvYmFja3RyYWNlLWNsZWFuZXItbm9kZS5qc1wiXG5pbXBvcnQgcGljb2NvbG9ycyBmcm9tIFwicGljb2NvbG9yc1wiXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcbmltcG9ydCB7IHRlc3RFdmVudHMgfSBmcm9tIFwiLi90ZXN0LmpzXCJcblxuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCJAdmVsb2Npb3VzL3Rlc3RpbmcvcnVubmVyXCIpLlRlc3REZWNsYXJhdGlvbn0gUGFja2FnZVRlc3REZWNsYXJhdGlvbiAqL1xuXG4vKiogU3RvcHMgcGFja2FnZSB0cmF2ZXJzYWwgYWZ0ZXIgZnJhbWV3b3JrLW93bmVkIGNvbm5lY3Rpb24gcXVhcmFudGluZS4gKi9cbmV4cG9ydCBjbGFzcyBBYm9ydFJlbWFpbmluZ1Rlc3RzRXJyb3IgZXh0ZW5kcyBFcnJvciB7fVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNSdW5uZXJSZXBvcnRlciB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSBsZWdhY3kgZXZlbnQgYW5kIHJlc3VsdCBwcm9qZWN0aW9uIGFkYXB0ZXIuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQ29uc3RydWN0b3IgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuZGVmYXVsdH0gYXJncy50ZXN0UnVubmVyIC0gT3duaW5nIFZlbG9jaW91cyBydW5uZXIuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7dGVzdFJ1bm5lciwgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcbiAgICB0aGlzLnRlc3RSdW5uZXIgPSB0ZXN0UnVubmVyXG4gICAgLyoqIEB0eXBlIHtXZWFrTWFwPFBhY2thZ2VUZXN0RGVjbGFyYXRpb24sIGltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQXR0ZW1wdENvbnNvbGVPdXRwdXRbXT59ICovXG4gICAgdGhpcy5hdHRlbXB0Q29uc29sZU91dHB1dHMgPSBuZXcgV2Vha01hcCgpXG4gICAgLyoqIEB0eXBlIHtQYWNrYWdlVGVzdERlY2xhcmF0aW9uIHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuYWN0aXZlVGVzdCA9IHVuZGVmaW5lZFxuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zbGF0ZXMgb25lIGF3YWl0ZWQgcGFja2FnZSBydW5uZXIgZXZlbnQgaW50byB0aGUgbGVnYWN5IGNvbnRyYWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIkB2ZWxvY2lvdXMvdGVzdGluZy9ydW5uZXJcIikuUnVubmVyRXZlbnR9IGV2ZW50IC0gU3RydWN0dXJlZCBwYWNrYWdlIGV2ZW50LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBsZWdhY3kgbGlzdGVuZXJzIGZpbmlzaC5cbiAgICovXG4gIGFzeW5jIG9uRXZlbnQoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJ0ZXN0OnN0YXJ0XCIpIHtcbiAgICAgIHRoaXMuYWN0aXZlVGVzdCA9IHRoaXMudGVzdFJ1bm5lci5maW5kVGVzdERlY2xhcmF0aW9uKGV2ZW50LmZ1bGxOYW1lKVxuICAgICAgaWYgKHRoaXMuYWN0aXZlVGVzdCkge1xuICAgICAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMudGVzdFJ1bm5lci50ZXN0TWV0YWRhdGEodGhpcy5hY3RpdmVUZXN0KVxuICAgICAgICBjb25zb2xlLmxvZyhgJHtcIiBcIi5yZXBlYXQobWV0YWRhdGEuZGVzY3JpcHRpb25zLmxlbmd0aCAqIDIpfWl0ICR7bWV0YWRhdGEudGVzdERlc2NyaXB0aW9ufWApXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJhdHRlbXB0OmZpbmlzaFwiKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlcG9ydEF0dGVtcHRFdmVudChldmVudClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChldmVudC50eXBlID09PSBcInRlc3Q6ZmluaXNoXCIpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVwb3J0VGVzdEV2ZW50KGV2ZW50KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKGV2ZW50LnR5cGUgPT09IFwicnVuOmZpbmlzaFwiKSB0aGlzLnRlc3RSdW5uZXIucmVjb3JkUGFja2FnZVJlc3VsdChldmVudC5yZXN1bHQpXG4gIH1cblxuICAvKipcbiAgICogUHJvamVjdHMgYXR0ZW1wdCBmYWlsdXJlL3JldHJ5IGV2ZW50cyB3aGlsZSByZXRhaW5pbmcgdGhlIHJhdyB0aHJvd24gdmFsdWUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiKS5SdW5uZXJFdmVudH0gZXZlbnQgLSBBdHRlbXB0IGV2ZW50LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBsaXN0ZW5lcnMgZmluaXNoLlxuICAgKi9cbiAgYXN5bmMgcmVwb3J0QXR0ZW1wdEV2ZW50KGV2ZW50KSB7XG4gICAgY29uc3QgdGVzdCA9IHRoaXMuYWN0aXZlVGVzdCB8fCB0aGlzLnRlc3RSdW5uZXIuZmluZFRlc3REZWNsYXJhdGlvbihldmVudC5mdWxsTmFtZSlcblxuICAgIGlmICghdGVzdCkgdGhyb3cgbmV3IEVycm9yKGBQYWNrYWdlIHJ1bm5lciBhdHRlbXB0IGRpZCBub3QgbWF0Y2ggYSBkZWNsYXJhdGlvbjogJHtldmVudC5mdWxsTmFtZX1gKVxuXG4gICAgLy8gTmFycm93cyB0aGUgc3RydWN0dXJlZCBldmVudCBwYXlsb2FkIGZvciB0aGlzIGV2ZW50IGRpc2NyaW1pbmF0b3IuXG4gICAgY29uc3QgYXR0ZW1wdCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiKS5UZXN0QXR0ZW1wdFJlc3VsdH0gKi8gKGV2ZW50LmF0dGVtcHQpXG4gICAgY29uc3Qgb3V0Y29tZSA9IHRoaXMudGVzdFJ1bm5lci5hdHRlbXB0T3V0Y29tZSh0ZXN0LCBhdHRlbXB0LmF0dGVtcHROdW1iZXIpXG4gICAgY29uc3QgYXR0ZW1wdENvbnNvbGVPdXRwdXRzID0gdGhpcy5hdHRlbXB0Q29uc29sZU91dHB1dHMuZ2V0KHRlc3QpIHx8IFtdXG5cbiAgICBpZiAoYXR0ZW1wdC5jb25zb2xlT3V0cHV0KSB7XG4gICAgICBhdHRlbXB0Q29uc29sZU91dHB1dHMucHVzaCh7YXR0ZW1wdE51bWJlcjogYXR0ZW1wdC5hdHRlbXB0TnVtYmVyLCBvdXRwdXQ6IGF0dGVtcHQuY29uc29sZU91dHB1dC50cmltRW5kKCl9KVxuICAgICAgdGhpcy5hdHRlbXB0Q29uc29sZU91dHB1dHMuc2V0KHRlc3QsIGF0dGVtcHRDb25zb2xlT3V0cHV0cylcbiAgICB9XG5cbiAgICBjb25zdCByZXRyeUNvdW50ID0gdGhpcy50ZXN0UnVubmVyLnJldHJ5Q291bnQodGVzdClcbiAgICBjb25zdCBmYWlsZWQgPSBvdXRjb21lPy5mYWlsZWQgPz8gQm9vbGVhbihhdHRlbXB0LmVycm9yKVxuICAgIGNvbnN0IGVycm9yID0gb3V0Y29tZT8uZXJyb3JcbiAgICBjb25zdCByZXRyaWVzVXNlZCA9IE1hdGgubWluKGF0dGVtcHQuYXR0ZW1wdE51bWJlciwgcmV0cnlDb3VudClcbiAgICBjb25zdCB3aWxsUmV0cnkgPSBmYWlsZWQgJiYgIW91dGNvbWU/LmFib3J0UmVtYWluaW5nVGVzdHMgJiYgYXR0ZW1wdC5hdHRlbXB0TnVtYmVyIDw9IHJldHJ5Q291bnRcbiAgICBjb25zdCB7ZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb259ID0gdGhpcy50ZXN0UnVubmVyLnRlc3RNZXRhZGF0YSh0ZXN0KVxuICAgIGNvbnN0IGNvbXBhdGliaWxpdHkgPSB0aGlzLnRlc3RSdW5uZXIudGVzdERhdGEodGVzdClcblxuICAgIGlmIChmYWlsZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdEF0dGVtcHRGYWlsZWRcIiwge1xuICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLnRlc3RSdW5uZXIuZ2V0Q29uZmlndXJhdGlvbigpLFxuICAgICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBhdHRlbXB0TnVtYmVyOiBhdHRlbXB0LmF0dGVtcHROdW1iZXIsXG4gICAgICAgIG5leHRBdHRlbXB0OiB3aWxsUmV0cnkgPyBhdHRlbXB0LmF0dGVtcHROdW1iZXIgKyAxIDogdW5kZWZpbmVkLFxuICAgICAgICByZXRyaWVzVXNlZCxcbiAgICAgICAgcmV0cnlDb3VudCxcbiAgICAgICAgdGVzdEFyZ3M6IGNvbXBhdGliaWxpdHkudGVzdEFyZ3MsXG4gICAgICAgIHRlc3REYXRhOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLFxuICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgIHRlc3RSdW5uZXI6IHRoaXMudGVzdFJ1bm5lcixcbiAgICAgICAgd2lsbFJldHJ5XG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmICh3aWxsUmV0cnkpIHtcbiAgICAgIGNvbnNvbGUud2FybihwaWNvY29sb3JzLnJlZChgJHtcIiBcIi5yZXBlYXQoZGVzY3JpcHRpb25zLmxlbmd0aCAqIDIpfSAgUmV0cnlpbmcgKCR7cmV0cmllc1VzZWR9LyR7cmV0cnlDb3VudH0pIGFmdGVyIGVycm9yOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gKSlcbiAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdFJldHJ5aW5nXCIsIHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy50ZXN0UnVubmVyLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgbmV4dEF0dGVtcHQ6IGF0dGVtcHQuYXR0ZW1wdE51bWJlciArIDEsXG4gICAgICAgIHJldHJpZXNVc2VkLFxuICAgICAgICByZXRyeUNvdW50LFxuICAgICAgICB0ZXN0QXJnczogY29tcGF0aWJpbGl0eS50ZXN0QXJncyxcbiAgICAgICAgdGVzdERhdGE6IGNvbXBhdGliaWxpdHkudGVzdERhdGEsXG4gICAgICAgIHRlc3REZXNjcmlwdGlvbixcbiAgICAgICAgdGVzdFJ1bm5lcjogdGhpcy50ZXN0UnVubmVyXG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmIChhdHRlbXB0LmF0dGVtcHROdW1iZXIgPiAxKSB7XG4gICAgICBhd2FpdCB0aGlzLmVtaXRFdmVudChcInRlc3RSZXRyaWVkXCIsIHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy50ZXN0UnVubmVyLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgYXR0ZW1wdE51bWJlcjogYXR0ZW1wdC5hdHRlbXB0TnVtYmVyLFxuICAgICAgICByZXRyaWVzVXNlZCxcbiAgICAgICAgcmV0cnlDb3VudCxcbiAgICAgICAgdGVzdEFyZ3M6IGNvbXBhdGliaWxpdHkudGVzdEFyZ3MsXG4gICAgICAgIHRlc3REYXRhOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLFxuICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgIHRlc3RSdW5uZXI6IHRoaXMudGVzdFJ1bm5lclxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAob3V0Y29tZT8uYWJvcnRSZW1haW5pbmdUZXN0cykge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnRlc3RSdW5uZXIudGVzdE1ldGFkYXRhKHRlc3QpXG5cbiAgICAgIHRoaXMudGVzdFJ1bm5lci5yZWNvcmRUZXN0RHVyYXRpb24oe1xuICAgICAgICBkdXJhdGlvbk1zOiBhdHRlbXB0LmR1cmF0aW9uTXMsXG4gICAgICAgIGZpbGVQYXRoOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLmZpbGVQYXRoID8/IFwiPHVua25vd24+XCIsXG4gICAgICAgIGZ1bGxEZXNjcmlwdGlvbjogbWV0YWRhdGEuZnVsbERlc2NyaXB0aW9uLFxuICAgICAgICBsaW5lOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLmxpbmUgPz8gMFxuICAgICAgfSlcbiAgICAgIGF3YWl0IHRoaXMucmVwb3J0RmFpbGVkVGVzdCh7XG4gICAgICAgIGF0dGVtcHRDb25zb2xlT3V0cHV0cyxcbiAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgbGVmdFBhZGRpbmc6IFwiIFwiLnJlcGVhdChkZXNjcmlwdGlvbnMubGVuZ3RoICogMiksXG4gICAgICAgIHRlc3RBcmdzOiBjb21wYXRpYmlsaXR5LnRlc3RBcmdzLFxuICAgICAgICB0ZXN0RGF0YTogY29tcGF0aWJpbGl0eS50ZXN0RGF0YSxcbiAgICAgICAgdGVzdERlc2NyaXB0aW9uXG4gICAgICB9KVxuICAgICAgdGhpcy50ZXN0UnVubmVyLmNvbXBsZXRlVGVzdERlY2xhcmF0aW9uKHRlc3QpXG4gICAgICB0aGlzLmFjdGl2ZVRlc3QgPSB1bmRlZmluZWRcbiAgICAgIHRocm93IG5ldyBBYm9ydFJlbWFpbmluZ1Rlc3RzRXJyb3IoXCJWZWxvY2lvdXMgcXVhcmFudGluZWQgYW4gYXR0ZW1wdC1vd25lZCBkYXRhYmFzZSBjb25uZWN0aW9uXCIpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFByb2plY3RzIGZpbmFsIHBhY2thZ2UgcmVzdWx0IGFjY291bnRpbmcgYW5kIGZhaWx1cmVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIkB2ZWxvY2lvdXMvdGVzdGluZy9ydW5uZXJcIikuUnVubmVyRXZlbnR9IGV2ZW50IC0gVGVzdCByZXN1bHQgZXZlbnQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIGxpc3RlbmVycyBmaW5pc2guXG4gICAqL1xuICBhc3luYyByZXBvcnRUZXN0RXZlbnQoZXZlbnQpIHtcbiAgICAvLyBOYXJyb3dzIHRoZSBzdHJ1Y3R1cmVkIGV2ZW50IHBheWxvYWQgZm9yIHRoaXMgZXZlbnQgZGlzY3JpbWluYXRvci5cbiAgICBjb25zdCBwYWNrYWdlVGVzdFJlc3VsdCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiKS5UZXN0UmVzdWx0fSAqLyAoZXZlbnQudGVzdClcbiAgICBjb25zdCB0ZXN0ID0gdGhpcy5hY3RpdmVUZXN0IHx8IHRoaXMudGVzdFJ1bm5lci5maW5kVGVzdERlY2xhcmF0aW9uKHBhY2thZ2VUZXN0UmVzdWx0LmZ1bGxOYW1lKVxuXG4gICAgaWYgKCF0ZXN0KSB0aHJvdyBuZXcgRXJyb3IoYFBhY2thZ2UgcnVubmVyIHJlc3VsdCBkaWQgbm90IG1hdGNoIGEgZGVjbGFyYXRpb246ICR7cGFja2FnZVRlc3RSZXN1bHQuZnVsbE5hbWV9YClcblxuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy50ZXN0UnVubmVyLnRlc3RNZXRhZGF0YSh0ZXN0KVxuICAgIGNvbnN0IGNvbXBhdGliaWxpdHkgPSB0aGlzLnRlc3RSdW5uZXIudGVzdERhdGEodGVzdClcbiAgICBjb25zdCBkdXJhdGlvbk1zID0gcGFja2FnZVRlc3RSZXN1bHQuYXR0ZW1wdHMucmVkdWNlKCh0b3RhbCwgYXR0ZW1wdCkgPT4gdG90YWwgKyBhdHRlbXB0LmR1cmF0aW9uTXMsIDApXG5cbiAgICBpZiAocGFja2FnZVRlc3RSZXN1bHQuYXR0ZW1wdHMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy50ZXN0UnVubmVyLnJlY29yZFRlc3REdXJhdGlvbih7XG4gICAgICAgIGR1cmF0aW9uTXMsXG4gICAgICAgIGZpbGVQYXRoOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLmZpbGVQYXRoID8/IFwiPHVua25vd24+XCIsXG4gICAgICAgIGZ1bGxEZXNjcmlwdGlvbjogbWV0YWRhdGEuZnVsbERlc2NyaXB0aW9uLFxuICAgICAgICBsaW5lOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLmxpbmUgPz8gMFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAocGFja2FnZVRlc3RSZXN1bHQuc3RhdHVzID09PSBcInBhc3NlZFwiKSB7XG4gICAgICB0aGlzLnRlc3RSdW5uZXIucmVjb3JkU3VjY2Vzc2Z1bFRlc3QoKVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBmaW5hbEF0dGVtcHQgPSBwYWNrYWdlVGVzdFJlc3VsdC5hdHRlbXB0cy5hdCgtMSlcbiAgICAgIGNvbnN0IG91dGNvbWUgPSBmaW5hbEF0dGVtcHRcbiAgICAgICAgPyB0aGlzLnRlc3RSdW5uZXIuYXR0ZW1wdE91dGNvbWUodGVzdCwgZmluYWxBdHRlbXB0LmF0dGVtcHROdW1iZXIpXG4gICAgICAgIDogdW5kZWZpbmVkXG4gICAgICBjb25zdCBlcnJvciA9IG91dGNvbWU/LmZhaWxlZFxuICAgICAgICA/IG91dGNvbWUuZXJyb3JcbiAgICAgICAgOiB0aGlzLnRlc3RSdW5uZXIuc2V0dXBGYWlsdXJlRm9yKHRlc3QpXG5cbiAgICAgIGF3YWl0IHRoaXMucmVwb3J0RmFpbGVkVGVzdCh7XG4gICAgICAgIGF0dGVtcHRDb25zb2xlT3V0cHV0czogdGhpcy5hdHRlbXB0Q29uc29sZU91dHB1dHMuZ2V0KHRlc3QpIHx8IFtdLFxuICAgICAgICBkZXNjcmlwdGlvbnM6IG1ldGFkYXRhLmRlc2NyaXB0aW9ucyxcbiAgICAgICAgZXJyb3IsXG4gICAgICAgIGxlZnRQYWRkaW5nOiBcIiBcIi5yZXBlYXQobWV0YWRhdGEuZGVzY3JpcHRpb25zLmxlbmd0aCAqIDIpLFxuICAgICAgICB0ZXN0QXJnczogY29tcGF0aWJpbGl0eS50ZXN0QXJncyxcbiAgICAgICAgdGVzdERhdGE6IGNvbXBhdGliaWxpdHkudGVzdERhdGEsXG4gICAgICAgIHRlc3REZXNjcmlwdGlvbjogbWV0YWRhdGEudGVzdERlc2NyaXB0aW9uXG4gICAgICB9KVxuICAgIH1cblxuICAgIHRoaXMudGVzdFJ1bm5lci5jb21wbGV0ZVRlc3REZWNsYXJhdGlvbih0ZXN0KVxuICAgIHRoaXMuYWN0aXZlVGVzdCA9IHVuZGVmaW5lZFxuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZHMgYW5kIGVtaXRzIG9uZSBmaW5hbCBmYWlsZWQgdGVzdCByZXN1bHQuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gRmluYWwgZmFpbHVyZSBtZXRhZGF0YS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3Rlc3QtcnVubmVyLmpzXCIpLkF0dGVtcHRDb25zb2xlT3V0cHV0W119IGFyZ3MuYXR0ZW1wdENvbnNvbGVPdXRwdXRzIC0gQ2FwdHVyZWQgb3V0cHV0IGFjcm9zcyBhdHRlbXB0cy5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gYXJncy5kZXNjcmlwdGlvbnMgLSBQYXJlbnQgZGVzY3JpcHRpb24gc3RhY2suXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IGFyZ3MuZXJyb3IgLSBSYXcgZmluYWwgZmFpbHVyZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MubGVmdFBhZGRpbmcgLSBDb25zb2xlIGluZGVudGF0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuVGVzdEFyZ3N9IGFyZ3MudGVzdEFyZ3MgLSBTdGFibGUgdGVzdCBhcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5UZXN0RGF0YX0gYXJncy50ZXN0RGF0YSAtIFRlc3QgcmVnaXN0cmF0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy50ZXN0RGVzY3JpcHRpb24gLSBUZXN0IGRlc2NyaXB0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciB0aGUgZmluYWwtZmFpbHVyZSBsaXN0ZW5lciBjb21wbGV0ZXMuXG4gICAqL1xuICBhc3luYyByZXBvcnRGYWlsZWRUZXN0KHthdHRlbXB0Q29uc29sZU91dHB1dHMsIGRlc2NyaXB0aW9ucywgZXJyb3IsIGxlZnRQYWRkaW5nLCB0ZXN0QXJncywgdGVzdERhdGEsIHRlc3REZXNjcmlwdGlvbn0pIHtcbiAgICBjb25zdCB0ZXN0UnVubmVyID0gdGhpcy50ZXN0UnVubmVyXG4gICAgY29uc3QgY29uc29sZU91dHB1dCA9IHRlc3RSdW5uZXIuYnVpbGRDb25zb2xlT3V0cHV0KGF0dGVtcHRDb25zb2xlT3V0cHV0cylcblxuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGAke2xlZnRQYWRkaW5nfSAgVGVzdCBmYWlsZWQ6ICR7ZXJyb3IubWVzc2FnZX1gKSlcbiAgICAgIGFkZFRyYWNrZWRTdGFja1RvRXJyb3IoZXJyb3IpXG5cbiAgICAgIGNvbnN0IGJhY2t0cmFjZUNsZWFuZXIgPSBuZXcgQmFja3RyYWNlQ2xlYW5lcihlcnJvcilcbiAgICAgIGNvbnN0IGNsZWFuZWRTdGFjayA9IGJhY2t0cmFjZUNsZWFuZXIuZ2V0Q2xlYW5lZFN0YWNrKClcbiAgICAgIGNvbnN0IHN0YWNrTGluZXMgPSBjbGVhbmVkU3RhY2s/LnNwbGl0KFwiXFxuXCIpXG5cbiAgICAgIGlmIChzdGFja0xpbmVzKSB7XG4gICAgICAgIGZvciAoY29uc3Qgc3RhY2tMaW5lIG9mIHN0YWNrTGluZXMpIGNvbnNvbGUuZXJyb3IocGljb2NvbG9ycy5yZWQoYCR7bGVmdFBhZGRpbmd9ICAke3N0YWNrTGluZX1gKSlcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gIFRlc3QgZmFpbGVkIHdpdGggYSAke3R5cGVvZiBlcnJvcn06ICR7U3RyaW5nKGVycm9yKX1gKSlcbiAgICB9XG5cbiAgICB0ZXN0UnVubmVyLnByaW50RmFpbGVkQ29uc29sZU91dHB1dCh7Y29uc29sZU91dHB1dCwgbGVmdFBhZGRpbmd9KVxuICAgIHRlc3RSdW5uZXIucmVjb3JkRmFpbGVkVGVzdCh7ZGVzY3JpcHRpb25zLCBlcnJvciwgY29uc29sZU91dHB1dCwgdGVzdERhdGEsIHRlc3REZXNjcmlwdGlvbn0pXG5cbiAgICBhd2FpdCB0aGlzLmVtaXRFdmVudChcInRlc3RGYWlsZWRcIiwge1xuICAgICAgY29uZmlndXJhdGlvbjogdGVzdFJ1bm5lci5nZXRDb25maWd1cmF0aW9uKCksXG4gICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICBlcnJvcixcbiAgICAgIHRlc3RBcmdzLFxuICAgICAgdGVzdERhdGEsXG4gICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICB0ZXN0UnVubmVyXG4gICAgfSlcblxuICAgIHRlc3RSdW5uZXIucHJpbnRSZXJ1bkNvbW1hbmQoe2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uLCB0ZXN0RGF0YSwgbGVmdFBhZGRpbmd9KVxuICB9XG5cbiAgLyoqXG4gICAqIEVtaXRzIG9uZSBsZWdhY3kgZXZlbnQgYW5kIGF3YWl0cyBsaXN0ZW5lcnMgaW4gcmVnaXN0cmF0aW9uIG9yZGVyLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIC0gRXZlbnQgbmFtZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IHBheWxvYWQgLSBFdmVudCBwYXlsb2FkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGFsbCBsaXN0ZW5lcnMgY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBlbWl0RXZlbnQoZXZlbnROYW1lLCBwYXlsb2FkKSB7XG4gICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiB0ZXN0RXZlbnRzLmxpc3RlbmVycyhldmVudE5hbWUpKSBhd2FpdCBsaXN0ZW5lcihwYXlsb2FkKVxuICB9XG59XG4iXX0=
|
|
260
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVsb2Npb3VzLXJ1bm5lci1yZXBvcnRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0aW5nL3ZlbG9jaW91cy1ydW5uZXItcmVwb3J0ZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFBO0FBQ3ZFLE9BQU8sZ0JBQWdCLE1BQU0sb0NBQW9DLENBQUE7QUFDakUsT0FBTyxVQUFVLE1BQU0sWUFBWSxDQUFBO0FBQ25DLE9BQU8sYUFBYSxNQUFNLDZCQUE2QixDQUFBO0FBQ3ZELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFFdEMsNEZBQTRGO0FBQzVGLDRGQUE0RjtBQUU1Rjs7OztHQUlHO0FBQ0gsU0FBUyxzQkFBc0IsQ0FBQyxXQUFXO0lBQ3pDLE1BQU0sS0FBSyxHQUFHLFdBQVcsQ0FBQyxNQUFNO1FBQzlCLENBQUMsQ0FBQyxJQUFJLGNBQWMsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxPQUFPLENBQUM7UUFDekYsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUVsQyxLQUFLLENBQUMsSUFBSSxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUE7SUFDN0IsSUFBSSxXQUFXLENBQUMsS0FBSztRQUFFLEtBQUssQ0FBQyxLQUFLLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQTtJQUV0RCxPQUFPLEtBQUssQ0FBQTtBQUNkLENBQUM7QUFFRCwyRUFBMkU7QUFDM0UsTUFBTSxPQUFPLHdCQUF5QixTQUFRLEtBQUs7Q0FBRztBQUV0RCxNQUFNLENBQUMsT0FBTyxPQUFPLHVCQUF1QjtJQUMxQzs7OztPQUlHO0lBQ0gsWUFBWSxFQUFDLFVBQVUsRUFBRSxHQUFHLFFBQVEsRUFBQztRQUNuQyxhQUFh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QUNMLFFBQVE7WUFDUixRQUFRO1lBQ1IsZUFBZTtZQUNmLFVBQVU7U0FDWCxDQUFDLENBQUE7UUFFRixVQUFVLENBQUMsaUJBQWlCLENBQUMsRUFBQyxZQUFZLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFBO0lBQ3RGLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLE9BQU87UUFDaEMsS0FBSyxNQUFNLFFBQVEsSUFBSSxVQUFVLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQztZQUFFLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ2pGLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgeyBhZGRUcmFja2VkU3RhY2tUb0Vycm9yIH0gZnJvbSBcIi4uL3V0aWxzL3dpdGgtdHJhY2tlZC1zdGFjay5qc1wiXG5pbXBvcnQgQmFja3RyYWNlQ2xlYW5lciBmcm9tIFwiLi4vdXRpbHMvYmFja3RyYWNlLWNsZWFuZXItbm9kZS5qc1wiXG5pbXBvcnQgcGljb2NvbG9ycyBmcm9tIFwicGljb2NvbG9yc1wiXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcbmltcG9ydCB7IHRlc3RFdmVudHMgfSBmcm9tIFwiLi90ZXN0LmpzXCJcblxuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCJAdmVsb2Npb3VzL3Rlc3RpbmcvcnVubmVyXCIpLlRlc3REZWNsYXJhdGlvbn0gUGFja2FnZVRlc3REZWNsYXJhdGlvbiAqL1xuLyoqIEB0eXBlZGVmIHtpbXBvcnQoXCJAdmVsb2Npb3VzL3Rlc3RpbmcvcnVubmVyXCIpLlRlc3RFcnJvclJlY29yZH0gUGFja2FnZVRlc3RFcnJvclJlY29yZCAqL1xuXG4vKipcbiAqIFJlc3RvcmVzIHRoZSBFcnJvciBzaGFwZSBzZXJpYWxpemVkIGJ5IHRoZSBwYWNrYWdlIHJ1bm5lci5cbiAqIEBwYXJhbSB7UGFja2FnZVRlc3RFcnJvclJlY29yZH0gZXJyb3JSZWNvcmQgLSBTZXJpYWxpemVkIHBhY2thZ2UgZmFpbHVyZS5cbiAqIEByZXR1cm5zIHtFcnJvcn0gLSBFcnJvciBjb21wYXRpYmxlIHdpdGggVmVsb2Npb3VzJ3MgbGVnYWN5IHJlcG9ydGVyIGNvbnRyYWN0LlxuICovXG5mdW5jdGlvbiBlcnJvckZyb21QYWNrYWdlUmVjb3JkKGVycm9yUmVjb3JkKSB7XG4gIGNvbnN0IGVycm9yID0gZXJyb3JSZWNvcmQuZXJyb3JzXG4gICAgPyBuZXcgQWdncmVnYXRlRXJyb3IoZXJyb3JSZWNvcmQuZXJyb3JzLm1hcChlcnJvckZyb21QYWNrYWdlUmVjb3JkKSwgZXJyb3JSZWNvcmQubWVzc2FnZSlcbiAgICA6IG5ldyBFcnJvcihlcnJvclJlY29yZC5tZXNzYWdlKVxuXG4gIGVycm9yLm5hbWUgPSBlcnJvclJlY29yZC5uYW1lXG4gIGlmIChlcnJvclJlY29yZC5zdGFjaykgZXJyb3Iuc3RhY2sgPSBlcnJvclJlY29yZC5zdGFja1xuXG4gIHJldHVybiBlcnJvclxufVxuXG4vKiogU3RvcHMgcGFja2FnZSB0cmF2ZXJzYWwgYWZ0ZXIgZnJhbWV3b3JrLW93bmVkIGNvbm5lY3Rpb24gcXVhcmFudGluZS4gKi9cbmV4cG9ydCBjbGFzcyBBYm9ydFJlbWFpbmluZ1Rlc3RzRXJyb3IgZXh0ZW5kcyBFcnJvciB7fVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNSdW5uZXJSZXBvcnRlciB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSBsZWdhY3kgZXZlbnQgYW5kIHJlc3VsdCBwcm9qZWN0aW9uIGFkYXB0ZXIuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQ29uc3RydWN0b3IgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuZGVmYXVsdH0gYXJncy50ZXN0UnVubmVyIC0gT3duaW5nIFZlbG9jaW91cyBydW5uZXIuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7dGVzdFJ1bm5lciwgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcbiAgICB0aGlzLnRlc3RSdW5uZXIgPSB0ZXN0UnVubmVyXG4gICAgLyoqIEB0eXBlIHtXZWFrTWFwPFBhY2thZ2VUZXN0RGVjbGFyYXRpb24sIGltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQXR0ZW1wdENvbnNvbGVPdXRwdXRbXT59ICovXG4gICAgdGhpcy5hdHRlbXB0Q29uc29sZU91dHB1dHMgPSBuZXcgV2Vha01hcCgpXG4gICAgLyoqIEB0eXBlIHtQYWNrYWdlVGVzdERlY2xhcmF0aW9uIHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuYWN0aXZlVGVzdCA9IHVuZGVmaW5lZFxuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zbGF0ZXMgb25lIGF3YWl0ZWQgcGFja2FnZSBydW5uZXIgZXZlbnQgaW50byB0aGUgbGVnYWN5IGNvbnRyYWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIkB2ZWxvY2lvdXMvdGVzdGluZy9ydW5uZXJcIikuUnVubmVyRXZlbnR9IGV2ZW50IC0gU3RydWN0dXJlZCBwYWNrYWdlIGV2ZW50LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBsZWdhY3kgbGlzdGVuZXJzIGZpbmlzaC5cbiAgICovXG4gIGFzeW5jIG9uRXZlbnQoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJ0ZXN0OnN0YXJ0XCIpIHtcbiAgICAgIHRoaXMuYWN0aXZlVGVzdCA9IHRoaXMudGVzdFJ1bm5lci5maW5kVGVzdERlY2xhcmF0aW9uKGV2ZW50LmZ1bGxOYW1lKVxuICAgICAgaWYgKHRoaXMuYWN0aXZlVGVzdCkge1xuICAgICAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMudGVzdFJ1bm5lci50ZXN0TWV0YWRhdGEodGhpcy5hY3RpdmVUZXN0KVxuICAgICAgICBjb25zb2xlLmxvZyhgJHtcIiBcIi5yZXBlYXQobWV0YWRhdGEuZGVzY3JpcHRpb25zLmxlbmd0aCAqIDIpfWl0ICR7bWV0YWRhdGEudGVzdERlc2NyaXB0aW9ufWApXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJhdHRlbXB0OmZpbmlzaFwiKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlcG9ydEF0dGVtcHRFdmVudChldmVudClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChldmVudC50eXBlID09PSBcInRlc3Q6ZmluaXNoXCIpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVwb3J0VGVzdEV2ZW50KGV2ZW50KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKGV2ZW50LnR5cGUgPT09IFwicnVuOmZpbmlzaFwiKSB0aGlzLnRlc3RSdW5uZXIucmVjb3JkUGFja2FnZVJlc3VsdChldmVudC5yZXN1bHQpXG4gIH1cblxuICAvKipcbiAgICogUHJvamVjdHMgYXR0ZW1wdCBmYWlsdXJlL3JldHJ5IGV2ZW50cyB3aGlsZSByZXRhaW5pbmcgdGhlIHJhdyB0aHJvd24gdmFsdWUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiKS5SdW5uZXJFdmVudH0gZXZlbnQgLSBBdHRlbXB0IGV2ZW50LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBsaXN0ZW5lcnMgZmluaXNoLlxuICAgKi9cbiAgYXN5bmMgcmVwb3J0QXR0ZW1wdEV2ZW50KGV2ZW50KSB7XG4gICAgY29uc3QgdGVzdCA9IHRoaXMuYWN0aXZlVGVzdCB8fCB0aGlzLnRlc3RSdW5uZXIuZmluZFRlc3REZWNsYXJhdGlvbihldmVudC5mdWxsTmFtZSlcblxuICAgIGlmICghdGVzdCkgdGhyb3cgbmV3IEVycm9yKGBQYWNrYWdlIHJ1bm5lciBhdHRlbXB0IGRpZCBub3QgbWF0Y2ggYSBkZWNsYXJhdGlvbjogJHtldmVudC5mdWxsTmFtZX1gKVxuXG4gICAgLy8gTmFycm93cyB0aGUgc3RydWN0dXJlZCBldmVudCBwYXlsb2FkIGZvciB0aGlzIGV2ZW50IGRpc2NyaW1pbmF0b3IuXG4gICAgY29uc3QgYXR0ZW1wdCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiKS5UZXN0QXR0ZW1wdFJlc3VsdH0gKi8gKGV2ZW50LmF0dGVtcHQpXG4gICAgY29uc3Qgb3V0Y29tZSA9IHRoaXMudGVzdFJ1bm5lci5hdHRlbXB0T3V0Y29tZSh0ZXN0LCBhdHRlbXB0LmF0dGVtcHROdW1iZXIpXG4gICAgY29uc3QgYXR0ZW1wdENvbnNvbGVPdXRwdXRzID0gdGhpcy5hdHRlbXB0Q29uc29sZU91dHB1dHMuZ2V0KHRlc3QpIHx8IFtdXG5cbiAgICBpZiAoYXR0ZW1wdC5jb25zb2xlT3V0cHV0KSB7XG4gICAgICBhdHRlbXB0Q29uc29sZU91dHB1dHMucHVzaCh7YXR0ZW1wdE51bWJlcjogYXR0ZW1wdC5hdHRlbXB0TnVtYmVyLCBvdXRwdXQ6IGF0dGVtcHQuY29uc29sZU91dHB1dC50cmltRW5kKCl9KVxuICAgICAgdGhpcy5hdHRlbXB0Q29uc29sZU91dHB1dHMuc2V0KHRlc3QsIGF0dGVtcHRDb25zb2xlT3V0cHV0cylcbiAgICB9XG5cbiAgICBjb25zdCByZXRyeUNvdW50ID0gdGhpcy50ZXN0UnVubmVyLnJldHJ5Q291bnQodGVzdClcbiAgICBjb25zdCBmYWlsZWQgPSBvdXRjb21lPy5mYWlsZWQgPz8gQm9vbGVhbihhdHRlbXB0LmVycm9yKVxuICAgIGNvbnN0IGVycm9yID0gb3V0Y29tZT8uZXJyb3JcbiAgICBjb25zdCByZXRyaWVzVXNlZCA9IE1hdGgubWluKGF0dGVtcHQuYXR0ZW1wdE51bWJlciwgcmV0cnlDb3VudClcbiAgICBjb25zdCB3aWxsUmV0cnkgPSBmYWlsZWQgJiYgIW91dGNvbWU/LmFib3J0UmVtYWluaW5nVGVzdHMgJiYgYXR0ZW1wdC5hdHRlbXB0TnVtYmVyIDw9IHJldHJ5Q291bnRcbiAgICBjb25zdCB7ZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb259ID0gdGhpcy50ZXN0UnVubmVyLnRlc3RNZXRhZGF0YSh0ZXN0KVxuICAgIGNvbnN0IGNvbXBhdGliaWxpdHkgPSB0aGlzLnRlc3RSdW5uZXIudGVzdERhdGEodGVzdClcblxuICAgIGlmIChmYWlsZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdEF0dGVtcHRGYWlsZWRcIiwge1xuICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLnRlc3RSdW5uZXIuZ2V0Q29uZmlndXJhdGlvbigpLFxuICAgICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBhdHRlbXB0TnVtYmVyOiBhdHRlbXB0LmF0dGVtcHROdW1iZXIsXG4gICAgICAgIG5leHRBdHRlbXB0OiB3aWxsUmV0cnkgPyBhdHRlbXB0LmF0dGVtcHROdW1iZXIgKyAxIDogdW5kZWZpbmVkLFxuICAgICAgICByZXRyaWVzVXNlZCxcbiAgICAgICAgcmV0cnlDb3VudCxcbiAgICAgICAgdGVzdEFyZ3M6IGNvbXBhdGliaWxpdHkudGVzdEFyZ3MsXG4gICAgICAgIHRlc3REYXRhOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLFxuICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgIHRlc3RSdW5uZXI6IHRoaXMudGVzdFJ1bm5lcixcbiAgICAgICAgd2lsbFJldHJ5XG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmICh3aWxsUmV0cnkpIHtcbiAgICAgIGNvbnNvbGUud2FybihwaWNvY29sb3JzLnJlZChgJHtcIiBcIi5yZXBlYXQoZGVzY3JpcHRpb25zLmxlbmd0aCAqIDIpfSAgUmV0cnlpbmcgKCR7cmV0cmllc1VzZWR9LyR7cmV0cnlDb3VudH0pIGFmdGVyIGVycm9yOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gKSlcbiAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdFJldHJ5aW5nXCIsIHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy50ZXN0UnVubmVyLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgbmV4dEF0dGVtcHQ6IGF0dGVtcHQuYXR0ZW1wdE51bWJlciArIDEsXG4gICAgICAgIHJldHJpZXNVc2VkLFxuICAgICAgICByZXRyeUNvdW50LFxuICAgICAgICB0ZXN0QXJnczogY29tcGF0aWJpbGl0eS50ZXN0QXJncyxcbiAgICAgICAgdGVzdERhdGE6IGNvbXBhdGliaWxpdHkudGVzdERhdGEsXG4gICAgICAgIHRlc3REZXNjcmlwdGlvbixcbiAgICAgICAgdGVzdFJ1bm5lcjogdGhpcy50ZXN0UnVubmVyXG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmIChhdHRlbXB0LmF0dGVtcHROdW1iZXIgPiAxKSB7XG4gICAgICBhd2FpdCB0aGlzLmVtaXRFdmVudChcInRlc3RSZXRyaWVkXCIsIHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy50ZXN0UnVubmVyLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgYXR0ZW1wdE51bWJlcjogYXR0ZW1wdC5hdHRlbXB0TnVtYmVyLFxuICAgICAgICByZXRyaWVzVXNlZCxcbiAgICAgICAgcmV0cnlDb3VudCxcbiAgICAgICAgdGVzdEFyZ3M6IGNvbXBhdGliaWxpdHkudGVzdEFyZ3MsXG4gICAgICAgIHRlc3REYXRhOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLFxuICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgIHRlc3RSdW5uZXI6IHRoaXMudGVzdFJ1bm5lclxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAob3V0Y29tZT8uYWJvcnRSZW1haW5pbmdUZXN0cykge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnRlc3RSdW5uZXIudGVzdE1ldGFkYXRhKHRlc3QpXG5cbiAgICAgIHRoaXMudGVzdFJ1bm5lci5yZWNvcmRUZXN0RHVyYXRpb24oe1xuICAgICAgICBkdXJhdGlvbk1zOiBhdHRlbXB0LmR1cmF0aW9uTXMsXG4gICAgICAgIGZpbGVQYXRoOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLmZpbGVQYXRoID8/IFwiPHVua25vd24+XCIsXG4gICAgICAgIGZ1bGxEZXNjcmlwdGlvbjogbWV0YWRhdGEuZnVsbERlc2NyaXB0aW9uLFxuICAgICAgICBsaW5lOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLmxpbmUgPz8gMFxuICAgICAgfSlcbiAgICAgIGF3YWl0IHRoaXMucmVwb3J0RmFpbGVkVGVzdCh7XG4gICAgICAgIGF0dGVtcHRDb25zb2xlT3V0cHV0cyxcbiAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgbGVmdFBhZGRpbmc6IFwiIFwiLnJlcGVhdChkZXNjcmlwdGlvbnMubGVuZ3RoICogMiksXG4gICAgICAgIHRlc3RBcmdzOiBjb21wYXRpYmlsaXR5LnRlc3RBcmdzLFxuICAgICAgICB0ZXN0RGF0YTogY29tcGF0aWJpbGl0eS50ZXN0RGF0YSxcbiAgICAgICAgdGVzdERlc2NyaXB0aW9uXG4gICAgICB9KVxuICAgICAgdGhpcy50ZXN0UnVubmVyLmNvbXBsZXRlVGVzdERlY2xhcmF0aW9uKHRlc3QpXG4gICAgICB0aGlzLmFjdGl2ZVRlc3QgPSB1bmRlZmluZWRcbiAgICAgIHRocm93IG5ldyBBYm9ydFJlbWFpbmluZ1Rlc3RzRXJyb3IoXCJWZWxvY2lvdXMgcXVhcmFudGluZWQgYW4gYXR0ZW1wdC1vd25lZCBkYXRhYmFzZSBjb25uZWN0aW9uXCIpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFByb2plY3RzIGZpbmFsIHBhY2thZ2UgcmVzdWx0IGFjY291bnRpbmcgYW5kIGZhaWx1cmVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIkB2ZWxvY2lvdXMvdGVzdGluZy9ydW5uZXJcIikuUnVubmVyRXZlbnR9IGV2ZW50IC0gVGVzdCByZXN1bHQgZXZlbnQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIGxpc3RlbmVycyBmaW5pc2guXG4gICAqL1xuICBhc3luYyByZXBvcnRUZXN0RXZlbnQoZXZlbnQpIHtcbiAgICAvLyBOYXJyb3dzIHRoZSBzdHJ1Y3R1cmVkIGV2ZW50IHBheWxvYWQgZm9yIHRoaXMgZXZlbnQgZGlzY3JpbWluYXRvci5cbiAgICBjb25zdCBwYWNrYWdlVGVzdFJlc3VsdCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiKS5UZXN0UmVzdWx0fSAqLyAoZXZlbnQudGVzdClcbiAgICBjb25zdCB0ZXN0ID0gdGhpcy5hY3RpdmVUZXN0IHx8IHRoaXMudGVzdFJ1bm5lci5maW5kVGVzdERlY2xhcmF0aW9uKHBhY2thZ2VUZXN0UmVzdWx0LmZ1bGxOYW1lKVxuXG4gICAgaWYgKCF0ZXN0KSB0aHJvdyBuZXcgRXJyb3IoYFBhY2thZ2UgcnVubmVyIHJlc3VsdCBkaWQgbm90IG1hdGNoIGEgZGVjbGFyYXRpb246ICR7cGFja2FnZVRlc3RSZXN1bHQuZnVsbE5hbWV9YClcblxuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy50ZXN0UnVubmVyLnRlc3RNZXRhZGF0YSh0ZXN0KVxuICAgIGNvbnN0IGNvbXBhdGliaWxpdHkgPSB0aGlzLnRlc3RSdW5uZXIudGVzdERhdGEodGVzdClcbiAgICBjb25zdCBkdXJhdGlvbk1zID0gcGFja2FnZVRlc3RSZXN1bHQuYXR0ZW1wdHMucmVkdWNlKCh0b3RhbCwgYXR0ZW1wdCkgPT4gdG90YWwgKyBhdHRlbXB0LmR1cmF0aW9uTXMsIDApXG5cbiAgICBpZiAocGFja2FnZVRlc3RSZXN1bHQuYXR0ZW1wdHMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy50ZXN0UnVubmVyLnJlY29yZFRlc3REdXJhdGlvbih7XG4gICAgICAgIGR1cmF0aW9uTXMsXG4gICAgICAgIGZpbGVQYXRoOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLmZpbGVQYXRoID8/IFwiPHVua25vd24+XCIsXG4gICAgICAgIGZ1bGxEZXNjcmlwdGlvbjogbWV0YWRhdGEuZnVsbERlc2NyaXB0aW9uLFxuICAgICAgICBsaW5lOiBjb21wYXRpYmlsaXR5LnRlc3REYXRhLmxpbmUgPz8gMFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAocGFja2FnZVRlc3RSZXN1bHQuc3RhdHVzID09PSBcInBhc3NlZFwiKSB7XG4gICAgICB0aGlzLnRlc3RSdW5uZXIucmVjb3JkU3VjY2Vzc2Z1bFRlc3QoKVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBmaW5hbEF0dGVtcHQgPSBwYWNrYWdlVGVzdFJlc3VsdC5hdHRlbXB0cy5hdCgtMSlcbiAgICAgIGNvbnN0IG91dGNvbWUgPSBmaW5hbEF0dGVtcHRcbiAgICAgICAgPyB0aGlzLnRlc3RSdW5uZXIuYXR0ZW1wdE91dGNvbWUodGVzdCwgZmluYWxBdHRlbXB0LmF0dGVtcHROdW1iZXIpXG4gICAgICAgIDogdW5kZWZpbmVkXG4gICAgICBjb25zdCBzZXR1cEZhaWx1cmUgPSB0aGlzLnRlc3RSdW5uZXIuc2V0dXBGYWlsdXJlT3V0Y29tZUZvcih0ZXN0KVxuICAgICAgY29uc3QgZXJyb3IgPSBvdXRjb21lPy5mYWlsZWRcbiAgICAgICAgPyBvdXRjb21lLmVycm9yXG4gICAgICAgIDogc2V0dXBGYWlsdXJlLmZhaWxlZFxuICAgICAgICAgID8gc2V0dXBGYWlsdXJlLmVycm9yXG4gICAgICAgICAgOiBwYWNrYWdlVGVzdFJlc3VsdC5lcnJvclxuICAgICAgICAgICAgPyBlcnJvckZyb21QYWNrYWdlUmVjb3JkKHBhY2thZ2VUZXN0UmVzdWx0LmVycm9yKVxuICAgICAgICAgICAgOiB1bmRlZmluZWRcblxuICAgICAgYXdhaXQgdGhpcy5yZXBvcnRGYWlsZWRUZXN0KHtcbiAgICAgICAgYXR0ZW1wdENvbnNvbGVPdXRwdXRzOiB0aGlzLmF0dGVtcHRDb25zb2xlT3V0cHV0cy5nZXQodGVzdCkgfHwgW10sXG4gICAgICAgIGRlc2NyaXB0aW9uczogbWV0YWRhdGEuZGVzY3JpcHRpb25zLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgbGVmdFBhZGRpbmc6IFwiIFwiLnJlcGVhdChtZXRhZGF0YS5kZXNjcmlwdGlvbnMubGVuZ3RoICogMiksXG4gICAgICAgIHRlc3RBcmdzOiBjb21wYXRpYmlsaXR5LnRlc3RBcmdzLFxuICAgICAgICB0ZXN0RGF0YTogY29tcGF0aWJpbGl0eS50ZXN0RGF0YSxcbiAgICAgICAgdGVzdERlc2NyaXB0aW9uOiBtZXRhZGF0YS50ZXN0RGVzY3JpcHRpb25cbiAgICAgIH0pXG4gICAgfVxuXG4gICAgdGhpcy50ZXN0UnVubmVyLmNvbXBsZXRlVGVzdERlY2xhcmF0aW9uKHRlc3QpXG4gICAgdGhpcy5hY3RpdmVUZXN0ID0gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogUmVjb3JkcyBhbmQgZW1pdHMgb25lIGZpbmFsIGZhaWxlZCB0ZXN0IHJlc3VsdC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBGaW5hbCBmYWlsdXJlIG1ldGFkYXRhLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQXR0ZW1wdENvbnNvbGVPdXRwdXRbXX0gYXJncy5hdHRlbXB0Q29uc29sZU91dHB1dHMgLSBDYXB0dXJlZCBvdXRwdXQgYWNyb3NzIGF0dGVtcHRzLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLmRlc2NyaXB0aW9ucyAtIFBhcmVudCBkZXNjcmlwdGlvbiBzdGFjay5cbiAgICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gYXJncy5lcnJvciAtIFJhdyBmaW5hbCBmYWlsdXJlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5sZWZ0UGFkZGluZyAtIENvbnNvbGUgaW5kZW50YXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5UZXN0QXJnc30gYXJncy50ZXN0QXJncyAtIFN0YWJsZSB0ZXN0IGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3Rlc3QtcnVubmVyLmpzXCIpLlRlc3REYXRhfSBhcmdzLnRlc3REYXRhIC0gVGVzdCByZWdpc3RyYXRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLnRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIHRoZSBmaW5hbC1mYWlsdXJlIGxpc3RlbmVyIGNvbXBsZXRlcy5cbiAgICovXG4gIGFzeW5jIHJlcG9ydEZhaWxlZFRlc3Qoe2F0dGVtcHRDb25zb2xlT3V0cHV0cywgZGVzY3JpcHRpb25zLCBlcnJvciwgbGVmdFBhZGRpbmcsIHRlc3RBcmdzLCB0ZXN0RGF0YSwgdGVzdERlc2NyaXB0aW9ufSkge1xuICAgIGNvbnN0IHRlc3RSdW5uZXIgPSB0aGlzLnRlc3RSdW5uZXJcbiAgICBjb25zdCBjb25zb2xlT3V0cHV0ID0gdGVzdFJ1bm5lci5idWlsZENvbnNvbGVPdXRwdXQoYXR0ZW1wdENvbnNvbGVPdXRwdXRzKVxuXG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IocGljb2NvbG9ycy5yZWQoYCR7bGVmdFBhZGRpbmd9ICBUZXN0IGZhaWxlZDogJHtlcnJvci5tZXNzYWdlfWApKVxuICAgICAgYWRkVHJhY2tlZFN0YWNrVG9FcnJvcihlcnJvcilcblxuICAgICAgY29uc3QgYmFja3RyYWNlQ2xlYW5lciA9IG5ldyBCYWNrdHJhY2VDbGVhbmVyKGVycm9yKVxuICAgICAgY29uc3QgY2xlYW5lZFN0YWNrID0gYmFja3RyYWNlQ2xlYW5lci5nZXRDbGVhbmVkU3RhY2soKVxuICAgICAgY29uc3Qgc3RhY2tMaW5lcyA9IGNsZWFuZWRTdGFjaz8uc3BsaXQoXCJcXG5cIilcblxuICAgICAgaWYgKHN0YWNrTGluZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBzdGFja0xpbmUgb2Ygc3RhY2tMaW5lcykgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gICR7c3RhY2tMaW5lfWApKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGAke2xlZnRQYWRkaW5nfSAgVGVzdCBmYWlsZWQgd2l0aCBhICR7dHlwZW9mIGVycm9yfTogJHtTdHJpbmcoZXJyb3IpfWApKVxuICAgIH1cblxuICAgIHRlc3RSdW5uZXIucHJpbnRGYWlsZWRDb25zb2xlT3V0cHV0KHtjb25zb2xlT3V0cHV0LCBsZWZ0UGFkZGluZ30pXG4gICAgdGVzdFJ1bm5lci5yZWNvcmRGYWlsZWRUZXN0KHtkZXNjcmlwdGlvbnMsIGVycm9yLCBjb25zb2xlT3V0cHV0LCB0ZXN0RGF0YSwgdGVzdERlc2NyaXB0aW9ufSlcblxuICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdEZhaWxlZFwiLCB7XG4gICAgICBjb25maWd1cmF0aW9uOiB0ZXN0UnVubmVyLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgIGRlc2NyaXB0aW9ucyxcbiAgICAgIGVycm9yLFxuICAgICAgdGVzdEFyZ3MsXG4gICAgICB0ZXN0RGF0YSxcbiAgICAgIHRlc3REZXNjcmlwdGlvbixcbiAgICAgIHRlc3RSdW5uZXJcbiAgICB9KVxuXG4gICAgdGVzdFJ1bm5lci5wcmludFJlcnVuQ29tbWFuZCh7ZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24sIHRlc3REYXRhLCBsZWZ0UGFkZGluZ30pXG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgb25lIGxlZ2FjeSBldmVudCBhbmQgYXdhaXRzIGxpc3RlbmVycyBpbiByZWdpc3RyYXRpb24gb3JkZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgLSBFdmVudCBuYW1lLlxuICAgKiBAcGFyYW0ge29iamVjdH0gcGF5bG9hZCAtIEV2ZW50IHBheWxvYWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gYWxsIGxpc3RlbmVycyBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGVtaXRFdmVudChldmVudE5hbWUsIHBheWxvYWQpIHtcbiAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIHRlc3RFdmVudHMubGlzdGVuZXJzKGV2ZW50TmFtZSkpIGF3YWl0IGxpc3RlbmVyKHBheWxvYWQpXG4gIH1cbn1cbiJdfQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"velocious-suite-hook-executor.d.ts","sourceRoot":"","sources":["../../../src/testing/velocious-suite-hook-executor.js"],"names":[],"mappings":"AAIA,MAAM,CAAC,OAAO,OAAO,0BAA0B;IAQtC,UAAU;IAPjB;;;;OAIG;IACH,YAAY,EAAC,UAAU,EAAE,GAAG,QAAQ,EAAC,EAFlC;QAAiD,UAAU,EAAnD,OAAO,kBAAkB,EAAE,OAAO,CAC5C;KACoC,EAGpC;IAED;;;;;OAKG;IACG,OAAO,CAAC,EAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,QAAQ,EAAC,EAHlF,OAAO,2BAA2B,EAAE,sBAG8C,GAFhF,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"velocious-suite-hook-executor.d.ts","sourceRoot":"","sources":["../../../src/testing/velocious-suite-hook-executor.js"],"names":[],"mappings":"AAIA,MAAM,CAAC,OAAO,OAAO,0BAA0B;IAQtC,UAAU;IAPjB;;;;OAIG;IACH,YAAY,EAAC,UAAU,EAAE,GAAG,QAAQ,EAAC,EAFlC;QAAiD,UAAU,EAAnD,OAAO,kBAAkB,EAAE,OAAO,CAC5C;KACoC,EAGpC;IAED;;;;;OAKG;IACG,OAAO,CAAC,EAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,QAAQ,EAAC,EAHlF,OAAO,2BAA2B,EAAE,sBAG8C,GAFhF,OAAO,CAAC,IAAI,CAAC,CAyBzB;CACF"}
|
|
@@ -22,12 +22,15 @@ export default class VelociousSuiteHookExecutor {
|
|
|
22
22
|
void fullName;
|
|
23
23
|
void timeoutMs;
|
|
24
24
|
const metadata = this.testRunner.hookMetadata(hook);
|
|
25
|
+
const filePath = metadata.ownerFilePath && this.testRunner.getTestFiles().includes(metadata.ownerFilePath)
|
|
26
|
+
? metadata.ownerFilePath
|
|
27
|
+
: undefined;
|
|
25
28
|
try {
|
|
26
29
|
await this.testRunner.runProfileSpan({
|
|
27
30
|
phase,
|
|
28
31
|
declarationIndex: metadata.declarationIndex,
|
|
29
32
|
declarationScopeId: metadata.declarationScopeId,
|
|
30
|
-
filePath
|
|
33
|
+
filePath
|
|
31
34
|
}, async () => {
|
|
32
35
|
await defaultExecute([{ configuration: this.testRunner.getConfiguration() }]);
|
|
33
36
|
});
|
|
@@ -38,4 +41,4 @@ export default class VelociousSuiteHookExecutor {
|
|
|
38
41
|
}
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
44
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVsb2Npb3VzLXN1aXRlLWhvb2stZXhlY3V0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy92ZWxvY2lvdXMtc3VpdGUtaG9vay1leGVjdXRvci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxhQUFhLE1BQU0sNkJBQTZCLENBQUE7QUFFdkQsTUFBTSxDQUFDLE9BQU8sT0FBTywwQkFBMEI7SUFDN0M7Ozs7T0FJRztJQUNILFlBQVksRUFBQyxVQUFVLEVBQUUsR0FBRyxRQUFRLEVBQUM7UUFDbkMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFBO0lBQzlCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBQyxPQUFPLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsR0FBRyxRQUFRLEVBQUM7UUFDM0YsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBQ3ZCLEtBQUssT0FBTyxDQUFBO1FBQ1osS0FBSyxRQUFRLENBQUE7UUFDYixLQUFLLFNBQVMsQ0FBQTtRQUNkLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ25ELE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQztZQUN4RyxDQUFDLENBQUMsUUFBUSxDQUFDLGFBQWE7WUFDeEIsQ0FBQyxDQUFDLFNBQVMsQ0FBQTtRQUViLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUM7Z0JBQ25DLEtBQUs7Z0JBQ0wsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDLGdCQUFnQjtnQkFDM0Msa0JBQWtCLEVBQUUsUUFBUSxDQUFDLGtCQUFrQjtnQkFDL0MsUUFBUTthQUNULEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQ1osTUFBTSxjQUFjLENBQUMsQ0FBQyxFQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLGdCQUFnQixFQUFFLEVBQUMsQ0FBQyxDQUFDLENBQUE7WUFDN0UsQ0FBQyxDQUFDLENBQUE7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksQ0FBQyxVQUFVLENBQUMsc0JBQXNCLENBQUMsRUFBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUE7WUFDN0QsTUFBTSxLQUFLLENBQUE7UUFDYixDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCByZXN0QXJnc0Vycm9yIGZyb20gXCIuLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNTdWl0ZUhvb2tFeGVjdXRvciB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGV4ZWN1dG9yIGZvciBWZWxvY2lvdXMgc3VpdGUgaG9va3MuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQ29uc3RydWN0b3IgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuZGVmYXVsdH0gYXJncy50ZXN0UnVubmVyIC0gT3duaW5nIFZlbG9jaW91cyBydW5uZXIuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7dGVzdFJ1bm5lciwgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcbiAgICB0aGlzLnRlc3RSdW5uZXIgPSB0ZXN0UnVubmVyXG4gIH1cblxuICAvKipcbiAgICogU3VwcGxpZXMgdGhlIGZyYW1ld29yayBjb25maWd1cmF0aW9uIHdoaWxlIHBhY2thZ2UgdHJhdmVyc2FsIG93bnMgb3JkZXJpbmcsXG4gICAqIHRpbWVvdXQgZW5mb3JjZW1lbnQsIGFnZ3JlZ2F0aW9uLCBhbmQgYWN0aXZlLXNjb3BlIGNsZWFudXAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiKS5TdWl0ZUhvb2tFeGVjdXRvcklucHV0fSBpbnB1dCAtIFBhY2thZ2UgaG9vayBpbnB1dC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgdGhlIGhvb2sgY29tcGxldGVzLlxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZSh7Y29udGV4dCwgZGVmYXVsdEV4ZWN1dGUsIGZ1bGxOYW1lLCBob29rLCBwaGFzZSwgc3VpdGUsIHRpbWVvdXRNcywgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcbiAgICB2b2lkIGNvbnRleHRcbiAgICB2b2lkIGZ1bGxOYW1lXG4gICAgdm9pZCB0aW1lb3V0TXNcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMudGVzdFJ1bm5lci5ob29rTWV0YWRhdGEoaG9vaylcbiAgICBjb25zdCBmaWxlUGF0aCA9IG1ldGFkYXRhLm93bmVyRmlsZVBhdGggJiYgdGhpcy50ZXN0UnVubmVyLmdldFRlc3RGaWxlcygpLmluY2x1ZGVzKG1ldGFkYXRhLm93bmVyRmlsZVBhdGgpXG4gICAgICA/IG1ldGFkYXRhLm93bmVyRmlsZVBhdGhcbiAgICAgIDogdW5kZWZpbmVkXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy50ZXN0UnVubmVyLnJ1blByb2ZpbGVTcGFuKHtcbiAgICAgICAgcGhhc2UsXG4gICAgICAgIGRlY2xhcmF0aW9uSW5kZXg6IG1ldGFkYXRhLmRlY2xhcmF0aW9uSW5kZXgsXG4gICAgICAgIGRlY2xhcmF0aW9uU2NvcGVJZDogbWV0YWRhdGEuZGVjbGFyYXRpb25TY29wZUlkLFxuICAgICAgICBmaWxlUGF0aFxuICAgICAgfSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBkZWZhdWx0RXhlY3V0ZShbe2NvbmZpZ3VyYXRpb246IHRoaXMudGVzdFJ1bm5lci5nZXRDb25maWd1cmF0aW9uKCl9XSlcbiAgICAgIH0pXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMudGVzdFJ1bm5lci5yZWNvcmRTdWl0ZUhvb2tGYWlsdXJlKHtzdWl0ZSwgcGhhc2UsIGVycm9yfSlcbiAgICAgIHRocm93IGVycm9yXG4gICAgfVxuICB9XG59XG4iXX0=
|
|
@@ -163,6 +163,12 @@ export function createSharedTransactionProxyDriver(DriverClass, config, configur
|
|
|
163
163
|
* @returns {Promise<import("../database/drivers/base.js").QueryResultType>} - Rows.
|
|
164
164
|
*/
|
|
165
165
|
async _queryActual(sql) { return await this.sharedTransactionClient.call("_queryActual", [sql]) }
|
|
166
|
+
/**
|
|
167
|
+
* Keeps MS-SQL session-owned advisory locks on the parent broker session.
|
|
168
|
+
* @param {string} sql - Advisory-lock SQL statement.
|
|
169
|
+
* @returns {Promise<import("../database/drivers/base.js").QueryResultType>} - Result rows.
|
|
170
|
+
*/
|
|
171
|
+
async _advisoryLockQuery(sql) { return await this.sharedTransactionClient.call("_queryActual", [sql]) }
|
|
166
172
|
/**
|
|
167
173
|
* Routes an affected-row query.
|
|
168
174
|
* @param {string} sql - SQL statement.
|
|
@@ -1484,13 +1484,15 @@ export default class TestRunner {
|
|
|
1484
1484
|
recordSuiteHookFailure(failure) { this._suiteHookFailures.push(failure) }
|
|
1485
1485
|
|
|
1486
1486
|
/**
|
|
1487
|
-
* Gets the raw ancestor setup failure for a package test.
|
|
1487
|
+
* Gets the raw ancestor setup failure outcome for a package test.
|
|
1488
1488
|
* @param {PackageTestDeclaration} test - Package test declaration.
|
|
1489
|
-
* @returns {ReturnType<typeof JSON.parse>} - Raw setup failure.
|
|
1489
|
+
* @returns {{failed: false} | {failed: true, error: ReturnType<typeof JSON.parse>}} - Raw setup failure outcome.
|
|
1490
1490
|
*/
|
|
1491
|
-
|
|
1491
|
+
setupFailureOutcomeFor(test) {
|
|
1492
1492
|
const suites = this.testMetadata(test).suites
|
|
1493
|
-
|
|
1493
|
+
const failure = this._suiteHookFailures.find((entry) => entry.phase === "beforeAll" && suites.includes(entry.suite))
|
|
1494
|
+
|
|
1495
|
+
return failure ? {failed: true, error: failure.error} : {failed: false}
|
|
1494
1496
|
}
|
|
1495
1497
|
|
|
1496
1498
|
/**
|
|
@@ -7,6 +7,23 @@ import restArgsError from "../utils/rest-args-error.js"
|
|
|
7
7
|
import { testEvents } from "./test.js"
|
|
8
8
|
|
|
9
9
|
/** @typedef {import("@velocious/testing/runner").TestDeclaration} PackageTestDeclaration */
|
|
10
|
+
/** @typedef {import("@velocious/testing/runner").TestErrorRecord} PackageTestErrorRecord */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Restores the Error shape serialized by the package runner.
|
|
14
|
+
* @param {PackageTestErrorRecord} errorRecord - Serialized package failure.
|
|
15
|
+
* @returns {Error} - Error compatible with Velocious's legacy reporter contract.
|
|
16
|
+
*/
|
|
17
|
+
function errorFromPackageRecord(errorRecord) {
|
|
18
|
+
const error = errorRecord.errors
|
|
19
|
+
? new AggregateError(errorRecord.errors.map(errorFromPackageRecord), errorRecord.message)
|
|
20
|
+
: new Error(errorRecord.message)
|
|
21
|
+
|
|
22
|
+
error.name = errorRecord.name
|
|
23
|
+
if (errorRecord.stack) error.stack = errorRecord.stack
|
|
24
|
+
|
|
25
|
+
return error
|
|
26
|
+
}
|
|
10
27
|
|
|
11
28
|
/** Stops package traversal after framework-owned connection quarantine. */
|
|
12
29
|
export class AbortRemainingTestsError extends Error {}
|
|
@@ -186,9 +203,14 @@ export default class VelociousRunnerReporter {
|
|
|
186
203
|
const outcome = finalAttempt
|
|
187
204
|
? this.testRunner.attemptOutcome(test, finalAttempt.attemptNumber)
|
|
188
205
|
: undefined
|
|
206
|
+
const setupFailure = this.testRunner.setupFailureOutcomeFor(test)
|
|
189
207
|
const error = outcome?.failed
|
|
190
208
|
? outcome.error
|
|
191
|
-
:
|
|
209
|
+
: setupFailure.failed
|
|
210
|
+
? setupFailure.error
|
|
211
|
+
: packageTestResult.error
|
|
212
|
+
? errorFromPackageRecord(packageTestResult.error)
|
|
213
|
+
: undefined
|
|
192
214
|
|
|
193
215
|
await this.reportFailedTest({
|
|
194
216
|
attemptConsoleOutputs: this.attemptConsoleOutputs.get(test) || [],
|
|
@@ -25,13 +25,16 @@ export default class VelociousSuiteHookExecutor {
|
|
|
25
25
|
void fullName
|
|
26
26
|
void timeoutMs
|
|
27
27
|
const metadata = this.testRunner.hookMetadata(hook)
|
|
28
|
+
const filePath = metadata.ownerFilePath && this.testRunner.getTestFiles().includes(metadata.ownerFilePath)
|
|
29
|
+
? metadata.ownerFilePath
|
|
30
|
+
: undefined
|
|
28
31
|
|
|
29
32
|
try {
|
|
30
33
|
await this.testRunner.runProfileSpan({
|
|
31
34
|
phase,
|
|
32
35
|
declarationIndex: metadata.declarationIndex,
|
|
33
36
|
declarationScopeId: metadata.declarationScopeId,
|
|
34
|
-
filePath
|
|
37
|
+
filePath
|
|
35
38
|
}, async () => {
|
|
36
39
|
await defaultExecute([{configuration: this.testRunner.getConfiguration()}])
|
|
37
40
|
})
|
package/package.json
CHANGED
|
@@ -45,13 +45,14 @@ export default class DbBaseCommand extends BaseCommand {
|
|
|
45
45
|
* Runs query or collect sqls.
|
|
46
46
|
* @param {string[]} sqls - SQL statements.
|
|
47
47
|
* @param {(sql: string) => object} resultEntryForSql - Test result entry builder.
|
|
48
|
+
* @param {import("../../../database/drivers/base.js").QueryOptions} [options] - Query options.
|
|
48
49
|
* @returns {Promise<void>} - Resolves when SQLs have been collected or executed.
|
|
49
50
|
*/
|
|
50
|
-
async queryOrCollectSqls(sqls, resultEntryForSql) {
|
|
51
|
+
async queryOrCollectSqls(sqls, resultEntryForSql, options = {}) {
|
|
51
52
|
if (this.args.testing) {
|
|
52
53
|
this.collectSqlResults(sqls, resultEntryForSql)
|
|
53
54
|
} else {
|
|
54
|
-
await this.querySqls(sqls)
|
|
55
|
+
await this.querySqls(sqls, options)
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
|
|
@@ -72,11 +73,12 @@ export default class DbBaseCommand extends BaseCommand {
|
|
|
72
73
|
/**
|
|
73
74
|
* Runs query sqls.
|
|
74
75
|
* @param {string[]} sqls - SQL statements.
|
|
76
|
+
* @param {import("../../../database/drivers/base.js").QueryOptions} [options] - Query options.
|
|
75
77
|
* @returns {Promise<void>} - Resolves when complete.
|
|
76
78
|
*/
|
|
77
|
-
async querySqls(sqls) {
|
|
79
|
+
async querySqls(sqls, options = {}) {
|
|
78
80
|
for (const sql of sqls) {
|
|
79
|
-
await this.getDatabaseConnection().query(sql)
|
|
81
|
+
await this.getDatabaseConnection().query(sql, options)
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
}
|
|
@@ -46,7 +46,7 @@ export default class DbCreate extends DbBaseCommand{
|
|
|
46
46
|
const databaseName = digg(databaseConfiguration, "database")
|
|
47
47
|
const {databaseCharset, databaseCollation} = databaseConfiguration
|
|
48
48
|
const sqls = this.getDatabaseConnection().createDatabaseSql(databaseName, {ifNotExists: true, databaseCharset, databaseCollation})
|
|
49
|
-
await this.queryOrCollectSqls(sqls, (sql) => ({databaseName, sql}))
|
|
49
|
+
await this.queryOrCollectSqls(sqls, (sql) => ({databaseName, sql}), {requestTimeoutMs: 0})
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
/**
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
* @property {string} [logName] - Query log subject.
|
|
65
65
|
* @property {boolean} [logQuery] - Whether to log the query.
|
|
66
66
|
* @property {boolean} [processListComment] - Whether to add process-list comments to the query.
|
|
67
|
+
* @property {number} [requestTimeoutMs] - Per-request driver timeout in milliseconds; zero disables the deadline on supporting drivers.
|
|
67
68
|
* @property {boolean} [retry] - Whether retryable errors may retry the query; defaults to true.
|
|
68
69
|
* @property {boolean} [sessionTimeZone] - Whether to ensure the configured database session time zone before the query.
|
|
69
70
|
* @property {boolean} [sqliteScript] - Internal SQLite flag selecting native multi-statement script execution.
|
|
@@ -320,9 +320,10 @@ export default class VelociousDatabaseDriversMssql extends Base{
|
|
|
320
320
|
/**
|
|
321
321
|
* Runs query actual.
|
|
322
322
|
* @param {string} sql - SQL string.
|
|
323
|
+
* @param {import("../base.js").QueryOptions} [options] - Query options.
|
|
323
324
|
* @returns {Promise<import("../base.js").QueryResultType>} - Resolves with the query actual.
|
|
324
325
|
*/
|
|
325
|
-
async _queryActual(sql) {
|
|
326
|
+
async _queryActual(sql, options = {}) {
|
|
326
327
|
let result
|
|
327
328
|
let tries = 0
|
|
328
329
|
|
|
@@ -330,9 +331,16 @@ export default class VelociousDatabaseDriversMssql extends Base{
|
|
|
330
331
|
tries++
|
|
331
332
|
|
|
332
333
|
try {
|
|
333
|
-
const
|
|
334
|
-
?
|
|
335
|
-
:
|
|
334
|
+
const requestOptions = options.requestTimeoutMs === undefined
|
|
335
|
+
? undefined
|
|
336
|
+
: {requestTimeout: options.requestTimeoutMs}
|
|
337
|
+
// node-mssql supports request-local overrides, but its DefinitelyTyped
|
|
338
|
+
// constructor declaration still exposes only the legacy first argument.
|
|
339
|
+
const request = requestOptions
|
|
340
|
+
? Reflect.construct(mssql.Request, [this._currentTransaction || this.connection, requestOptions])
|
|
341
|
+
: this._currentTransaction
|
|
342
|
+
? new mssql.Request(this._currentTransaction)
|
|
343
|
+
: new mssql.Request(this.connection)
|
|
336
344
|
result = await request.query(sql)
|
|
337
345
|
break
|
|
338
346
|
} catch (error) {
|
|
@@ -992,11 +992,18 @@ export default class VelociousDatabaseQueryModelClassQuery extends DatabaseQuery
|
|
|
992
992
|
async load() {
|
|
993
993
|
const models = []
|
|
994
994
|
const results = await this.results()
|
|
995
|
+
const selectedAttributeAliases = new Set()
|
|
996
|
+
|
|
997
|
+
for (const select of this.getSelects()) {
|
|
998
|
+
const alias = select.getAlias(this.driver)
|
|
999
|
+
|
|
1000
|
+
if (alias) selectedAttributeAliases.add(alias)
|
|
1001
|
+
}
|
|
995
1002
|
|
|
996
1003
|
for (const result of results) {
|
|
997
1004
|
const model = this.build()
|
|
998
1005
|
|
|
999
|
-
model.loadExistingRecord(result)
|
|
1006
|
+
model.loadExistingRecord(result, selectedAttributeAliases)
|
|
1000
1007
|
models.push(model)
|
|
1001
1008
|
}
|
|
1002
1009
|
|
|
@@ -315,12 +315,11 @@ function selectedAliases(query) {
|
|
|
315
315
|
const aliases = []
|
|
316
316
|
|
|
317
317
|
for (const select of query.getSelects().slice(1)) {
|
|
318
|
-
const
|
|
319
|
-
const match = sql.match(/\sAS\s+([^\s]+)\s*$/iu)
|
|
318
|
+
const alias = select.getAlias(query.driver)
|
|
320
319
|
|
|
321
|
-
if (!
|
|
320
|
+
if (!alias) return null
|
|
322
321
|
|
|
323
|
-
aliases.push(
|
|
322
|
+
aliases.push(alias)
|
|
324
323
|
}
|
|
325
324
|
|
|
326
325
|
return aliases
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
export default class VelociousDatabaseQuerySelectBase {
|
|
4
|
+
/**
|
|
5
|
+
* Returns the explicit result alias carried by this select.
|
|
6
|
+
* @param {{getType: () => string}} _driver - Driver that determines returned identifier spelling.
|
|
7
|
+
* @returns {string | undefined} - Selected result alias, or undefined when the select has none.
|
|
8
|
+
*/
|
|
9
|
+
getAlias(_driver) {
|
|
10
|
+
return undefined
|
|
11
|
+
}
|
|
12
|
+
|
|
4
13
|
/**
|
|
5
14
|
* Runs get options.
|
|
6
15
|
* @returns {import("../query-parser/options.js").default} - The options options.
|
|
@@ -10,6 +10,30 @@ export default class VelociousDatabaseQuerySelectPlain extends SelectBase {
|
|
|
10
10
|
constructor(plain) {
|
|
11
11
|
super()
|
|
12
12
|
this.plain = plain
|
|
13
|
+
|
|
14
|
+
const aliasMatch = plain.match(/\sAS\s+([^\s]+)\s*$/iu)
|
|
15
|
+
const aliasSql = aliasMatch ? aliasMatch[1] : undefined
|
|
16
|
+
|
|
17
|
+
this.alias = aliasSql
|
|
18
|
+
? aliasSql.replace(/^["[`]|["`\]]$/gu, "")
|
|
19
|
+
: undefined
|
|
20
|
+
this.aliasQuoted = Boolean(aliasSql && (
|
|
21
|
+
(aliasSql.startsWith('"') && aliasSql.endsWith('"'))
|
|
22
|
+
|| (aliasSql.startsWith("`") && aliasSql.endsWith("`"))
|
|
23
|
+
|| (aliasSql.startsWith("[") && aliasSql.endsWith("]"))
|
|
24
|
+
))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Returns the explicit terminal AS alias parsed at the raw-select boundary.
|
|
29
|
+
* @param {{getType: () => string}} driver - Driver that determines returned identifier spelling.
|
|
30
|
+
* @returns {string | undefined} - Driver-returned terminal AS alias, or undefined when absent.
|
|
31
|
+
*/
|
|
32
|
+
getAlias(driver) {
|
|
33
|
+
if (!this.alias) return undefined
|
|
34
|
+
if (!this.aliasQuoted && driver.getType() == "pgsql") return this.alias.toLowerCase()
|
|
35
|
+
|
|
36
|
+
return this.alias
|
|
13
37
|
}
|
|
14
38
|
|
|
15
39
|
toSql() {
|
|
@@ -345,7 +345,7 @@ export default class VelociousDatabaseQueryWhereModelClassHash extends WhereBase
|
|
|
345
345
|
if (!columnType) return value
|
|
346
346
|
|
|
347
347
|
const normalizedType = columnType.toLowerCase()
|
|
348
|
-
const stringTypes = new Set(["char", "varchar", "nvarchar", "string", "enum", "json", "jsonb", "citext", "binary", "varbinary"])
|
|
348
|
+
const stringTypes = new Set(["char", "varchar", "nvarchar", "string", "enum", "json", "jsonb", "citext", "binary", "varbinary", "character varying"])
|
|
349
349
|
const isUuidType = normalizedType.includes("uuid")
|
|
350
350
|
const shouldCoerceToString = normalizedType.includes("uuid") ||
|
|
351
351
|
normalizedType.includes("text") ||
|
|
@@ -516,6 +516,11 @@ class VelociousDatabaseRecord {
|
|
|
516
516
|
* @type {Record<string, ReturnType<typeof JSON.parse>>} */
|
|
517
517
|
_attributes = {}
|
|
518
518
|
|
|
519
|
+
/**
|
|
520
|
+
* Unmapped result aliases explicitly selected by the query that hydrated this record.
|
|
521
|
+
* @type {Set<string>} */
|
|
522
|
+
_selectedAttributeAliases = new Set()
|
|
523
|
+
|
|
519
524
|
/**
|
|
520
525
|
* Changes.
|
|
521
526
|
* @type {Record<string, ReturnType<typeof JSON.parse>>} */
|
|
@@ -3809,11 +3814,13 @@ class VelociousDatabaseRecord {
|
|
|
3809
3814
|
|
|
3810
3815
|
/**
|
|
3811
3816
|
* Runs load existing record.
|
|
3812
|
-
* @param {
|
|
3817
|
+
* @param {Record<string, ReturnType<typeof JSON.parse>>} attributes - Column-keyed database values.
|
|
3818
|
+
* @param {Set<string>} [selectedAttributeAliases] - Explicit result aliases selected by the loading query.
|
|
3813
3819
|
* @returns {void} - No return value.
|
|
3814
3820
|
*/
|
|
3815
|
-
loadExistingRecord(attributes) {
|
|
3821
|
+
loadExistingRecord(attributes, selectedAttributeAliases = new Set()) {
|
|
3816
3822
|
this._attributes = attributes
|
|
3823
|
+
this._selectedAttributeAliases = new Set(selectedAttributeAliases)
|
|
3817
3824
|
this._isNewRecord = false
|
|
3818
3825
|
}
|
|
3819
3826
|
|
|
@@ -3843,9 +3850,13 @@ class VelociousDatabaseRecord {
|
|
|
3843
3850
|
const attributes = {}
|
|
3844
3851
|
|
|
3845
3852
|
for (const columnName in data) {
|
|
3846
|
-
|
|
3853
|
+
if (Object.hasOwn(columnNameToAttributeName, columnName)) {
|
|
3854
|
+
const attributeName = columnNameToAttributeName[columnName]
|
|
3847
3855
|
|
|
3848
|
-
|
|
3856
|
+
attributes[attributeName] = this.readAttribute(attributeName)
|
|
3857
|
+
} else if (this._selectedAttributeAliases.has(columnName)) {
|
|
3858
|
+
attributes[columnName] = data[columnName]
|
|
3859
|
+
}
|
|
3849
3860
|
}
|
|
3850
3861
|
|
|
3851
3862
|
return attributes
|
|
@@ -4918,7 +4929,7 @@ class VelociousDatabaseRecord {
|
|
|
4918
4929
|
|
|
4919
4930
|
if (!reloadedModel) throw new Error(`${this.constructor.name}#${id} couldn't be reloaded - record didn't exist`)
|
|
4920
4931
|
|
|
4921
|
-
this.
|
|
4932
|
+
this.loadExistingRecord(reloadedModel.rawAttributes(), reloadedModel._selectedAttributeAliases)
|
|
4922
4933
|
this._changes = {}
|
|
4923
4934
|
this._assignedAttributeNames = undefined
|
|
4924
4935
|
}
|
|
@@ -163,6 +163,12 @@ export function createSharedTransactionProxyDriver(DriverClass, config, configur
|
|
|
163
163
|
* @returns {Promise<import("../database/drivers/base.js").QueryResultType>} - Rows.
|
|
164
164
|
*/
|
|
165
165
|
async _queryActual(sql) { return await this.sharedTransactionClient.call("_queryActual", [sql]) }
|
|
166
|
+
/**
|
|
167
|
+
* Keeps MS-SQL session-owned advisory locks on the parent broker session.
|
|
168
|
+
* @param {string} sql - Advisory-lock SQL statement.
|
|
169
|
+
* @returns {Promise<import("../database/drivers/base.js").QueryResultType>} - Result rows.
|
|
170
|
+
*/
|
|
171
|
+
async _advisoryLockQuery(sql) { return await this.sharedTransactionClient.call("_queryActual", [sql]) }
|
|
166
172
|
/**
|
|
167
173
|
* Routes an affected-row query.
|
|
168
174
|
* @param {string} sql - SQL statement.
|
|
@@ -1484,13 +1484,15 @@ export default class TestRunner {
|
|
|
1484
1484
|
recordSuiteHookFailure(failure) { this._suiteHookFailures.push(failure) }
|
|
1485
1485
|
|
|
1486
1486
|
/**
|
|
1487
|
-
* Gets the raw ancestor setup failure for a package test.
|
|
1487
|
+
* Gets the raw ancestor setup failure outcome for a package test.
|
|
1488
1488
|
* @param {PackageTestDeclaration} test - Package test declaration.
|
|
1489
|
-
* @returns {ReturnType<typeof JSON.parse>} - Raw setup failure.
|
|
1489
|
+
* @returns {{failed: false} | {failed: true, error: ReturnType<typeof JSON.parse>}} - Raw setup failure outcome.
|
|
1490
1490
|
*/
|
|
1491
|
-
|
|
1491
|
+
setupFailureOutcomeFor(test) {
|
|
1492
1492
|
const suites = this.testMetadata(test).suites
|
|
1493
|
-
|
|
1493
|
+
const failure = this._suiteHookFailures.find((entry) => entry.phase === "beforeAll" && suites.includes(entry.suite))
|
|
1494
|
+
|
|
1495
|
+
return failure ? {failed: true, error: failure.error} : {failed: false}
|
|
1494
1496
|
}
|
|
1495
1497
|
|
|
1496
1498
|
/**
|