jest-preview
Version:
Preview your Jest tests in a browser
104 lines (97 loc) • 4.25 kB
JavaScript
;
require('fs');
var path = require('path');
require('crypto');
require('child_process');
require('url');
var camelcase = require('camelcase');
var slash = require('slash');
var core = require('@svgr/core');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var camelcase__default = /*#__PURE__*/_interopDefaultLegacy(camelcase);
var slash__default = /*#__PURE__*/_interopDefaultLegacy(slash);
function getRelativeFilename(filename) {
return slash__default["default"](filename.split(process.cwd())[1]);
}
function processFile(src, filename) {
// /Users/your-name/your-project/src/assets/image.png => /src/assets/image.png
const relativeFilenameStringified = JSON.stringify(getRelativeFilename(filename));
// TODO: To support https://github.com/jpkleemans/vite-svg-loader and https://github.com/pd4d10/vite-plugin-svgr (already supported) as well
if (filename.match(/\.svg$/)) {
// Based on how SVGR generates a component name:
// https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
const pascalCaseFilename = camelcase__default["default"](path__default["default"].parse(filename).name, {
pascalCase: true,
});
const componentName = `Svg${pascalCaseFilename}`;
try {
const svgComponent = core.transform.sync(src, {
// Do not insert `import * as React from "react";`
jsxRuntime: 'automatic',
}, { componentName });
// We need to transpile jsx to vanilla jsx so Jest can understand
// @babel/core is bundled with jest
// I guess @babel/plugin-transform-react-jsx is installed by default? TODO: To validate this assumption
// TODO: Do we have any other option to transpile jsx to vanilla jsx?
// vite-plugin-svgr uses esbuild https://github.com/pd4d10/vite-plugin-svgr/blob/main/src/index.ts
// How about add esbuild as dependency then use esbuild to transpile jsx to vanilla jsx?
const babel = require('@babel/core');
const result = babel.transformSync(svgComponent, {
plugins: ['@babel/plugin-transform-react-jsx'],
});
// TODO: This is workaround to remove "export default". We might comeback to find a better solution
const componentCodeWithoutExport = result.code
.split('\n')
.slice(0, -1) // Remove the last line
.join('\n');
return {
// TODO: To render actual SVG to the snapshot
code: `const React = require('react')
${componentCodeWithoutExport}
module.exports = {
__esModule: true,
default: ${relativeFilenameStringified},
ReactComponent: ${componentName}
};`,
};
}
catch (error) {
// In case of there is any error, fallback to a span with filename
return {
code: `const React = require('react');
module.exports = {
__esModule: true,
default: ${relativeFilenameStringified},
ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
return {
$$typeof: Symbol.for('react.element'),
type: 'span',
ref: ref,
key: null,
props: Object.assign({}, props, {
children: ${relativeFilenameStringified}
})
};
}),
};`,
};
}
}
return {
code: `module.exports = {
__esModule: true,
default: ${relativeFilenameStringified},
};`,
};
}
// We keep processFileCRA for backward compatible reason
function processFileCRA(src, filename) {
// TODO: To add deprecation warning here (using chalk)
return processFile(src, filename);
}
function process$1(src, filename) {
return processFileCRA(src, filename);
}
var fileCRA = { process: process$1 };
module.exports = fileCRA;