[d565449] | 1 | /* eslint-env jest */
|
---|
| 2 | import getProp from '../src/getProp';
|
---|
| 3 |
|
---|
| 4 | const nodeVersion = parseInt(process.version.match(/^v(\d+)\./)[1], 10);
|
---|
| 5 |
|
---|
| 6 | export const fallbackToBabylon = nodeVersion < 6;
|
---|
| 7 |
|
---|
| 8 | let parserName;
|
---|
| 9 | const babelParser = fallbackToBabylon ? require('babylon') : require('@babel/parser');
|
---|
| 10 | const flowParser = require('flow-parser');
|
---|
| 11 |
|
---|
| 12 | const defaultPlugins = [
|
---|
| 13 | 'jsx',
|
---|
| 14 | 'functionBind',
|
---|
| 15 | 'estree',
|
---|
| 16 | 'objectRestSpread',
|
---|
| 17 | 'optionalChaining',
|
---|
| 18 | // 'nullishCoalescing', // TODO: update to babel 7
|
---|
| 19 | ];
|
---|
| 20 | let plugins = [...defaultPlugins];
|
---|
| 21 | let isESM = false;
|
---|
| 22 |
|
---|
| 23 | export function setParserName(name) {
|
---|
| 24 | parserName = name;
|
---|
| 25 | }
|
---|
| 26 |
|
---|
| 27 | export function changePlugins(pluginOrFn) {
|
---|
| 28 | if (Array.isArray(pluginOrFn)) {
|
---|
| 29 | plugins = pluginOrFn;
|
---|
| 30 | } else if (typeof pluginOrFn === 'function') {
|
---|
| 31 | plugins = pluginOrFn(plugins);
|
---|
| 32 | } else {
|
---|
| 33 | throw new Error('changePlugins argument should be either an array or a function');
|
---|
| 34 | }
|
---|
| 35 | }
|
---|
| 36 |
|
---|
| 37 | export function setIsESM() {
|
---|
| 38 | isESM = true;
|
---|
| 39 | }
|
---|
| 40 |
|
---|
| 41 | beforeEach(() => {
|
---|
| 42 | plugins = [...defaultPlugins];
|
---|
| 43 | isESM = false;
|
---|
| 44 | });
|
---|
| 45 |
|
---|
| 46 | function parse(code) {
|
---|
| 47 | if (parserName === undefined) {
|
---|
| 48 | throw new Error('No parser specified');
|
---|
| 49 | }
|
---|
| 50 | if (parserName === 'babel') {
|
---|
| 51 | try {
|
---|
| 52 | return babelParser.parse(code, { plugins, sourceFilename: 'test.js', ...(isESM && { sourceType: 'module' }) });
|
---|
| 53 | } catch (_) {
|
---|
| 54 | // eslint-disable-next-line no-console
|
---|
| 55 | console.warn(`Failed to parse with ${fallbackToBabylon ? 'babylon' : 'Babel'} parser.`);
|
---|
| 56 | }
|
---|
| 57 | }
|
---|
| 58 | if (parserName === 'flow') {
|
---|
| 59 | try {
|
---|
| 60 | return flowParser.parse(code, { plugins });
|
---|
| 61 | } catch (_) {
|
---|
| 62 | // eslint-disable-next-line no-console
|
---|
| 63 | console.warn('Failed to parse with the Flow parser');
|
---|
| 64 | }
|
---|
| 65 | }
|
---|
| 66 | throw new Error(`The parser ${parserName} is not yet supported for testing.`);
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | export function getOpeningElement(code) {
|
---|
| 70 | const parsedCode = parse(code);
|
---|
| 71 | let body;
|
---|
| 72 | if (parsedCode.program) {
|
---|
| 73 | // eslint-disable-next-line prefer-destructuring
|
---|
| 74 | body = parsedCode.program.body;
|
---|
| 75 | } else {
|
---|
| 76 | // eslint-disable-next-line prefer-destructuring
|
---|
| 77 | body = parsedCode.body;
|
---|
| 78 | }
|
---|
| 79 | if (Array.isArray(body) && body[0] != null) {
|
---|
| 80 | const [{ expression }] = body;
|
---|
| 81 | return expression.type === 'JSXFragment' ? expression.openingFragment : expression.openingElement;
|
---|
| 82 | }
|
---|
| 83 |
|
---|
| 84 | return null;
|
---|
| 85 | }
|
---|
| 86 |
|
---|
| 87 | export function extractProp(code, prop = 'foo') {
|
---|
| 88 | const node = getOpeningElement(code);
|
---|
| 89 | const { attributes: props } = node;
|
---|
| 90 | return getProp(props, prop);
|
---|
| 91 | }
|
---|
| 92 |
|
---|
| 93 | export const describeIfNotBabylon = fallbackToBabylon ? describe.skip : describe;
|
---|