Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/wojtekmaj/vitest-react-native. Run React Native unit and component tests with Vitest
Something went wrong. Try again.
3.6 kB · 114 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115import { readFileSync } from 'node:fs';import { fileURLToPath } from 'node:url';
import { mockSuffix, presetApiPrefix } from './preset.js';import { findPackageDirectory, readPackageManifest } from './resolve.js';import { transformNative } from './transform.js';
import type { LoadHookSync } from 'node:module';import type { NativeRuntime } from './runtime-types.js';
/** * Supplies virtual native mocks and Babel-compiled sources to Node's synchronous loader. */export function createLoadHook(runtime: NativeRuntime): LoadHookSync { const { root, options, compilerDirectories, nativeSetupFiles, loadedFiles } = runtime; const packageCache = new Map<string, boolean>();
return (url, context, nextLoad) => { if (url.startsWith(presetApiPrefix)) { const parent = decodeURIComponent(url.slice(presetApiPrefix.length));
return { format: 'commonjs', shortCircuit: true, source: `module.exports = { jest: globalThis.__vitestReactNative.createPresetApi(${JSON.stringify(parent)}) };`, }; }
if (!url.startsWith('file:')) { return nextLoad(url, context); }
const filename = fileURLToPath(url);
// Compiler plugins must load normally to avoid invoking Babel recursively if (compilerDirectories.some((directory) => filename.startsWith(`${directory}/`))) { return nextLoad(url, context); }
if (filename.endsWith(mockSuffix)) { loadedFiles.add(filename);
return { format: 'commonjs', shortCircuit: true, source: `module.exports = globalThis.__vitestReactNative.getMock(${JSON.stringify(filename.slice(0, -mockSuffix.length))});`, }; }
const normalized = filename.replaceAll('\\', '/'); const packageDirectory = findPackageDirectory(filename); let nativePackage = false;
// Inspect each package once; native libraries frequently ship raw source if (packageDirectory) { if (!packageCache.has(packageDirectory)) { const manifest = readPackageManifest(packageDirectory);
packageCache.set( packageDirectory, Boolean( options.transformPackages?.includes(manifest.name) || manifest['react-native'] || manifest.peerDependencies?.['react-native'] || manifest.dependencies?.['react-native'] || /^(?:react-native(?:-|$)|@react-navigation\/|@react-native-|@react-native\/(?:jest-preset|js-polyfills|virtualized-lists)$)/.test( manifest.name, ), ), ); }
nativePackage = packageCache.get(packageDirectory) ?? false; }
const extraPackage = options.transformPackages?.some((name) => normalized.includes(`/node_modules/${name}/`), );
if (/\.(?:svg|png|jpe?g|gif|webp|avif|mp3|mp4|ttf|otf|woff2?)$/.test(filename)) { loadedFiles.add(filename);
return { format: 'commonjs', shortCircuit: true, source: filename.endsWith('.svg') ? "module.exports = require('react-native').View;" : 'module.exports = 1;', }; }
const typescript = /\.tsx?$/.test(filename);
if ( (nativePackage || extraPackage || typescript || nativeSetupFiles.includes(filename)) && /\.[cm]?[jt]sx?$/.test(filename) ) { loadedFiles.add(filename);
return { format: 'commonjs', shortCircuit: true, source: transformNative( readFileSync(filename, 'utf8'), filename, root, options.babelPlugins, ), }; }
return nextLoad(url, context); };}