testcafe
Version:
Automated browser testing for the modern web development stack.
209 lines • 26.7 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const promisify_1 = __importDefault(require("../../utils/promisify"));
const util_1 = require("util");
const runtime_1 = require("../../errors/runtime");
const types_1 = require("../../errors/types");
const readFile = promisify_1.default(fs_1.default.readFile);
const METHODS_SPECIFYING_NAME = ['only', 'skip'];
const COMPUTED_NAME_TEXT_TMP = '<computed name>(line: %s)';
class Fixture {
constructor(name, start, end, loc, meta) {
this.name = name;
this.loc = loc;
this.start = start;
this.end = end;
this.meta = meta;
this.tests = [];
}
}
exports.Fixture = Fixture;
class Test {
constructor(name, start, end, loc, meta) {
this.name = name;
this.loc = loc;
this.start = start;
this.end = end;
this.meta = meta;
}
}
exports.Test = Test;
class TestFileParserBase {
constructor(tokenType) {
this.tokenType = tokenType;
}
static formatComputedName(line) {
return 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;
}, []);
}
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));
return;
}
if (!fixtures.length)
return;
const test = new Test(call.value, call.start, call.end, call.loc, call.meta);
fixtures[fixtures.length - 1].tests.push(test);
});
return fixtures;
}
async readFile(filePath) {
let fileContent = '';
try {
fileContent = await 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1maWxlLXBhcnNlci1iYXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBpbGVyL3Rlc3QtZmlsZS90ZXN0LWZpbGUtcGFyc2VyLWJhc2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw0Q0FBb0I7QUFDcEIsc0VBQThDO0FBQzlDLCtCQUE4QjtBQUM5QixrREFBb0Q7QUFDcEQsOENBQW9EO0FBRXBELE1BQU0sUUFBUSxHQUFHLG1CQUFTLENBQUMsWUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBRXhDLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDakQsTUFBTSxzQkFBc0IsR0FBSSwyQkFBMkIsQ0FBQztBQUU1RCxNQUFhLE9BQU87SUFDaEIsWUFBYSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSTtRQUNwQyxJQUFJLENBQUMsSUFBSSxHQUFJLElBQUksQ0FBQztRQUNsQixJQUFJLENBQUMsR0FBRyxHQUFLLEdBQUcsQ0FBQztRQUNqQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsR0FBRyxHQUFLLEdBQUcsQ0FBQztRQUNqQixJQUFJLENBQUMsSUFBSSxHQUFJLElBQUksQ0FBQztRQUNsQixJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztJQUNwQixDQUFDO0NBQ0o7QUFURCwwQkFTQztBQUVELE1BQWEsSUFBSTtJQUNiLFlBQWEsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUk7UUFDcEMsSUFBSSxDQUFDLElBQUksR0FBSSxJQUFJLENBQUM7UUFDbEIsSUFBSSxDQUFDLEdBQUcsR0FBSyxHQUFHLENBQUM7UUFDakIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLEdBQUcsR0FBSyxHQUFHLENBQUM7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RSxDQUFDO1FBRXJCLElBQUk7WUFDQSxXQUFXLEdBQUcsTUFBTSxRQUFRLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1NBQ2xEO1FBRUQsT0FBTyxHQUFHLEVBQUU7WUFDUixNQUFNLElBQUksc0JBQVksQ0FBQyxzQkFBYyxDQUFDLDZCQUE2QixFQUFFLFFBQVEsQ0FBQyxDQUFDO1NBQ2xGO1FBRUQsT0FBTyxXQUFXLENBQUM7SUFDdkIsQ0FBQztJQUVELEtBQUssQ0FBQyxXQUFXLENBQUUsUUFBUTtRQUN2QixNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFbEQsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRCxtQkFBbUIsQ0FBRSxJQUFJO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1QixDQUFDO0NBQ0o7QUF4T0QsZ0RBd09DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBwcm9taXNpZnkgZnJvbSAnLi4vLi4vdXRpbHMvcHJvbWlzaWZ5JztcbmltcG9ydCB7IGZvcm1hdCB9IGZyb20gJ3V0aWwnO1xuaW1wb3J0IHsgR2VuZXJhbEVycm9yIH0gZnJvbSAnLi4vLi4vZXJyb3JzL3J1bnRpbWUnO1xuaW1wb3J0IHsgUlVOVElNRV9FUlJPUlMgfSBmcm9tICcuLi8uLi9lcnJvcnMvdHlwZXMnO1xuXG5jb25zdCByZWFkRmlsZSA9IHByb21pc2lmeShmcy5yZWFkRmlsZSk7XG5cbmNvbnN0IE1FVEhPRFNfU1BFQ0lGWUlOR19OQU1FID0gWydvbmx5JywgJ3NraXAnXTtcbmNvbnN0IENPTVBVVEVEX05BTUVfVEVYVF9UTVAgID0gJzxjb21wdXRlZCBuYW1lPihsaW5lOiAlcyknO1xuXG5leHBvcnQgY2xhc3MgRml4dHVyZSB7XG4gICAgY29uc3RydWN0b3IgKG5hbWUsIHN0YXJ0LCBlbmQsIGxvYywgbWV0YSkge1xuICAgICAgICB0aGlzLm5hbWUgID0gbmFtZTtcbiAgICAgICAgdGhpcy5sb2MgICA9IGxvYztcbiAgICAgICAgdGhpcy5zdGFydCA9IHN0YXJ0O1xuICAgICAgICB0aGlzLmVuZCAgID0gZW5kO1xuICAgICAgICB0aGlzLm1ldGEgID0gbWV0YTtcbiAgICAgICAgdGhpcy50ZXN0cyA9IFtdO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFRlc3Qge1xuICAgIGNvbnN0cnVjdG9yIChuYW1lLCBzdGFydCwgZW5kLCBsb2MsIG1ldGEpIHtcbiAgICAgICAgdGhpcy5uYW1lICA9IG5hbWU7XG4gICAgICAgIHRoaXMubG9jICAgPSBsb2M7XG4gICAgICAgIHRoaXMuc3RhcnQgPSBzdGFydDtcbiAgICAgICAgdGhpcy5lbmQgICA9IGVuZDtcbiAgICAgICAgdGhpcy5tZXRhICA9IG1ldGE7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgVGVzdEZpbGVQYXJzZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvciAodG9rZW5UeXBlKSB7XG4gICAgICAgIHRoaXMudG9rZW5UeXBlID0gdG9rZW5UeXBlO1xuICAgIH1cblxuICAgIHN0YXRpYyBmb3JtYXRDb21wdXRlZE5hbWUgKGxpbmUpIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdChDT01QVVRFRF9OQU1FX1RFWFRfVE1QLCBsaW5lKTtcbiAgICB9XG5cbiAgICBpc0FzeW5jRm4gKC8qIHRva2VuICovKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgZ2V0UlZhbHVlICgvKiB0b2tlbiAqLykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIGdldEZ1bmN0aW9uQm9keSAoLyogdG9rZW4gKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBmb3JtYXRGbkRhdGEgKC8qIG5hbWUsIHZhbHVlLCB0b2tlbiAqLykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIGFuYWx5emVNZW1iZXJFeHAgKC8qIHRva2VuICovKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgZm9ybWF0Rm5BcmcgKC8qIGFyZyAqLykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIGdldEZuQ2FsbCAoLyogdG9rZW4gKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBnZXRUYWdnZWRUZW1wbGF0ZUV4cCAoLyogdG9rZW4gKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBhbmFseXplRm5DYWxsICgvKiB0b2tlbiAqLykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIHBhcnNlICgvKiBmaWxlUGF0aCwgY29kZSAqLykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIGdldFRva2VuVHlwZSAoLyogdG9rZW4gKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBnZXRDYWxsZWVUb2tlbiAoLyogdG9rZW4gKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBnZXRNZW1iZXJGbk5hbWUgKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIGdldEtleVZhbHVlICgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBnZXRTdHJpbmdWYWx1ZSAoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgaXNBcGlGbiAoZm4pIHtcbiAgICAgICAgcmV0dXJuIGZuID09PSAnZml4dHVyZScgfHwgZm4gPT09ICd0ZXN0JztcbiAgICB9XG5cbiAgICBzZXJpYWxpemVPYmpFeHAgKHRva2VuKSB7XG4gICAgICAgIGlmICh0aGlzLmdldFRva2VuVHlwZSh0b2tlbikgIT09IHRoaXMudG9rZW5UeXBlLk9iamVjdExpdGVyYWxFeHByZXNzaW9uKVxuICAgICAgICAgICAgcmV0dXJuIHt9O1xuXG4gICAgICAgIHJldHVybiB0b2tlbi5wcm9wZXJ0aWVzLnJlZHVjZSgob2JqLCBwcm9wKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGtleSwgdmFsdWUgfSA9IHRoaXMuZ2V0S2V5VmFsdWUocHJvcCk7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSByZXR1cm4ge307XG5cbiAgICAgICAgICAgIG9ialtrZXldID0gdmFsdWU7XG5cbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH0sIHt9KTtcbiAgICB9XG5cbiAgICBwcm9jZXNzTWV0YUFyZ3MgKHRva2VuKSB7XG4gICAgICAgIGlmICh0aGlzLmdldFRva2VuVHlwZSh0b2tlbikgIT09IHRoaXMudG9rZW5UeXBlLkNhbGxFeHByZXNzaW9uKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgY29uc3QgYXJncyA9IHRva2VuLmFyZ3VtZW50cztcblxuICAgICAgICBsZXQgbWV0YSA9IHt9O1xuXG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldFN0cmluZ1ZhbHVlKGFyZ3NbMV0pO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykgcmV0dXJuIHt9O1xuXG4gICAgICAgICAgICBtZXRhID0geyBbdGhpcy5mb3JtYXRGbkFyZyhhcmdzWzBdKV06IHZhbHVlIH07XG4gICAgICAgIH1cblxuICAgICAgICBlbHNlIGlmIChhcmdzLmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICAgIG1ldGEgPSB0aGlzLnNlcmlhbGl6ZU9iakV4cChhcmdzWzBdKTtcblxuICAgICAgICByZXR1cm4gbWV0YTtcbiAgICB9XG5cbiAgICBnZXRNZXRhSW5mbyAoY2FsbFN0YWNrKSB7XG4gICAgICAgIHJldHVybiBjYWxsU3RhY2sucmVkdWNlKChtZXRhQ2FsbHMsIGV4cCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuZ2V0VG9rZW5UeXBlKGV4cCkgIT09IHRoaXMudG9rZW5UeXBlLkNhbGxFeHByZXNzaW9uKVxuICAgICAgICAgICAgICAgIHJldHVybiBtZXRhQ2FsbHM7XG5cbiAgICAgICAgICAgIGNvbnN0IGNhbGxlZSAgICAgICAgICAgID0gdGhpcy5nZXRDYWxsZWVUb2tlbihleHApO1xuICAgICAgICAgICAgY29uc3QgY2FsbGVlVHlwZSAgICAgICAgPSB0aGlzLmdldFRva2VuVHlwZShjYWxsZWUpO1xuICAgICAgICAgICAgY29uc3QgaXNDYWxsZWVNZW1iZXJFeHAgPSBjYWxsZWVUeXBlID09PSB0aGlzLnRva2VuVHlwZS5Qcm9wZXJ0eUFjY2Vzc0V4cHJlc3Npb247XG5cbiAgICAgICAgICAgIGlmIChpc0NhbGxlZU1lbWJlckV4cCAmJiB0aGlzLmdldE1lbWJlckZuTmFtZShleHApID09PSAnbWV0YScpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFt0aGlzLnByb2Nlc3NNZXRhQXJncyhleHApXS5jb25jYXQobWV0YUNhbGxzKTtcblxuICAgICAgICAgICAgcmV0dXJuIG1ldGFDYWxscztcbiAgICAgICAgfSwgW10pO1xuICAgIH1cblxuICAgIGNoZWNrRXhwRGVmaW5lVGFyZ2V0TmFtZSAodHlwZSwgYXBpRm4pIHtcbiAgICAgICAgLy9OT1RFOiBmaXh0dXJlKCdmaXh0dXJlTmFtZScpLmNoYWluRm4gb3IgdGVzdCgndGVzdE5hbWUnKS5jaGFpbkZuXG4gICAgICAgIGNvbnN0IGlzRGlyZWN0Q2FsbCA9IHR5cGUgPT09IHRoaXMudG9rZW5UeXBlLklkZW50aWZpZXI7XG5cbiAgICAgICAgLy9OT1RFOiBmaXh0dXJlLnNraXAoJ2ZpeHR1cmVOYW1lJyksIHRlc3Qub25seSgndGVzdE5hbWUnKSBldGMuXG4gICAgICAgIGNvbnN0IGlzTWVtYmVyQ2FsbCA9IHR5cGUgPT09IHRoaXMudG9rZW5UeXBlLlByb3BlcnR5QWNjZXNzRXhwcmVzc2lvbiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNRVRIT0RTX1NQRUNJRllJTkdfTkFNRS5pbmRleE9mKGFwaUZuKSA+IC0xO1xuXG4gICAgICAgIC8vTk9URTogZml4dHVyZS5iZWZvcmUoKS5hZnRlcigpKCdmaXh0dXJlTmFtZScpLCB0ZXN0LmJlZm9yZSgpYHRlc3ROYW1lYC5hZnRlcigpIGV0Yy5cbiAgICAgICAgY29uc3QgaXNUYWlsQ2FsbCA9IHR5cGUgPT09IHRoaXMudG9rZW5UeXBlLkNhbGxFeHByZXNzaW9uO1xuXG4gICAgICAgIHJldHVybiBpc0RpcmVjdENhbGwgfHwgaXNNZW1iZXJDYWxsIHx8IGlzVGFpbENhbGw7XG4gICAgfVxuXG4gICAgYW5hbHl6ZVRva2VuICh0b2tlbikge1xuICAgICAgICBjb25zdCB0b2tlblR5cGUgICAgID0gdGhpcy50b2tlblR5cGU7XG4gICAgICAgIGNvbnN0IGN1cnJUb2tlblR5cGUgPSB0aGlzLmdldFRva2VuVHlwZSh0b2tlbik7XG5cbiAgICAgICAgc3dpdGNoIChjdXJyVG9rZW5UeXBlKSB7XG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5FeHByZXNzaW9uU3RhdGVtZW50OlxuICAgICAgICAgICAgY2FzZSB0b2tlblR5cGUuVHlwZUFzc2VydGlvbkV4cHJlc3Npb246XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYW5hbHl6ZVRva2VuKHRva2VuLmV4cHJlc3Npb24pO1xuXG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5GdW5jdGlvbkRlY2xhcmF0aW9uOlxuICAgICAgICAgICAgY2FzZSB0b2tlblR5cGUuRnVuY3Rpb25FeHByZXNzaW9uOlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzQXN5bmNGbih0b2tlbikpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RnVuY3Rpb25Cb2R5KHRva2VuKS5tYXAodGhpcy5hbmFseXplVG9rZW4sIHRoaXMpO1xuXG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5WYXJpYWJsZURlY2xhcmF0aW9uOlxuICAgICAgICAgICAgY2FzZSB0b2tlblR5cGUuVmFyaWFibGVTdGF0ZW1lbnQ6IHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YXJpYWJsZVZhbHVlID0gdGhpcy5nZXRSVmFsdWUodG9rZW4pOyAvLyBTa2lwIHZhcmlhYmxlIGRlY2xhcmF0aW9ucyBsaWtlIGB2YXIgZm9vO2BcblxuICAgICAgICAgICAgICAgIHJldHVybiB2YXJpYWJsZVZhbHVlID8gdGhpcy5hbmFseXplVG9rZW4odmFyaWFibGVWYWx1ZSkgOiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSB0b2tlblR5cGUuQ2FsbEV4cHJlc3Npb246XG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5Qcm9wZXJ0eUFjY2Vzc0V4cHJlc3Npb246XG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5UYWdnZWRUZW1wbGF0ZUV4cHJlc3Npb246XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYW5hbHl6ZUZuQ2FsbCh0b2tlbik7XG5cbiAgICAgICAgICAgIGNhc2UgdG9rZW5UeXBlLlJldHVyblN0YXRlbWVudDpcbiAgICAgICAgICAgICAgICByZXR1cm4gdG9rZW4uYXJndW1lbnQgPyB0aGlzLmFuYWx5emVUb2tlbih0b2tlbi5hcmd1bWVudCkgOiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29sbGVjdFRlc3RDYWZlQ2FsbHMgKGFzdEJvZHkpIHtcbiAgICAgICAgbGV0IGNhbGxzID0gW107XG5cbiAgICAgICAgYXN0Qm9keS5mb3JFYWNoKHRva2VuID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNhbGxFeHBzID0gdGhpcy5hbmFseXplVG9rZW4odG9rZW4pO1xuXG4gICAgICAgICAgICBpZiAoY2FsbEV4cHMpXG4gICAgICAgICAgICAgICAgY2FsbHMgPSBjYWxscy5jb25jYXQoY2FsbEV4cHMpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gY2FsbHM7XG4gICAgfVxuXG4gICAgYW5hbHl6ZSAoYXN0Qm9keSkge1xuICAgICAgICBjb25zdCBmaXh0dXJlcyAgICAgICAgID0gW107XG4gICAgICAgIGNvbnN0IHRlc3RDYWZlQVBJQ2FsbHMgPSB0aGlzLmNvbGxlY3RUZXN0Q2FmZUNhbGxzKGFzdEJvZHkpO1xuXG4gICAgICAgIHRlc3RDYWZlQVBJQ2FsbHMuZm9yRWFjaChjYWxsID0+IHtcbiAgICAgICAgICAgIGlmICghY2FsbCB8fCB0eXBlb2YgY2FsbC52YWx1ZSAhPT0gJ3N0cmluZycpIHJldHVybjtcblxuICAgICAgICAgICAgaWYgKGNhbGwuZm5OYW1lID09PSAnZml4dHVyZScpIHtcbiAgICAgICAgICAgICAgICBmaXh0dXJlcy5wdXNoKG5ldyBGaXh0dXJlKGNhbGwudmFsdWUsIGNhbGwuc3RhcnQsIGNhbGwuZW5kLCBjYWxsLmxvYywgY2FsbC5tZXRhKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWZpeHR1cmVzLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgICAgICAgICBjb25zdCB0ZXN0ID0gbmV3IFRlc3QoY2FsbC52YWx1ZSwgY2FsbC5zdGFydCwgY2FsbC5lbmQsIGNhbGwubG9jLCBjYWxsLm1ldGEpO1xuXG4gICAgICAgICAgICBmaXh0dXJlc1tmaXh0dXJlcy5sZW5ndGggLSAxXS50ZXN0cy5wdXNoKHRlc3QpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gZml4dHVyZXM7XG4gICAgfVxuXG4gICAgYXN5bmMgcmVhZEZpbGUgKGZpbGVQYXRoKSB7XG4gICAgICAgIGxldCBmaWxlQ29udGVudCA9ICcnO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmaWxlQ29udGVudCA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoLCAndXRmOCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEdlbmVyYWxFcnJvcihSVU5USU1FX0VSUk9SUy5jYW5ub3RGaW5kU3BlY2lmaWVkVGVzdFNvdXJjZSwgZmlsZVBhdGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZpbGVDb250ZW50O1xuICAgIH1cblxuICAgIGFzeW5jIGdldFRlc3RMaXN0IChmaWxlUGF0aCkge1xuICAgICAgICBjb25zdCBmaWxlQ29udGVudCA9IGF3YWl0IHRoaXMucmVhZEZpbGUoZmlsZVBhdGgpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlKGZpbGVDb250ZW50KTtcbiAgICB9XG5cbiAgICBnZXRUZXN0TGlzdEZyb21Db2RlIChjb2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlKGNvZGUpO1xuICAgIH1cbn1cbiJdfQ==