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;
|
---|