UNPKG

@browserstack/testcafe

Version:

Automated browser testing for the modern web development stack.

204 lines 26.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 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)'; 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 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1maWxlLXBhcnNlci1iYXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBpbGVyL3Rlc3QtZmlsZS90ZXN0LWZpbGUtcGFyc2VyLWJhc2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2RUFBNkQ7QUFDN0QsK0JBQThCO0FBQzlCLGtEQUFvRDtBQUNwRCw4Q0FBb0Q7QUFFcEQsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUNqRCxNQUFNLHNCQUFzQixHQUFJLDJCQUEyQixDQUFDO0FBRTVELE1BQWEsT0FBTztJQUNoQixZQUFhLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJO1FBQ3BDLElBQUksQ0FBQyxJQUFJLEdBQUksSUFBSSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxHQUFHLEdBQUssR0FBRyxDQUFDO1FBQ2pCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxHQUFHLEdBQUssR0FBRyxDQUFDO1FBQ2pCLElBQUksQ0FBQyxJQUFJLEdBQUksSUFBSSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO0lBQ3BCLENBQUM7Q0FDSjtBQVRELDBCQVNDO0FBRUQsTUFBYSxJQUFJO0lBQ2IsWUFBYSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSTtRQUNwQyxJQUFJLENBQUMsSUFBSSxHQUFJLElBQUksQ0FBQztRQUNsQixJQUFJLENBQUMsR0FBRyxHQUFLLEdBQUcsQ0FBQztRQUNqQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsR0FBRyxHQUFLLEdBQUcsQ0FBQztRQUNqQixJQUFJLENBQUMsSUFBSSxHQUFJLElBQUksQ0FBQztJQUN0QixDQUFDO0NBQ0o7QUFSRCxvQkFRQztBQUVELE1BQWEs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O1NBQ2xEO1FBRUQsT0FBTyxHQUFHLEVBQUU7WUFDUixNQUFNLElBQUksc0JBQVksQ0FBQyxzQkFBYyxDQUFDLDZCQUE2QixFQUFFLFFBQVEsQ0FBQyxDQUFDO1NBQ2xGO1FBRUQsT0FBTyxXQUFXLENBQUM7SUFDdkIsQ0FBQztJQUVELEtBQUssQ0FBQyxXQUFXLENBQUUsUUFBUTtRQUN2QixNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFbEQsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRCxtQkFBbUIsQ0FBRSxJQUFJO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1QixDQUFDO0NBQ0o7QUF4T0QsZ0RBd09DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVhZEZpbGUgfSBmcm9tICcuLi8uLi91dGlscy9wcm9taXNpZmllZC1mdW5jdGlvbnMnO1xuaW1wb3J0IHsgZm9ybWF0IH0gZnJvbSAndXRpbCc7XG5pbXBvcnQgeyBHZW5lcmFsRXJyb3IgfSBmcm9tICcuLi8uLi9lcnJvcnMvcnVudGltZSc7XG5pbXBvcnQgeyBSVU5USU1FX0VSUk9SUyB9IGZyb20gJy4uLy4uL2Vycm9ycy90eXBlcyc7XG5cbmNvbnN0IE1FVEhPRFNfU1BFQ0lGWUlOR19OQU1FID0gWydvbmx5JywgJ3NraXAnXTtcbmNvbnN0IENPTVBVVEVEX05BTUVfVEVYVF9UTVAgID0gJzxjb21wdXRlZCBuYW1lPihsaW5lOiAlcyknO1xuXG5leHBvcnQgY2xhc3MgRml4dHVyZSB7XG4gICAgY29uc3RydWN0b3IgKG5hbWUsIHN0YXJ0LCBlbmQsIGxvYywgbWV0YSkge1xuICAgICAgICB0aGlzLm5hbWUgID0gbmFtZTtcbiAgICAgICAgdGhpcy5sb2MgICA9IGxvYztcbiAgICAgICAgdGhpcy5zdGFydCA9IHN0YXJ0O1xuICAgICAgICB0aGlzLmVuZCAgID0gZW5kO1xuICAgICAgICB0aGlzLm1ldGEgID0gbWV0YTtcbiAgICAgICAgdGhpcy50ZXN0cyA9IFtdO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFRlc3Qge1xuICAgIGNvbnN0cnVjdG9yIChuYW1lLCBzdGFydCwgZW5kLCBsb2MsIG1ldGEpIHtcbiAgICAgICAgdGhpcy5uYW1lICA9IG5hbWU7XG4gICAgICAgIHRoaXMubG9jICAgPSBsb2M7XG4gICAgICAgIHRoaXMuc3RhcnQgPSBzdGFydDtcbiAgICAgICAgdGhpcy5lbmQgICA9IGVuZDtcbiAgICAgICAgdGhpcy5tZXRhICA9IG1ldGE7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgVGVzdEZpbGVQYXJzZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvciAodG9rZW5UeXBlKSB7XG4gICAgICAgIHRoaXMudG9rZW5UeXBlID0gdG9rZW5UeXBlO1xuICAgIH1cblxuICAgIHN0YXRpYyBmb3JtYXRDb21wdXRlZE5hbWUgKGxpbmUpIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdChDT01QVVRFRF9OQU1FX1RFWFRfVE1QLCBsaW5lKTtcbiAgICB9XG5cbiAgICBpc0FzeW5jRm4gKC8qIHRva2VuICovKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgZ2V0UlZhbHVlICgvKiB0b2tlbiAqLykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIGdldEZ1bmN0aW9uQm9keSAoLyogdG9rZW4gKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBmb3JtYXRGbkRhdGEgKC8qIG5hbWUsIHZhbHVlLCB0b2tlbiAqLykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIGFuYWx5emVNZW1iZXJFeHAgKC8qIHRva2VuICovKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgZm9ybWF0Rm5BcmcgKC8qIGFyZyAqLykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIGdldEZuQ2FsbCAoLyogdG9rZW4gKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBnZXRUYWdnZWRUZW1wbGF0ZUV4cCAoLyogdG9rZW4gKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBhbmFseXplRm5DYWxsICgvKiB0b2tlbiAqLykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIHBhcnNlICgvKiBmaWxlUGF0aCwgY29kZSAqLykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIGdldFRva2VuVHlwZSAoLyogdG9rZW4gKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBnZXRDYWxsZWVUb2tlbiAoLyogdG9rZW4gKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBnZXRNZW1iZXJGbk5hbWUgKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIGdldEtleVZhbHVlICgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBnZXRTdHJpbmdWYWx1ZSAoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgaXNBcGlGbiAoZm4pIHtcbiAgICAgICAgcmV0dXJuIGZuID09PSAnZml4dHVyZScgfHwgZm4gPT09ICd0ZXN0JztcbiAgICB9XG5cbiAgICBzZXJpYWxpemVPYmpFeHAgKHRva2VuKSB7XG4gICAgICAgIGlmICh0aGlzLmdldFRva2VuVHlwZSh0b2tlbikgIT09IHRoaXMudG9rZW5UeXBlLk9iamVjdExpdGVyYWxFeHByZXNzaW9uKVxuICAgICAgICAgICAgcmV0dXJuIHt9O1xuXG4gICAgICAgIHJldHVybiB0b2tlbi5wcm9wZXJ0aWVzLnJlZHVjZSgob2JqLCBwcm9wKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGtleSwgdmFsdWUgfSA9IHRoaXMuZ2V0S2V5VmFsdWUocHJvcCk7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSByZXR1cm4ge307XG5cbiAgICAgICAgICAgIG9ialtrZXldID0gdmFsdWU7XG5cbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH0sIHt9KTtcbiAgICB9XG5cbiAgICBwcm9jZXNzTWV0YUFyZ3MgKHRva2VuKSB7XG4gICAgICAgIGlmICh0aGlzLmdldFRva2VuVHlwZSh0b2tlbikgIT09IHRoaXMudG9rZW5UeXBlLkNhbGxFeHByZXNzaW9uKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgY29uc3QgYXJncyA9IHRva2VuLmFyZ3VtZW50cztcblxuICAgICAgICBsZXQgbWV0YSA9IHt9O1xuXG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldFN0cmluZ1ZhbHVlKGFyZ3NbMV0pO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykgcmV0dXJuIHt9O1xuXG4gICAgICAgICAgICBtZXRhID0geyBbdGhpcy5mb3JtYXRGbkFyZyhhcmdzWzBdKV06IHZhbHVlIH07XG4gICAgICAgIH1cblxuICAgICAgICBlbHNlIGlmIChhcmdzLmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICAgIG1ldGEgPSB0aGlzLnNlcmlhbGl6ZU9iakV4cChhcmdzWzBdKTtcblxuICAgICAgICByZXR1cm4gbWV0YTtcbiAgICB9XG5cbiAgICBnZXRNZXRhSW5mbyAoY2FsbFN0YWNrKSB7XG4gICAgICAgIHJldHVybiBjYWxsU3RhY2sucmVkdWNlKChtZXRhQ2FsbHMsIGV4cCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuZ2V0VG9rZW5UeXBlKGV4cCkgIT09IHRoaXMudG9rZW5UeXBlLkNhbGxFeHByZXNzaW9uKVxuICAgICAgICAgICAgICAgIHJldHVybiBtZXRhQ2FsbHM7XG5cbiAgICAgICAgICAgIGNvbnN0IGNhbGxlZSAgICAgICAgICAgID0gdGhpcy5nZXRDYWxsZWVUb2tlbihleHApO1xuICAgICAgICAgICAgY29uc3QgY2FsbGVlVHlwZSAgICAgICAgPSB0aGlzLmdldFRva2VuVHlwZShjYWxsZWUpO1xuICAgICAgICAgICAgY29uc3QgaXNDYWxsZWVNZW1iZXJFeHAgPSBjYWxsZWVUeXBlID09PSB0aGlzLnRva2VuVHlwZS5Qcm9wZXJ0eUFjY2Vzc0V4cHJlc3Npb247XG5cbiAgICAgICAgICAgIGlmIChpc0NhbGxlZU1lbWJlckV4cCAmJiB0aGlzLmdldE1lbWJlckZuTmFtZShleHApID09PSAnbWV0YScpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFt0aGlzLnByb2Nlc3NNZXRhQXJncyhleHApXS5jb25jYXQobWV0YUNhbGxzKTtcblxuICAgICAgICAgICAgcmV0dXJuIG1ldGFDYWxscztcbiAgICAgICAgfSwgW10pO1xuICAgIH1cblxuICAgIGNoZWNrRXhwRGVmaW5lVGFyZ2V0TmFtZSAodHlwZSwgYXBpRm4pIHtcbiAgICAgICAgLy9OT1RFOiBmaXh0dXJlKCdmaXh0dXJlTmFtZScpLmNoYWluRm4gb3IgdGVzdCgndGVzdE5hbWUnKS5jaGFpbkZuXG4gICAgICAgIGNvbnN0IGlzRGlyZWN0Q2FsbCA9IHR5cGUgPT09IHRoaXMudG9rZW5UeXBlLklkZW50aWZpZXI7XG5cbiAgICAgICAgLy9OT1RFOiBmaXh0dXJlLnNraXAoJ2ZpeHR1cmVOYW1lJyksIHRlc3Qub25seSgndGVzdE5hbWUnKSBldGMuXG4gICAgICAgIGNvbnN0IGlzTWVtYmVyQ2FsbCA9IHR5cGUgPT09IHRoaXMudG9rZW5UeXBlLlByb3BlcnR5QWNjZXNzRXhwcmVzc2lvbiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNRVRIT0RTX1NQRUNJRllJTkdfTkFNRS5pbmRleE9mKGFwaUZuKSA+IC0xO1xuXG4gICAgICAgIC8vTk9URTogZml4dHVyZS5iZWZvcmUoKS5hZnRlcigpKCdmaXh0dXJlTmFtZScpLCB0ZXN0LmJlZm9yZSgpYHRlc3ROYW1lYC5hZnRlcigpIGV0Yy5cbiAgICAgICAgY29uc3QgaXNUYWlsQ2FsbCA9IHR5cGUgPT09IHRoaXMudG9rZW5UeXBlLkNhbGxFeHByZXNzaW9uO1xuXG4gICAgICAgIHJldHVybiBpc0RpcmVjdENhbGwgfHwgaXNNZW1iZXJDYWxsIHx8IGlzVGFpbENhbGw7XG4gICAgfVxuXG4gICAgYW5hbHl6ZVRva2VuICh0b2tlbikge1xuICAgICAgICBjb25zdCB0b2tlblR5cGUgICAgID0gdGhpcy50b2tlblR5cGU7XG4gICAgICAgIGNvbnN0IGN1cnJUb2tlblR5cGUgPSB0aGlzLmdldFRva2VuVHlwZSh0b2tlbik7XG5cbiAgICAgICAgc3dpdGNoIChjdXJyVG9rZW5UeXBlKSB7XG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5FeHByZXNzaW9uU3RhdGVtZW50OlxuICAgICAgICAgICAgY2FzZSB0b2tlblR5cGUuVHlwZUFzc2VydGlvbkV4cHJlc3Npb246XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYW5hbHl6ZVRva2VuKHRva2VuLmV4cHJlc3Npb24pO1xuXG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5GdW5jdGlvbkRlY2xhcmF0aW9uOlxuICAgICAgICAgICAgY2FzZSB0b2tlblR5cGUuRnVuY3Rpb25FeHByZXNzaW9uOlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzQXN5bmNGbih0b2tlbikpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RnVuY3Rpb25Cb2R5KHRva2VuKS5tYXAodGhpcy5hbmFseXplVG9rZW4sIHRoaXMpO1xuXG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5WYXJpYWJsZURlY2xhcmF0aW9uOlxuICAgICAgICAgICAgY2FzZSB0b2tlblR5cGUuVmFyaWFibGVTdGF0ZW1lbnQ6IHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YXJpYWJsZVZhbHVlID0gdGhpcy5nZXRSVmFsdWUodG9rZW4pOyAvLyBTa2lwIHZhcmlhYmxlIGRlY2xhcmF0aW9ucyBsaWtlIGB2YXIgZm9vO2BcblxuICAgICAgICAgICAgICAgIHJldHVybiB2YXJpYWJsZVZhbHVlID8gdGhpcy5hbmFseXplVG9rZW4odmFyaWFibGVWYWx1ZSkgOiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSB0b2tlblR5cGUuQ2FsbEV4cHJlc3Npb246XG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5Qcm9wZXJ0eUFjY2Vzc0V4cHJlc3Npb246XG4gICAgICAgICAgICBjYXNlIHRva2VuVHlwZS5UYWdnZWRUZW1wbGF0ZUV4cHJlc3Npb246XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYW5hbHl6ZUZuQ2FsbCh0b2tlbik7XG5cbiAgICAgICAgICAgIGNhc2UgdG9rZW5UeXBlLlJldHVyblN0YXRlbWVudDpcbiAgICAgICAgICAgICAgICByZXR1cm4gdG9rZW4uYXJndW1lbnQgPyB0aGlzLmFuYWx5emVUb2tlbih0b2tlbi5hcmd1bWVudCkgOiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29sbGVjdFRlc3RDYWZlQ2FsbHMgKGFzdEJvZHkpIHtcbiAgICAgICAgbGV0IGNhbGxzID0gW107XG5cbiAgICAgICAgYXN0Qm9keS5mb3JFYWNoKHRva2VuID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNhbGxFeHBzID0gdGhpcy5hbmFseXplVG9rZW4odG9rZW4pO1xuXG4gICAgICAgICAgICBpZiAoY2FsbEV4cHMpXG4gICAgICAgICAgICAgICAgY2FsbHMgPSBjYWxscy5jb25jYXQoY2FsbEV4cHMpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gY2FsbHM7XG4gICAgfVxuXG4gICAgYW5hbHl6ZSAoYXN0Qm9keSkge1xuICAgICAgICBjb25zdCBmaXh0dXJlcyAgICAgICAgID0gW107XG4gICAgICAgIGNvbnN0IHRlc3RDYWZlQVBJQ2FsbHMgPSB0aGlzLmNvbGxlY3RUZXN0Q2FmZUNhbGxzKGFzdEJvZHkpO1xuXG4gICAgICAgIHRlc3RDYWZlQVBJQ2FsbHMuZm9yRWFjaChjYWxsID0+IHtcbiAgICAgICAgICAgIGlmICghY2FsbCB8fCB0eXBlb2YgY2FsbC52YWx1ZSAhPT0gJ3N0cmluZycpIHJldHVybjtcblxuICAgICAgICAgICAgaWYgKGNhbGwuZm5OYW1lID09PSAnZml4dHVyZScpIHtcbiAgICAgICAgICAgICAgICBmaXh0dXJlcy5wdXNoKG5ldyBGaXh0dXJlKGNhbGwudmFsdWUsIGNhbGwuc3RhcnQsIGNhbGwuZW5kLCBjYWxsLmxvYywgY2FsbC5tZXRhKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWZpeHR1cmVzLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgICAgICAgICBjb25zdCB0ZXN0ID0gbmV3IFRlc3QoY2FsbC52YWx1ZSwgY2FsbC5zdGFydCwgY2FsbC5lbmQsIGNhbGwubG9jLCBjYWxsLm1ldGEpO1xuXG4gICAgICAgICAgICBmaXh0dXJlc1tmaXh0dXJlcy5sZW5ndGggLSAxXS50ZXN0cy5wdXNoKHRlc3QpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gZml4dHVyZXM7XG4gICAgfVxuXG4gICAgYXN5bmMgcmVhZEZpbGUgKGZpbGVQYXRoKSB7XG4gICAgICAgIGxldCBmaWxlQ29udGVudCA9ICcnO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmaWxlQ29udGVudCA9IGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoLCAndXRmOCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEdlbmVyYWxFcnJvcihSVU5USU1FX0VSUk9SUy5jYW5ub3RGaW5kU3BlY2lmaWVkVGVzdFNvdXJjZSwgZmlsZVBhdGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZpbGVDb250ZW50O1xuICAgIH1cblxuICAgIGFzeW5jIGdldFRlc3RMaXN0IChmaWxlUGF0aCkge1xuICAgICAgICBjb25zdCBmaWxlQ29udGVudCA9IGF3YWl0IHRoaXMucmVhZEZpbGUoZmlsZVBhdGgpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlKGZpbGVDb250ZW50KTtcbiAgICB9XG5cbiAgICBnZXRUZXN0TGlzdEZyb21Db2RlIChjb2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlKGNvZGUpO1xuICAgIH1cbn1cbiJdfQ==