-
-
Notifications
You must be signed in to change notification settings - Fork 238
Expand file tree
/
Copy pathreactCompilerPreset.test.ts
More file actions
166 lines (155 loc) · 5.13 KB
/
reactCompilerPreset.test.ts
File metadata and controls
166 lines (155 loc) · 5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import { describe, expect, test } from 'vitest'
import { defaultCodeFilter } from './reactCompilerPreset'
describe('defaultCodeFilter', () => {
const cases: Record<string, [code: string, expected: boolean]> = {
directive: ['"use memo";', true],
'component declaration': ['function App() { return <></> }', true],
'component declaration with types': [
'function App(): Type { return <></> }',
true,
],
'component arrow expression': [
'const MyComponent = () => { return <></> }',
true,
],
'component arrow expression with types (1)': [
'const MyComponent = (): Type => { return <></> }',
true,
],
'component arrow expression with types (2)': [
'const MyComponent: Type = () => { return <></> }',
true,
],
'component arrow expression with types (3)': [
'const MyComponent: SomeComplexType<Generic, number> = () => { return <></> }',
true,
],
'component arrow expressions': [
'const a = 0, MyComponent = () => { return <></> }',
true,
],
'component arrow expressions (let)': [
'let a = 0, MyComponent = () => { return <></> }',
true,
],
'component function expression': [
'const MyComponent = function() { return <></> }',
true,
],
'component function expression with types (1)': [
'const MyComponent = function(): Type { return <></> }',
true,
],
'component function expression with types (2)': [
'const MyComponent: Type = function() { return <></> }',
true,
],
'component function expression with types (3)': [
'const MyComponent: SomeComplexType<Generic, number> = function() { return <></> }',
true,
],
'component function expression (let)': [
'let MyComponent = function() { return <></> }',
true,
],
'component function expression (var)': [
'var MyComponent = function() { return <></> }',
true,
],
'exported component declaration': [
'export default function Page() { return <></> }',
true,
],
'exported component declaration with types': [
'export default function Page(): Type { return <></> }',
true,
],
'component assignment': [
'let MyComponent; MyComponent = function() { return <></> }',
true,
],
'component default declaration': [
'const { MyComponent = function() { return <></> } } = {}',
true,
],
'component default assignment': [
'let MyComponent; ({ MyComponent = function() { return <></> } }) = {}',
true,
],
'component property function expression': [
'const components = { MyComponent: function() { return <></> } }',
true,
],
'component property arrow function expression': [
'const components = { MyComponent: () => <></> }',
true,
],
'component method': [
'const components = { MyComponent() { return <></> } }',
true,
],
'hook declaration': ['function useEffect() { return <></> }', true],
'hook arrow expression': ['const useMyHook = () => { return <></> }', true],
'hook function expression': [
'const useMyHook = function() { return <></> }',
true,
],
'hook with digit': ['function use0() { return <></> }', true],
'hook using hooks': [
'function useMyHook() { return useOtherHook() }',
true,
],
'hook using nested hooks': [
'function useMyHook() { return Foo.useOtherHook() }',
true,
],
'React.forwardRef': ['React.forwardRef(() => <></>)', true],
'React.memo': ['React.memo(() => <></>)', true],
forwardRef: [
'import { forwardRef } from "react"; forwardRef(() => <></>)',
true,
],
memo: ['import { memo } from "react"; memo(() => <></>)', true],
'edge case: memo callback with hooks': [
`import React, { useState } from "react";
import { jsx } from "react/jsx-runtime"
export const components = {
A: React.memo(() => {
const [state, setState] = useState(0);
return jsx("div", { children: state })
})
}`,
true,
],
'edge case: memo without namespace': [
`import { memo, useState } from "react";
export default memo(() => {
const [count, setCount] = useState(0);
return <div>{count}</div>
})`,
true,
],
'edge case: memo without namespace from re-export': [
`import { memo, useState } from "my-react";
export default memo(() => {
const [count, setCount] = useState(0);
return <div>{count}</div>
})`,
true,
],
'simple variable': ['const foo = 1', false],
'lowercase function': ['function bar() {}', false],
'lowercase arrow function': ['let baz = () => {}', false],
'non assignments (1)': ['(0,useState)()', false],
'non assignments (2)': ['[useState][0]()', false],
'non assignments (3)': ['useState;s()', false],
'non assignments (4)': ['useState,s()', false],
'object without methods (1)': ['const obj = { useState: 1 }', false],
'object without methods (2)': ['const obj = { Foo: 1 }', false],
}
for (const [name, [code, expected]] of Object.entries(cases)) {
test(name, () => {
expect(defaultCodeFilter.test(code)).toBe(expected)
})
}
})