Skip to content

Commit b3d1468

Browse files
committed
feat: added overwriteRoutes: true rule to codemods
1 parent 6894569 commit b3d1468

File tree

5 files changed

+75
-28
lines changed

5 files changed

+75
-28
lines changed

packages/codemods/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ For everyt variable containing an instance of fetch-mock imported using `require
2727
- Rewrite `.lastUrl()`, `.lastOptions()` and `lastResponse()` to their equivalents in fetch-mock@12
2828
- Adds an informative error whenever `.lastCall()` or `.calls()` are used with advice on how to manually correct these
2929
- Converts `.getOnce()`, `.getAnyOnce()`, `.postOnce()` etc... - which have been removed - to calls to the underlying `.get()` method with additional options passed in.
30-
- Removes uses of the deprecated options `overwriteRoutes`, `warnOnFallback`, `sendAsJson`
30+
- Removes uses of the deprecated options `warnOnFallback` and `sendAsJson`
31+
- Removes uses of the deprecated `overwriteRoutes` option, and adds an informative error with details of how to replace with the `modifyRoute()` method
3132
- Removes uses of the deprecated `fallbackToNetwork` option, and adds an informative error with details of how to replace with the `spyGlobal()` method
3233

3334
## Limitations/Out of scope

packages/codemods/src/__tests__/option-codemods.test.js

+50-19
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,22 @@ function expectCodemodResult(src, expected) {
99
}
1010

1111
describe('codemods operating on options', () => {
12+
const overwriteTrueErrorString =
13+
'throw new Error("`overwriteRoutes: true` option is deprecated. Use the `modifyRoute()` method instead")';
1214
['overwriteRoutes', 'warnOnFallback', 'sendAsJson'].forEach((optionName) => {
1315
describe(optionName, () => {
1416
it('Removes as global option when setting directly as property', () => {
15-
expectCodemodResult(`fetchMock.config.${optionName} = true`, '');
17+
expectCodemodResult(`fetchMock.config.${optionName} = false`, '');
1618
});
1719
it('Removes as global option when using Object.assign', () => {
1820
expectCodemodResult(
19-
`Object.assign(fetchMock.config, {${optionName}: true})`,
21+
`Object.assign(fetchMock.config, {${optionName}: false})`,
2022
'',
2123
);
2224
});
2325
it('Removes as global option when using Object.assign alongside other options', () => {
2426
expectCodemodResult(
25-
`Object.assign(fetchMock.config, {${optionName}: true, other: 'value'})`,
27+
`Object.assign(fetchMock.config, {${optionName}: false, other: 'value'})`,
2628
`Object.assign(fetchMock.config, {
2729
other: 'value'
2830
})`,
@@ -60,7 +62,7 @@ describe('codemods operating on options', () => {
6062
if (methodName === 'getAnyOnce') {
6163
it(`Removes as option on third parameter of ${methodName}()`, () => {
6264
expectCodemodResult(
63-
`fetchMock.getAnyOnce(200, {name: 'rio', ${optionName}: true})`,
65+
`fetchMock.getAnyOnce(200, {name: 'rio', ${optionName}: false})`,
6466
`fetchMock.getOnce("*", 200, {
6567
name: 'rio'
6668
})`,
@@ -69,14 +71,14 @@ describe('codemods operating on options', () => {
6971

7072
it(`Removes third parameter of ${methodName}() if no other options remain`, () => {
7173
expectCodemodResult(
72-
`fetchMock.getAnyOnce(200, {${optionName}: true})`,
74+
`fetchMock.getAnyOnce(200, {${optionName}: false})`,
7375
`fetchMock.getOnce("*", 200)`,
7476
);
7577
});
7678
} else if (/any/.test(methodName)) {
7779
it(`Removes as option on third parameter of ${methodName}()`, () => {
7880
expectCodemodResult(
79-
`fetchMock.${methodName}(200, {name: 'rio', ${optionName}: true})`,
81+
`fetchMock.${methodName}(200, {name: 'rio', ${optionName}: false})`,
8082
`fetchMock.${newMethodName}(200, {
8183
name: 'rio'
8284
})`,
@@ -85,14 +87,14 @@ describe('codemods operating on options', () => {
8587

8688
it(`Removes third parameter of ${methodName}() if no other options remain`, () => {
8789
expectCodemodResult(
88-
`fetchMock.${methodName}(200, {${optionName}: true})`,
90+
`fetchMock.${methodName}(200, {${optionName}: false})`,
8991
`fetchMock.${newMethodName}(200)`,
9092
);
9193
});
9294
} else {
9395
it(`Removes as option on first parameter of ${methodName}()`, () => {
9496
expectCodemodResult(
95-
`fetchMock.${methodName}({url: '*', response: 200, ${optionName}: true})`,
97+
`fetchMock.${methodName}({url: '*', response: 200, ${optionName}: false})`,
9698
`fetchMock.${newMethodName}({
9799
url: '*',
98100
response: 200
@@ -101,7 +103,7 @@ describe('codemods operating on options', () => {
101103
});
102104
it(`Removes as option on third parameter of ${methodName}()`, () => {
103105
expectCodemodResult(
104-
`fetchMock.${methodName}('*', 200, {name: 'rio', ${optionName}: true})`,
106+
`fetchMock.${methodName}('*', 200, {name: 'rio', ${optionName}: false})`,
105107
`fetchMock.${newMethodName}('*', 200, {
106108
name: 'rio'
107109
})`,
@@ -110,24 +112,53 @@ describe('codemods operating on options', () => {
110112

111113
it(`Removes third parameter of ${methodName}() if no other options remain`, () => {
112114
expectCodemodResult(
113-
`fetchMock.${methodName}('*', 200, {${optionName}: true})`,
115+
`fetchMock.${methodName}('*', 200, {${optionName}: false})`,
114116
`fetchMock.${newMethodName}('*', 200)`,
115117
);
116118
});
119+
120+
if (optionName === 'overwriteRoutes') {
121+
describe('overwriteRoutes: true', () => {
122+
it(`Removes as option on first parameter of ${methodName}()`, () => {
123+
expectCodemodResult(
124+
`fetchMock.${methodName}({url: '*', response: 200, ${optionName}: true})`,
125+
`fetchMock.${newMethodName}({
126+
url: '*',
127+
response: 200
128+
})${overwriteTrueErrorString}`,
129+
);
130+
});
131+
it(`Removes as option on third parameter of ${methodName}()`, () => {
132+
expectCodemodResult(
133+
`fetchMock.${methodName}('*', 200, {name: 'rio', ${optionName}: true})`,
134+
`fetchMock.${newMethodName}('*', 200, {
135+
name: 'rio'
136+
})${overwriteTrueErrorString}`,
137+
);
138+
});
139+
140+
it(`Removes third parameter of ${methodName}() if no other options remain`, () => {
141+
expectCodemodResult(
142+
`fetchMock.${methodName}('*', 200, {${optionName}: true})`,
143+
`fetchMock.${newMethodName}('*', 200)${overwriteTrueErrorString}`,
144+
);
145+
});
146+
});
147+
}
117148
}
118149
});
119150
});
120151
});
121152
describe('acting on combinations of the 3 options together', () => {
122153
it('Removes as global option when using Object.assign', () => {
123154
expectCodemodResult(
124-
`Object.assign(fetchMock.config, {sendAsJson: true, overwriteRoutes: true})`,
155+
`Object.assign(fetchMock.config, {sendAsJson: true, overwriteRoutes: false})`,
125156
'',
126157
);
127158
});
128159
it('Removes as global option when using Object.assign alongside other options', () => {
129160
expectCodemodResult(
130-
`Object.assign(fetchMock.config, {sendAsJson: true, overwriteRoutes: true, other: 'value'})`,
161+
`Object.assign(fetchMock.config, {sendAsJson: true, overwriteRoutes: false, other: 'value'})`,
131162
`Object.assign(fetchMock.config, {
132163
other: 'value'
133164
})`,
@@ -136,7 +167,7 @@ describe('codemods operating on options', () => {
136167

137168
it(`Removes as option on third parameter of getAnyOnce()`, () => {
138169
expectCodemodResult(
139-
`fetchMock.getAnyOnce(200, {name: 'rio', sendAsJson: true, overwriteRoutes: true})`,
170+
`fetchMock.getAnyOnce(200, {name: 'rio', sendAsJson: true, overwriteRoutes: false})`,
140171
`fetchMock.getOnce("*", 200, {
141172
name: 'rio'
142173
})`,
@@ -145,13 +176,13 @@ describe('codemods operating on options', () => {
145176

146177
it(`Removes third parameter of getAnyOnce() if no other options remain`, () => {
147178
expectCodemodResult(
148-
`fetchMock.getAnyOnce(200, {sendAsJson: true, overwriteRoutes: true})`,
179+
`fetchMock.getAnyOnce(200, {sendAsJson: true, overwriteRoutes: false})`,
149180
`fetchMock.getOnce("*", 200)`,
150181
);
151182
});
152183
it(`Removes as option on third parameter of any()`, () => {
153184
expectCodemodResult(
154-
`fetchMock.any(200, {name: 'rio', sendAsJson: true, overwriteRoutes: true})`,
185+
`fetchMock.any(200, {name: 'rio', sendAsJson: true, overwriteRoutes: false})`,
155186
`fetchMock.any(200, {
156187
name: 'rio'
157188
})`,
@@ -160,13 +191,13 @@ describe('codemods operating on options', () => {
160191

161192
it(`Removes third parameter of any() if no other options remain`, () => {
162193
expectCodemodResult(
163-
`fetchMock.any(200, {sendAsJson: true, overwriteRoutes: true})`,
194+
`fetchMock.any(200, {sendAsJson: true, overwriteRoutes: false})`,
164195
`fetchMock.any(200)`,
165196
);
166197
});
167198
it(`Removes as option on first parameter of get()`, () => {
168199
expectCodemodResult(
169-
`fetchMock.get({url: '*', response: 200, sendAsJson: true, overwriteRoutes: true})`,
200+
`fetchMock.get({url: '*', response: 200, sendAsJson: true, overwriteRoutes: false})`,
170201
`fetchMock.get({
171202
url: '*',
172203
response: 200
@@ -175,7 +206,7 @@ describe('codemods operating on options', () => {
175206
});
176207
it(`Removes as option on third parameter of get()`, () => {
177208
expectCodemodResult(
178-
`fetchMock.get('*', 200, {name: 'rio', sendAsJson: true, overwriteRoutes: true})`,
209+
`fetchMock.get('*', 200, {name: 'rio', sendAsJson: true, overwriteRoutes: false})`,
179210
`fetchMock.get('*', 200, {
180211
name: 'rio'
181212
})`,
@@ -184,7 +215,7 @@ describe('codemods operating on options', () => {
184215

185216
it(`Removes third parameter of get() if no other options remain`, () => {
186217
expectCodemodResult(
187-
`fetchMock.get('*', 200, {sendAsJson: true, overwriteRoutes: true})`,
218+
`fetchMock.get('*', 200, {sendAsJson: true, overwriteRoutes: false})`,
188219
`fetchMock.get('*', 200)`,
189220
);
190221
});

packages/codemods/src/codemods/options.js

+16-6
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,23 @@ module.exports.simpleOptions = function (fetchMockVariableName, root) {
107107
if (!optionsObjects.length) {
108108
return;
109109
}
110-
// TODO handle overwriteRoutes: true differently
111110
simpleOptionNames.forEach((optionName) => {
112-
optionsObjects
113-
.find(j.ObjectProperty, {
114-
key: { name: optionName },
115-
})
116-
.remove();
111+
const properties = optionsObjects.find(j.ObjectProperty, {
112+
key: { name: optionName },
113+
});
114+
115+
properties.forEach((path) => {
116+
if (
117+
path.value.key.name === 'overwriteRoutes' &&
118+
path.value.value.value === true
119+
) {
120+
const errorMessage =
121+
'`overwriteRoutes: true` option is deprecated. Use the `modifyRoute()` method instead';
122+
appendError(errorMessage, j(path));
123+
}
124+
});
125+
126+
properties.remove();
117127
});
118128
optionsObjects
119129
.filter((path) => {

packages/codemods/try.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const { codemod } = require('./src/index.js');
33
console.log(
44
codemod(
55
`const fetchMock = require('fetch-mock');
6-
fetchMock.get('*', 200, {name: 'rio', sendAsJson: true});
6+
fetchMock.get('*', 200, {overwriteRoutes: true});
77
`,
88
),
99
);

packages/fetch-mock/src/index.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ export {
55
} from './FetchMock.js';
66
export { CallHistoryFilter, CallLog } from './CallHistory.js';
77
export { RouteMatcher, MatcherDefinition } from './Matchers.js';
8-
export { UserRouteConfig, RouteResponse, RouteName, ModifyRouteConfig } from './Route.js';
8+
export {
9+
UserRouteConfig,
10+
RouteResponse,
11+
RouteName,
12+
ModifyRouteConfig,
13+
} from './Route.js';
914
export { RemoveRouteOptions } from './Router.js';
1015

1116
import fetchMock from './FetchMock.js';

0 commit comments

Comments
 (0)