@planningcenter/tapestry-migration-cli 2.8.0-rc.13 → 2.8.0-rc.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/components/button/transforms/themeVariantToKind.test.ts +1 -1
- package/src/components/radio/index.ts +38 -0
- package/src/components/radio/transforms/auditSpreadProps.test.ts +356 -0
- package/src/components/radio/transforms/auditSpreadProps.ts +10 -0
- package/src/components/radio/transforms/convertStyleProps.test.ts +161 -0
- package/src/components/radio/transforms/convertStyleProps.ts +10 -0
- package/src/components/radio/transforms/moveRadioImport.test.ts +152 -0
- package/src/components/radio/transforms/moveRadioImport.ts +13 -0
- package/src/components/radio/transforms/setDefaultSize.test.ts +287 -0
- package/src/components/radio/transforms/setDefaultSize.ts +28 -0
- package/src/components/radio/transforms/sizeMapping.test.ts +201 -0
- package/src/components/radio/transforms/sizeMapping.ts +49 -0
- package/src/components/radio/transforms/unsupportedProps.test.ts +241 -0
- package/src/components/radio/transforms/unsupportedProps.ts +35 -0
- package/src/components/shared/actions/getAttributeValue.test.ts +18 -0
- package/src/components/shared/actions/getAttributeValue.ts +18 -5
- package/src/components/shared/helpers/unsupportedPropsHelpers.ts +24 -9
- package/src/components/shared/transformFactories/commentOnSpreadPropsFactory.test.ts +84 -0
- package/src/components/shared/transformFactories/commentOnSpreadPropsFactory.ts +26 -0
- package/src/reportGenerator.ts +2 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import jscodeshift from "jscodeshift"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
|
|
4
|
+
import transform from "./moveRadioImport"
|
|
5
|
+
|
|
6
|
+
const j = jscodeshift.withParser("tsx")
|
|
7
|
+
|
|
8
|
+
function applyTransform(source: string): string {
|
|
9
|
+
const fileInfo = { path: "test.tsx", source }
|
|
10
|
+
const result = transform(
|
|
11
|
+
fileInfo,
|
|
12
|
+
{ j, jscodeshift: j, report: () => {}, stats: () => {} },
|
|
13
|
+
{}
|
|
14
|
+
) as string | null
|
|
15
|
+
return result || source
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe("moveRadioImport transform", () => {
|
|
19
|
+
describe("import migration", () => {
|
|
20
|
+
it("should change import from tapestry-react to tapestry", () => {
|
|
21
|
+
const input = `
|
|
22
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
23
|
+
|
|
24
|
+
function Test() {
|
|
25
|
+
return <Radio label="Test" />
|
|
26
|
+
}
|
|
27
|
+
`.trim()
|
|
28
|
+
|
|
29
|
+
const result = applyTransform(input)
|
|
30
|
+
expect(result).toContain(
|
|
31
|
+
'import { Radio } from "@planningcenter/tapestry"'
|
|
32
|
+
)
|
|
33
|
+
expect(result).not.toContain("@planningcenter/tapestry-react")
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it("should handle multiple imports", () => {
|
|
37
|
+
const input = `
|
|
38
|
+
import { Button, Radio } from "@planningcenter/tapestry-react"
|
|
39
|
+
|
|
40
|
+
function Test() {
|
|
41
|
+
return (
|
|
42
|
+
<div>
|
|
43
|
+
<Button>Click</Button>
|
|
44
|
+
<Radio label="Test" />
|
|
45
|
+
</div>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
`.trim()
|
|
49
|
+
|
|
50
|
+
const result = applyTransform(input)
|
|
51
|
+
expect(result).toContain(
|
|
52
|
+
'import { Button } from "@planningcenter/tapestry-react"'
|
|
53
|
+
)
|
|
54
|
+
expect(result).toContain(
|
|
55
|
+
'import { Radio } from "@planningcenter/tapestry"'
|
|
56
|
+
)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it("should handle mixed imports", () => {
|
|
60
|
+
const input = `
|
|
61
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
62
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
63
|
+
|
|
64
|
+
function Test() {
|
|
65
|
+
return (
|
|
66
|
+
<div>
|
|
67
|
+
<Button>Click</Button>
|
|
68
|
+
<Radio label="Test" />
|
|
69
|
+
</div>
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
`.trim()
|
|
73
|
+
|
|
74
|
+
const result = applyTransform(input)
|
|
75
|
+
expect(result).toContain(
|
|
76
|
+
'import { Button } from "@planningcenter/tapestry-react"'
|
|
77
|
+
)
|
|
78
|
+
expect(result).toContain(
|
|
79
|
+
'import { Radio } from "@planningcenter/tapestry"'
|
|
80
|
+
)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it("should not affect other components", () => {
|
|
84
|
+
const input = `
|
|
85
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
86
|
+
|
|
87
|
+
function Test() {
|
|
88
|
+
return <Button>Click me</Button>
|
|
89
|
+
}
|
|
90
|
+
`.trim()
|
|
91
|
+
|
|
92
|
+
const result = applyTransform(input)
|
|
93
|
+
expect(result).toContain(
|
|
94
|
+
'import { Button } from "@planningcenter/tapestry-react"'
|
|
95
|
+
)
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
describe("edge cases", () => {
|
|
100
|
+
it("should handle already migrated imports", () => {
|
|
101
|
+
const input = `
|
|
102
|
+
import { Radio } from "@planningcenter/tapestry"
|
|
103
|
+
|
|
104
|
+
function Test() {
|
|
105
|
+
return <Radio label="Test" />
|
|
106
|
+
}
|
|
107
|
+
`.trim()
|
|
108
|
+
|
|
109
|
+
const result = applyTransform(input)
|
|
110
|
+
expect(result).toContain(
|
|
111
|
+
'import { Radio } from "@planningcenter/tapestry"'
|
|
112
|
+
)
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it("should handle no imports", () => {
|
|
116
|
+
const input = `
|
|
117
|
+
function Test() {
|
|
118
|
+
return <div>No imports</div>
|
|
119
|
+
}
|
|
120
|
+
`.trim()
|
|
121
|
+
|
|
122
|
+
const result = applyTransform(input)
|
|
123
|
+
expect(result).toBe(input)
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it("should preserve other attributes", () => {
|
|
127
|
+
const input = `
|
|
128
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
129
|
+
|
|
130
|
+
function Test() {
|
|
131
|
+
return (
|
|
132
|
+
<Radio
|
|
133
|
+
label="Test"
|
|
134
|
+
checked
|
|
135
|
+
disabled
|
|
136
|
+
onChange={() => {}}
|
|
137
|
+
/>
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
`.trim()
|
|
141
|
+
|
|
142
|
+
const result = applyTransform(input)
|
|
143
|
+
expect(result).toContain(
|
|
144
|
+
'import { Radio } from "@planningcenter/tapestry"'
|
|
145
|
+
)
|
|
146
|
+
expect(result).toContain('label="Test"')
|
|
147
|
+
expect(result).toContain("checked")
|
|
148
|
+
expect(result).toContain("disabled")
|
|
149
|
+
expect(result).toContain("onChange={() => {}}")
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Transform } from "jscodeshift"
|
|
2
|
+
|
|
3
|
+
import { componentTransformFactory } from "../../shared/transformFactories/componentTransformFactory"
|
|
4
|
+
|
|
5
|
+
const transform: Transform = componentTransformFactory({
|
|
6
|
+
condition: () => true,
|
|
7
|
+
fromComponent: "Radio",
|
|
8
|
+
fromPackage: "@planningcenter/tapestry-react",
|
|
9
|
+
toComponent: "Radio",
|
|
10
|
+
toPackage: "@planningcenter/tapestry",
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
export default transform
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import jscodeshift from "jscodeshift"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
|
|
4
|
+
import transform from "./setDefaultSize"
|
|
5
|
+
|
|
6
|
+
const j = jscodeshift.withParser("tsx")
|
|
7
|
+
|
|
8
|
+
function applyTransform(source: string): string {
|
|
9
|
+
const fileInfo = { path: "test.tsx", source }
|
|
10
|
+
const result = transform(
|
|
11
|
+
fileInfo,
|
|
12
|
+
{ j, jscodeshift: j, report: () => {}, stats: () => {} },
|
|
13
|
+
{}
|
|
14
|
+
) as string | null
|
|
15
|
+
return result || source
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe("setDefaultSize transform", () => {
|
|
19
|
+
describe("setting default size", () => {
|
|
20
|
+
it("should set default size to 'xs' when size prop is missing", () => {
|
|
21
|
+
const input = `
|
|
22
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
23
|
+
|
|
24
|
+
function Test() {
|
|
25
|
+
return <Radio label="Test radio" />
|
|
26
|
+
}
|
|
27
|
+
`.trim()
|
|
28
|
+
|
|
29
|
+
const result = applyTransform(input)
|
|
30
|
+
expect(result).toContain('size="xs"')
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it("should set default size to 'xs' for multiple radios without size", () => {
|
|
34
|
+
const input = `
|
|
35
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
36
|
+
|
|
37
|
+
function Test() {
|
|
38
|
+
return (
|
|
39
|
+
<div>
|
|
40
|
+
<Radio label="First" />
|
|
41
|
+
<Radio label="Second" />
|
|
42
|
+
</div>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
`.trim()
|
|
46
|
+
|
|
47
|
+
const result = applyTransform(input)
|
|
48
|
+
const sizeMatches = result.match(/size="xs"/g)
|
|
49
|
+
expect(sizeMatches).toHaveLength(2)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it("should not set default size when size prop already exists", () => {
|
|
53
|
+
const input = `
|
|
54
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
55
|
+
|
|
56
|
+
function Test() {
|
|
57
|
+
return <Radio size="md" label="Test radio" />
|
|
58
|
+
}
|
|
59
|
+
`.trim()
|
|
60
|
+
|
|
61
|
+
const result = applyTransform(input)
|
|
62
|
+
expect(result).toContain('size="md"')
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it("should not set default size when size prop is an expression", () => {
|
|
66
|
+
const input = `
|
|
67
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
68
|
+
|
|
69
|
+
function Test() {
|
|
70
|
+
const size = "md"
|
|
71
|
+
return <Radio size={size} label="Test radio" />
|
|
72
|
+
}
|
|
73
|
+
`.trim()
|
|
74
|
+
|
|
75
|
+
const result = applyTransform(input)
|
|
76
|
+
expect(result).toContain("size={size}")
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
describe("andConditions logic", () => {
|
|
81
|
+
it("should only add default size when BOTH conditions are met: no size attribute AND no spread props", () => {
|
|
82
|
+
const input = `
|
|
83
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
84
|
+
|
|
85
|
+
function Test() {
|
|
86
|
+
return <Radio label="Test radio" />
|
|
87
|
+
}
|
|
88
|
+
`.trim()
|
|
89
|
+
|
|
90
|
+
const result = applyTransform(input)
|
|
91
|
+
expect(result).toContain('size="xs"')
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it("should not add default size when first condition fails: has size attribute (even without spread props)", () => {
|
|
95
|
+
const input = `
|
|
96
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
97
|
+
|
|
98
|
+
function Test() {
|
|
99
|
+
return <Radio size="md" label="Test radio" />
|
|
100
|
+
}
|
|
101
|
+
`.trim()
|
|
102
|
+
|
|
103
|
+
const result = applyTransform(input)
|
|
104
|
+
expect(result).toContain('size="md"')
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it("should not add default size when second condition fails: has spread props (even without explicit size)", () => {
|
|
108
|
+
const input = `
|
|
109
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
110
|
+
|
|
111
|
+
function Test() {
|
|
112
|
+
const props = { onChange: handleChange }
|
|
113
|
+
return <Radio {...props} label="Test radio" />
|
|
114
|
+
}
|
|
115
|
+
`.trim()
|
|
116
|
+
|
|
117
|
+
const result = applyTransform(input)
|
|
118
|
+
expect(result).toContain("{...props}")
|
|
119
|
+
expect(result).not.toContain('size="xs"')
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it("should not add default size when BOTH conditions fail: has size attribute AND has spread props", () => {
|
|
123
|
+
const input = `
|
|
124
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
125
|
+
|
|
126
|
+
function Test() {
|
|
127
|
+
const props = { onChange: handleChange }
|
|
128
|
+
return <Radio size="md" {...props} label="Test radio" />
|
|
129
|
+
}
|
|
130
|
+
`.trim()
|
|
131
|
+
|
|
132
|
+
const result = applyTransform(input)
|
|
133
|
+
expect(result).toContain('size="md"')
|
|
134
|
+
expect(result).toContain("{...props}")
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
describe("spread props handling", () => {
|
|
139
|
+
it("should not set default size when spread props are present", () => {
|
|
140
|
+
const input = `
|
|
141
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
142
|
+
|
|
143
|
+
function Test() {
|
|
144
|
+
const props = { onChange: handleChange }
|
|
145
|
+
return <Radio {...props} label="Test radio" />
|
|
146
|
+
}
|
|
147
|
+
`.trim()
|
|
148
|
+
|
|
149
|
+
const result = applyTransform(input)
|
|
150
|
+
expect(result).toContain("{...props}")
|
|
151
|
+
expect(result).not.toContain('size="xs"')
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
it("should not set default size when multiple spread props are present", () => {
|
|
155
|
+
const input = `
|
|
156
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
157
|
+
|
|
158
|
+
function Test() {
|
|
159
|
+
const baseProps = { onChange: handleChange }
|
|
160
|
+
const styleProps = { className: "radio" }
|
|
161
|
+
return <Radio {...baseProps} {...styleProps} label="Test radio" />
|
|
162
|
+
}
|
|
163
|
+
`.trim()
|
|
164
|
+
|
|
165
|
+
const result = applyTransform(input)
|
|
166
|
+
expect(result).toContain("{...baseProps}")
|
|
167
|
+
expect(result).toContain("{...styleProps}")
|
|
168
|
+
expect(result).not.toContain('size="xs"')
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
it("should not set default size when spread props are present even without explicit size", () => {
|
|
172
|
+
const input = `
|
|
173
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
174
|
+
|
|
175
|
+
function Test() {
|
|
176
|
+
const props = { label: "Test", checked: true }
|
|
177
|
+
return <Radio {...props} />
|
|
178
|
+
}
|
|
179
|
+
`.trim()
|
|
180
|
+
|
|
181
|
+
const result = applyTransform(input)
|
|
182
|
+
expect(result).toContain("{...props}")
|
|
183
|
+
expect(result).not.toContain('size="xs"')
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it("should not set default size when spread props contain size", () => {
|
|
187
|
+
const input = `
|
|
188
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
189
|
+
|
|
190
|
+
function Test() {
|
|
191
|
+
const props = { size: "md", label: "Test" }
|
|
192
|
+
return <Radio {...props} />
|
|
193
|
+
}
|
|
194
|
+
`.trim()
|
|
195
|
+
|
|
196
|
+
const result = applyTransform(input)
|
|
197
|
+
expect(result).toContain("{...props}")
|
|
198
|
+
expect(result).not.toContain('size="xs"')
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
it("should handle mix of radios with and without spread props", () => {
|
|
202
|
+
const input = `
|
|
203
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
204
|
+
|
|
205
|
+
function Test() {
|
|
206
|
+
const props = { onChange: handleChange }
|
|
207
|
+
return (
|
|
208
|
+
<div>
|
|
209
|
+
<Radio {...props} label="With spread" />
|
|
210
|
+
<Radio label="Without spread" />
|
|
211
|
+
</div>
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
`.trim()
|
|
215
|
+
|
|
216
|
+
const result = applyTransform(input)
|
|
217
|
+
expect(result).toContain("{...props}")
|
|
218
|
+
const sizeMatches = result.match(/size="xs"/g)
|
|
219
|
+
expect(sizeMatches).toHaveLength(1)
|
|
220
|
+
})
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
describe("edge cases", () => {
|
|
224
|
+
it("should preserve other props when setting default size", () => {
|
|
225
|
+
const input = `
|
|
226
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
227
|
+
|
|
228
|
+
function Test() {
|
|
229
|
+
return (
|
|
230
|
+
<Radio
|
|
231
|
+
label="Test"
|
|
232
|
+
checked
|
|
233
|
+
disabled
|
|
234
|
+
onChange={() => {}}
|
|
235
|
+
/>
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
`.trim()
|
|
239
|
+
|
|
240
|
+
const result = applyTransform(input)
|
|
241
|
+
expect(result).toContain('size="xs"')
|
|
242
|
+
expect(result).toContain('label="Test"')
|
|
243
|
+
expect(result).toContain("checked")
|
|
244
|
+
expect(result).toContain("disabled")
|
|
245
|
+
expect(result).toContain("onChange={() => {}}")
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
it("should not affect other components", () => {
|
|
249
|
+
const input = `
|
|
250
|
+
import { Button, Radio } from "@planningcenter/tapestry-react"
|
|
251
|
+
|
|
252
|
+
function Test() {
|
|
253
|
+
return (
|
|
254
|
+
<div>
|
|
255
|
+
<Button>Click me</Button>
|
|
256
|
+
<Radio label="Test radio" />
|
|
257
|
+
</div>
|
|
258
|
+
)
|
|
259
|
+
}
|
|
260
|
+
`.trim()
|
|
261
|
+
|
|
262
|
+
const result = applyTransform(input)
|
|
263
|
+
expect(result).toContain("<Button>Click me</Button>")
|
|
264
|
+
expect(result).toContain('size="xs"')
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
it("should handle radio groups", () => {
|
|
268
|
+
const input = `
|
|
269
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
270
|
+
|
|
271
|
+
function Test() {
|
|
272
|
+
return (
|
|
273
|
+
<div>
|
|
274
|
+
<Radio name="group" label="Option 1" />
|
|
275
|
+
<Radio name="group" label="Option 2" />
|
|
276
|
+
<Radio name="group" label="Option 3" />
|
|
277
|
+
</div>
|
|
278
|
+
)
|
|
279
|
+
}
|
|
280
|
+
`.trim()
|
|
281
|
+
|
|
282
|
+
const result = applyTransform(input)
|
|
283
|
+
const sizeMatches = result.match(/size="xs"/g)
|
|
284
|
+
expect(sizeMatches).toHaveLength(3)
|
|
285
|
+
})
|
|
286
|
+
})
|
|
287
|
+
})
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Transform } from "jscodeshift"
|
|
2
|
+
|
|
3
|
+
import { addAttribute } from "../../shared/actions/addAttribute"
|
|
4
|
+
import { hasSpreadProps } from "../../shared/actions/hasSpreadProps"
|
|
5
|
+
import { andConditions } from "../../shared/conditions/andConditions"
|
|
6
|
+
import { hasAttribute } from "../../shared/conditions/hasAttribute"
|
|
7
|
+
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
8
|
+
|
|
9
|
+
const transform: Transform = attributeTransformFactory({
|
|
10
|
+
condition: andConditions(
|
|
11
|
+
(element) => !hasAttribute("size")(element),
|
|
12
|
+
(element) => !hasSpreadProps(element)
|
|
13
|
+
),
|
|
14
|
+
targetComponent: "Radio",
|
|
15
|
+
targetPackage: "@planningcenter/tapestry-react",
|
|
16
|
+
transform: (element, { j }) => {
|
|
17
|
+
addAttribute({
|
|
18
|
+
element,
|
|
19
|
+
j,
|
|
20
|
+
name: "size",
|
|
21
|
+
value: "xs",
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
return true
|
|
25
|
+
},
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
export default transform
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import jscodeshift from "jscodeshift"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
|
|
4
|
+
import transform from "./sizeMapping"
|
|
5
|
+
|
|
6
|
+
const j = jscodeshift.withParser("tsx")
|
|
7
|
+
|
|
8
|
+
function applyTransform(source: string): string {
|
|
9
|
+
const fileInfo = { path: "test.tsx", source }
|
|
10
|
+
const result = transform(
|
|
11
|
+
fileInfo,
|
|
12
|
+
{ j, jscodeshift: j, report: () => {}, stats: () => {} },
|
|
13
|
+
{}
|
|
14
|
+
) as string | null
|
|
15
|
+
return result || source
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe("sizeMapping transform", () => {
|
|
19
|
+
describe("size value transformations", () => {
|
|
20
|
+
it("should transform lg to md", () => {
|
|
21
|
+
const input = `
|
|
22
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
23
|
+
|
|
24
|
+
function Test() {
|
|
25
|
+
return <Radio size="lg" label="Large radio" />
|
|
26
|
+
}
|
|
27
|
+
`.trim()
|
|
28
|
+
|
|
29
|
+
const result = applyTransform(input)
|
|
30
|
+
expect(result).toContain('size="md"')
|
|
31
|
+
expect(result).not.toContain('size="lg"')
|
|
32
|
+
expect(result).toContain('Size "lg" was mapped to "md"')
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('should transform size={"lg"} to md', () => {
|
|
36
|
+
const input = `
|
|
37
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
38
|
+
|
|
39
|
+
function Test() {
|
|
40
|
+
return <Radio size={"lg"} label="Large radio" />
|
|
41
|
+
}
|
|
42
|
+
`.trim()
|
|
43
|
+
|
|
44
|
+
const result = applyTransform(input)
|
|
45
|
+
expect(result).toContain('size="md"')
|
|
46
|
+
expect(result).toContain('Size "lg" was mapped to "md"')
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it("should transform xl to md", () => {
|
|
50
|
+
const input = `
|
|
51
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
52
|
+
|
|
53
|
+
function Test() {
|
|
54
|
+
return <Radio size="xl" label="Extra large radio" />
|
|
55
|
+
}
|
|
56
|
+
`.trim()
|
|
57
|
+
|
|
58
|
+
const result = applyTransform(input)
|
|
59
|
+
expect(result).toContain('size="md"')
|
|
60
|
+
expect(result).not.toContain('size="xl"')
|
|
61
|
+
expect(result).toContain('Size "xl" was mapped to "md"')
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it("should transform xs to sm", () => {
|
|
65
|
+
const input = `
|
|
66
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
67
|
+
|
|
68
|
+
function Test() {
|
|
69
|
+
return <Radio size="xs" label="Extra small radio" />
|
|
70
|
+
}
|
|
71
|
+
`.trim()
|
|
72
|
+
|
|
73
|
+
const result = applyTransform(input)
|
|
74
|
+
expect(result).toContain('size="sm"')
|
|
75
|
+
expect(result).not.toContain('size="xs"')
|
|
76
|
+
expect(result).toContain('Size "xs" was mapped to "sm"')
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it("should not transform supported sizes", () => {
|
|
80
|
+
const input = `
|
|
81
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
82
|
+
|
|
83
|
+
function Test() {
|
|
84
|
+
return (
|
|
85
|
+
<div>
|
|
86
|
+
<Radio size="md" label="Medium radio" />
|
|
87
|
+
<Radio size="sm" label="Small radio" />
|
|
88
|
+
</div>
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
`.trim()
|
|
92
|
+
|
|
93
|
+
const result = applyTransform(input)
|
|
94
|
+
expect(result).toContain('size="md"')
|
|
95
|
+
expect(result).toContain('size="sm"')
|
|
96
|
+
expect(result).not.toContain("TODO: tapestry-migration")
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
describe("edge cases", () => {
|
|
101
|
+
it("should not affect radio without size prop", () => {
|
|
102
|
+
const input = `
|
|
103
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
104
|
+
|
|
105
|
+
function Test() {
|
|
106
|
+
return <Radio label="No size" />
|
|
107
|
+
}
|
|
108
|
+
`.trim()
|
|
109
|
+
|
|
110
|
+
const result = applyTransform(input)
|
|
111
|
+
expect(result).toBe(input)
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it("should not affect other components", () => {
|
|
115
|
+
const input = `
|
|
116
|
+
import { Button, Radio } from "@planningcenter/tapestry-react"
|
|
117
|
+
|
|
118
|
+
function Test() {
|
|
119
|
+
return (
|
|
120
|
+
<div>
|
|
121
|
+
<Button size="lg">Large button</Button>
|
|
122
|
+
<Radio size="md" label="Medium radio" />
|
|
123
|
+
</div>
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
`.trim()
|
|
127
|
+
|
|
128
|
+
const result = applyTransform(input)
|
|
129
|
+
expect(result).toContain('size="lg"')
|
|
130
|
+
expect(result).toContain('size="md"')
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it("should handle multiple radios with different sizes", () => {
|
|
134
|
+
const input = `
|
|
135
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
136
|
+
|
|
137
|
+
function Test() {
|
|
138
|
+
return (
|
|
139
|
+
<div>
|
|
140
|
+
<Radio size="lg" label="Large" />
|
|
141
|
+
<Radio size="md" label="Medium" />
|
|
142
|
+
<Radio size="xl" label="Extra large" />
|
|
143
|
+
<Radio size="xs" label="Extra small" />
|
|
144
|
+
</div>
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
`.trim()
|
|
148
|
+
|
|
149
|
+
const result = applyTransform(input)
|
|
150
|
+
expect(result).toContain('size="md"')
|
|
151
|
+
expect(result).toContain('size="sm"')
|
|
152
|
+
expect(result).not.toContain('size="lg"')
|
|
153
|
+
expect(result).not.toContain('size="xl"')
|
|
154
|
+
expect(result).not.toContain('size="xs"')
|
|
155
|
+
// Should have 3 comments (one for lg->md, one for xl->md, one for xs->sm)
|
|
156
|
+
const sizeMappingMatches = result.match(/Size ".*" was mapped to/g)
|
|
157
|
+
expect(sizeMappingMatches).toHaveLength(3)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it("should preserve other props", () => {
|
|
161
|
+
const input = `
|
|
162
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
163
|
+
|
|
164
|
+
function Test() {
|
|
165
|
+
return (
|
|
166
|
+
<Radio
|
|
167
|
+
size="lg"
|
|
168
|
+
label="Test"
|
|
169
|
+
checked
|
|
170
|
+
disabled
|
|
171
|
+
onChange={() => {}}
|
|
172
|
+
/>
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
`.trim()
|
|
176
|
+
|
|
177
|
+
const result = applyTransform(input)
|
|
178
|
+
expect(result).toContain('size="md"')
|
|
179
|
+
expect(result).toContain('label="Test"')
|
|
180
|
+
expect(result).toContain("checked")
|
|
181
|
+
expect(result).toContain("disabled")
|
|
182
|
+
expect(result).toContain("onChange={() => {}}")
|
|
183
|
+
expect(result).toContain('Size "lg" was mapped to "md"')
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it("should not transform expression values", () => {
|
|
187
|
+
const input = `
|
|
188
|
+
import { Radio } from "@planningcenter/tapestry-react"
|
|
189
|
+
|
|
190
|
+
function Test() {
|
|
191
|
+
const size = "lg"
|
|
192
|
+
return <Radio size={size} label="Variable size" />
|
|
193
|
+
}
|
|
194
|
+
`.trim()
|
|
195
|
+
|
|
196
|
+
const result = applyTransform(input)
|
|
197
|
+
expect(result).toContain("size={size}")
|
|
198
|
+
expect(result).not.toContain("Size")
|
|
199
|
+
})
|
|
200
|
+
})
|
|
201
|
+
})
|