testcafe
Version:
Automated browser testing for the modern web development stack.
168 lines • 25.8 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTestListFromCode = exports.getTestList = exports.EsNextTestFileParser = void 0;
const lodash_1 = require("lodash");
const core_1 = require("@babel/core");
const compiler_1 = __importDefault(require("./compiler"));
const test_file_parser_base_1 = require("../../test-file-parser-base");
const TOKEN_TYPE = {
Identifier: 'Identifier',
PropertyAccessExpression: 'MemberExpression',
CallExpression: 'CallExpression',
TaggedTemplateExpression: 'TaggedTemplateExpression',
TemplateLiteral: 'TemplateLiteral',
StringLiteral: 'StringLiteral',
ArrowFunctionExpression: 'ArrowFunctionExpression',
FunctionExpression: 'FunctionExpression',
ExpressionStatement: 'ExpressionStatement',
ReturnStatement: 'ReturnStatement',
FunctionDeclaration: 'FunctionDeclaration',
VariableStatement: 'VariableStatement',
VariableDeclaration: 'VariableDeclaration',
ObjectLiteralExpression: 'ObjectExpression',
};
class EsNextTestFileParser extends test_file_parser_base_1.TestFileParserBase {
constructor() {
super(TOKEN_TYPE);
}
static getTagStrValue(exp) {
//NOTE: we set <computed name> if template literal has at least one computed substring ${...}
return exp.expressions.length ? EsNextTestFileParser.formatComputedName(exp.loc.start.line) : exp.quasis[0].value.raw;
}
isAsyncFn(token) {
return token.async || token.generator;
}
getTokenType(token) {
return token.type;
}
getRValue(token) {
return token.declarations[0].init;
}
getStringValue(token) {
const stringTypes = [this.tokenType.StringLiteral, this.tokenType.TemplateLiteral, this.tokenType.Identifier];
if (stringTypes.indexOf(token.type) > -1)
return this.formatFnArg(token);
return null;
}
getFunctionBody(token) {
return token.body && token.body.body ? token.body.body : [];
}
getCalleeToken(token) {
return token.callee;
}
getMemberFnName(token) {
return token.callee.property.name;
}
formatFnData(name, value, token, meta = [{}]) {
return {
fnName: name,
value: value,
loc: token.loc,
start: token.start,
end: token.end,
meta: (0, lodash_1.merge)({}, ...meta),
isSkipped: test_file_parser_base_1.TestFileParserBase.isSkipped(token),
};
}
getKeyValue(prop) {
const { key, value } = prop;
return {
key: key.name || this.formatFnArg(key),
value: this.getStringValue(value),
};
}
analyzeMemberExp(token) {
let exp = token;
const tokenType = this.tokenType;
const callStack = [exp];
while (exp.type !== tokenType.Identifier) {
if (exp.type === tokenType.CallExpression)
exp = exp.callee;
else if (exp.type === tokenType.PropertyAccessExpression)
exp = exp.object;
else if (exp.type === tokenType.TaggedTemplateExpression)
exp = exp.tag;
else
return null;
if (exp.type !== tokenType.Identifier)
callStack.push(exp);
}
if (!this.isApiFn(exp.name))
return null;
const meta = this.getMetaInfo(callStack.slice());
let parentExp = callStack.pop();
if (parentExp.type === tokenType.CallExpression)
return this.formatFnData(exp.name, this.formatFnArg(parentExp.arguments[0]), token, meta);
if (parentExp.type === tokenType.TaggedTemplateExpression)
return this.formatFnData(exp.name, EsNextTestFileParser.getTagStrValue(parentExp.quasi), token, meta);
if (parentExp.type === tokenType.PropertyAccessExpression) {
while (parentExp) {
if (parentExp.type === tokenType.CallExpression && parentExp.callee) {
const calleeType = parentExp.callee.type;
const calleeMemberFn = parentExp.callee.property && parentExp.callee.property.name;
if (this.checkExpDefineTargetName(calleeType, calleeMemberFn))
return this.formatFnData(exp.name, this.formatFnArg(parentExp.arguments[0]), token, meta);
}
if (parentExp.type === tokenType.TaggedTemplateExpression && parentExp.tag) {
const tagType = parentExp.tag.type;
const tagMemberFn = parentExp.tag.property && parentExp.tag.property.name;
if (this.checkExpDefineTargetName(tagType, tagMemberFn))
return this.formatFnData(exp.name, EsNextTestFileParser.getTagStrValue(parentExp.quasi), token, meta);
}
parentExp = callStack.pop();
}
}
return null;
}
formatFnArg(arg) {
if (arg.type === this.tokenType.Identifier)
return EsNextTestFileParser.formatComputedName(arg.loc.start.line);
if (arg.type === this.tokenType.TemplateLiteral)
return EsNextTestFileParser.getTagStrValue(arg);
if (arg.type === this.tokenType.StringLiteral)
return arg.value;
return null;
}
getFnCall(token) {
if (!this.isApiFn(token.callee.name))
return null;
return this.formatFnData(token.callee.name, this.formatFnArg(token.arguments[0]), token);
}
getTaggedTemplateExp(token) {
return this.formatFnData(token.tag.name, EsNextTestFileParser.getTagStrValue(token.quasi), token);
}
analyzeFnCall(token) {
const tokenType = this.tokenType;
if (token.type === tokenType.PropertyAccessExpression)
return this.analyzeMemberExp(token);
if (token.type === tokenType.CallExpression) {
const calleeType = token.callee.type;
if (calleeType === tokenType.PropertyAccessExpression || calleeType === tokenType.CallExpression)
return this.analyzeMemberExp(token);
if (calleeType === tokenType.FunctionExpression || calleeType === tokenType.ArrowFunctionExpression)
return this.collectTestCafeCalls(token.callee.body.body);
return this.getFnCall(token);
}
if (token.type === tokenType.TaggedTemplateExpression) {
if (token.tag.type === tokenType.PropertyAccessExpression)
return this.analyzeMemberExp(token);
return this.getTaggedTemplateExp(token);
}
return null;
}
parse(code) {
const compilerOptions = compiler_1.default.getBabelOptions(null, code);
delete compilerOptions.filename;
const opts = (0, lodash_1.assign)(compilerOptions, { ast: true });
const ast = (0, core_1.transform)(code, opts).ast;
return this.analyze(ast.program.body);
}
}
exports.EsNextTestFileParser = EsNextTestFileParser;
const parser = new EsNextTestFileParser();
exports.getTestList = parser.getTestList.bind(parser);
exports.getTestListFromCode = parser.getTestListFromCode.bind(parser);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0LXRlc3QtbGlzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21waWxlci90ZXN0LWZpbGUvZm9ybWF0cy9lcy1uZXh0L2dldC10ZXN0LWxpc3QuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsbUNBQXVDO0FBQ3ZDLHNDQUF3QztBQUN4QywwREFBZ0Q7QUFDaEQsdUVBQWlFO0FBRWpFLE1BQU0sVUFBVSxHQUFHO0lBQ2YsVUFBVSxFQUFnQixZQUFZO0lBQ3RDLHdCQUF3QixFQUFFLGtCQUFrQjtJQUM1QyxjQUFjLEVBQVksZ0JBQWdCO0lBQzFDLHdCQUF3QixFQUFFLDBCQUEwQjtJQUNwRCxlQUFlLEVBQVcsaUJBQWlCO0lBQzNDLGFBQWEsRUFBYSxlQUFlO0lBQ3pDLHVCQUF1QixFQUFHLHlCQUF5QjtJQUNuRCxrQkFBa0IsRUFBUSxvQkFBb0I7SUFDOUMsbUJBQW1CLEVBQU8scUJBQXFCO0lBQy9DLGVBQWUsRUFBVyxpQkFBaUI7SUFDM0MsbUJBQW1CLEVBQU8scUJBQXFCO0lBQy9DLGlCQUFpQixFQUFTLG1CQUFtQjtJQUM3QyxtQkFBbUIsRUFBTyxxQkFBcUI7SUFDL0MsdUJBQXVCLEVBQUcsa0JBQWtCO0NBQy9DLENBQUM7QUFFRixNQUFhLG9CQUFxQixTQUFRLDBDQUFrQjtJQUN4RDtRQUNJLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN0QixDQUFDO0lBRUQsTUFBTSxDQUFDLGNBQWMsQ0FBRSxHQUFHO1FBQ3RCLDZGQUE2RjtRQUM3RixPQUFPLEdBQUcsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDO0lBQzFILENB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eExELG9EQXdMQztBQUVELE1BQU0sTUFBTSxHQUFHLElBQUksb0JBQW9CLEVBQUUsQ0FBQztBQUU3QixRQUFBLFdBQVcsR0FBVyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN0RCxRQUFBLG1CQUFtQixHQUFHLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBhc3NpZ24sIG1lcmdlIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IHRyYW5zZm9ybSB9IGZyb20gJ0BiYWJlbC9jb3JlJztcbmltcG9ydCBFU05leHRUZXN0RmlsZUNvbXBpbGVyIGZyb20gJy4vY29tcGlsZXInO1xuaW1wb3J0IHsgVGVzdEZpbGVQYXJzZXJCYXNlIH0gZnJvbSAnLi4vLi4vdGVzdC1maWxlLXBhcnNlci1iYXNlJztcblxuY29uc3QgVE9LRU5fVFlQRSA9IHtcbiAgICBJZGVudGlmaWVyOiAgICAgICAgICAgICAgICdJZGVudGlmaWVyJyxcbiAgICBQcm9wZXJ0eUFjY2Vzc0V4cHJlc3Npb246ICdNZW1iZXJFeHByZXNzaW9uJyxcbiAgICBDYWxsRXhwcmVzc2lvbjogICAgICAgICAgICdDYWxsRXhwcmVzc2lvbicsXG4gICAgVGFnZ2VkVGVtcGxhdGVFeHByZXNzaW9uOiAnVGFnZ2VkVGVtcGxhdGVFeHByZXNzaW9uJyxcbiAgICBUZW1wbGF0ZUxpdGVyYWw6ICAgICAgICAgICdUZW1wbGF0ZUxpdGVyYWwnLFxuICAgIFN0cmluZ0xpdGVyYWw6ICAgICAgICAgICAgJ1N0cmluZ0xpdGVyYWwnLFxuICAgIEFycm93RnVuY3Rpb25FeHByZXNzaW9uOiAgJ0Fycm93RnVuY3Rpb25FeHByZXNzaW9uJyxcbiAgICBGdW5jdGlvbkV4cHJlc3Npb246ICAgICAgICdGdW5jdGlvbkV4cHJlc3Npb24nLFxuICAgIEV4cHJlc3Npb25TdGF0ZW1lbnQ6ICAgICAgJ0V4cHJlc3Npb25TdGF0ZW1lbnQnLFxuICAgIFJldHVyblN0YXRlbWVudDogICAgICAgICAgJ1JldHVyblN0YXRlbWVudCcsXG4gICAgRnVuY3Rpb25EZWNsYXJhdGlvbjogICAgICAnRnVuY3Rpb25EZWNsYXJhdGlvbicsXG4gICAgVmFyaWFibGVTdGF0ZW1lbnQ6ICAgICAgICAnVmFyaWFibGVTdGF0ZW1lbnQnLFxuICAgIFZhcmlhYmxlRGVjbGFyYXRpb246ICAgICAgJ1ZhcmlhYmxlRGVjbGFyYXRpb24nLFxuICAgIE9iamVjdExpdGVyYWxFeHByZXNzaW9uOiAgJ09iamVjdEV4cHJlc3Npb24nLFxufTtcblxuZXhwb3J0IGNsYXNzIEVzTmV4dFRlc3RGaWxlUGFyc2VyIGV4dGVuZHMgVGVzdEZpbGVQYXJzZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHN1cGVyKFRPS0VOX1RZUEUpO1xuICAgIH1cblxuICAgIHN0YXRpYyBnZXRUYWdTdHJWYWx1ZSAoZXhwKSB7XG4gICAgICAgIC8vTk9URTogd2Ugc2V0IDxjb21wdXRlZCBuYW1lPiBpZiB0ZW1wbGF0ZSBsaXRlcmFsIGhhcyBhdCBsZWFzdCBvbmUgY29tcHV0ZWQgc3Vic3RyaW5nICR7Li4ufVxuICAgICAgICByZXR1cm4gZXhwLmV4cHJlc3Npb25zLmxlbmd0aCA/IEVzTmV4dFRlc3RGaWxlUGFyc2VyLmZvcm1hdENvbXB1dGVkTmFtZShleHAubG9jLnN0YXJ0LmxpbmUpIDogZXhwLnF1YXNpc1swXS52YWx1ZS5yYXc7XG4gICAgfVxuXG4gICAgaXNBc3luY0ZuICh0b2tlbikge1xuICAgICAgICByZXR1cm4gdG9rZW4uYXN5bmMgfHwgdG9rZW4uZ2VuZXJhdG9yO1xuICAgIH1cblxuICAgIGdldFRva2VuVHlwZSAodG9rZW4pIHtcbiAgICAgICAgcmV0dXJuIHRva2VuLnR5cGU7XG4gICAgfVxuXG4gICAgZ2V0UlZhbHVlICh0b2tlbikge1xuICAgICAgICByZXR1cm4gdG9rZW4uZGVjbGFyYXRpb25zWzBdLmluaXQ7XG4gICAgfVxuXG4gICAgZ2V0U3RyaW5nVmFsdWUgKHRva2VuKSB7XG4gICAgICAgIGNvbnN0IHN0cmluZ1R5cGVzID0gW3RoaXMudG9rZW5UeXBlLlN0cmluZ0xpdGVyYWwsIHRoaXMudG9rZW5UeXBlLlRlbXBsYXRlTGl0ZXJhbCwgdGhpcy50b2tlblR5cGUuSWRlbnRpZmllcl07XG5cbiAgICAgICAgaWYgKHN0cmluZ1R5cGVzLmluZGV4T2YodG9rZW4udHlwZSkgPiAtMSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1hdEZuQXJnKHRva2VuKTtcblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBnZXRGdW5jdGlvbkJvZHkgKHRva2VuKSB7XG4gICAgICAgIHJldHVybiB0b2tlbi5ib2R5ICYmIHRva2VuLmJvZHkuYm9keSA/IHRva2VuLmJvZHkuYm9keSA6IFtdO1xuICAgIH1cblxuICAgIGdldENhbGxlZVRva2VuICh0b2tlbikge1xuICAgICAgICByZXR1cm4gdG9rZW4uY2FsbGVlO1xuICAgIH1cblxuICAgIGdldE1lbWJlckZuTmFtZSAodG9rZW4pIHtcbiAgICAgICAgcmV0dXJuIHRva2VuLmNhbGxlZS5wcm9wZXJ0eS5uYW1lO1xuICAgIH1cblxuICAgIGZvcm1hdEZuRGF0YSAobmFtZSwgdmFsdWUsIHRva2VuLCBtZXRhID0gW3t9XSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZm5OYW1lOiAgICBuYW1lLFxuICAgICAgICAgICAgdmFsdWU6ICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGxvYzogICAgICAgdG9rZW4ubG9jLFxuICAgICAgICAgICAgc3RhcnQ6ICAgICB0b2tlbi5zdGFydCxcbiAgICAgICAgICAgIGVuZDogICAgICAgdG9rZW4uZW5kLFxuICAgICAgICAgICAgbWV0YTogICAgICBtZXJnZSh7fSwgLi4ubWV0YSksXG4gICAgICAgICAgICBpc1NraXBwZWQ6IFRlc3RGaWxlUGFyc2VyQmFzZS5pc1NraXBwZWQodG9rZW4pLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGdldEtleVZhbHVlIChwcm9wKSB7XG4gICAgICAgIGNvbnN0IHsga2V5LCB2YWx1ZSB9ID0gcHJvcDtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAga2V5OiAgIGtleS5uYW1lIHx8IHRoaXMuZm9ybWF0Rm5Bcmcoa2V5KSxcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLmdldFN0cmluZ1ZhbHVlKHZhbHVlKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBhbmFseXplTWVtYmVyRXhwICh0b2tlbikge1xuICAgICAgICBsZXQgZXhwICAgICAgICAgPSB0b2tlbjtcbiAgICAgICAgY29uc3QgdG9rZW5UeXBlID0gdGhpcy50b2tlblR5cGU7XG4gICAgICAgIGNvbnN0IGNhbGxTdGFjayA9IFtleHBdO1xuXG4gICAgICAgIHdoaWxlIChleHAudHlwZSAhPT0gdG9rZW5UeXBlLklkZW50aWZpZXIpIHtcbiAgICAgICAgICAgIGlmIChleHAudHlwZSA9PT0gdG9rZW5UeXBlLkNhbGxFeHByZXNzaW9uKVxuICAgICAgICAgICAgICAgIGV4cCA9IGV4cC5jYWxsZWU7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKGV4cC50eXBlID09PSB0b2tlblR5cGUuUHJvcGVydHlBY2Nlc3NFeHByZXNzaW9uKVxuICAgICAgICAgICAgICAgIGV4cCA9IGV4cC5vYmplY3Q7XG5cbiAgICAgICAgICAgIGVsc2UgaWYgKGV4cC50eXBlID09PSB0b2tlblR5cGUuVGFnZ2VkVGVtcGxhdGVFeHByZXNzaW9uKVxuICAgICAgICAgICAgICAgIGV4cCA9IGV4cC50YWc7XG5cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICAgICAgaWYgKGV4cC50eXBlICE9PSB0b2tlblR5cGUuSWRlbnRpZmllcilcbiAgICAgICAgICAgICAgICBjYWxsU3RhY2sucHVzaChleHApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmlzQXBpRm4oZXhwLm5hbWUpKSByZXR1cm4gbnVsbDtcblxuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5nZXRNZXRhSW5mbyhjYWxsU3RhY2suc2xpY2UoKSk7XG5cbiAgICAgICAgbGV0IHBhcmVudEV4cCA9IGNhbGxTdGFjay5wb3AoKTtcblxuICAgICAgICBpZiAocGFyZW50RXhwLnR5cGUgPT09IHRva2VuVHlwZS5DYWxsRXhwcmVzc2lvbilcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1hdEZuRGF0YShleHAubmFtZSwgdGhpcy5mb3JtYXRGbkFyZyhwYXJlbnRFeHAuYXJndW1lbnRzWzBdKSwgdG9rZW4sIG1ldGEpO1xuXG4gICAgICAgIGlmIChwYXJlbnRFeHAudHlwZSA9PT0gdG9rZW5UeXBlLlRhZ2dlZFRlbXBsYXRlRXhwcmVzc2lvbilcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1hdEZuRGF0YShleHAubmFtZSwgRXNOZXh0VGVzdEZpbGVQYXJzZXIuZ2V0VGFnU3RyVmFsdWUocGFyZW50RXhwLnF1YXNpKSwgdG9rZW4sIG1ldGEpO1xuXG4gICAgICAgIGlmIChwYXJlbnRFeHAudHlwZSA9PT0gdG9rZW5UeXBlLlByb3BlcnR5QWNjZXNzRXhwcmVzc2lvbikge1xuICAgICAgICAgICAgd2hpbGUgKHBhcmVudEV4cCkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJlbnRFeHAudHlwZSA9PT0gdG9rZW5UeXBlLkNhbGxFeHByZXNzaW9uICYmIHBhcmVudEV4cC5jYWxsZWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FsbGVlVHlwZSAgICAgPSBwYXJlbnRFeHAuY2FsbGVlLnR5cGU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbGxlZU1lbWJlckZuID0gcGFyZW50RXhwLmNhbGxlZS5wcm9wZXJ0eSAmJiBwYXJlbnRFeHAuY2FsbGVlLnByb3BlcnR5Lm5hbWU7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY2hlY2tFeHBEZWZpbmVUYXJnZXROYW1lKGNhbGxlZVR5cGUsIGNhbGxlZU1lbWJlckZuKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1hdEZuRGF0YShleHAubmFtZSwgdGhpcy5mb3JtYXRGbkFyZyhwYXJlbnRFeHAuYXJndW1lbnRzWzBdKSwgdG9rZW4sIG1ldGEpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChwYXJlbnRFeHAudHlwZSA9PT0gdG9rZW5UeXBlLlRhZ2dlZFRlbXBsYXRlRXhwcmVzc2lvbiAmJiBwYXJlbnRFeHAudGFnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhZ1R5cGUgICAgID0gcGFyZW50RXhwLnRhZy50eXBlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0YWdNZW1iZXJGbiA9IHBhcmVudEV4cC50YWcucHJvcGVydHkgJiYgcGFyZW50RXhwLnRhZy5wcm9wZXJ0eS5uYW1lO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNoZWNrRXhwRGVmaW5lVGFyZ2V0TmFtZSh0YWdUeXBlLCB0YWdNZW1iZXJGbikpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRGbkRhdGEoZXhwLm5hbWUsIEVzTmV4dFRlc3RGaWxlUGFyc2VyLmdldFRhZ1N0clZhbHVlKHBhcmVudEV4cC5xdWFzaSksIHRva2VuLCBtZXRhKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBwYXJlbnRFeHAgPSBjYWxsU3RhY2sucG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBmb3JtYXRGbkFyZyAoYXJnKSB7XG4gICAgICAgIGlmIChhcmcudHlwZSA9PT0gdGhpcy50b2tlblR5cGUuSWRlbnRpZmllcilcbiAgICAgICAgICAgIHJldHVybiBFc05leHRUZXN0RmlsZVBhcnNlci5mb3JtYXRDb21wdXRlZE5hbWUoYXJnLmxvYy5zdGFydC5saW5lKTtcblxuICAgICAgICBpZiAoYXJnLnR5cGUgPT09IHRoaXMudG9rZW5UeXBlLlRlbXBsYXRlTGl0ZXJhbClcbiAgICAgICAgICAgIHJldHVybiBFc05leHRUZXN0RmlsZVBhcnNlci5nZXRUYWdTdHJWYWx1ZShhcmcpO1xuXG4gICAgICAgIGlmIChhcmcudHlwZSA9PT0gdGhpcy50b2tlblR5cGUuU3RyaW5nTGl0ZXJhbClcbiAgICAgICAgICAgIHJldHVybiBhcmcudmFsdWU7XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgZ2V0Rm5DYWxsICh0b2tlbikge1xuICAgICAgICBpZiAoIXRoaXMuaXNBcGlGbih0b2tlbi5jYWxsZWUubmFtZSkpIHJldHVybiBudWxsO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1hdEZuRGF0YSh0b2tlbi5jYWxsZWUubmFtZSwgdGhpcy5mb3JtYXRGbkFyZyh0b2tlbi5hcmd1bWVudHNbMF0pLCB0b2tlbik7XG4gICAgfVxuXG4gICAgZ2V0VGFnZ2VkVGVtcGxhdGVFeHAgKHRva2VuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1hdEZuRGF0YSh0b2tlbi50YWcubmFtZSwgRXNOZXh0VGVzdEZpbGVQYXJzZXIuZ2V0VGFnU3RyVmFsdWUodG9rZW4ucXVhc2kpLCB0b2tlbik7XG4gICAgfVxuXG4gICAgYW5hbHl6ZUZuQ2FsbCAodG9rZW4pIHtcbiAgICAgICAgY29uc3QgdG9rZW5UeXBlID0gdGhpcy50b2tlblR5cGU7XG5cbiAgICAgICAgaWYgKHRva2VuLnR5cGUgPT09IHRva2VuVHlwZS5Qcm9wZXJ0eUFjY2Vzc0V4cHJlc3Npb24pXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hbmFseXplTWVtYmVyRXhwKHRva2VuKTtcblxuICAgICAgICBpZiAodG9rZW4udHlwZSA9PT0gdG9rZW5UeXBlLkNhbGxFeHByZXNzaW9uKSB7XG4gICAgICAgICAgICBjb25zdCBjYWxsZWVUeXBlID0gdG9rZW4uY2FsbGVlLnR5cGU7XG5cbiAgICAgICAgICAgIGlmIChjYWxsZWVUeXBlID09PSB0b2tlblR5cGUuUHJvcGVydHlBY2Nlc3NFeHByZXNzaW9uIHx8IGNhbGxlZVR5cGUgPT09IHRva2VuVHlwZS5DYWxsRXhwcmVzc2lvbilcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hbmFseXplTWVtYmVyRXhwKHRva2VuKTtcblxuICAgICAgICAgICAgaWYgKGNhbGxlZVR5cGUgPT09IHRva2VuVHlwZS5GdW5jdGlvbkV4cHJlc3Npb24gfHwgY2FsbGVlVHlwZSA9PT0gdG9rZW5UeXBlLkFycm93RnVuY3Rpb25FeHByZXNzaW9uKVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbGxlY3RUZXN0Q2FmZUNhbGxzKHRva2VuLmNhbGxlZS5ib2R5LmJvZHkpO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRGbkNhbGwodG9rZW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRva2VuLnR5cGUgPT09IHRva2VuVHlwZS5UYWdnZWRUZW1wbGF0ZUV4cHJlc3Npb24pIHtcbiAgICAgICAgICAgIGlmICh0b2tlbi50YWcudHlwZSA9PT0gdG9rZW5UeXBlLlByb3BlcnR5QWNjZXNzRXhwcmVzc2lvbilcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hbmFseXplTWVtYmVyRXhwKHRva2VuKTtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VGFnZ2VkVGVtcGxhdGVFeHAodG9rZW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcGFyc2UgKGNvZGUpIHtcbiAgICAgICAgY29uc3QgY29tcGlsZXJPcHRpb25zID0gRVNOZXh0VGVzdEZpbGVDb21waWxlci5nZXRCYWJlbE9wdGlvbnMobnVsbCwgY29kZSk7XG5cbiAgICAgICAgZGVsZXRlIGNvbXBpbGVyT3B0aW9ucy5maWxlbmFtZTtcblxuICAgICAgICBjb25zdCBvcHRzID0gYXNzaWduKGNvbXBpbGVyT3B0aW9ucywgeyBhc3Q6IHRydWUgfSk7XG4gICAgICAgIGNvbnN0IGFzdCAgPSB0cmFuc2Zvcm0oY29kZSwgb3B0cykuYXN0O1xuXG4gICAgICAgIHJldHVybiB0aGlzLmFuYWx5emUoYXN0LnByb2dyYW0uYm9keSk7XG4gICAgfVxufVxuXG5jb25zdCBwYXJzZXIgPSBuZXcgRXNOZXh0VGVzdEZpbGVQYXJzZXIoKTtcblxuZXhwb3J0IGNvbnN0IGdldFRlc3RMaXN0ICAgICAgICAgPSBwYXJzZXIuZ2V0VGVzdExpc3QuYmluZChwYXJzZXIpO1xuZXhwb3J0IGNvbnN0IGdldFRlc3RMaXN0RnJvbUNvZGUgPSBwYXJzZXIuZ2V0VGVzdExpc3RGcm9tQ29kZS5iaW5kKHBhcnNlcik7XG4iXX0=