UNPKG

4.76 kBJavaScriptView Raw
1const babel = require("@babel/core");
2const reactPlugin = require("../lib/index");
3
4function transform(
5 code,
6 { pluginsBefore = [], pluginsAfter = [], filename = "test.js" } = {}
7) {
8 return babel.transform(code, {
9 filename,
10 cwd: __dirname,
11 plugins: [
12 "@babel/plugin-syntax-jsx",
13 ...pluginsBefore,
14 reactPlugin,
15 ...pluginsAfter,
16 ],
17 }).code;
18}
19
20const somePluginEnter = ({ types: t }) => ({
21 visitor: {
22 Program(path) {
23 path.unshiftContainer(
24 "body",
25 t.importDeclaration(
26 [t.importDefaultSpecifier(t.identifier("React"))],
27 t.stringLiteral("react")
28 )
29 );
30 },
31 },
32});
33
34const somePluginExit = ({ types: t }) => ({
35 visitor: {
36 Program: {
37 exit(path) {
38 path.unshiftContainer(
39 "body",
40 t.importDeclaration(
41 [t.importDefaultSpecifier(t.identifier("React"))],
42 t.stringLiteral("react")
43 )
44 );
45 },
46 },
47 },
48});
49
50const somePluginThatCrawl = () => ({
51 visitor: {
52 Program(path) {
53 path.scope.crawl();
54 },
55 },
56});
57
58const somePluginCrazy = () => ({
59 visitor: {
60 Program(_, { file }) {
61 file.get("ourPath").remove();
62 },
63 },
64});
65
66const genericInput =
67 "export default class Component {render() {return <div />}}";
68const genericOutput =
69 'import React from "react";\nexport default class Component {\n render() {\n return <div />;\n }\n}';
70
71describe("babel-plugin-react", () => {
72 it("should return transpiled code with required React", () => {
73 const transformed = transform(genericInput);
74
75 expect(transformed).toBe(genericOutput);
76 });
77
78 it("should return not transpiled code", () => {
79 const transformed = transform(
80 'import x from "y";\nconsole.log("hello world")'
81 );
82
83 expect(transformed).toBe('import x from "y";\nconsole.log("hello world");');
84 });
85
86 it("should check that plugin does not import React twice", () => {
87 const transformed = transform(
88 "class Component{render(){return <div/>}} class Component2{render(){return <div />}}"
89 );
90
91 expect(transformed).toBe(
92 'import React from "react";\nclass Component {\n render() {\n return <div />;\n }\n}\n' +
93 "class Component2 {\n render() {\n return <div />;\n }\n}"
94 );
95 });
96
97 it("should does not replace users import on plugins import", () => {
98 const transformed = transform(
99 'import React from"react/addons"\nclass Component{render(){return <div/>}}'
100 );
101
102 expect(transformed).toBe(
103 'import React from "react/addons";\nclass Component {\n render() {\n return <div />;\n }\n}'
104 );
105 });
106
107 it("should get along with other plugins which add React import", () => {
108 expect(transform(genericInput, { pluginsBefore: [somePluginEnter] })).toBe(
109 genericOutput
110 );
111 expect(transform(genericInput, { pluginsBefore: [somePluginExit] })).toBe(
112 genericOutput
113 );
114 expect(transform(genericInput, { pluginsAfter: [somePluginEnter] })).toBe(
115 genericOutput
116 );
117 expect(transform(genericInput, { pluginsAfter: [somePluginExit] })).toBe(
118 genericOutput
119 );
120 });
121
122 it("should work with other plugins which use scope.crawl on files which already contains React import", () => {
123 const transformed = transform('import * as React from "react";', {
124 pluginsAfter: [somePluginThatCrawl],
125 });
126
127 expect(transformed).toBe('import * as React from "react";');
128 });
129
130 it("should not blow up if another plugin removes our import", () => {
131 expect(transform(genericInput, { pluginsAfter: [somePluginCrazy] })).toBe(
132 "export default class Component {\n render() {\n return <div />;\n }\n}"
133 );
134 expect(transform("const x = 1;", { pluginsAfter: [somePluginCrazy] })).toBe(
135 "const x = 1;"
136 );
137 expect(
138 transform("", {
139 pluginsBefore: [somePluginEnter],
140 pluginsAfter: [somePluginCrazy],
141 })
142 ).toBe('import React from "react";');
143 });
144
145 it("should support JSX fragments", () => {
146 const transformed = transform("function Thing() {\n return <>Hi</>;\n}");
147
148 expect(transformed).toBe(
149 'import React from "react";\nfunction Thing() {\n return <>Hi</>;\n}'
150 );
151 });
152
153 it("should work with babel-plugin-inline-react-svg", () => {
154 const transformed = transform('import svg from "./test.svg";', {
155 filename: "test.svg",
156 pluginsAfter: ["inline-react-svg"],
157 });
158
159 expect(transformed).toBe(
160 'import React from "react";\nvar svg = function svg(props) {\n return <svg {...props}><path fill="none" stroke="#000" strokeWidth="5" strokeOpacity=".5" d="M0 0h400v400H0z" /></svg>;\n};\nsvg.defaultProps = {\n xmlns: "http://www.w3.org/2000/svg"\n};'
161 );
162 });
163});