Skip to content

Commit e4f6b2d

Browse files
committed
✨ Adds toggle codemods!
1 parent 2bdc677 commit e4f6b2d

File tree

10 files changed

+653
-2
lines changed

10 files changed

+653
-2
lines changed

community/@atlaskit__breadcrumbs/11.0.0/_tests_/elevate-stateless-to-default.spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { API, FileInfo, Options } from 'jscodeshift';
22
import elevateStatelessToDefault from '../motions/elevate-stateless-to-default';
3+
const defineInlineTest = require('jscodeshift/dist/testUtils').defineInlineTest;
34

45
function transformer(
56
fileInfo: FileInfo,
@@ -13,8 +14,6 @@ function transformer(
1314
return source.toSource(options.printOptions);
1415
}
1516

16-
const defineInlineTest = require('jscodeshift/dist/testUtils').defineInlineTest;
17-
1817
describe('@atlaskit/breadcrumbs@11.0.0 motion: Elevate BreadcrumbsStateless', () => {
1918
defineInlineTest(
2019
{ default: transformer, parser: 'tsx' },
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import transformer from '../transform';
2+
3+
const defineInlineTest = require('jscodeshift/dist/testUtils').defineInlineTest;
4+
5+
describe('@atlaskit/toggle@11.0.0 transform', () => {
6+
defineInlineTest(
7+
{ default: transformer, parser: 'tsx' },
8+
{},
9+
`
10+
import React from "react";
11+
import { X as Toggle } from "x";
12+
() => {
13+
return (
14+
<div>
15+
<Toggle isDefaultChecked={true} />
16+
</div>
17+
);
18+
};
19+
`,
20+
`
21+
import React from "react";
22+
import { X as Toggle } from "x";
23+
() => {
24+
return (
25+
<div>
26+
<Toggle isDefaultChecked={true} />
27+
</div>
28+
);
29+
};
30+
`,
31+
'should not transform if imports are not present',
32+
);
33+
34+
defineInlineTest(
35+
{ default: transformer, parser: 'tsx' },
36+
{},
37+
`
38+
import React from "react";
39+
import Toggle from "@atlaskit/toggle";
40+
() => {
41+
return (
42+
<div>
43+
<Toggle isDefaultChecked={true} />
44+
</div>
45+
);
46+
};
47+
`,
48+
`
49+
import React from "react";
50+
import Toggle from "@atlaskit/toggle";
51+
() => {
52+
return (
53+
<div>
54+
<Toggle defaultChecked={true} />
55+
</div>
56+
);
57+
};
58+
`,
59+
'transforms `isDefaultChecked` to `defaultChecked` when `@atlaskit/toggle` is imported',
60+
);
61+
62+
defineInlineTest(
63+
{ default: transformer, parser: 'tsx' },
64+
{},
65+
`
66+
import React from "react";
67+
import Toggle from "@atlaskit/toggle";
68+
() => {
69+
return (
70+
<div>
71+
<Toggle isDefaultChecked={false} />
72+
</div>
73+
);
74+
};
75+
`,
76+
`
77+
import React from "react";
78+
import Toggle from "@atlaskit/toggle";
79+
() => {
80+
return (
81+
<div>
82+
<Toggle defaultChecked={false} />
83+
</div>
84+
);
85+
};
86+
`,
87+
'transforms `isDefaultChecked` to `defaultChecked` when `@atlaskit/toggle` is imported - without changing the value',
88+
);
89+
90+
defineInlineTest(
91+
{ default: transformer, parser: 'tsx' },
92+
{},
93+
`
94+
import React from "react";
95+
import Toggle from "@atlaskit/toggle";
96+
() => {
97+
const T = Toggle;
98+
const X = Toggle;
99+
const Z = Toggle;
100+
101+
const FOO = "bar";
102+
return (
103+
<div>
104+
<Toggle isDefaultChecked={true} />
105+
<T isDefaultChecked={true} />
106+
<X id={true} />
107+
<Z isDefaultChecked={true} />
108+
</div>
109+
);
110+
};
111+
`,
112+
`
113+
import React from "react";
114+
import Toggle from "@atlaskit/toggle";
115+
() => {
116+
const T = Toggle;
117+
const X = Toggle;
118+
const Z = Toggle;
119+
120+
const FOO = "bar";
121+
return (
122+
<div>
123+
<Toggle defaultChecked={true} />
124+
<T defaultChecked={true} />
125+
<X id={true} />
126+
<Z defaultChecked={true} />
127+
</div>
128+
);
129+
};
130+
`,
131+
'transforms `isDefaultChecked` to `defaultChecked` when `@atlaskit/toggle` is imported',
132+
);
133+
});
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import core, { API, Collection, FileInfo, Options } from 'jscodeshift';
2+
import {
3+
getDefaultImportSpecifierName,
4+
hasImportDeclaration,
5+
getJSXAttributesByName,
6+
} from '@codeshift/utils';
7+
8+
function findIdentifierAndReplaceAttribute(
9+
j: core.JSCodeshift,
10+
source: Collection<any>,
11+
identifierName: string,
12+
searchAttr: string,
13+
replaceWithAttr: string,
14+
) {
15+
source
16+
.find(j.JSXElement)
17+
.find(j.JSXOpeningElement)
18+
.filter(path => {
19+
return !!j(path.node)
20+
.find(j.JSXIdentifier)
21+
.filter(identifier => identifier.value.name === identifierName);
22+
})
23+
.find(j.JSXAttribute)
24+
.find(j.JSXIdentifier)
25+
.filter(attr => attr.node.name === searchAttr)
26+
.replaceWith(j.jsxIdentifier(replaceWithAttr));
27+
}
28+
29+
function hasVariableAssignment(
30+
j: core.JSCodeshift,
31+
source: Collection<any>,
32+
identifierName: string,
33+
) {
34+
const occurrence = source.find(j.VariableDeclaration).filter(
35+
path =>
36+
!!j(path.node)
37+
.find(j.VariableDeclarator)
38+
.find(j.Identifier)
39+
.filter(identifier => identifier.node.name === identifierName).length,
40+
);
41+
return !!occurrence.length ? occurrence : false;
42+
}
43+
44+
export default function transformer(
45+
fileInfo: FileInfo,
46+
{ jscodeshift: j }: API,
47+
options: Options,
48+
) {
49+
const source = j(fileInfo.source);
50+
51+
/**
52+
* Early exit condition
53+
* -----
54+
* It is often good practice to exit early and return the original source file
55+
* if it does not contain code relevant to the codemod.
56+
* See this page for more information:
57+
* https://codeshiftcommunity.github.io/CodeshiftCommunity/docs/your-first-codemod#output
58+
*/
59+
if (!hasImportDeclaration(j, source, '@atlaskit/toggle')) {
60+
return fileInfo.source;
61+
}
62+
63+
const defaultSpecifier = getDefaultImportSpecifierName(
64+
j,
65+
source,
66+
'@atlaskit/toggle',
67+
);
68+
69+
if (!defaultSpecifier) return fileInfo.source;
70+
71+
source.findJSXElements(defaultSpecifier).forEach(element => {
72+
getJSXAttributesByName(j, element, 'isDefaultChecked').forEach(
73+
attribute => {
74+
j(attribute).replaceWith(
75+
j.jsxAttribute(
76+
j.jsxIdentifier('defaultChecked'),
77+
attribute.node.value,
78+
),
79+
);
80+
},
81+
);
82+
});
83+
84+
const variable = hasVariableAssignment(j, source, defaultSpecifier);
85+
86+
if (variable) {
87+
variable.find(j.VariableDeclarator).forEach(declarator => {
88+
j(declarator)
89+
.find(j.Identifier)
90+
.filter(identifier => identifier.name === 'id')
91+
.forEach(ids => {
92+
findIdentifierAndReplaceAttribute(
93+
j,
94+
source,
95+
ids.node.name,
96+
'isDefaultChecked',
97+
'defaultChecked',
98+
);
99+
});
100+
});
101+
}
102+
103+
return source.toSource(options.printOptions);
104+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { API, FileInfo, Options } from 'jscodeshift';
2+
import elevateStateless from '../motions/elevate-stateless';
3+
4+
const defineInlineTest = require('jscodeshift/dist/testUtils').defineInlineTest;
5+
6+
function transformer(
7+
fileInfo: FileInfo,
8+
{ jscodeshift: j }: API,
9+
options: Options,
10+
) {
11+
const source = j(fileInfo.source);
12+
13+
elevateStateless(j, source);
14+
15+
return source.toSource(options.printOptions);
16+
}
17+
18+
describe('Merge Toggle and ToggleStateless', () => {
19+
defineInlineTest(
20+
{ default: transformer, parser: 'tsx' },
21+
{},
22+
`
23+
import React from 'react';
24+
import Toggle from "@atlaskit/toggle";
25+
26+
export default () => (
27+
<Toggle size="large" defaultChecked />
28+
);
29+
`,
30+
`
31+
import React from 'react';
32+
import Toggle from "@atlaskit/toggle";
33+
34+
export default () => (
35+
<Toggle size="large" defaultChecked />
36+
);
37+
`,
38+
'nothing would change if Toggle is used',
39+
);
40+
41+
defineInlineTest(
42+
{ default: transformer, parser: 'tsx' },
43+
{},
44+
`
45+
import React from 'react';
46+
import { ToggleStateless } from "@atlaskit/toggle";
47+
48+
export default () => (
49+
<ToggleStateless size="large" isChecked />
50+
);
51+
`,
52+
`
53+
import React from 'react';
54+
import ToggleStateless from "@atlaskit/toggle";
55+
56+
export default () => (
57+
<ToggleStateless size="large" isChecked />
58+
);
59+
`,
60+
'change to new Toggle when ToggleStateless is used',
61+
);
62+
63+
defineInlineTest(
64+
{ default: transformer, parser: 'tsx' },
65+
{},
66+
`
67+
import React from 'react';
68+
import { ToggleStateless as Toggle } from "@atlaskit/toggle";
69+
70+
export default () => (
71+
<Toggle size="large" isChecked />
72+
);
73+
`,
74+
`
75+
import React from 'react';
76+
import Toggle from "@atlaskit/toggle";
77+
78+
export default () => (
79+
<Toggle size="large" isChecked />
80+
);
81+
`,
82+
'change to new Toggle when ToggleStateless is used, with alias',
83+
);
84+
});

0 commit comments

Comments
 (0)