@planningcenter/tapestry-migration-cli 3.2.3-rc.4 → 3.2.3-rc.5
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 +3 -3
- package/src/components/date-picker/index.ts +56 -0
- package/src/components/date-picker/transforms/auditSpreadProps.test.ts +97 -0
- package/src/components/date-picker/transforms/auditSpreadProps.ts +10 -0
- package/src/components/date-picker/transforms/convertStyleProps.test.ts +58 -0
- package/src/components/date-picker/transforms/convertStyleProps.ts +10 -0
- package/src/components/date-picker/transforms/maxDateToMax.test.ts +87 -0
- package/src/components/date-picker/transforms/maxDateToMax.ts +16 -0
- package/src/components/date-picker/transforms/mergeFieldIntoDateField.test.ts +240 -0
- package/src/components/date-picker/transforms/mergeFieldIntoDateField.ts +5 -0
- package/src/components/date-picker/transforms/minDateToMin.test.ts +87 -0
- package/src/components/date-picker/transforms/minDateToMin.ts +16 -0
- package/src/components/date-picker/transforms/momentToDateString.test.ts +240 -0
- package/src/components/date-picker/transforms/momentToDateString.ts +87 -0
- package/src/components/date-picker/transforms/moveDatePickerImport.test.ts +157 -0
- package/src/components/date-picker/transforms/moveDatePickerImport.ts +14 -0
- package/src/components/date-picker/transforms/nativeDateToString.test.ts +220 -0
- package/src/components/date-picker/transforms/nativeDateToString.ts +59 -0
- package/src/components/date-picker/transforms/removeDuplicateKeys.test.ts +120 -0
- package/src/components/date-picker/transforms/removeDuplicateKeys.ts +8 -0
- package/src/components/date-picker/transforms/removeFormatValue.test.ts +119 -0
- package/src/components/date-picker/transforms/removeFormatValue.ts +22 -0
- package/src/components/date-picker/transforms/removePlaceholder.test.ts +117 -0
- package/src/components/date-picker/transforms/removePlaceholder.ts +22 -0
- package/src/components/date-picker/transforms/sizeMapping.test.ts +173 -0
- package/src/components/date-picker/transforms/sizeMapping.ts +15 -0
- package/src/components/date-picker/transforms/stateToInvalid.test.ts +109 -0
- package/src/components/date-picker/transforms/stateToInvalid.ts +57 -0
- package/src/components/date-picker/transforms/stateToInvalidTernary.test.ts +72 -0
- package/src/components/date-picker/transforms/stateToInvalidTernary.ts +11 -0
- package/src/components/date-picker/transforms/unsupportedProps.test.ts +170 -0
- package/src/components/date-picker/transforms/unsupportedProps.ts +37 -0
- package/src/components/shared/helpers/unsupportedPropsHelpers.ts +18 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Transform } from "jscodeshift"
|
|
2
|
+
|
|
3
|
+
import { transformAttributeName } from "../../shared/actions/transformAttributeName"
|
|
4
|
+
import { hasAttribute } from "../../shared/conditions/hasAttribute"
|
|
5
|
+
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
6
|
+
|
|
7
|
+
const transform: Transform = attributeTransformFactory({
|
|
8
|
+
condition: hasAttribute("minDate"),
|
|
9
|
+
targetComponent: "DateField",
|
|
10
|
+
targetPackage: "@planningcenter/tapestry-react",
|
|
11
|
+
transform: (element, { j, options }) => {
|
|
12
|
+
return transformAttributeName("minDate", "min", { element, j, options })
|
|
13
|
+
},
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export default transform
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import jscodeshift from "jscodeshift"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
|
|
4
|
+
import transform from "./momentToDateString"
|
|
5
|
+
|
|
6
|
+
const j = jscodeshift.withParser("tsx")
|
|
7
|
+
|
|
8
|
+
function applyTransform(source: string): string | null {
|
|
9
|
+
const fileInfo = { path: "test.tsx", source }
|
|
10
|
+
return transform(
|
|
11
|
+
fileInfo,
|
|
12
|
+
{ j, jscodeshift: j, report: () => {}, stats: () => {} },
|
|
13
|
+
{}
|
|
14
|
+
) as string | null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe("momentToDateString transform", () => {
|
|
18
|
+
describe("minDate with moment().toDate()", () => {
|
|
19
|
+
it("converts moment(starts).add(1, 'day').toDate() to .format()", () => {
|
|
20
|
+
const input = `
|
|
21
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
22
|
+
|
|
23
|
+
function Test() {
|
|
24
|
+
return <DateField minDate={moment(starts).add(1, 'day').toDate()} value={date} onChange={setDate} />
|
|
25
|
+
}
|
|
26
|
+
`.trim()
|
|
27
|
+
|
|
28
|
+
const result = applyTransform(input)
|
|
29
|
+
expect(result).not.toBeNull()
|
|
30
|
+
expect(result).toContain('.format("YYYY-MM-DD")')
|
|
31
|
+
expect(result).not.toContain(".toDate()}")
|
|
32
|
+
expect(result).toContain("moment(starts).add(1, 'day')")
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it("converts moment().add(-10, 'years').toDate() to .format()", () => {
|
|
36
|
+
const input = `
|
|
37
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
38
|
+
|
|
39
|
+
function Test() {
|
|
40
|
+
return <DateField minDate={moment().add(-10, 'years').toDate()} value={date} onChange={setDate} />
|
|
41
|
+
}
|
|
42
|
+
`.trim()
|
|
43
|
+
|
|
44
|
+
const result = applyTransform(input)
|
|
45
|
+
expect(result).not.toBeNull()
|
|
46
|
+
expect(result).toContain('.format("YYYY-MM-DD")')
|
|
47
|
+
expect(result).not.toContain(".toDate()}")
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it("converts simple moment().toDate() to .format()", () => {
|
|
51
|
+
const input = `
|
|
52
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
53
|
+
|
|
54
|
+
function Test() {
|
|
55
|
+
return <DateField minDate={moment().toDate()} value={date} onChange={setDate} />
|
|
56
|
+
}
|
|
57
|
+
`.trim()
|
|
58
|
+
|
|
59
|
+
const result = applyTransform(input)
|
|
60
|
+
expect(result).not.toBeNull()
|
|
61
|
+
expect(result).toContain('moment().format("YYYY-MM-DD")')
|
|
62
|
+
expect(result).not.toContain(".toDate()}")
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it("adds a change comment noting the conversion", () => {
|
|
66
|
+
const input = `
|
|
67
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
68
|
+
|
|
69
|
+
function Test() {
|
|
70
|
+
return <DateField minDate={moment().toDate()} value={date} onChange={setDate} />
|
|
71
|
+
}
|
|
72
|
+
`.trim()
|
|
73
|
+
|
|
74
|
+
const result = applyTransform(input)
|
|
75
|
+
expect(result).not.toBeNull()
|
|
76
|
+
expect(result).toContain("Converted .toDate()")
|
|
77
|
+
expect(result).toContain("ISO date strings")
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
describe("maxDate with moment().toDate()", () => {
|
|
82
|
+
it("converts maxDate moment chain to .format()", () => {
|
|
83
|
+
const input = `
|
|
84
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
85
|
+
|
|
86
|
+
function Test() {
|
|
87
|
+
return <DateField maxDate={moment(ends).subtract(1, 'day').toDate()} value={date} onChange={setDate} />
|
|
88
|
+
}
|
|
89
|
+
`.trim()
|
|
90
|
+
|
|
91
|
+
const result = applyTransform(input)
|
|
92
|
+
expect(result).not.toBeNull()
|
|
93
|
+
expect(result).toContain('.format("YYYY-MM-DD")')
|
|
94
|
+
expect(result).not.toContain(".toDate()}")
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
describe("value with moment().toDate()", () => {
|
|
99
|
+
it("converts value moment chain to .format()", () => {
|
|
100
|
+
const input = `
|
|
101
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
102
|
+
|
|
103
|
+
function Test() {
|
|
104
|
+
return <DateField value={moment(selectedDate).toDate()} onChange={setDate} />
|
|
105
|
+
}
|
|
106
|
+
`.trim()
|
|
107
|
+
|
|
108
|
+
const result = applyTransform(input)
|
|
109
|
+
expect(result).not.toBeNull()
|
|
110
|
+
expect(result).toContain('.format("YYYY-MM-DD")')
|
|
111
|
+
expect(result).not.toContain(".toDate()}")
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
describe("multiple props with moment", () => {
|
|
116
|
+
it("converts both minDate and maxDate moment chains", () => {
|
|
117
|
+
const input = `
|
|
118
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
119
|
+
|
|
120
|
+
function Test() {
|
|
121
|
+
return (
|
|
122
|
+
<DateField
|
|
123
|
+
minDate={moment().add(-10, 'years').toDate()}
|
|
124
|
+
maxDate={moment().toDate()}
|
|
125
|
+
value={date}
|
|
126
|
+
onChange={setDate}
|
|
127
|
+
/>
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
`.trim()
|
|
131
|
+
|
|
132
|
+
const result = applyTransform(input)
|
|
133
|
+
expect(result).not.toBeNull()
|
|
134
|
+
expect(result).not.toContain(".toDate()}")
|
|
135
|
+
const formatMatches = result!.match(/\)\.format\("YYYY-MM-DD"\)\}/g)
|
|
136
|
+
expect(formatMatches).toHaveLength(2)
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
describe("moment without .toDate()", () => {
|
|
141
|
+
it("adds TODO comment when moment is used without .toDate()", () => {
|
|
142
|
+
const input = `
|
|
143
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
144
|
+
|
|
145
|
+
function Test() {
|
|
146
|
+
return <DateField minDate={moment(starts)} value={date} onChange={setDate} />
|
|
147
|
+
}
|
|
148
|
+
`.trim()
|
|
149
|
+
|
|
150
|
+
const result = applyTransform(input)
|
|
151
|
+
expect(result).not.toBeNull()
|
|
152
|
+
expect(result).toContain("TODO: tapestry-migration")
|
|
153
|
+
expect(result).toContain("manual conversion")
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it("adds TODO for moment variable reference in value", () => {
|
|
157
|
+
const input = `
|
|
158
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
159
|
+
|
|
160
|
+
function Test() {
|
|
161
|
+
const d = moment()
|
|
162
|
+
return <DateField value={moment(d)} onChange={setDate} />
|
|
163
|
+
}
|
|
164
|
+
`.trim()
|
|
165
|
+
|
|
166
|
+
const result = applyTransform(input)
|
|
167
|
+
expect(result).not.toBeNull()
|
|
168
|
+
expect(result).toContain("TODO: tapestry-migration")
|
|
169
|
+
})
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
describe("non-date values", () => {
|
|
173
|
+
it("does not transform string values", () => {
|
|
174
|
+
const input = `
|
|
175
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
176
|
+
|
|
177
|
+
function Test() {
|
|
178
|
+
return <DateField value="2024-01-01" onChange={setDate} />
|
|
179
|
+
}
|
|
180
|
+
`.trim()
|
|
181
|
+
|
|
182
|
+
const result = applyTransform(input)
|
|
183
|
+
expect(result).toBeNull()
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it("does not transform variable references", () => {
|
|
187
|
+
const input = `
|
|
188
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
189
|
+
|
|
190
|
+
function Test() {
|
|
191
|
+
return <DateField minDate={startDate} value={date} onChange={setDate} />
|
|
192
|
+
}
|
|
193
|
+
`.trim()
|
|
194
|
+
|
|
195
|
+
const result = applyTransform(input)
|
|
196
|
+
expect(result).toBeNull()
|
|
197
|
+
})
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
describe("edge cases", () => {
|
|
201
|
+
it("does not affect other components", () => {
|
|
202
|
+
const input = `
|
|
203
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
204
|
+
|
|
205
|
+
function Test() {
|
|
206
|
+
return <Input value={moment().toDate()} label="Name" />
|
|
207
|
+
}
|
|
208
|
+
`.trim()
|
|
209
|
+
|
|
210
|
+
const result = applyTransform(input)
|
|
211
|
+
expect(result).toBeNull()
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
it("does not transform non-date props that use moment", () => {
|
|
215
|
+
const input = `
|
|
216
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
217
|
+
|
|
218
|
+
function Test() {
|
|
219
|
+
return <DateField onChange={moment().toDate()} value={date} />
|
|
220
|
+
}
|
|
221
|
+
`.trim()
|
|
222
|
+
|
|
223
|
+
const result = applyTransform(input)
|
|
224
|
+
expect(result).toBeNull()
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
it("does not transform DateField from other packages", () => {
|
|
228
|
+
const input = `
|
|
229
|
+
import { DateField } from "other-library"
|
|
230
|
+
|
|
231
|
+
function Test() {
|
|
232
|
+
return <DateField minDate={moment().toDate()} value={date} onChange={setDate} />
|
|
233
|
+
}
|
|
234
|
+
`.trim()
|
|
235
|
+
|
|
236
|
+
const result = applyTransform(input)
|
|
237
|
+
expect(result).toBeNull()
|
|
238
|
+
})
|
|
239
|
+
})
|
|
240
|
+
})
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CallExpression,
|
|
3
|
+
Expression,
|
|
4
|
+
MemberExpression,
|
|
5
|
+
Transform,
|
|
6
|
+
} from "jscodeshift"
|
|
7
|
+
|
|
8
|
+
import { addCommentToAttribute } from "../../shared/actions/addCommentToAttribute"
|
|
9
|
+
import { getAttribute } from "../../shared/actions/getAttribute"
|
|
10
|
+
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
11
|
+
|
|
12
|
+
const DATE_PROPS = ["minDate", "maxDate", "value"]
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Checks if an expression is a call to `.toDate()` at the end of a chain
|
|
16
|
+
*/
|
|
17
|
+
function isToDateCall(expr: Expression): expr is CallExpression {
|
|
18
|
+
return (
|
|
19
|
+
expr.type === "CallExpression" &&
|
|
20
|
+
expr.callee.type === "MemberExpression" &&
|
|
21
|
+
expr.callee.property.type === "Identifier" &&
|
|
22
|
+
expr.callee.property.name === "toDate" &&
|
|
23
|
+
expr.arguments.length === 0
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Checks whether an expression references `moment` anywhere in its call chain
|
|
29
|
+
*/
|
|
30
|
+
function usesMoment(expr: Expression): boolean {
|
|
31
|
+
if (expr.type === "Identifier" && expr.name === "moment") return true
|
|
32
|
+
if (expr.type === "CallExpression") {
|
|
33
|
+
if (usesMoment(expr.callee as Expression)) return true
|
|
34
|
+
return expr.arguments.some((arg) =>
|
|
35
|
+
arg.type !== "SpreadElement" ? usesMoment(arg as Expression) : false
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
if (expr.type === "MemberExpression") {
|
|
39
|
+
return usesMoment(expr.object as Expression)
|
|
40
|
+
}
|
|
41
|
+
return false
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const transform: Transform = attributeTransformFactory({
|
|
45
|
+
targetComponent: "DateField",
|
|
46
|
+
targetPackage: "@planningcenter/tapestry-react",
|
|
47
|
+
transform: (element, { j }) => {
|
|
48
|
+
let hasChanges = false
|
|
49
|
+
|
|
50
|
+
for (const propName of DATE_PROPS) {
|
|
51
|
+
const attr = getAttribute({ element, name: propName })
|
|
52
|
+
if (!attr?.value) continue
|
|
53
|
+
if (attr.value.type !== "JSXExpressionContainer") continue
|
|
54
|
+
|
|
55
|
+
const expr = attr.value.expression
|
|
56
|
+
if (expr.type === "JSXEmptyExpression") continue
|
|
57
|
+
|
|
58
|
+
if (!usesMoment(expr as Expression)) continue
|
|
59
|
+
|
|
60
|
+
if (isToDateCall(expr as Expression)) {
|
|
61
|
+
const callExpr = expr as CallExpression
|
|
62
|
+
const memberExpr = callExpr.callee as MemberExpression
|
|
63
|
+
memberExpr.property = j.identifier("format")
|
|
64
|
+
callExpr.arguments = [j.stringLiteral("YYYY-MM-DD")]
|
|
65
|
+
|
|
66
|
+
addCommentToAttribute({
|
|
67
|
+
attribute: attr,
|
|
68
|
+
commentKind: "change",
|
|
69
|
+
j,
|
|
70
|
+
text: `Converted .toDate() to .format("YYYY-MM-DD") — DatePicker accepts ISO date strings instead of Date objects. Verify the format is correct.`,
|
|
71
|
+
})
|
|
72
|
+
hasChanges = true
|
|
73
|
+
} else {
|
|
74
|
+
addCommentToAttribute({
|
|
75
|
+
attribute: attr,
|
|
76
|
+
j,
|
|
77
|
+
text: `This prop uses moment and may need manual conversion. DatePicker accepts DateValue or ISO date strings (YYYY-MM-DD) instead of Date objects.`,
|
|
78
|
+
})
|
|
79
|
+
hasChanges = true
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return hasChanges
|
|
84
|
+
},
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
export default transform
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import jscodeshift from "jscodeshift"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
|
|
4
|
+
import transform from "./moveDatePickerImport"
|
|
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("moveDatePickerImport transform", () => {
|
|
19
|
+
describe("import migration", () => {
|
|
20
|
+
it("should rename DateField to DatePicker and change import", () => {
|
|
21
|
+
const input = `
|
|
22
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
23
|
+
|
|
24
|
+
function Test() {
|
|
25
|
+
return <DateField value={date} onChange={setDate} />
|
|
26
|
+
}
|
|
27
|
+
`.trim()
|
|
28
|
+
|
|
29
|
+
const result = applyTransform(input)
|
|
30
|
+
expect(result).toContain(
|
|
31
|
+
'import { DatePicker } from "@planningcenter/tapestry"'
|
|
32
|
+
)
|
|
33
|
+
expect(result).not.toContain("@planningcenter/tapestry-react")
|
|
34
|
+
expect(result).toContain("<DatePicker")
|
|
35
|
+
expect(result).not.toContain("<DateField")
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it("should only move DateField, leaving other imports in place", () => {
|
|
39
|
+
const input = `
|
|
40
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
41
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
42
|
+
|
|
43
|
+
function Test() {
|
|
44
|
+
return (
|
|
45
|
+
<div>
|
|
46
|
+
<Button>Click</Button>
|
|
47
|
+
<DateField value={date} onChange={setDate} />
|
|
48
|
+
</div>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
`.trim()
|
|
52
|
+
|
|
53
|
+
const result = applyTransform(input)
|
|
54
|
+
expect(result).toContain(
|
|
55
|
+
'import { Button } from "@planningcenter/tapestry-react"'
|
|
56
|
+
)
|
|
57
|
+
expect(result).toContain(
|
|
58
|
+
'import { DatePicker } from "@planningcenter/tapestry"'
|
|
59
|
+
)
|
|
60
|
+
expect(result).toContain("<DatePicker")
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
describe("import conflict handling", () => {
|
|
65
|
+
it("should use TdsDatePicker alias when DatePicker is already imported from another package", () => {
|
|
66
|
+
const input = `
|
|
67
|
+
import { DatePicker } from "some-other-library"
|
|
68
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
69
|
+
|
|
70
|
+
function Test() {
|
|
71
|
+
return (
|
|
72
|
+
<div>
|
|
73
|
+
<DatePicker />
|
|
74
|
+
<DateField value={date} onChange={setDate} />
|
|
75
|
+
</div>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
`.trim()
|
|
79
|
+
|
|
80
|
+
const result = applyTransform(input)
|
|
81
|
+
expect(result).toContain(
|
|
82
|
+
'import { DatePicker } from "some-other-library"'
|
|
83
|
+
)
|
|
84
|
+
expect(result).toContain(
|
|
85
|
+
'import { DatePicker as TdsDatePicker } from "@planningcenter/tapestry"'
|
|
86
|
+
)
|
|
87
|
+
expect(result).toContain("<TdsDatePicker")
|
|
88
|
+
expect(result).not.toContain("<DateField")
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
describe("edge cases", () => {
|
|
93
|
+
it("should not affect other components", () => {
|
|
94
|
+
const input = `
|
|
95
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
96
|
+
|
|
97
|
+
function Test() {
|
|
98
|
+
return <Button>Click me</Button>
|
|
99
|
+
}
|
|
100
|
+
`.trim()
|
|
101
|
+
|
|
102
|
+
const result = applyTransform(input)
|
|
103
|
+
expect(result).toContain(
|
|
104
|
+
'import { Button } from "@planningcenter/tapestry-react"'
|
|
105
|
+
)
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it("should handle no imports", () => {
|
|
109
|
+
const input = `
|
|
110
|
+
function Test() {
|
|
111
|
+
return <div>No imports</div>
|
|
112
|
+
}
|
|
113
|
+
`.trim()
|
|
114
|
+
|
|
115
|
+
const result = applyTransform(input)
|
|
116
|
+
expect(result).toBe(input)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it("should preserve all attributes", () => {
|
|
120
|
+
const input = `
|
|
121
|
+
import { DateField } from "@planningcenter/tapestry-react"
|
|
122
|
+
|
|
123
|
+
function Test() {
|
|
124
|
+
return (
|
|
125
|
+
<DateField
|
|
126
|
+
value={date}
|
|
127
|
+
onChange={setDate}
|
|
128
|
+
disabled
|
|
129
|
+
/>
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
`.trim()
|
|
133
|
+
|
|
134
|
+
const result = applyTransform(input)
|
|
135
|
+
expect(result).toContain(
|
|
136
|
+
'import { DatePicker } from "@planningcenter/tapestry"'
|
|
137
|
+
)
|
|
138
|
+
expect(result).toContain("value={date}")
|
|
139
|
+
expect(result).toContain("onChange={setDate}")
|
|
140
|
+
expect(result).toContain("disabled")
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it("should handle alias import", () => {
|
|
144
|
+
const input = `
|
|
145
|
+
import { DateField as TapestryDateField } from "@planningcenter/tapestry-react"
|
|
146
|
+
|
|
147
|
+
function Test() {
|
|
148
|
+
return <TapestryDateField value={date} onChange={setDate} />
|
|
149
|
+
}
|
|
150
|
+
`.trim()
|
|
151
|
+
|
|
152
|
+
const result = applyTransform(input)
|
|
153
|
+
expect(result).toContain("@planningcenter/tapestry")
|
|
154
|
+
expect(result).not.toContain("@planningcenter/tapestry-react")
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Transform } from "jscodeshift"
|
|
2
|
+
|
|
3
|
+
import { componentTransformFactory } from "../../shared/transformFactories/componentTransformFactory"
|
|
4
|
+
|
|
5
|
+
const transform: Transform = componentTransformFactory({
|
|
6
|
+
condition: () => true,
|
|
7
|
+
conflictAlias: "TdsDatePicker",
|
|
8
|
+
fromComponent: "DateField",
|
|
9
|
+
fromPackage: "@planningcenter/tapestry-react",
|
|
10
|
+
toComponent: "DatePicker",
|
|
11
|
+
toPackage: "@planningcenter/tapestry",
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export default transform
|