Innovenergy_trunk/frontend/node_modules/testcafe/lib/compiler/test-file/api-based.js

220 lines
31 KiB
JavaScript
Raw Permalink Normal View History

"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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