javascript - funcion - mostrar loading mientras carga pagina jquery
Especifique el código para ejecutar antes de que ocurra cualquier configuración de Jest (3)
El tl; dr es:
1) ¿Cómo puedo hacer que Jest use la función nativa require
para cargar todos los módulos en mis pruebas en cualquier lugar?
2) ¿Dónde / cómo iría para modificar (es decir, reemplazar con el cargador de esm) https://github.com/standard-things/esm la función requerida en un lugar, antes de que se ejecuten las pruebas, por lo que todas las pruebas usarán la versión modificada? exigir.
Me gustaría usar el esm-loader con mis archivos de prueba de Jest. Para hacerlo, necesito parchear la función require globalmente, antes de que se ejecute cualquier código de prueba, con algo como
require = require("@std/esm")(module, { esm: "js", cjs: true });
¿Cómo le digo a Jest que ejecute ese código antes de tocar o solicitar algo más?
Intenté apuntar tanto setupTestFrameworkScriptFile
como una entrada de array setupFiles
a un archivo con eso, pero ninguno funcionó (aunque sí confirmé que ambos se ejecutaron).
Alternativamente, estoy disparando estas pruebas con un script npm
"scripts": {
"test": "jest"
}
¿Hay alguna magia CLI por la que solo pueda cargar un módulo y luego ejecutar jest
?
Editar: las opciones testEnvironment
y resolver
me hacen preguntarme si esto está incluso utilizando la función de Nodo real para cargar módulos, o en su lugar utiliza su propio cargador de módulos. Si es así me pregunto si esto es posible.
Así que este fue un poco difícil de trabajar. La solución es bastante simple, pero me tomó un tiempo hacerlo funcionar. El problema es que siempre que uses cualquier módulo en jest.
- Archivos de configuración
- Archivos de Framework de instalación
- Archivos de prueba
- Archivos de módulo
Todos ellos están cargados en forma inferior
({"Objeto": función (módulo, exportaciones, requerimiento, __ dirname, __ filename, global, jest) { / * Código de módulo dentro de * / }});
Si echa un vistazo a node_modules/jest-runtime/build/index.js:495:510
const dirname = (_path || _load_path()).default.dirname(filename);
localModule.children = [];
localModule.parent = mockParentModule;
localModule.paths = this._resolver.getModulePaths(dirname);
localModule.require = this._createRequireImplementation(filename, options);
const transformedFile = this._scriptTransformer.transform(
filename,
{
collectCoverage: this._coverageOptions.collectCoverage,
collectCoverageFrom: this._coverageOptions.collectCoverageFrom,
collectCoverageOnlyFrom: this._coverageOptions.collectCoverageOnlyFrom,
isInternalModule,
mapCoverage: this._coverageOptions.mapCoverage },
this._cacheFS[filename]);
this._createRequireImplementation(filename, options);
le da a cada módulo un objeto de requerimiento personalizado. Por lo tanto, usted como tal no obtiene la función de requerimiento nativo en ningún lugar. Una vez que jest haya comenzado, todos los módulos cargados a partir de ese momento tendrán la función personalizada require
jest.
Cuando requireModule
un módulo, se requireModule
métodos requireModule
de jest-runtime
. A continuación se muestra un extracto de la misma
moduleRegistry[modulePath] = localModule;
if ((_path || _load_path()).default.extname(modulePath) === ''.json'') {
localModule.exports = this._environment.global.JSON.parse(
(0, (_stripBom || _load_stripBom()).default)((_gracefulFs || _load_gracefulFs()).default.readFileSync(modulePath, ''utf8'')));
} else if ((_path || _load_path()).default.extname(modulePath) === ''.node'') {
// $FlowFixMe
localModule.exports = require(modulePath);
} else {
this._execModule(localModule, options);
}
Como puede ver si la extensión del archivo es .node
, carga el módulo directamente, sino que llama al _execModule
. Esta función es el mismo código que publiqué anteriormente, que realiza la transformación del código.
const isInternalModule = !!(options && options.isInternalModule);
const filename = localModule.filename;
const lastExecutingModulePath = this._currentlyExecutingModulePath;
this._currentlyExecutingModulePath = filename;
const origCurrExecutingManualMock = this._isCurrentlyExecutingManualMock;
this._isCurrentlyExecutingManualMock = filename;
const dirname = (_path || _load_path()).default.dirname(filename);
localModule.children = [];
localModule.parent = mockParentModule;
localModule.paths = this._resolver.getModulePaths(dirname);
localModule.require = this._createRequireImplementation(filename, options);
Ahora, cuando queremos modificar la función require
para nuestra prueba, necesitamos _execModule
para exportar nuestro código directamente. Por lo tanto, el código debe ser similar a la carga de un módulo .node
} else if ((_path || _load_path()).default.extname(modulePath) === ''.mjs'') {
// $FlowFixMe
require = require("@std/esm")(localModule);
localModule.exports = require(modulePath);
} else {
Pero hacer eso significaría parchear el código, lo que queremos evitar. Entonces, lo que hacemos en su lugar es evitar usar el comando jest directamente, y crear nuestro propio jestload.js
y ejecutar eso. El código para cargar jest es simple.
#!/usr/bin/env node
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
cli = require(''jest/bin/jest'');
Ahora queremos modificar el _execModule
antes de que _execModule
el cli. Así que agregamos el siguiente código
const jestRuntime = require("jest-runtime");
oldexecModule = jestRuntime.prototype._execModule;
jestRuntime.prototype._execModule = function (localModule, options) {
if (localModule.id.indexOf(".mjs") > 0) {
localModule.exports = require("@std/esm")(localModule)(localModule.id);
return localModule;
}
return oldexecModule.apply(this, [localModule, options]);
};
cli = require(''jest/bin/jest'');
Ahora es el momento para una prueba
//__test__/sum.test.js
sum = require(''../sum.mjs'').sum;
test(''adds 1 + 2 to equal 3'', () => {
expect(sum(1, 2)).toBe(3);
});
test(''adds 2 + 3 to equal 5'', () => {
expect(sum(3, 2)).toBe(5);
});
Y un archivo sum.mjs
export function sum (x, y) { return x + y }
Ahora corremos la prueba
La solución está disponible en el siguiente repositorio.
https://github.com/tarunlalwani/jest-overriding-require-function-
Puede clonar y probar la solución ejecutando la npm test
.
Intenté usar node -r @std/esm run.js
donde run.js es solo un script que llama jest, pero no funciona y se bloquea aquí: https://github.com/facebook/jest/blob/master/packages/jest-runtime/src/script_transformer.js#L305 .
Por lo que entiendo de esta línea significa que no es posible porque jest compila el módulo usando el módulo vm
nativo. Las líneas anteriores (290):
if (willTransform) {
const transformedSource = this.transformSource(
filename,
content,
instrument,
!!(options && options.mapCoverage));
wrappedCode = wrap(transformedSource.code);
sourceMapPath = transformedSource.sourceMapPath;
} else {
es el código al que se llama cuando está especificando transformaciones en su jest config.
Conclusión: hasta que se admita .mjs
(y estarán bajo la extensión .mjs
) no se pueden importar módulos en jest sin especificar una transformación. Usted podría tratar de mono parche vm
pero realmente desaconsejaría esta opción.
Especificar una transformación jest no es realmente tan difícil, y para los módulos es realmente tan simple como usar babel-jest
con la configuración babel correcta:
Debajo de un package.json con configuraciones mínimas.
{
"dependencies": {
"babel-jest": "^21.2.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"jest": "^21.2.1"
},
"jest": {
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.js?(x)",
"<rootDir>/src/**/?(*.)(spec|test).js?(x)"
],
"transform": {
"^.+//.(js|jsx)$": "<rootDir>/node_modules/babel-jest"
},
"testEnvironment": "node",
"testURL": "http://localhost",
"moduleFileExtensions": [
"js",
"json"
]
},
"babel": {
"plugins": ["babel-plugin-transform-es2015-modules-commonjs"]
}
}
setupFiles
funcionó para mí. Agregue esto en package.json:
"jest": {
"setupFiles": ["./my_file.js"]
},
https://jestjs.io/docs/en/configuration.html#setupfiles-array