@tunnckocore/jest
Version:
Shareable configurations for all @tunnckoCore projects
128 lines (105 loc) • 3.6 kB
JavaScript
const fs = require('fs');
const os = require('os');
const path = require('path');
const { transformFileSync } = require('@babel/core');
const { pass, fail } = require('@tunnckocore/create-jest-runner');
const { isMonorepo } = require('../../../src/index-cjs');
const isWin32 = os.platform() === 'win32';
/* eslint max-statements: ["error", 50] */
module.exports = async function babelRunner({ testPath, config }) {
const start = new Date();
const name = '@tunnckocore/jest-runner-babel';
/**
* ! JEST HACK !
* Jest HACK for getting passed Runner's options to the jest config.
* All of these are usually arrays, you need to pass named property there.
*
* For example this `jest.config.js`:
*
* ```js
* const config = {
* displayName: 'lint',
* testEnvironment: 'node',
* testMatch: [
* '<rootDir>/src/**'
* ]
* };
*
* config.testMatch['jest-runner-eslint'] = { some: 'options' };
* module.exports = config;
* ```
*/
const runnerOptions =
// ? possible in future v25?
config.runnerOptions ||
config.runnerConfig ||
// ! hacks
config.testMatch[name] ||
config.testPathIgnorePatterns[name] ||
config.moduleDirectories[name] ||
config.modulePathIgnorePatterns[name] ||
config.setupFiles[name] ||
// ! extreme hack, because above stopped working in this monorepo for some reason
// ! it's not about the jest version update, something other is messed.
(process.env[name] ? JSON.parse(process.env[name]) : {});
const runnerConfig = { ...runnerOptions };
let result = null;
try {
result = transformFileSync(testPath, runnerConfig);
} catch (err) {
return fail({
start,
end: new Date(),
test: { path: testPath, title: 'Babel', errorMessage: err.message },
});
}
// Classic in the genre! Yes, it's possible.
if (!result) {
return fail({
start,
end: new Date(),
test: { path: testPath, title: 'Babel', errorMessage: 'faling...' },
});
}
runnerConfig.outDir = runnerConfig.outDir || runnerConfig.outdir;
if (typeof runnerConfig.outDir !== 'string') {
runnerConfig.outDir = 'dist';
}
let { rootDir } = config;
let relativePath = path.relative(rootDir, testPath);
// console.log(testPath);
// we are in monorepo environment,
// so make dist folder in each package root
if (isMonorepo(config.cwd)) {
if (isWin32 && !relativePath.includes('/')) {
relativePath = relativePath.replace(/\\/g, '/');
}
const segments = relativePath.split('/');
while (segments.length > 3) segments.pop();
rootDir = path.join(rootDir, ...segments);
// common case
if (rootDir.endsWith('src')) {
relativePath = path.relative(rootDir, testPath);
rootDir = path.dirname(rootDir);
}
}
// common case
if (relativePath.startsWith('src')) {
relativePath = path.relative(path.join(rootDir, 'src'), testPath);
}
// ! important: the `rootDir` here is already a package's directory
// ! like <monorepo root>/<workspace name>/<package dir> so we can append the dist
let outDir = path.resolve(rootDir, runnerConfig.outDir);
let outFile = path.join(outDir, relativePath);
// the new dir of the new file
outDir = path.dirname(outFile);
const basename = path.basename(outFile, path.extname(outFile));
outFile = path.join(outDir, `${basename}.js`);
fs.mkdirSync(path.dirname(outFile), { recursive: true });
fs.writeFileSync(outFile, result.code);
return pass({
start,
end: new Date(),
test: { path: outFile },
});
};