Innovenergy_trunk/frontend/node_modules/testcafe/lib/compiler/test-file/test-file-parser-base.js

232 lines
31 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestFileParserBase = exports.Test = exports.Fixture = void 0;
const promisified_functions_1 = require("../../utils/promisified-functions");
const util_1 = require("util");
const runtime_1 = require("../../errors/runtime");
const types_1 = require("../../errors/types");
const METHODS_SPECIFYING_NAME = ['only', 'skip'];
const COMPUTED_NAME_TEXT_TMP = '<computed name>(line: %s)';
const SKIP_PROPERTY_NAME = 'skip';
function getLoc(loc) {
// NOTE: Don't modify the Babel's parser data structure
const locCopy = Object.assign({}, loc);
// NOTE: 'fileName' and 'identifierName' fields with 'undefined' values added in the SourceLocation class constructor.
// https://github.com/babel/babel/blob/d51aa6d76177b544590cdfe3868f9f4d33d8813d/packages/babel-parser/src/util/location.js#L22
// Since this is useless information, we remove it.
delete locCopy.filename;
delete locCopy.identifierName;
delete locCopy.start.index;
delete locCopy.end.index;
return locCopy;
}
class Fixture {
constructor(name, start, end, loc, meta, isSkipped) {
this.name = name;
this.loc = getLoc(loc);
this.start = start;
this.end = end;
this.meta = meta;
this.tests = [];
this.isSkipped = !!isSkipped;
}
}
exports.Fixture = Fixture;
class Test {
constructor(name, start, end, loc, meta, isSkipped) {
this.name = name;
this.loc = getLoc(loc);
this.start = start;
this.end = end;
this.meta = meta;
this.isSkipped = !!isSkipped;
}
}
exports.Test = Test;
class TestFileParserBase {
constructor(tokenType) {
this.tokenType = tokenType;
}
static formatComputedName(line) {
return (0, util_1.format)(COMPUTED_NAME_TEXT_TMP, line);
}
isAsyncFn( /* token */) {
throw new Error('Not implemented');
}
getRValue( /* token */) {
throw new Error('Not implemented');
}
getFunctionBody( /* token */) {
throw new Error('Not implemented');
}
formatFnData( /* name, value, token */) {
throw new Error('Not implemented');
}
analyzeMemberExp( /* token */) {
throw new Error('Not implemented');
}
formatFnArg( /* arg */) {
throw new Error('Not implemented');
}
getFnCall( /* token */) {
throw new Error('Not implemented');
}
getTaggedTemplateExp( /* token */) {
throw new Error('Not implemented');
}
analyzeFnCall( /* token */) {
throw new Error('Not implemented');
}
parse( /* filePath, code */) {
throw new Error('Not implemented');
}
getTokenType( /* token */) {
throw new Error('Not implemented');
}
getCalleeToken( /* token */) {
throw new Error('Not implemented');
}
getMemberFnName() {
throw new Error('Not implemented');
}
getKeyValue() {
throw new Error('Not implemented');
}
getStringValue() {
throw new Error('Not implemented');
}
isApiFn(fn) {
return fn === 'fixture' || fn === 'test';
}
serializeObjExp(token) {
if (this.getTokenType(token) !== this.tokenType.ObjectLiteralExpression)
return {};
return token.properties.reduce((obj, prop) => {
const { key, value } = this.getKeyValue(prop);
if (typeof value !== 'string')
return {};
obj[key] = value;
return obj;
}, {});
}
processMetaArgs(token) {
if (this.getTokenType(token) !== this.tokenType.CallExpression)
return null;
const args = token.arguments;
let meta = {};
if (args.length === 2) {
const value = this.getStringValue(args[1]);
if (typeof value !== 'string')
return {};
meta = { [this.formatFnArg(args[0])]: value };
}
else if (args.length === 1)
meta = this.serializeObjExp(args[0]);
return meta;
}
getMetaInfo(callStack) {
return callStack.reduce((metaCalls, exp) => {
if (this.getTokenType(exp) !== this.tokenType.CallExpression)
return metaCalls;
const callee = this.getCalleeToken(exp);
const calleeType = this.getTokenType(callee);
const isCalleeMemberExp = calleeType === this.tokenType.PropertyAccessExpression;
if (isCalleeMemberExp && this.getMemberFnName(exp) === 'meta')
return [this.processMetaArgs(exp)].concat(metaCalls);
return metaCalls;
}, []);
}
static isSkipped(originalToken, token = originalToken) {
var _a, _b;
const needSkip = ((_a = token === null || token === void 0 ? void 0 : token.property) === null || _a === void 0 ? void 0 : _a.name) === SKIP_PROPERTY_NAME || ((_b = token === null || token === void 0 ? void 0 : token.name) === null || _b === void 0 ? void 0 : _b.text) === SKIP_PROPERTY_NAME;
if (!needSkip) {
token = token.callee || token.tag || token.object || token.expression;
return token ? TestFileParserBase.isSkipped(originalToken, token) : false;
}
return true;
}
checkExpDefineTargetName(type, apiFn) {
//NOTE: fixture('fixtureName').chainFn or test('testName').chainFn
const isDirectCall = type === this.tokenType.Identifier;
//NOTE: fixture.skip('fixtureName'), test.only('testName') etc.
const isMemberCall = type === this.tokenType.PropertyAccessExpression &&
METHODS_SPECIFYING_NAME.indexOf(apiFn) > -1;
//NOTE: fixture.before().after()('fixtureName'), test.before()`testName`.after() etc.
const isTailCall = type === this.tokenType.CallExpression;
return isDirectCall || isMemberCall || isTailCall;
}
analyzeToken(token) {
const tokenType = this.tokenType;
const currTokenType = this.getTokenType(token);
switch (currTokenType) {
case tokenType.ExpressionStatement:
case tokenType.TypeAssertionExpression:
return this.analyzeToken(token.expression);
case tokenType.FunctionDeclaration:
case tokenType.FunctionExpression:
if (this.isAsyncFn(token))
return null;
return this.getFunctionBody(token).map(this.analyzeToken, this);
case tokenType.VariableDeclaration:
case tokenType.VariableStatement: {
const variableValue = this.getRValue(token); // Skip variable declarations like `var foo;`
return variableValue ? this.analyzeToken(variableValue) : null;
}
case tokenType.CallExpression:
case tokenType.PropertyAccessExpression:
case tokenType.TaggedTemplateExpression:
return this.analyzeFnCall(token);
case tokenType.ReturnStatement:
return token.argument ? this.analyzeToken(token.argument) : null;
}
return null;
}
collectTestCafeCalls(astBody) {
let calls = [];
astBody.forEach(token => {
const callExps = this.analyzeToken(token);
if (callExps)
calls = calls.concat(callExps);
});
return calls;
}
analyze(astBody) {
const fixtures = [];
const testCafeAPICalls = this.collectTestCafeCalls(astBody);
testCafeAPICalls.forEach(call => {
if (!call || typeof call.value !== 'string')
return;
if (call.fnName === 'fixture') {
fixtures.push(new Fixture(call.value, call.start, call.end, call.loc, call.meta, call.isSkipped));
return;
}
if (!fixtures.length)
return;
// NOTE: If the fixture is skipped, mark all the tests in the fixture skipped, otherwise, use the current test identifier
const currentFixture = fixtures[fixtures.length - 1];
const testIsSkipped = currentFixture.isSkipped || call.isSkipped;
const test = new Test(call.value, call.start, call.end, call.loc, call.meta, testIsSkipped);
currentFixture.tests.push(test);
});
return fixtures;
}
async readFile(filePath) {
let fileContent = '';
try {
fileContent = await (0, promisified_functions_1.readFile)(filePath, 'utf8');
}
catch (err) {
throw new runtime_1.GeneralError(types_1.RUNTIME_ERRORS.cannotFindSpecifiedTestSource, filePath);
}
return fileContent;
}
async getTestList(filePath) {
const fileContent = await this.readFile(filePath);
return this.parse(fileContent);
}
getTestListFromCode(code) {
return this.parse(code);
}
}
exports.TestFileParserBase = TestFileParserBase;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1maWxlLXBhcnNlci1iYXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBpbGVyL3Rlc3QtZmlsZS90ZXN0LWZpbGUtcGFyc2VyLWJhc2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkVBQTZEO0FBQzdELCtCQUE4QjtBQUM5QixrREFBb0Q7QUFDcEQsOENBQW9EO0FBRXBELE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDakQsTUFBTSxzQkFBc0IsR0FBSSwyQkFBMkIsQ0FBQztBQUM1RCxNQUFNLGtCQUFrQixHQUFRLE1BQU0sQ0FBQztBQUV2QyxTQUFTLE1BQU0sQ0FBRSxHQUFHO0lBQ2hCLHVEQUF1RDtJQUN2RCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUV2QyxzSEFBc0g7SUFDdEgsOEhBQThIO0lBQzlILG1EQUFtRDtJQUNuRCxPQUFPLE9BQU8sQ0FBQyxRQUFRLENBQUM7SUFDeEIsT0FBTyxPQUFPLENBQUMsY0FBYyxDQUFDO0lBQzlCLE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7SUFDM0IsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQztJQUV6QixPQUFPLE9BQU8sQ0FBQztBQUNuQixDQUFDO0FBRUQsTUFBYSxPQUFPO0lBQ2hCLFlBQWEsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTO1FBQy9DLElBQUksQ0FBQyxJQUFJLEdBQVEsSUFBSSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxHQUFHLEdBQVMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzdCLElBQUksQ0FBQyxLQUFLLEdBQU8sS0FBSyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxHQUFHLEdBQVMsR0FBRyxDQUFDO1FBQ3JCLElB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SyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQyxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sUUFBUSxDQUFDO0lBQ3BCLENBQUM7SUFFRCxLQUFLLENBQUMsUUFBUSxDQUFFLFFBQVE7UUFDcEIsSUFBSSxXQUFXLEdBQUcsRUFBRSxDQUFDO1FBRXJCLElBQUk7WUFDQSxXQUFXLEdBQUcsTUFBTSxJQUFBLGdDQUFRLEVBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1NBQ2xEO1FBRUQsT0FBTyxHQUFHLEVBQUU7WUFDUixNQUFNLElBQUksc0JBQVksQ0FBQyxzQkFBYyxDQUFDLDZCQUE2QixFQUFFLFFBQVEsQ0FBQyxDQUFDO1NBQ2xGO1FBRUQsT0FBTyxXQUFXLENBQUM7SUFDdkIsQ0FBQztJQUVELEtBQUssQ0FBQyxXQUFXLENBQUUsUUFBUTtRQUN2QixNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFbEQsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRCxtQkFBbUIsQ0FBRSxJQUFJO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1QixDQUFDO0NBQ0o7QUF4UEQsZ0RBd1BDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVhZEZpbGUgfSBmcm9tICcuLi8uLi91dGlscy9wcm9taXNpZmllZC1mdW5jdGlvbnMnO1xuaW1wb3J0IHsgZm9ybWF0IH0gZnJvbSAndXRpbCc7XG5pbXBvcnQgeyBHZW5lcmFsRXJyb3IgfSBmcm9tICcuLi8uLi9lcnJvcnMvcnVudGltZSc7XG5pbXBvcnQgeyBSVU5USU1FX0VSUk9SUyB9IGZyb20gJy4uLy4uL2Vycm9ycy90eXBlcyc7XG5cbmNvbnN0IE1FVEhPRFNfU1BFQ0lGWUlOR19OQU1FID0gWydvbmx5JywgJ3NraXAnXTtcbmNvbnN0IENPTVBVVEVEX05BTUVfVEVYVF9UTVAgID0gJzxjb21wdXRlZCBuYW1lPihsaW5lOiAlcyknO1xuY29uc3QgU0tJUF9QUk9QRVJUWV9OQU1FICAgICAgPSAnc2tpcCc7XG5cbmZ1bmN0aW9uIGdldExvYyAobG9jKSB7XG4gICAgLy8gTk9URTogRG9uJ3QgbW9kaWZ5IHRoZSBCYWJlbCdzIHBhcnNlciBkYXRhIHN0cnVjdHVyZVxuICAgIGNvbnN0IGxvY0NvcHkgPSBPYmplY3QuYXNzaWduKHt9LCBsb2MpO1xuXG4gICAgLy8gTk9URTogJ2ZpbGVOYW1lJyBhbmQgJ2lkZW50aWZpZXJOYW1lJyBmaWVsZHMgd2l0aCAndW5kZWZpbmVkJyB2YWx1ZXMgYWRkZWQgaW4gdGhlIFNvdXJjZUxvY2F0aW9uIGNsYXNzIGNvbnN0cnVjdG9yLlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9iYWJlbC9iYWJlbC9ibG9iL2Q1MWFhNmQ3NjE3N2I1NDQ1OTBjZGZlMzg2OGY5ZjRkMzNkODgxM2QvcGFja2FnZXMvYmFiZWwtcGFyc2VyL3NyYy91dGlsL2xvY2F0aW9uLmpzI0wyMlxuICAgIC8vIFNpbmNlIHRoaXMgaXMgdXNlbGVzcyBpbmZvcm1hdGlvbiwgd2UgcmVtb3ZlIGl0LlxuICAgIGRlbGV0ZSBsb2NDb3B5LmZpbGVuYW1lO1xuICAgIGRlbGV0ZSBsb2NDb3B5LmlkZW50aWZpZXJOYW1lO1xuICAgIGRlbGV0ZSBsb2NDb3B5LnN0YXJ0LmluZGV4O1xuICAgIGRlbGV0ZSBsb2NDb3B5LmVuZC5pbmRleDtcblxuICAgIHJldHVybiBsb2NDb3B5O1xufVxuXG5leHBvcnQgY2xhc3MgRml4dHVyZSB7XG4gICAgY29uc3RydWN0b3IgKG5hbWUsIHN0YXJ0LCBlbmQsIGxvYywgbWV0YSwgaXNTa2lwcGVkKSB7XG4gICAgICAgIHRoaXMubmFtZSAgICAgID0gbmFtZTtcbiAgICAgICAgdGhpcy5sb2MgICAgICAgPSBnZXRMb2MobG9jKTtcbiAgICAgICAgdGhpcy5zdGFydCAgICAgPSBzdGFydDtcbiAgICAgICAgdGhpcy5lbmQgICAgICAgPSBlbmQ7XG4gICAgICAgIHRoaXMubWV0YSAgICAgID0gbWV0YTtcbiAgICAgICAgdGhpcy50ZXN0cyAgICAgPSBbXTtcbiAgICAgICAgdGhpcy5pc1NraXBwZWQgPSAhIWlzU2tpcHBlZDtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBUZXN0IHtcbiAgICBjb25zdHJ1Y3RvciAobmFtZSwgc3RhcnQsIGVuZCwgbG9jLCBtZXRhLCBpc1NraXBwZWQpIHtcbiAgICAgICAgdGhpcy5uYW1lICAgICAgPSBuYW1lO1xuICAgICAgICB0aGlzLmxvYyAgICAgICA9IGdldExvYyhsb2MpO1xuICAgICAgICB0aGlzLnN0YXJ0ICAgICA9IHN0YXJ0O1xuICAgICAgICB0aGlzLmVuZCAgICAgICA9IGVuZDtcbiAgICAgICAgdGhpcy5tZXRhICAgICAgPSBtZXRhO1xuICAgICAgICB0aGlzLmlzU2tpcHBlZCA9ICEhaXNTa2lwcGVkO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFRlc3RGaWxlUGFyc2VyQmFzZSB7XG4gICAgY29uc3RydWN0b3IgKHRva2VuVHlwZSkge1xuICAgICAgICB0aGlzLnRva2VuVHlwZSA9IHRva2VuVHlwZTtcbiAgICB9XG5cbiAgICBzdGF0aWMgZm9ybWF0Q29tcHV0ZWROYW1lIChsaW5lKSB7XG4gICAgICAgIHJldHVybiBmb3JtYXQoQ09NUFVURURfTkFNRV9URVhUX1RNUCwgbGluZSk7XG4gICAgfVxuXG4gICAgaXNBc3luY0ZuICgvKiB0b2tlbiAqLykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIGdldFJWYWx1ZSAoLyogdG9rZW4gKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBnZXRGdW5jdGlvbkJvZHkgKC8qIHRva2VuICovKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgZm9ybWF0Rm5EYXRhICgvKiBuYW1lLCB2YWx1ZSwgdG9rZW4gKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBhbmFseXplTWVtYmVyRXhwICgvKiB0b2tlbiAqLykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIGZvcm1hdEZuQXJnICgvKiBhcmcgKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBnZXRGbkNhbGwgKC8qIHRva2VuICovKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgZ2V0VGFnZ2VkVGVtcGxhdGVFeHAgKC8qIHRva2VuICovKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgYW5hbHl6ZUZuQ2FsbCAoLyogdG9rZW4gKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBwYXJzZSAoLyogZmlsZVBhdGgsIGNvZGUgKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBnZXRUb2tlblR5cGUgKC8qIHRva2VuICovKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgZ2V0Q2FsbGVlVG9rZW4gKC8qIHRva2VuICovKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgZ2V0TWVtYmVyRm5OYW1lICgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBnZXRLZXlWYWx1ZSAoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgZ2V0U3RyaW5nVmFsdWUgKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIGlzQXBpRm4gKGZuKSB7XG4gICAgICAgIHJldHVybiBmbiA9PT0gJ2ZpeHR1cmUnIHx8IGZuID09PSAndGVzdCc7XG4gICAgfVxuXG4gICAgc2VyaWFsaXplT2JqRXhwICh0b2tlbikge1xuICAgICAgICBpZiAodGhpcy5nZXRUb2tlblR5cGUodG9rZW4pICE9PSB0aGlzLnRva2VuVHlwZS5PYmplY3RMaXRlcmFsRXhwcmVzc2lvbilcbiAgICAgICAgICAgIHJldHVybiB7fTtcblxuICAgICAgICByZXR1cm4gdG9rZW4ucHJvcGVydGllcy5yZWR1Y2UoKG9iaiwgcHJvcCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBrZXksIHZhbHVlIH0gPSB0aGlzLmdldEtleVZhbHVlKHByb3ApO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykgcmV0dXJuIHt9O1xuXG4gICAgICAgICAgICBvYmpba2V5XSA9IHZhbHVlO1xuXG4gICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9LCB7fSk7XG4gICAgfVxuXG4gICAgcHJvY2Vzc01ldGFBcmdzICh0b2tlbikge1xuICAgICAgICBpZiAodGhpcy5nZXRUb2tlblR5cGUodG9rZW4pICE9PSB0aGlzLnRva2VuVHlwZS5DYWxsRXhwcmVzc2lvbilcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgIGNvbnN0IGFyZ3MgPSB0b2tlbi5hcmd1bWVudHM7XG5cbiAgICAgICAgbGV0IG1ldGEgPSB7fTtcblxuICAgICAgICBpZiAoYXJncy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXRTdHJpbmdWYWx1ZShhcmdzWzFdKTtcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHJldHVybiB7fTtcblxuICAgICAgICAgICAgbWV0YSA9IHsgW3RoaXMuZm9ybWF0Rm5BcmcoYXJnc1swXSldOiB2YWx1ZSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgZWxzZSBpZiAoYXJncy5sZW5ndGggPT09IDEpXG4gICAgICAgICAgICBtZXRhID0gdGhpcy5zZXJpYWxpemVPYmpFeHAoYXJnc1swXSk7XG5cbiAgICAgICAgcmV0dXJuIG1ldGE7XG4gICAgfVxuXG4gICAgZ2V0TWV0YUluZm8gKGNhbGxTdGFjaykge1xuICAgICAgICByZXR1cm4gY2FsbFN0YWNrLnJlZHVjZSgobWV0YUNhbGxzLCBleHApID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmdldFRva2VuVHlwZShleHApICE9PSB0aGlzLnRva2VuVHlwZS5DYWxsRXhwcmVzc2lvbilcbiAgICAgICAgICAgICAgICByZXR1cm4gbWV0YUNhbGxzO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsZWUgICAgICAgICAgICA9IHRoaXMuZ2V0Q2FsbGVlVG9rZW4oZXhwKTtcbiAgICAgICAgICAgIGNvbnN0IGNhbGxlZVR5cGUgICAgICAgID0gdGhpcy5nZXRUb2tlblR5cGUoY2FsbGVlKTtcbiAgICAgICAgICAgIGNvbnN0IGlzQ2FsbGVlTWVtYmVyRXhwID0gY2FsbGVlVHlwZSA9PT0gdGhpcy50b2tlblR5cGUuUHJvcGVydHlBY2Nlc3NFeHByZXNzaW9uO1xuXG4gICAgICAgICAgICBpZiAoaXNDYWxsZWVNZW1iZXJFeHAgJiYgdGhpcy5nZXRNZW1iZXJGbk5hbWUoZXhwKSA9PT0gJ21ldGEnKVxuICAgICAgICAgICAgICAgIHJldHVybiBbdGhpcy5wcm9jZXNzTWV0YUFyZ3MoZXhwKV0uY29uY2F0KG1ldGFDYWxscyk7XG5cbiAgICAgICAgICAgIHJldHVybiBtZXRhQ2FsbHM7XG4gICAgICAgIH0sIFtdKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgaXNTa2lwcGVkIChvcmlnaW5hbFRva2VuLCB0b2tlbiA9IG9yaWdpbmFsVG9rZW4pIHtcbiAgICAgICAgY29uc3QgbmVlZFNraXAgPSB0b2tlbj8ucHJvcGVydHk/Lm5hbWUgPT09IFNLSVBfUFJPUEVSVFlfTkFNRSB8fCB0b2tlbj8ubmFtZT8udGV4dCA9PT0gU0tJUF9QUk9QRVJUWV9OQU1FO1xuXG4gICAgICAgIGlmICghbmVlZFNraXApIHtcbiAgICAgICAgICAgIHRva2VuID0gdG9rZW4uY2FsbGVlIHx8IHRva2VuLnRhZyB8fCB0b2tlbi5vYmplY3QgfHwgdG9rZW4uZXhwcmVzc2lvbjtcblxuICAgICAgICAgICAgcmV0dXJuIHRva2VuID8gVGVzdEZpbGVQYXJzZXJCYXNlLmlzU2tpcHBlZChvcmlnaW5hbFRva2VuLCB0b2tlbikgOiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNoZWNrRXhwRGVmaW5lVGFyZ2V0TmFtZSAodHlwZSwgYXBpRm4pIHtcbiAgICAgICAgLy9OT1RFOiBmaXh0dXJlKCdmaXh0dXJlTmFtZScpLmNoYWluRm4gb3IgdGVzdCgndGVzdE5hbWUnKS5jaGFpbkZuXG4gICAgICAgIGNvbnN0IGlzRGlyZWN0Q2FsbCA9IHR5cGUgPT09IHRoaXMudG9rZW5UeXBlLklkZW50aWZpZXI7XG5cbiAgICAgICAgLy9OT1RFOiBmaXh0dXJlLnNraXAoJ2ZpeHR1cmVOYW1lJyksIHRlc3Qub25seSgndGVzdE5hbWUnKSBldGMuXG4gICAgICAgIGNvbnN0IGlzTWVtYmVyQ2FsbCA9IHR5cGUgPT09IHRoaXMudG9rZW5UeXBlLlByb3BlcnR5QWNjZXNzRXhwcmVzc2lvbiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNRVRIT0RTX1NQRUNJRllJTkdfTkFNRS5pbmRleE9mKGFwaUZuKSA+IC0xO1xuXG4gICAgICAgIC8vTk9URTogZml4dHVyZS5iZWZvcmUoKS5hZnRlcigpKCdmaXh0dXJlTmFtZScpLCB0ZXN0LmJlZm9yZSgpYHRlc3ROYW1lYC5hZnRlcigpIGV0Yy5cbiAgICAgICAgY29uc3QgaXNUYWlsQ2FsbCA9IHR5cGUgPT09IHRoaXMudG9rZW5UeXBlLkNhbGxFeHByZXNzaW9uO1xuXG4gICAgICAgIHJldHVybiBpc0RpcmVjdENhbGwgfHwgaXNNZW1iZXJDYWxsIHx8IGlzVGFpbENhbGw7XG4gICAgfVxuXG4gICAgYW5hbHl6ZVRva2VuICh0b2tlbikge1xuICAgICAgICBjb25zdCB0b2tlblR5cGUgICAgID0gdGhpcy50b2tlblR5cGU7XG4gICAgICAgIGNvbnN0IGN1cnJUb2tlblR5cGUgPSB0aGlzLmdldFRva2VuVHlwZSh0b2tlbik7XG5cbiAgICAgICAgc3dpdGNoIChjdXJyVG9rZW5UeXBlKSB7XG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5FeHByZXNzaW9uU3RhdGVtZW50OlxuICAgICAgICAgICAgY2FzZSB0b2tlblR5cGUuVHlwZUFzc2VydGlvbkV4cHJlc3Npb246XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYW5hbHl6ZVRva2VuKHRva2VuLmV4cHJlc3Npb24pO1xuXG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5GdW5jdGlvbkRlY2xhcmF0aW9uOlxuICAgICAgICAgICAgY2FzZSB0b2tlblR5cGUuRnVuY3Rpb25FeHByZXNzaW9uOlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzQXN5bmNGbih0b2tlbikpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RnVuY3Rpb25Cb2R5KHRva2VuKS5tYXAodGhpcy5hbmFseXplVG9rZW4sIHRoaXMpO1xuXG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5WYXJpYWJsZURlY2xhcmF0aW9uOlxuICAgICAgICAgICAgY2FzZSB0b2tlblR5cGUuVmFyaWFibGVTdGF0ZW1lbnQ6IHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YXJpYWJsZVZhbHVlID0gdGhpcy5nZXRSVmFsdWUodG9rZW4pOyAvLyBTa2lwIHZhcmlhYmxlIGRlY2xhcmF0aW9ucyBsaWtlIGB2YXIgZm9vO2BcblxuICAgICAgICAgICAgICAgIHJldHVybiB2YXJpYWJsZVZhbHVlID8gdGhpcy5hbmFseXplVG9rZW4odmFyaWFibGVWYWx1ZSkgOiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSB0b2tlblR5cGUuQ2FsbEV4cHJlc3Npb246XG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5Qcm9wZXJ0eUFjY2Vzc0V4cHJlc3Npb246XG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5UYWdnZWRUZW1wbGF0ZUV4cHJlc3Npb246XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYW5hbHl6ZUZuQ2FsbCh0b2tlbik7XG5cbiAgICAgICAgICAgIGNhc2UgdG9rZW5UeXBlLlJldHVyblN0YXRlbWVudDpcbiAgICAgICAgICAgICAgICByZXR1cm4gdG9rZW4uYXJndW1lbnQgPyB0aGlzLmFuYWx5emVUb2tlbih0b2tlbi5hcmd1bWVudCkgOiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29sbGVjdFRlc3RDYWZlQ2FsbHMgKGFzdEJvZHkpIHtcbiAgICAgICAgbGV0IGNhbGxzID0gW107XG5cbiAgICAgICAgYXN0Qm9keS5mb3JFYWNoKHRva2VuID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNhbGxFeHBzID0gdGhpcy5hbmFseXplVG9rZW4odG9rZW4pO1xuXG4gICAgICAgICAgICBpZiAoY2FsbEV4cHMpXG4gICAgICAgICAgICAgICAgY2FsbHMgPSBjYWxscy5jb25jYXQoY2FsbEV4cHMpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gY2FsbHM7XG4gICAgfVxuXG4gICAgYW5hbHl6ZSAoYXN0Qm9keSkge1xuICAgICAgICBjb25zdCBmaXh0dXJlcyAgICAgICAgID0gW107XG4gICAgICAgIGNvbnN0IHRlc3RDYWZlQVBJQ2FsbHMgPSB0aGlzLmNvbGxlY3RUZXN0Q2FmZUNhbGxzKGFzdEJvZHkpO1xuXG4gICAgICAgIHRlc3RDYWZlQVBJQ2FsbHMuZm9yRWFjaChjYWxsID0+IHtcbiAgICAgICAgICAgIGlmICghY2FsbCB8fCB0eXBlb2YgY2FsbC52YWx1ZSAhPT0gJ3N0cmluZycpIHJldHVybjtcblxuICAgICAgICAgICAgaWYgKGNhbGwuZm5OYW1lID09PSAnZml4dHVyZScpIHtcbiAgICAgICAgICAgICAgICBmaXh0dXJlcy5wdXNoKG5ldyBGaXh0dXJlKGNhbGwudmFsdWUsIGNhbGwuc3RhcnQsIGNhbGwuZW5kLCBjYWxsLmxvYywgY2FsbC5tZXRhLCBjYWxsLmlzU2tpcHBlZCkpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWZpeHR1cmVzLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgICAgICAgICAvLyBOT1RFOiBJZiB0aGUgZml4dHVyZSBpcyBza2lwcGVkLCBtYXJrIGFsbCB0aGUgdGVzdHMgaW4gdGhlIGZpeHR1cmUgc2tpcHBlZCwgb3RoZXJ3aXNlLCB1c2UgdGhlIGN1cnJlbnQgdGVzdCBpZGVudGlmaWVyXG4gICAgICAgICAgICBjb25zdCBjdXJyZW50Rml4dHVyZSA9IGZpeHR1cmVzW2ZpeHR1cmVzLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgY29uc3QgdGVzdElzU2tpcHBlZCAgPSBjdXJyZW50Rml4dHVyZS5pc1NraXBwZWQgfHwgY2FsbC5pc1NraXBwZWQ7XG4gICAgICAgICAgICBjb25zdCB0ZXN0ICAgICAgICAgICA9IG5ldyBUZXN0KGNhbGwudmFsdWUsIGNhbGwuc3RhcnQsIGNhbGwuZW5kLCBjYWxsLmxvYywgY2FsbC5tZXRhLCB0ZXN0SXNTa2lwcGVkKTtcblxuICAgICAgICAgICAgY3VycmVudEZpeHR1cmUudGVzdHMucHVzaCh0ZXN0KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIGZpeHR1cmVzO1xuICAgIH1cblxuICAgIGFzeW5jIHJlYWRGaWxlIChmaWxlUGF0aCkge1xuICAgICAgICBsZXQgZmlsZUNvbnRlbnQgPSAnJztcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZmlsZUNvbnRlbnQgPSBhd2FpdCByZWFkRmlsZShmaWxlUGF0aCwgJ3V0ZjgnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBHZW5lcmFsRXJyb3IoUlVOVElNRV9FUlJPUlMuY2Fubm90RmluZFNwZWNpZmllZFRlc3RTb3VyY2UsIGZpbGVQYXRoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmaWxlQ29udGVudDtcbiAgICB9XG5cbiAgICBhc3luYyBnZXRUZXN0TGlzdCAoZmlsZVBhdGgpIHtcbiAgICAgICAgY29uc3QgZmlsZUNvbnRlbnQgPSBhd2FpdCB0aGlzLnJlYWRGaWxlKGZpbGVQYXRoKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5wYXJzZShmaWxlQ29udGVudCk7XG4gICAgfVxuXG4gICAgZ2V0VGVzdExpc3RGcm9tQ29kZSAoY29kZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJzZShjb2RlKTtcbiAgICB9XG59XG4iXX0=