"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = require("path"); const fs_1 = require("fs"); const strip_bom_1 = __importDefault(require("strip-bom")); const nanoid_1 = require("nanoid"); const base_1 = __importDefault(require("./base")); const test_file_1 = __importDefault(require("../../api/structure/test-file")); const fixture_1 = __importDefault(require("../../api/structure/fixture")); const test_1 = __importDefault(require("../../api/structure/test")); const runtime_1 = require("../../errors/runtime"); const stack_cleaning_hook_1 = __importDefault(require("../../errors/stack-cleaning-hook")); const node_modules_folder_name_1 = __importDefault(require("../../utils/node-modules-folder-name")); const cache_proxy_1 = __importDefault(require("./cache-proxy")); const exportable_lib_1 = __importDefault(require("../../api/exportable-lib")); const test_file_temp_variable_name_1 = __importDefault(require("./test-file-temp-variable-name")); const add_export_api_1 = __importDefault(require("./add-export-api")); const url_1 = __importDefault(require("url")); const prevent_module_caching_suffix_1 = __importDefault(require("../prevent-module-caching-suffix")); const CWD = process.cwd(); const FIXTURE_RE = /(^|;|\s+)fixture\s*(\.|\(|`)/; const TEST_RE = /(^|;|\s+)test\s*(\.|\()/; const TESTCAFE_LIB_FOLDER_NAME = 'lib'; const Module = module.constructor; const errRequireEsmErrorCode = 'ERR_REQUIRE_ESM'; class APIBasedTestFileCompilerBase extends base_1.default { constructor({ isCompilerServiceMode, baseUrl, experimentalEsm }) { super({ baseUrl }); this.isCompilerServiceMode = isCompilerServiceMode; this.cache = Object.create(null); this.origRequireExtensions = Object.create(null); this.cachePrefix = (0, nanoid_1.nanoid)(7); this.experimentalEsm = experimentalEsm; } static _getNodeModulesLookupPath(filename) { const dir = (0, path_1.dirname)(filename); return Module._nodeModulePaths(dir); } static _isNodeModulesDep(filename) { return (0, path_1.relative)(CWD, filename) .split(path_1.sep) .includes(node_modules_folder_name_1.default); } static _isTestCafeLibDep(filename) { return (0, path_1.relative)(CWD, filename) .split(path_1.sep) .includes(TESTCAFE_LIB_FOLDER_NAME); } async _execAsModule(code, filename) { if (this.experimentalEsm) { const fileUrl = url_1.default.pathToFileURL(filename); //NOTE: It is necessary to prevent module caching during live mode. // eslint-disable-next-line no-eval await eval(`import('${fileUrl}?${prevent_module_caching_suffix_1.default}=${Date.now()}')`); } else { const mod = new Module(filename, module.parent); mod.filename = filename; mod.paths = APIBasedTestFileCompilerBase._getNodeModulesLookupPath(filename); cache_proxy_1.default.startExternalCaching(this.cachePrefix); mod._compile(code, filename); cache_proxy_1.default.stopExternalCaching(); } } _compileCode(code, filename) { if (this.canPrecompile) return this._precompileCode([{ code, filename }])[0]; throw new Error('Not implemented'); } // eslint-disable-next-line @typescript-eslint/no-unused-vars _precompileCode(testFilesInfo) { throw new Error('Not implemented'); } _getRequireCompilers() { throw new Error('Not implemented'); } _compileExternalModule(mod, filename, requireCompiler, origExt) { if (APIBasedTestFileCompilerBase._isNodeModulesDep(filename) && origExt) origExt(mod, filename); else this._compileModule(mod, filename, requireCompiler, origExt); } _compileExternalModuleInEsmMode(mod, filename, requireCompiler, origExt) { if (!origExt) origExt = this.origRequireExtensions['.js']; if (!APIBasedTestFileCompilerBase._isNodeModulesDep(filename) && !APIBasedTestFileCompilerBase._isTestCafeLibDep(filename)) { global.customExtensionHook = () => { global.customExtensionHook = null; this._compileModule(mod, filename, requireCompiler); }; } return origExt(mod, filename); } _compileModule(mod, filename, requireCompiler) { const code = (0, fs_1.readFileSync)(filename).toString(); const compiledCode = requireCompiler((0, strip_bom_1.default)(code), filename); mod.paths = APIBasedTestFileCompilerBase._getNodeModulesLookupPath(filename); mod._compile(compiledCode, filename); } _setupRequireHook(testFile) { const requireCompilers = this._getRequireCompilers(); this.origRequireExtensions = Object.create(null); Object.keys(requireCompilers).forEach(ext => { const origExt = require.extensions[ext]; this.origRequireExtensions[ext] = origExt; require.extensions[ext] = (mod, filename) => { const hadGlobalAPI = this._hasGlobalAPI(); // NOTE: remove global API so that it will be unavailable for the dependencies if (APIBasedTestFileCompilerBase._isNodeModulesDep(filename) && hadGlobalAPI) this._removeGlobalAPI(); if (this.isCompilerServiceMode) this._compileExternalModuleInEsmMode(mod, filename, requireCompilers[ext], origExt); else this._compileExternalModule(mod, filename, requireCompilers[ext], origExt); if (hadGlobalAPI && !this._hasGlobalAPI()) this._addGlobalAPI(testFile); }; }); } _removeRequireHook() { Object.keys(this.origRequireExtensions).forEach(ext => { require.extensions[ext] = this.origRequireExtensions[ext]; }); } _compileCodeForTestFiles(testFilesInfo) { stack_cleaning_hook_1.default.enabled = true; try { if (this.canPrecompile) return this._precompileCode(testFilesInfo); return testFilesInfo.map(({ code, filename }) => this._compileCode(code, filename)); } catch (err) { throw new runtime_1.TestCompilationError(stack_cleaning_hook_1.default.cleanError(err)); } finally { stack_cleaning_hook_1.default.enabled = false; } } _addGlobalAPI(testFile) { Object.defineProperty(global, 'fixture', { get: () => new fixture_1.default(testFile, this.baseUrl), configurable: true, }); Object.defineProperty(global, 'test', { get: () => new test_1.default(testFile, false, this.baseUrl), configurable: true, }); } _addExportAPIInCompilerServiceMode(testFile) { // 'esm' library has an issue with loading modules // in case of the combination of require and import directives. // This hack allowing achieve the desired behavior. const exportableLibPath = require.resolve('../../api/exportable-lib'); delete require.cache[exportableLibPath]; global[test_file_temp_variable_name_1.default] = { testFile, baseUrl: this.baseUrl }; require('../../api/exportable-lib'); } _addExportAPI(testFile) { if (this.isCompilerServiceMode) this._addExportAPIInCompilerServiceMode(testFile); else (0, add_export_api_1.default)(testFile, exportable_lib_1.default, { baseUrl: this.baseUrl }); } _removeGlobalAPI() { delete global.fixture; delete global.test; } _hasGlobalAPI() { return global.fixture && global.test; } async _runCompiledCode(compiledCode, filename) { const testFile = new test_file_1.default(filename); this._addGlobalAPI(testFile); this._addExportAPI(testFile); stack_cleaning_hook_1.default.enabled = true; this._setupRequireHook(testFile); try { await this._execAsModule(compiledCode, filename); } catch (err) { if (err.code === errRequireEsmErrorCode) throw new runtime_1.ImportESMInCommonJSError(err, filename); if (!(err instanceof runtime_1.APIError)) throw new runtime_1.TestCompilationError(stack_cleaning_hook_1.default.cleanError(err)); throw err; } finally { this._removeRequireHook(); stack_cleaning_hook_1.default.enabled = false; if (!this.experimentalEsm) this._removeGlobalAPI(); } return testFile.getTests(); } precompile(testFilesInfo) { return this._compileCodeForTestFiles(testFilesInfo); } execute(compiledCode, filename) { return this._runCompiledCode(compiledCode, filename); } async compile(code, filename) { const [compiledCode] = await this.precompile([{ code, filename }]); if (compiledCode) return this.execute(compiledCode, filename); return Promise.resolve(); } _hasTests(code) { return FIXTURE_RE.test(code) && TEST_RE.test(code); } cleanUp() { this.cache = {}; } } exports.default = APIBasedTestFileCompilerBase; module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLWJhc2VkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBpbGVyL3Rlc3QtZmlsZS9hcGktYmFzZWQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSwrQkFJYztBQUVkLDJCQUFrQztBQUNsQywwREFBaUM7QUFDakMsbUNBQWdDO0FBQ2hDLGtEQUEwQztBQUMxQyw4RUFBcUQ7QUFDckQsMEVBQWtEO0FBQ2xELG9FQUE0QztBQUM1QyxrREFJOEI7QUFDOUIsMkZBQWlFO0FBQ2pFLG9HQUFnRTtBQUNoRSxnRUFBdUM7QUFDdkMsOEVBQXFEO0FBQ3JELGtHQUEwRTtBQUMxRSxzRUFBNEM7QUFDNUMsOENBQXNCO0FBQ3RCLHFHQUE2RTtBQUc3RSxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7QUFFMUIsTUFBTSxVQUFVLEdBQUcsOEJBQThCLENBQUM7QUFDbEQsTUFBTSxPQUFPLEdBQU0seUJBQXlCLENBQUM7QUFFN0MsTUFBTSx3QkFBd0IsR0FBRyxLQUFLLENBQUM7QUFFdkMsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQztBQUVsQyxNQUFNLHNCQUFzQixHQUFHLGlCQUFpQixDQUFDO0FBRWpELE1BQXFCLDRCQUE2QixTQUFRLGNBQW9CO0lBQzFFLFlBQWEsRUFBRSxxQkFBcUIsRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFO1FBQzVELEtBQUssQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFFbkIsSUFBSSxDQUFDLHFCQUFxQixHQUFHLHFCQUFxQixDQUFDO1FBQ25ELElBQUksQ0FBQyxLQUFLLEdBQW1CLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLHFCQUFxQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLFdBQVcsR0FBYSxJQUFBLGVBQU0sRUFB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MVBELCtDQTBQQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgZGlybmFtZSxcbiAgICByZWxhdGl2ZSxcbiAgICBzZXAgYXMgcGF0aFNlcCxcbn0gZnJvbSAncGF0aCc7XG5cbmltcG9ydCB7IHJlYWRGaWxlU3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCBzdHJpcEJvbSBmcm9tICdzdHJpcC1ib20nO1xuaW1wb3J0IHsgbmFub2lkIH0gZnJvbSAnbmFub2lkJztcbmltcG9ydCBUZXN0RmlsZUNvbXBpbGVyQmFzZSBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0IFRlc3RGaWxlIGZyb20gJy4uLy4uL2FwaS9zdHJ1Y3R1cmUvdGVzdC1maWxlJztcbmltcG9ydCBGaXh0dXJlIGZyb20gJy4uLy4uL2FwaS9zdHJ1Y3R1cmUvZml4dHVyZSc7XG5pbXBvcnQgVGVzdCBmcm9tICcuLi8uLi9hcGkvc3RydWN0dXJlL3Rlc3QnO1xuaW1wb3J0IHtcbiAgICBUZXN0Q29tcGlsYXRpb25FcnJvcixcbiAgICBBUElFcnJvcixcbiAgICBJbXBvcnRFU01JbkNvbW1vbkpTRXJyb3IsXG59IGZyb20gJy4uLy4uL2Vycm9ycy9ydW50aW1lJztcbmltcG9ydCBzdGFja0NsZWFuaW5nSG9vayBmcm9tICcuLi8uLi9lcnJvcnMvc3RhY2stY2xlYW5pbmctaG9vayc7XG5pbXBvcnQgTk9ERV9NT0RVTEVTIGZyb20gJy4uLy4uL3V0aWxzL25vZGUtbW9kdWxlcy1mb2xkZXItbmFtZSc7XG5pbXBvcnQgY2FjaGVQcm94eSBmcm9tICcuL2NhY2hlLXByb3h5JztcbmltcG9ydCBleHBvcnRhYmxlTGliIGZyb20gJy4uLy4uL2FwaS9leHBvcnRhYmxlLWxpYic7XG5pbXBvcnQgVEVTVF9GSUxFX1RFTVBfVkFSSUFCTEVfTkFNRSBmcm9tICcuL3Rlc3QtZmlsZS10ZW1wLXZhcmlhYmxlLW5hbWUnO1xuaW1wb3J0IGFkZEV4cG9ydEFQSSBmcm9tICcuL2FkZC1leHBvcnQtYXBpJztcbmltcG9ydCB1cmwgZnJvbSAndXJsJztcbmltcG9ydCBQUkVWRU5UX01PRFVMRV9DQUNISU5HX1NVRkZJWCBmcm9tICcuLi9wcmV2ZW50LW1vZHVsZS1jYWNoaW5nLXN1ZmZpeCc7XG5cblxuY29uc3QgQ1dEID0gcHJvY2Vzcy5jd2QoKTtcblxuY29uc3QgRklYVFVSRV9SRSA9IC8oXnw7fFxccyspZml4dHVyZVxccyooXFwufFxcKHxgKS87XG5jb25zdCBURVNUX1JFICAgID0gLyhefDt8XFxzKyl0ZXN0XFxzKihcXC58XFwoKS87XG5cbmNvbnN0IFRFU1RDQUZFX0xJQl9GT0xERVJfTkFNRSA9ICdsaWInO1xuXG5jb25zdCBNb2R1bGUgPSBtb2R1bGUuY29uc3RydWN0b3I7XG5cbmNvbnN0IGVyclJlcXVpcmVFc21FcnJvckNvZGUgPSAnRVJSX1JFUVVJUkVfRVNNJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQVBJQmFzZWRUZXN0RmlsZUNvbXBpbGVyQmFzZSBleHRlbmRzIFRlc3RGaWxlQ29tcGlsZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvciAoeyBpc0NvbXBpbGVyU2VydmljZU1vZGUsIGJhc2VVcmwsIGV4cGVyaW1lbnRhbEVzbSB9KSB7XG4gICAgICAgIHN1cGVyKHsgYmFzZVVybCB9KTtcblxuICAgICAgICB0aGlzLmlzQ29tcGlsZXJTZXJ2aWNlTW9kZSA9IGlzQ29tcGlsZXJTZXJ2aWNlTW9kZTtcbiAgICAgICAgdGhpcy5jYWNoZSAgICAgICAgICAgICAgICAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICB0aGlzLm9yaWdSZXF1aXJlRXh0ZW5zaW9ucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuY2FjaGVQcmVmaXggICAgICAgICAgID0gbmFub2lkKDcpO1xuICAgICAgICB0aGlzLmV4cGVyaW1lbnRhbEVzbSAgICAgICA9IGV4cGVyaW1lbnRhbEVzbTtcbiAgICB9XG5cbiAgICBzdGF0aWMgX2dldE5vZGVNb2R1bGVzTG9va3VwUGF0aCAoZmlsZW5hbWUpIHtcbiAgICAgICAgY29uc3QgZGlyID0gZGlybmFtZShmaWxlbmFtZSk7XG5cbiAgICAgICAgcmV0dXJuIE1vZHVsZS5fbm9kZU1vZHVsZVBhdGhzKGRpcik7XG4gICAgfVxuXG4gICAgc3RhdGljIF9pc05vZGVNb2R1bGVzRGVwIChmaWxlbmFtZSkge1xuICAgICAgICByZXR1cm4gcmVsYXRpdmUoQ1dELCBmaWxlbmFtZSlcbiAgICAgICAgICAgIC5zcGxpdChwYXRoU2VwKVxuICAgICAgICAgICAgLmluY2x1ZGVzKE5PREVfTU9EVUxFUyk7XG4gICAgfVxuXG4gICAgc3RhdGljIF9pc1Rlc3RDYWZlTGliRGVwIChmaWxlbmFtZSkge1xuICAgICAgICByZXR1cm4gcmVsYXRpdmUoQ1dELCBmaWxlbmFtZSlcbiAgICAgICAgICAgIC5zcGxpdChwYXRoU2VwKVxuICAgICAgICAgICAgLmluY2x1ZGVzKFRFU1RDQUZFX0xJQl9GT0xERVJfTkFNRSk7XG4gICAgfVxuXG4gICAgYXN5bmMgX2V4ZWNBc01vZHVsZSAoY29kZSwgZmlsZW5hbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuZXhwZXJpbWVudGFsRXNtKSB7XG4gICAgICAgICAgICBjb25zdCBmaWxlVXJsID0gdXJsLnBhdGhUb0ZpbGVVUkwoZmlsZW5hbWUpO1xuXG4gICAgICAgICAgICAvL05PVEU6IEl0IGlzIG5lY2Vzc2FyeSB0byBwcmV2ZW50IG1vZHVsZSBjYWNoaW5nIGR1cmluZyBsaXZlIG1vZGUuXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXZhbFxuICAgICAgICAgICAgYXdhaXQgZXZhbChgaW1wb3J0KCcke2ZpbGVVcmx9PyR7UFJFVkVOVF9NT0RVTEVfQ0FDSElOR19TVUZGSVh9PSR7RGF0ZS5ub3coKX0nKWApO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgbW9kID0gbmV3IE1vZHVsZShmaWxlbmFtZSwgbW9kdWxlLnBhcmVudCk7XG5cbiAgICAgICAgICAgIG1vZC5maWxlbmFtZSA9IGZpbGVuYW1lO1xuICAgICAgICAgICAgbW9kLnBhdGhzICAgID0gQVBJQmFzZWRUZXN0RmlsZUNvbXBpbGVyQmFzZS5fZ2V0Tm9kZU1vZHVsZXNMb29rdXBQYXRoKGZpbGVuYW1lKTtcblxuICAgICAgICAgICAgY2FjaGVQcm94eS5zdGFydEV4dGVybmFsQ2FjaGluZyh0aGlzLmNhY2hlUHJlZml4KTtcblxuICAgICAgICAgICAgbW9kLl9jb21waWxlKGNvZGUsIGZpbGVuYW1lKTtcblxuICAgICAgICAgICAgY2FjaGVQcm94eS5zdG9wRXh0ZXJuYWxDYWNoaW5nKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfY29tcGlsZUNvZGUgKGNvZGUsIGZpbGVuYW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmNhblByZWNvbXBpbGUpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcHJlY29tcGlsZUNvZGUoW3sgY29kZSwgZmlsZW5hbWUgfV0pWzBdO1xuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIF9wcmVjb21waWxlQ29kZSAodGVzdEZpbGVzSW5mbykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIF9nZXRSZXF1aXJlQ29tcGlsZXJzICgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBfY29tcGlsZUV4dGVybmFsTW9kdWxlIChtb2QsIGZpbGVuYW1lLCByZXF1aXJlQ29tcGlsZXIsIG9yaWdFeHQpIHtcbiAgICAgICAgaWYgKEFQSUJhc2VkVGVzdEZpbGVDb21waWxlckJhc2UuX2lzTm9kZU1vZHVsZXNEZXAoZmlsZW5hbWUpICYmIG9yaWdFeHQpXG4gICAgICAgICAgICBvcmlnRXh0KCBtb2QsIGZpbGVuYW1lICk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRoaXMuX2NvbXBpbGVNb2R1bGUobW9kLCBmaWxlbmFtZSwgcmVxdWlyZUNvbXBpbGVyLCBvcmlnRXh0KTtcbiAgICB9XG5cbiAgICBfY29tcGlsZUV4dGVybmFsTW9kdWxlSW5Fc21Nb2RlIChtb2QsIGZpbGVuYW1lLCByZXF1aXJlQ29tcGlsZXIsIG9yaWdFeHQpIHtcbiAgICAgICAgaWYgKCFvcmlnRXh0KVxuICAgICAgICAgICAgb3JpZ0V4dCA9IHRoaXMub3JpZ1JlcXVpcmVFeHRlbnNpb25zWycuanMnXTtcblxuICAgICAgICBpZiAoIUFQSUJhc2VkVGVzdEZpbGVDb21waWxlckJhc2UuX2lzTm9kZU1vZHVsZXNEZXAoZmlsZW5hbWUpICYmXG4gICAgICAgICAgICAhQVBJQmFzZWRUZXN0RmlsZUNvbXBpbGVyQmFzZS5faXNUZXN0Q2FmZUxpYkRlcChmaWxlbmFtZSkpIHtcbiAgICAgICAgICAgIGdsb2JhbC5jdXN0b21FeHRlbnNpb25Ib29rID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGdsb2JhbC5jdXN0b21FeHRlbnNpb25Ib29rID0gbnVsbDtcblxuICAgICAgICAgICAgICAgIHRoaXMuX2NvbXBpbGVNb2R1bGUobW9kLCBmaWxlbmFtZSwgcmVxdWlyZUNvbXBpbGVyKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb3JpZ0V4dChtb2QsIGZpbGVuYW1lKTtcbiAgICB9XG5cblxuICAgIF9jb21waWxlTW9kdWxlIChtb2QsIGZpbGVuYW1lLCByZXF1aXJlQ29tcGlsZXIpIHtcbiAgICAgICAgY29uc3QgY29kZSAgICAgICAgID0gcmVhZEZpbGVTeW5jKGZpbGVuYW1lKS50b1N0cmluZygpO1xuICAgICAgICBjb25zdCBjb21waWxlZENvZGUgPSByZXF1aXJlQ29tcGlsZXIoc3RyaXBCb20oY29kZSksIGZpbGVuYW1lKTtcblxuICAgICAgICBtb2QucGF0aHMgPSBBUElCYXNlZFRlc3RGaWxlQ29tcGlsZXJCYXNlLl9nZXROb2RlTW9kdWxlc0xvb2t1cFBhdGgoZmlsZW5hbWUpO1xuXG4gICAgICAgIG1vZC5fY29tcGlsZShjb21waWxlZENvZGUsIGZpbGVuYW1lKTtcbiAgICB9XG5cbiAgICBfc2V0dXBSZXF1aXJlSG9vayAodGVzdEZpbGUpIHtcbiAgICAgICAgY29uc3QgcmVxdWlyZUNvbXBpbGVycyA9IHRoaXMuX2dldFJlcXVpcmVDb21waWxlcnMoKTtcblxuICAgICAgICB0aGlzLm9yaWdSZXF1aXJlRXh0ZW5zaW9ucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgICAgICAgT2JqZWN0LmtleXMocmVxdWlyZUNvbXBpbGVycykuZm9yRWFjaChleHQgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb3JpZ0V4dCA9IHJlcXVpcmUuZXh0ZW5zaW9uc1tleHRdO1xuXG4gICAgICAgICAgICB0aGlzLm9yaWdSZXF1aXJlRXh0ZW5zaW9uc1tleHRdID0gb3JpZ0V4dDtcblxuICAgICAgICAgICAgcmVxdWlyZS5leHRlbnNpb25zW2V4dF0gPSAobW9kLCBmaWxlbmFtZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhZEdsb2JhbEFQSSA9IHRoaXMuX2hhc0dsb2JhbEFQSSgpO1xuXG4gICAgICAgICAgICAgICAgLy8gTk9URTogcmVtb3ZlIGdsb2JhbCBBUEkgc28gdGhhdCBpdCB3aWxsIGJlIHVuYXZhaWxhYmxlIGZvciB0aGUgZGVwZW5kZW5jaWVzXG4gICAgICAgICAgICAgICAgaWYgKEFQSUJhc2VkVGVzdEZpbGVDb21waWxlckJhc2UuX2lzTm9kZU1vZHVsZXNEZXAoZmlsZW5hbWUpICYmIGhhZEdsb2JhbEFQSSlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVtb3ZlR2xvYmFsQVBJKCk7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0NvbXBpbGVyU2VydmljZU1vZGUpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NvbXBpbGVFeHRlcm5hbE1vZHVsZUluRXNtTW9kZShtb2QsIGZpbGVuYW1lLCByZXF1aXJlQ29tcGlsZXJzW2V4dF0sIG9yaWdFeHQpO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29tcGlsZUV4dGVybmFsTW9kdWxlKG1vZCwgZmlsZW5hbWUsIHJlcXVpcmVDb21waWxlcnNbZXh0XSwgb3JpZ0V4dCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoaGFkR2xvYmFsQVBJICYmICF0aGlzLl9oYXNHbG9iYWxBUEkoKSlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYWRkR2xvYmFsQVBJKHRlc3RGaWxlKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9yZW1vdmVSZXF1aXJlSG9vayAoKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMub3JpZ1JlcXVpcmVFeHRlbnNpb25zKS5mb3JFYWNoKGV4dCA9PiB7XG4gICAgICAgICAgICByZXF1aXJlLmV4dGVuc2lvbnNbZXh0XSA9IHRoaXMub3JpZ1JlcXVpcmVFeHRlbnNpb25zW2V4dF07XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9jb21waWxlQ29kZUZvclRlc3RGaWxlcyAodGVzdEZpbGVzSW5mbykge1xuICAgICAgICBzdGFja0NsZWFuaW5nSG9vay5lbmFibGVkID0gdHJ1ZTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHRoaXMuY2FuUHJlY29tcGlsZSlcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcHJlY29tcGlsZUNvZGUodGVzdEZpbGVzSW5mbyk7XG5cbiAgICAgICAgICAgIHJldHVybiB0ZXN0RmlsZXNJbmZvLm1hcCgoeyBjb2RlLCBmaWxlbmFtZSB9KSA9PiB0aGlzLl9jb21waWxlQ29kZShjb2RlLCBmaWxlbmFtZSkpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUZXN0Q29tcGlsYXRpb25FcnJvcihzdGFja0NsZWFuaW5nSG9vay5jbGVhbkVycm9yKGVycikpO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgc3RhY2tDbGVhbmluZ0hvb2suZW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2FkZEdsb2JhbEFQSSAodGVzdEZpbGUpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGdsb2JhbCwgJ2ZpeHR1cmUnLCB7XG4gICAgICAgICAgICBnZXQ6ICAgICAgICAgICgpID0+IG5ldyBGaXh0dXJlKHRlc3RGaWxlLCB0aGlzLmJhc2VVcmwpLFxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB9KTtcblxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsLCAndGVzdCcsIHtcbiAgICAgICAgICAgIGdldDogICAgICAgICAgKCkgPT4gbmV3IFRlc3QodGVzdEZpbGUsIGZhbHNlLCB0aGlzLmJhc2VVcmwpLFxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfYWRkRXhwb3J0QVBJSW5Db21waWxlclNlcnZpY2VNb2RlICh0ZXN0RmlsZSkge1xuICAgICAgICAvLyAnZXNtJyBsaWJyYXJ5IGhhcyBhbiBpc3N1ZSB3aXRoIGxvYWRpbmcgbW9kdWxlc1xuICAgICAgICAvLyBpbiBjYXNlIG9mIHRoZSBjb21iaW5hdGlvbiBvZiByZXF1aXJlIGFuZCBpbXBvcnQgZGlyZWN0aXZlcy5cbiAgICAgICAgLy8gVGhpcyBoYWNrIGFsbG93aW5nIGFjaGlldmUgdGhlIGRlc2lyZWQgYmVoYXZpb3IuXG4gICAgICAgIGNvbnN0IGV4cG9ydGFibGVMaWJQYXRoID0gcmVxdWlyZS5yZXNvbHZlKCcuLi8uLi9hcGkvZXhwb3J0YWJsZS1saWInKTtcblxuICAgICAgICBkZWxldGUgcmVxdWlyZS5jYWNoZVtleHBvcnRhYmxlTGliUGF0aF07XG5cbiAgICAgICAgZ2xvYmFsW1RFU1RfRklMRV9URU1QX1ZBUklBQkxFX05BTUVdID0geyB0ZXN0RmlsZSwgYmFzZVVybDogdGhpcy5iYXNlVXJsIH07XG5cbiAgICAgICAgcmVxdWlyZSgnLi4vLi4vYXBpL2V4cG9ydGFibGUtbGliJyk7XG4gICAgfVxuXG4gICAgX2FkZEV4cG9ydEFQSSAodGVzdEZpbGUpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNDb21waWxlclNlcnZpY2VNb2RlKVxuICAgICAgICAgICAgdGhpcy5fYWRkRXhwb3J0QVBJSW5Db21waWxlclNlcnZpY2VNb2RlKHRlc3RGaWxlKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgYWRkRXhwb3J0QVBJKHRlc3RGaWxlLCBleHBvcnRhYmxlTGliLCB7IGJhc2VVcmw6IHRoaXMuYmFzZVVybCB9KTtcbiAgICB9XG5cbiAgICBfcmVtb3ZlR2xvYmFsQVBJICgpIHtcbiAgICAgICAgZGVsZXRlIGdsb2JhbC5maXh0dXJlO1xuICAgICAgICBkZWxldGUgZ2xvYmFsLnRlc3Q7XG4gICAgfVxuXG4gICAgX2hhc0dsb2JhbEFQSSAoKSB7XG4gICAgICAgIHJldHVybiBnbG9iYWwuZml4dHVyZSAmJiBnbG9iYWwudGVzdDtcbiAgICB9XG5cbiAgICBhc3luYyBfcnVuQ29tcGlsZWRDb2RlIChjb21waWxlZENvZGUsIGZpbGVuYW1lKSB7XG4gICAgICAgIGNvbnN0IHRlc3RGaWxlID0gbmV3IFRlc3RGaWxlKGZpbGVuYW1lKTtcblxuICAgICAgICB0aGlzLl9hZGRHbG9iYWxBUEkodGVzdEZpbGUpO1xuICAgICAgICB0aGlzLl9hZGRFeHBvcnRBUEkodGVzdEZpbGUpO1xuXG4gICAgICAgIHN0YWNrQ2xlYW5pbmdIb29rLmVuYWJsZWQgPSB0cnVlO1xuXG4gICAgICAgIHRoaXMuX3NldHVwUmVxdWlyZUhvb2sodGVzdEZpbGUpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9leGVjQXNNb2R1bGUoY29tcGlsZWRDb2RlLCBmaWxlbmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSBlcnJSZXF1aXJlRXNtRXJyb3JDb2RlKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbXBvcnRFU01JbkNvbW1vbkpTRXJyb3IoZXJyLCBmaWxlbmFtZSk7XG5cbiAgICAgICAgICAgIGlmICghKGVyciBpbnN0YW5jZW9mIEFQSUVycm9yKSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVGVzdENvbXBpbGF0aW9uRXJyb3Ioc3RhY2tDbGVhbmluZ0hvb2suY2xlYW5FcnJvcihlcnIpKTtcblxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlUmVxdWlyZUhvb2soKTtcbiAgICAgICAgICAgIHN0YWNrQ2xlYW5pbmdIb29rLmVuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmV4cGVyaW1lbnRhbEVzbSlcbiAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVHbG9iYWxBUEkoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0ZXN0RmlsZS5nZXRUZXN0cygpO1xuICAgIH1cblxuXG4gICAgcHJlY29tcGlsZSAodGVzdEZpbGVzSW5mbykge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29tcGlsZUNvZGVGb3JUZXN0RmlsZXModGVzdEZpbGVzSW5mbyk7XG4gICAgfVxuXG4gICAgZXhlY3V0ZSAoY29tcGlsZWRDb2RlLCBmaWxlbmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcnVuQ29tcGlsZWRDb2RlKGNvbXBpbGVkQ29kZSwgZmlsZW5hbWUpO1xuICAgIH1cblxuICAgIGFzeW5jIGNvbXBpbGUgKGNvZGUsIGZpbGVuYW1lKSB7XG4gICAgICAgIGNvbnN0IFtjb21waWxlZENvZGVdID0gYXdhaXQgdGhpcy5wcmVjb21waWxlKFt7IGNvZGUsIGZpbGVuYW1lIH1dKTtcblxuICAgICAgICBpZiAoY29tcGlsZWRDb2RlKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZShjb21waWxlZENvZGUsIGZpbGVuYW1lKTtcblxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgX2hhc1Rlc3RzIChjb2RlKSB7XG4gICAgICAgIHJldHVybiBGSVhUVVJFX1JFLnRlc3QoY29kZSkgJiYgVEVTVF9SRS50ZXN0KGNvZGUpO1xuICAgIH1cblxuICAgIGNsZWFuVXAgKCkge1xuICAgICAgICB0aGlzLmNhY2hlID0ge307XG4gICAgfVxufVxuIl19