@planningcenter/tapestry-migration-cli 3.0.0-rc.8 → 3.0.0
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/README.md +5 -2
- package/dist/tapestry-react-shim.cjs +384 -318
- package/package.json +4 -3
- package/src/components/button/transforms/auditSpreadProps.ts +2 -16
- package/src/components/button/transforms/themeVariantToKind.test.ts +1 -1
- package/src/components/button/transforms/tooltipToWrapper.test.ts +5 -3
- package/src/components/button/transforms/unsupportedProps.test.ts +305 -0
- package/src/components/button/transforms/unsupportedProps.ts +5 -2
- package/src/components/checkbox/index.ts +2 -0
- package/src/components/checkbox/transforms/auditSpreadProps.test.ts +356 -0
- package/src/components/checkbox/transforms/auditSpreadProps.ts +10 -0
- package/src/components/checkbox/transforms/sizeMapping.test.ts +88 -9
- package/src/components/checkbox/transforms/sizeMapping.ts +7 -37
- package/src/components/checkbox/transforms/unsupportedProps.ts +6 -11
- package/src/components/link/transforms/auditSpreadProps.ts +2 -16
- package/src/components/link/transforms/tooltipToWrapper.test.ts +5 -3
- package/src/components/link/transforms/unsupportedProps.ts +2 -2
- 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 +29 -0
- package/src/components/radio/transforms/sizeMapping.test.ts +201 -0
- package/src/components/radio/transforms/sizeMapping.ts +15 -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/actions/getAttributeValueAsProps.ts +15 -0
- package/src/components/shared/conditions/notCondition.test.ts +35 -0
- package/src/components/shared/conditions/notCondition.ts +12 -0
- package/src/components/shared/helpers/unsupportedPropsHelpers.ts +26 -10
- package/src/components/shared/transformFactories/commentOnSpreadPropsFactory.test.ts +84 -0
- package/src/components/shared/transformFactories/commentOnSpreadPropsFactory.ts +26 -0
- package/src/components/shared/transformFactories/sizeMappingFactory.ts +56 -0
- package/src/components/toggle-switch/index.ts +40 -0
- package/src/components/toggle-switch/transforms/ariaLabelToLabel.test.ts +236 -0
- package/src/components/toggle-switch/transforms/ariaLabelToLabel.ts +35 -0
- package/src/components/toggle-switch/transforms/auditSpreadProps.test.ts +352 -0
- package/src/components/toggle-switch/transforms/auditSpreadProps.ts +10 -0
- package/src/components/toggle-switch/transforms/convertStyleProps.test.ts +161 -0
- package/src/components/toggle-switch/transforms/convertStyleProps.ts +10 -0
- package/src/components/toggle-switch/transforms/isCheckedToChecked.test.ts +175 -0
- package/src/components/toggle-switch/transforms/isCheckedToChecked.ts +18 -0
- package/src/components/toggle-switch/transforms/moveToggleSwitchImport.test.ts +192 -0
- package/src/components/toggle-switch/transforms/moveToggleSwitchImport.ts +13 -0
- package/src/components/toggle-switch/transforms/sizeMapping.test.ts +188 -0
- package/src/components/toggle-switch/transforms/sizeMapping.ts +13 -0
- package/src/components/toggle-switch/transforms/unsupportedProps.test.ts +241 -0
- package/src/components/toggle-switch/transforms/unsupportedProps.ts +42 -0
- package/src/index.ts +12 -5
- package/src/reportGenerator.ts +4 -0
- package/src/utils/componentNameNormalizer.test.ts +91 -0
- package/src/utils/componentNameNormalizer.ts +39 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import jscodeshift from "jscodeshift"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
|
|
4
|
+
import transform from "./auditSpreadProps"
|
|
5
|
+
|
|
6
|
+
const j = jscodeshift.withParser("tsx")
|
|
7
|
+
|
|
8
|
+
const AUDIT_COMMENT =
|
|
9
|
+
"TODO: tapestry-migration (spreadAttribute): Spread props can contain unsupported props, please explore usages and migrate as needed."
|
|
10
|
+
|
|
11
|
+
function applyTransform(source: string) {
|
|
12
|
+
const fileInfo = { path: "test.tsx", source }
|
|
13
|
+
return transform(
|
|
14
|
+
fileInfo,
|
|
15
|
+
{ j, jscodeshift: j, report: () => {}, stats: () => {} },
|
|
16
|
+
{}
|
|
17
|
+
) as string | null
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
describe("auditSpreadProps transform", () => {
|
|
21
|
+
describe("basic transformations", () => {
|
|
22
|
+
it("should add comment to Checkbox with single spread prop", () => {
|
|
23
|
+
const input = `
|
|
24
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
25
|
+
|
|
26
|
+
export default function Test() {
|
|
27
|
+
const props = { onChange: handleChange }
|
|
28
|
+
return <Checkbox {...props} label="Save" name="choice" />
|
|
29
|
+
}
|
|
30
|
+
`.trim()
|
|
31
|
+
|
|
32
|
+
const result = applyTransform(input)
|
|
33
|
+
expect(result).toContain(AUDIT_COMMENT)
|
|
34
|
+
expect(result).toContain("{...props}")
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it("should add comment to Checkbox with multiple spread props", () => {
|
|
38
|
+
const input = `
|
|
39
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
40
|
+
|
|
41
|
+
export default function Test() {
|
|
42
|
+
const baseProps = { onChange: handleChange }
|
|
43
|
+
const styleProps = { className: "checkbox" }
|
|
44
|
+
return <Checkbox {...baseProps} {...styleProps} label="Save" name="choice" />
|
|
45
|
+
}
|
|
46
|
+
`.trim()
|
|
47
|
+
|
|
48
|
+
const result = applyTransform(input)
|
|
49
|
+
expect(result).toContain(AUDIT_COMMENT)
|
|
50
|
+
expect(result).toContain("{...baseProps}")
|
|
51
|
+
expect(result).toContain("{...styleProps}")
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it("should handle Checkbox with spread props and regular attributes", () => {
|
|
55
|
+
const input = `
|
|
56
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
57
|
+
|
|
58
|
+
export default function Test() {
|
|
59
|
+
const props = { onChange: handleChange }
|
|
60
|
+
return <Checkbox label="Save" name="choice" {...props} disabled />
|
|
61
|
+
}
|
|
62
|
+
`.trim()
|
|
63
|
+
|
|
64
|
+
const result = applyTransform(input)
|
|
65
|
+
expect(result).toContain(AUDIT_COMMENT)
|
|
66
|
+
expect(result).toContain('label="Save"')
|
|
67
|
+
expect(result).toContain('name="choice"')
|
|
68
|
+
expect(result).toContain("{...props}")
|
|
69
|
+
expect(result).toContain("disabled")
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it("should handle multiple Checkbox components with spread props", () => {
|
|
73
|
+
const input = `
|
|
74
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
75
|
+
|
|
76
|
+
export default function Test() {
|
|
77
|
+
const props1 = { onChange: handleChange1 }
|
|
78
|
+
const props2 = { onChange: handleChange2 }
|
|
79
|
+
return (
|
|
80
|
+
<div>
|
|
81
|
+
<Checkbox {...props1} label="Save" name="choice" />
|
|
82
|
+
<Checkbox {...props2} label="Cancel" name="choice" />
|
|
83
|
+
</div>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
`.trim()
|
|
87
|
+
|
|
88
|
+
const result = applyTransform(input)
|
|
89
|
+
expect(result).toContain(AUDIT_COMMENT)
|
|
90
|
+
expect(result).toContain("{...props1}")
|
|
91
|
+
expect(result).toContain("{...props2}")
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
describe("edge cases", () => {
|
|
96
|
+
it("should not transform Checkbox without spread props", () => {
|
|
97
|
+
const input = `
|
|
98
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
99
|
+
|
|
100
|
+
export default function Test() {
|
|
101
|
+
return <Checkbox onChange={handleChange} label="Save" name="choice" />
|
|
102
|
+
}
|
|
103
|
+
`.trim()
|
|
104
|
+
|
|
105
|
+
const result = applyTransform(input)
|
|
106
|
+
expect(result).toBe(null)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it("should not transform if Checkbox is not imported from @planningcenter/tapestry-react", () => {
|
|
110
|
+
const input = `
|
|
111
|
+
import { Checkbox } from "other-library"
|
|
112
|
+
|
|
113
|
+
export default function Test() {
|
|
114
|
+
const props = { onChange: handleChange }
|
|
115
|
+
return <Checkbox {...props} label="Save" name="choice" />
|
|
116
|
+
}
|
|
117
|
+
`.trim()
|
|
118
|
+
|
|
119
|
+
const result = applyTransform(input)
|
|
120
|
+
expect(result).toBe(null)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it("should handle Checkbox with alias import", () => {
|
|
124
|
+
const input = `
|
|
125
|
+
import { Checkbox as TapestryCheckbox } from "@planningcenter/tapestry-react"
|
|
126
|
+
|
|
127
|
+
export default function Test() {
|
|
128
|
+
const props = { onChange: handleChange }
|
|
129
|
+
return <TapestryCheckbox {...props} label="Save" name="choice" />
|
|
130
|
+
}
|
|
131
|
+
`.trim()
|
|
132
|
+
|
|
133
|
+
const result = applyTransform(input)
|
|
134
|
+
expect(result).toContain(AUDIT_COMMENT)
|
|
135
|
+
expect(result).toContain("{...props}")
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it("should handle mixed Checkbox components (with and without spread props)", () => {
|
|
139
|
+
const input = `
|
|
140
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
141
|
+
|
|
142
|
+
export default function Test() {
|
|
143
|
+
const props = { onChange: handleSave }
|
|
144
|
+
return (
|
|
145
|
+
<div>
|
|
146
|
+
<Checkbox {...props} label="Save" name="choice" />
|
|
147
|
+
<Checkbox label="Cancel" name="choice" />
|
|
148
|
+
<Checkbox onChange={handleDelete} label="Delete" name="choice" />
|
|
149
|
+
</div>
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
`.trim()
|
|
153
|
+
|
|
154
|
+
const result = applyTransform(input)
|
|
155
|
+
expect(result).toContain(AUDIT_COMMENT)
|
|
156
|
+
expect(result).toContain("{...props}")
|
|
157
|
+
expect(result).toContain('<Checkbox label="Cancel" name="choice" />')
|
|
158
|
+
expect(result).toContain("onChange={handleDelete}")
|
|
159
|
+
})
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
describe("complex spread prop scenarios", () => {
|
|
163
|
+
it("should handle Checkbox with complex spread expression", () => {
|
|
164
|
+
const input = `
|
|
165
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
166
|
+
|
|
167
|
+
export default function Test() {
|
|
168
|
+
const baseProps = { className: "checkbox" }
|
|
169
|
+
const additionalProps = isDisabled ? { disabled: true } : {}
|
|
170
|
+
return <Checkbox {...baseProps} {...additionalProps} label="Save" name="choice" />
|
|
171
|
+
}
|
|
172
|
+
`.trim()
|
|
173
|
+
|
|
174
|
+
const result = applyTransform(input)
|
|
175
|
+
expect(result).toContain(AUDIT_COMMENT)
|
|
176
|
+
expect(result).toContain("{...baseProps}")
|
|
177
|
+
expect(result).toContain("{...additionalProps}")
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
it("should handle Checkbox with spread props in different positions", () => {
|
|
181
|
+
const input = `
|
|
182
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
183
|
+
|
|
184
|
+
export default function Test() {
|
|
185
|
+
const props = { className: "checkbox" }
|
|
186
|
+
return (
|
|
187
|
+
<Checkbox
|
|
188
|
+
label="Save"
|
|
189
|
+
name="choice"
|
|
190
|
+
{...props}
|
|
191
|
+
disabled={false}
|
|
192
|
+
onChange={handleSave}
|
|
193
|
+
/>
|
|
194
|
+
)
|
|
195
|
+
}
|
|
196
|
+
`.trim()
|
|
197
|
+
|
|
198
|
+
const result = applyTransform(input)
|
|
199
|
+
expect(result).toContain(AUDIT_COMMENT)
|
|
200
|
+
expect(result).toContain('label="Save"')
|
|
201
|
+
expect(result).toContain('name="choice"')
|
|
202
|
+
expect(result).toContain("{...props}")
|
|
203
|
+
expect(result).toContain("disabled={false}")
|
|
204
|
+
expect(result).toContain("onChange={handleSave}")
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
it("should handle spread props with object expressions", () => {
|
|
208
|
+
const input = `
|
|
209
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
210
|
+
|
|
211
|
+
export default function Test() {
|
|
212
|
+
return <Checkbox {...{ onChange: handleChange, className: "checkbox" }} label="Save" name="choice" />
|
|
213
|
+
}
|
|
214
|
+
`.trim()
|
|
215
|
+
|
|
216
|
+
const result = applyTransform(input)
|
|
217
|
+
expect(result).toContain(AUDIT_COMMENT)
|
|
218
|
+
expect(result).toContain(
|
|
219
|
+
'{...{ onChange: handleChange, className: "checkbox" }}'
|
|
220
|
+
)
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
it("should handle spread props with function calls", () => {
|
|
224
|
+
const input = `
|
|
225
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
226
|
+
|
|
227
|
+
export default function Test() {
|
|
228
|
+
return <Checkbox {...getCheckboxProps()} {...getStyleProps()} label="Save" name="choice" />
|
|
229
|
+
}
|
|
230
|
+
`.trim()
|
|
231
|
+
|
|
232
|
+
const result = applyTransform(input)
|
|
233
|
+
expect(result).toContain(AUDIT_COMMENT)
|
|
234
|
+
expect(result).toContain("{...getCheckboxProps()}")
|
|
235
|
+
expect(result).toContain("{...getStyleProps()}")
|
|
236
|
+
})
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
describe("self-closing Checkbox components", () => {
|
|
240
|
+
it("should handle self-closing Checkbox with spread props", () => {
|
|
241
|
+
const input = `
|
|
242
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
243
|
+
|
|
244
|
+
export default function Test() {
|
|
245
|
+
const props = { label: "Close", name: "choice", onChange: handleClose }
|
|
246
|
+
return <Checkbox {...props} />
|
|
247
|
+
}
|
|
248
|
+
`.trim()
|
|
249
|
+
|
|
250
|
+
const result = applyTransform(input)
|
|
251
|
+
expect(result).toContain(AUDIT_COMMENT)
|
|
252
|
+
expect(result).toContain("{...props}")
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
it("should handle self-closing Checkbox with multiple spread props and attributes", () => {
|
|
256
|
+
const input = `
|
|
257
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
258
|
+
|
|
259
|
+
export default function Test() {
|
|
260
|
+
const baseProps = { onChange: handleChange }
|
|
261
|
+
const styleProps = { className: "checkbox" }
|
|
262
|
+
return <Checkbox label="Action" name="choice" {...baseProps} {...styleProps} disabled />
|
|
263
|
+
}
|
|
264
|
+
`.trim()
|
|
265
|
+
|
|
266
|
+
const result = applyTransform(input)
|
|
267
|
+
expect(result).toContain(AUDIT_COMMENT)
|
|
268
|
+
expect(result).toContain('label="Action"')
|
|
269
|
+
expect(result).toContain('name="choice"')
|
|
270
|
+
expect(result).toContain("{...baseProps}")
|
|
271
|
+
expect(result).toContain("{...styleProps}")
|
|
272
|
+
expect(result).toContain("disabled")
|
|
273
|
+
})
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
describe("no changes scenarios", () => {
|
|
277
|
+
it("should return null when no Checkbox components have spread props", () => {
|
|
278
|
+
const input = `
|
|
279
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
280
|
+
|
|
281
|
+
export default function Test() {
|
|
282
|
+
return (
|
|
283
|
+
<div>
|
|
284
|
+
<Checkbox label="Save" name="choice" />
|
|
285
|
+
<Checkbox label="Delete" name="choice" />
|
|
286
|
+
<Checkbox onChange={handleChange} label="Cancel" name="choice" />
|
|
287
|
+
</div>
|
|
288
|
+
)
|
|
289
|
+
}
|
|
290
|
+
`.trim()
|
|
291
|
+
|
|
292
|
+
const result = applyTransform(input)
|
|
293
|
+
expect(result).toBe(null)
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
it("should return null when no Checkbox imports exist", () => {
|
|
297
|
+
const input = `
|
|
298
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
299
|
+
|
|
300
|
+
export default function Test() {
|
|
301
|
+
const props = { onClick: handleClick }
|
|
302
|
+
return <Button {...props}>Save</Button>
|
|
303
|
+
}
|
|
304
|
+
`.trim()
|
|
305
|
+
|
|
306
|
+
const result = applyTransform(input)
|
|
307
|
+
expect(result).toBe(null)
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
it("should return null for empty file", () => {
|
|
311
|
+
const result = applyTransform("")
|
|
312
|
+
expect(result).toBe(null)
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
it("should return null when file has no JSX", () => {
|
|
316
|
+
const input = `
|
|
317
|
+
export function handleChange() {
|
|
318
|
+
console.log("changed")
|
|
319
|
+
}
|
|
320
|
+
`.trim()
|
|
321
|
+
|
|
322
|
+
const result = applyTransform(input)
|
|
323
|
+
expect(result).toBe(null)
|
|
324
|
+
})
|
|
325
|
+
})
|
|
326
|
+
|
|
327
|
+
describe("different import scenarios", () => {
|
|
328
|
+
it("should handle default import with spread props", () => {
|
|
329
|
+
const input = `
|
|
330
|
+
import Checkbox from "@planningcenter/tapestry-react"
|
|
331
|
+
|
|
332
|
+
export default function Test() {
|
|
333
|
+
const props = { onChange: handleChange }
|
|
334
|
+
return <Checkbox {...props} label="Save" name="choice" />
|
|
335
|
+
}
|
|
336
|
+
`.trim()
|
|
337
|
+
|
|
338
|
+
const result = applyTransform(input)
|
|
339
|
+
expect(result).toBe(null)
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
it("should handle namespace import", () => {
|
|
343
|
+
const input = `
|
|
344
|
+
import * as Tapestry from "@planningcenter/tapestry-react"
|
|
345
|
+
|
|
346
|
+
export default function Test() {
|
|
347
|
+
const props = { onChange: handleChange }
|
|
348
|
+
return <Tapestry.Checkbox {...props} label="Save" name="choice" />
|
|
349
|
+
}
|
|
350
|
+
`.trim()
|
|
351
|
+
|
|
352
|
+
const result = applyTransform(input)
|
|
353
|
+
expect(result).toBe(null)
|
|
354
|
+
})
|
|
355
|
+
})
|
|
356
|
+
})
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Transform } from "jscodeshift"
|
|
2
|
+
|
|
3
|
+
import { commentOnSpreadPropsFactory } from "../../shared/transformFactories/commentOnSpreadPropsFactory"
|
|
4
|
+
|
|
5
|
+
const transform: Transform = commentOnSpreadPropsFactory({
|
|
6
|
+
targetComponent: "Checkbox",
|
|
7
|
+
targetPackage: "@planningcenter/tapestry-react",
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
export default transform
|
|
@@ -34,6 +34,23 @@ function Test() {
|
|
|
34
34
|
)
|
|
35
35
|
})
|
|
36
36
|
|
|
37
|
+
it('should transform size={"lg"} to md', () => {
|
|
38
|
+
const input = `
|
|
39
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
40
|
+
|
|
41
|
+
function Test() {
|
|
42
|
+
return <Checkbox size={"lg"} label="Large checkbox" />
|
|
43
|
+
}
|
|
44
|
+
`.trim()
|
|
45
|
+
|
|
46
|
+
const result = applyTransform(input)
|
|
47
|
+
expect(result).toContain('size="md"')
|
|
48
|
+
expect(result).not.toContain('size={"lg"}')
|
|
49
|
+
expect(result).toContain(
|
|
50
|
+
'TODO: tapestry-migration (size): Size "lg" was mapped to "md"'
|
|
51
|
+
)
|
|
52
|
+
})
|
|
53
|
+
|
|
37
54
|
it("should transform xl to md", () => {
|
|
38
55
|
const input = `
|
|
39
56
|
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
@@ -51,7 +68,24 @@ function Test() {
|
|
|
51
68
|
)
|
|
52
69
|
})
|
|
53
70
|
|
|
54
|
-
it(
|
|
71
|
+
it('should transform size={"xl"} to md', () => {
|
|
72
|
+
const input = `
|
|
73
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
74
|
+
|
|
75
|
+
function Test() {
|
|
76
|
+
return <Checkbox size={"xl"} label="Extra large checkbox" />
|
|
77
|
+
}
|
|
78
|
+
`.trim()
|
|
79
|
+
|
|
80
|
+
const result = applyTransform(input)
|
|
81
|
+
expect(result).toContain('size="md"')
|
|
82
|
+
expect(result).not.toContain('size={"xl"}')
|
|
83
|
+
expect(result).toContain(
|
|
84
|
+
'TODO: tapestry-migration (size): Size "xl" was mapped to "md"'
|
|
85
|
+
)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it("should transform xs to sm", () => {
|
|
55
89
|
const input = `
|
|
56
90
|
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
57
91
|
|
|
@@ -61,8 +95,28 @@ function Test() {
|
|
|
61
95
|
`.trim()
|
|
62
96
|
|
|
63
97
|
const result = applyTransform(input)
|
|
64
|
-
expect(result).toContain('size="
|
|
65
|
-
expect(result).not.toContain("
|
|
98
|
+
expect(result).toContain('size="sm"')
|
|
99
|
+
expect(result).not.toContain('size="xs"')
|
|
100
|
+
expect(result).toContain(
|
|
101
|
+
'TODO: tapestry-migration (size): Size "xs" was mapped to "sm"'
|
|
102
|
+
)
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it('should transform size={"xs"} to sm', () => {
|
|
106
|
+
const input = `
|
|
107
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
108
|
+
|
|
109
|
+
function Test() {
|
|
110
|
+
return <Checkbox size={"xs"} label="Extra small checkbox" />
|
|
111
|
+
}
|
|
112
|
+
`.trim()
|
|
113
|
+
|
|
114
|
+
const result = applyTransform(input)
|
|
115
|
+
expect(result).toContain('size="sm"')
|
|
116
|
+
expect(result).not.toContain('size={"xs"}')
|
|
117
|
+
expect(result).toContain(
|
|
118
|
+
'TODO: tapestry-migration (size): Size "xs" was mapped to "sm"'
|
|
119
|
+
)
|
|
66
120
|
})
|
|
67
121
|
|
|
68
122
|
it("should not transform supported sizes", () => {
|
|
@@ -74,7 +128,6 @@ function Test() {
|
|
|
74
128
|
<div>
|
|
75
129
|
<Checkbox size="md" label="Medium checkbox" />
|
|
76
130
|
<Checkbox size="sm" label="Small checkbox" />
|
|
77
|
-
<Checkbox size="xs" label="Extra small checkbox" />
|
|
78
131
|
</div>
|
|
79
132
|
)
|
|
80
133
|
}
|
|
@@ -83,7 +136,6 @@ function Test() {
|
|
|
83
136
|
const result = applyTransform(input)
|
|
84
137
|
expect(result).toContain('size="md"')
|
|
85
138
|
expect(result).toContain('size="sm"')
|
|
86
|
-
expect(result).toContain('size="xs"')
|
|
87
139
|
expect(result).not.toContain("TODO: tapestry-migration")
|
|
88
140
|
})
|
|
89
141
|
})
|
|
@@ -139,12 +191,13 @@ function Test() {
|
|
|
139
191
|
|
|
140
192
|
const result = applyTransform(input)
|
|
141
193
|
expect(result).toContain('size="md"')
|
|
142
|
-
expect(result).toContain('size="
|
|
194
|
+
expect(result).toContain('size="sm"')
|
|
143
195
|
expect(result).not.toContain('size="lg"')
|
|
144
196
|
expect(result).not.toContain('size="xl"')
|
|
145
|
-
|
|
197
|
+
expect(result).not.toContain('size="xs"')
|
|
198
|
+
// Should have 3 TODO comments (one for lg->md, one for xl->md, one for xs->sm)
|
|
146
199
|
const todoMatches = result.match(/TODO: tapestry-migration \(size\)/g)
|
|
147
|
-
expect(todoMatches).toHaveLength(
|
|
200
|
+
expect(todoMatches).toHaveLength(3)
|
|
148
201
|
})
|
|
149
202
|
|
|
150
203
|
it("should preserve other props", () => {
|
|
@@ -175,7 +228,33 @@ function Test() {
|
|
|
175
228
|
)
|
|
176
229
|
})
|
|
177
230
|
|
|
178
|
-
it("should
|
|
231
|
+
it("should handle mixed string literals and JSXExpressionContainers", () => {
|
|
232
|
+
const input = `
|
|
233
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
234
|
+
|
|
235
|
+
function Test() {
|
|
236
|
+
return (
|
|
237
|
+
<div>
|
|
238
|
+
<Checkbox size="lg" label="String literal" />
|
|
239
|
+
<Checkbox size={"xl"} label="JSXExpressionContainer" />
|
|
240
|
+
<Checkbox size="xs" label="Another string literal" />
|
|
241
|
+
</div>
|
|
242
|
+
)
|
|
243
|
+
}
|
|
244
|
+
`.trim()
|
|
245
|
+
|
|
246
|
+
const result = applyTransform(input)
|
|
247
|
+
expect(result).toContain('size="md"')
|
|
248
|
+
expect(result).toContain('size="sm"')
|
|
249
|
+
expect(result).not.toContain('size="lg"')
|
|
250
|
+
expect(result).not.toContain('size={"xl"}')
|
|
251
|
+
expect(result).not.toContain('size="xs"')
|
|
252
|
+
// Should have 3 TODO comments (one for lg->md, one for xl->md, one for xs->sm)
|
|
253
|
+
const todoMatches = result.match(/TODO: tapestry-migration \(size\)/g)
|
|
254
|
+
expect(todoMatches).toHaveLength(3)
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
it("should not transform variable expression values", () => {
|
|
179
258
|
const input = `
|
|
180
259
|
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
181
260
|
|
|
@@ -1,45 +1,15 @@
|
|
|
1
1
|
import { Transform } from "jscodeshift"
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { hasAttribute } from "../../shared/conditions/hasAttribute"
|
|
5
|
-
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
3
|
+
import { sizeMappingFactory } from "../../shared/transformFactories/sizeMappingFactory"
|
|
6
4
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
condition: hasAttribute("size"),
|
|
5
|
+
const transform: Transform = sizeMappingFactory({
|
|
6
|
+
sizeMapping: {
|
|
7
|
+
lg: "md",
|
|
8
|
+
xl: "md",
|
|
9
|
+
xs: "sm",
|
|
10
|
+
},
|
|
14
11
|
targetComponent: "Checkbox",
|
|
15
12
|
targetPackage: "@planningcenter/tapestry-react",
|
|
16
|
-
transform: (element, { j }) => {
|
|
17
|
-
let hasChanges = false
|
|
18
|
-
|
|
19
|
-
const sizeAttr = element.openingElement.attributes?.find(
|
|
20
|
-
(attr) => attr.type === "JSXAttribute" && attr.name.name === "size"
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
if (sizeAttr && sizeAttr.type === "JSXAttribute") {
|
|
24
|
-
if (sizeAttr.value?.type === "StringLiteral") {
|
|
25
|
-
const sizeValue = sizeAttr.value.value as string
|
|
26
|
-
const mappedSize = SIZE_MAPPING[sizeValue as keyof typeof SIZE_MAPPING]
|
|
27
|
-
|
|
28
|
-
if (mappedSize && mappedSize !== sizeValue) {
|
|
29
|
-
sizeAttr.value.value = mappedSize
|
|
30
|
-
hasChanges = true
|
|
31
|
-
|
|
32
|
-
addCommentToAttribute({
|
|
33
|
-
attribute: sizeAttr,
|
|
34
|
-
j,
|
|
35
|
-
text: `Size "${sizeValue}" was mapped to "${mappedSize}". Verify visual appearance as sizes may differ slightly.`,
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return hasChanges
|
|
42
|
-
},
|
|
43
13
|
})
|
|
44
14
|
|
|
45
15
|
export default transform
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import { JSXAttribute, Transform } from "jscodeshift"
|
|
2
2
|
|
|
3
3
|
import { addCommentToUnsupportedProps } from "../../shared/actions/addCommentToUnsupportedProps"
|
|
4
|
-
import {
|
|
4
|
+
import { CHECKBOX_RADIO_SUPPORTED_PROPS } from "../../shared/helpers/unsupportedPropsHelpers"
|
|
5
5
|
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
6
6
|
|
|
7
|
-
const CHECKBOX_SPECIFIC_PROPS = [
|
|
8
|
-
"checked",
|
|
9
|
-
"disabled",
|
|
10
|
-
"indeterminate",
|
|
11
|
-
"label",
|
|
12
|
-
"name",
|
|
13
|
-
"onChange",
|
|
14
|
-
"value",
|
|
15
|
-
]
|
|
7
|
+
const CHECKBOX_SPECIFIC_PROPS = ["indeterminate"]
|
|
16
8
|
|
|
17
|
-
const SUPPORTED_PROPS = [
|
|
9
|
+
const SUPPORTED_PROPS = [
|
|
10
|
+
...CHECKBOX_RADIO_SUPPORTED_PROPS,
|
|
11
|
+
...CHECKBOX_SPECIFIC_PROPS,
|
|
12
|
+
]
|
|
18
13
|
|
|
19
14
|
const transform: Transform = attributeTransformFactory({
|
|
20
15
|
targetComponent: "Checkbox",
|
|
@@ -1,24 +1,10 @@
|
|
|
1
1
|
import { Transform } from "jscodeshift"
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { getSpreadProps } from "../../shared/actions/getSpreadProps"
|
|
5
|
-
import { hasSpreadProps } from "../../shared/actions/hasSpreadProps"
|
|
6
|
-
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
3
|
+
import { commentOnSpreadPropsFactory } from "../../shared/transformFactories/commentOnSpreadPropsFactory"
|
|
7
4
|
|
|
8
|
-
const
|
|
9
|
-
"Spread props can contain unsupported props, please explore usages and migrate as needed."
|
|
10
|
-
|
|
11
|
-
const transform: Transform = attributeTransformFactory({
|
|
12
|
-
condition: hasSpreadProps,
|
|
5
|
+
const transform: Transform = commentOnSpreadPropsFactory({
|
|
13
6
|
targetComponent: "Link",
|
|
14
7
|
targetPackage: "@planningcenter/tapestry-react",
|
|
15
|
-
transform: (element, { j }) => {
|
|
16
|
-
const spreadProps = getSpreadProps(element)
|
|
17
|
-
spreadProps.forEach((prop) =>
|
|
18
|
-
addCommentToAttribute({ attribute: prop, j, text: COMMENT })
|
|
19
|
-
)
|
|
20
|
-
return spreadProps.length > 0
|
|
21
|
-
},
|
|
22
8
|
})
|
|
23
9
|
|
|
24
10
|
export default transform
|
|
@@ -302,10 +302,12 @@ export default function Test({ items }) {
|
|
|
302
302
|
}
|
|
303
303
|
`.trim()
|
|
304
304
|
|
|
305
|
-
const result = applyTransform(input)
|
|
305
|
+
const result = applyTransform(input)!
|
|
306
306
|
|
|
307
|
-
expect(result).toContain(
|
|
308
|
-
|
|
307
|
+
expect(result).toContain("<Tooltip")
|
|
308
|
+
expect(result).toContain("key={item.id}")
|
|
309
|
+
expect(result.replace(/\s+/g, " ")).toContain(
|
|
310
|
+
"{...{ title: `Save ${item.name}` }}"
|
|
309
311
|
)
|
|
310
312
|
expect(result).toContain(
|
|
311
313
|
"<Link href={item.url} onClick={() => save(item)}>"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { JSXAttribute, Transform } from "jscodeshift"
|
|
2
2
|
|
|
3
3
|
import { addCommentToUnsupportedProps } from "../../shared/actions/addCommentToUnsupportedProps"
|
|
4
|
-
import {
|
|
4
|
+
import { BUTTON_LINK_SUPPORTED_PROPS } from "../../shared/helpers/unsupportedPropsHelpers"
|
|
5
5
|
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
6
6
|
|
|
7
7
|
// Note: 'target' and 'rel' are NOT included because they are handled by targetBlankToExternal transform
|
|
@@ -16,7 +16,7 @@ const LINK_SPECIFIC_PROPS = [
|
|
|
16
16
|
"type",
|
|
17
17
|
]
|
|
18
18
|
|
|
19
|
-
const SUPPORTED_PROPS = [...
|
|
19
|
+
const SUPPORTED_PROPS = [...BUTTON_LINK_SUPPORTED_PROPS, ...LINK_SPECIFIC_PROPS]
|
|
20
20
|
|
|
21
21
|
const transform: Transform = attributeTransformFactory({
|
|
22
22
|
targetComponent: "Link",
|