main
js 113 lines 3.43 KB
Raw
1 'use strict';
2
3 const getComments = require('./getComments');
4
5 const GATE_VERSION_STR = '@reactVersion ';
6 const REACT_VERSION_ENV = process.env.REACT_VERSION;
7
8 function transform(babel) {
9 const {types: t} = babel;
10
11 // Runs tests conditionally based on the version of react (semver range) we are running
12 // Input:
13 // @reactVersion >= 17.0
14 // test('some test', () => {/*...*/})
15 //
16 // Output:
17 // @reactVersion >= 17.0
18 // _test_react_version('>= 17.0', 'some test', () => {/*...*/});
19 //
20 // See info about semver ranges here:
21 // https://www.npmjs.com/package/semver
22 function buildGateVersionCondition(comments) {
23 if (!comments) {
24 return null;
25 }
26
27 const resultingCondition = comments.reduce(
28 (accumulatedCondition, commentLine) => {
29 const commentStr = commentLine.value.trim();
30
31 if (!commentStr.startsWith(GATE_VERSION_STR)) {
32 return accumulatedCondition;
33 }
34
35 const condition = commentStr.slice(GATE_VERSION_STR.length);
36 if (accumulatedCondition === null) {
37 return condition;
38 }
39
40 return accumulatedCondition.concat(' ', condition);
41 },
42 null
43 );
44
45 if (resultingCondition === null) {
46 return null;
47 }
48
49 return t.stringLiteral(resultingCondition);
50 }
51
52 return {
53 name: 'transform-react-version-pragma',
54 visitor: {
55 ExpressionStatement(path) {
56 const statement = path.node;
57 const expression = statement.expression;
58 if (expression.type === 'CallExpression') {
59 const callee = expression.callee;
60 switch (callee.type) {
61 case 'Identifier': {
62 if (
63 callee.name === 'test' ||
64 callee.name === 'it' ||
65 callee.name === 'fit'
66 ) {
67 const comments = getComments(path);
68 const condition = buildGateVersionCondition(comments);
69 if (condition !== null) {
70 callee.name =
71 callee.name === 'fit'
72 ? '_test_react_version_focus'
73 : '_test_react_version';
74 expression.arguments = [condition, ...expression.arguments];
75 } else if (REACT_VERSION_ENV) {
76 callee.name = '_test_ignore_for_react_version';
77 }
78 }
79 break;
80 }
81 case 'MemberExpression': {
82 if (
83 callee.object.type === 'Identifier' &&
84 (callee.object.name === 'test' ||
85 callee.object.name === 'it') &&
86 callee.property.type === 'Identifier' &&
87 callee.property.name === 'only'
88 ) {
89 const comments = getComments(path);
90 const condition = buildGateVersionCondition(comments);
91 if (condition !== null) {
92 statement.expression = t.callExpression(
93 t.identifier('_test_react_version_focus'),
94 [condition, ...expression.arguments]
95 );
96 } else if (REACT_VERSION_ENV) {
97 statement.expression = t.callExpression(
98 t.identifier('_test_ignore_for_react_version'),
99 expression.arguments
100 );
101 }
102 }
103 break;
104 }
105 }
106 }
107 return;
108 },
109 },
110 };
111 }
112
113 module.exports = transform;