Skip to content

Commit f6979d5

Browse files
committed
fetcher tests
1 parent 7e3a6d9 commit f6979d5

File tree

3 files changed

+221
-26
lines changed

3 files changed

+221
-26
lines changed

packages/cli/src/main.spec.ts

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
jest.mock('globby');
12
jest.mock('live-plugin-manager');
23
jest.mock('jscodeshift/src/Runner', () => ({
34
run: jest.fn().mockImplementation(() => Promise.resolve()),
45
}));
56

7+
import path from 'path';
68
// @ts-ignore
79
import * as jscodeshift from 'jscodeshift/src/Runner';
810
import { PluginManager } from 'live-plugin-manager';
11+
import globby from 'globby';
912

1013
import main from './main';
1114

@@ -532,28 +535,45 @@ describe('main', () => {
532535
});
533536

534537
describe('when running transforms from NPM with the -p flag', () => {
538+
const mockMatchedPath = path.join(
539+
__dirname,
540+
'path',
541+
'to',
542+
'codeshift.config.js',
543+
);
544+
535545
beforeEach(() => {
546+
((globby as unknown) as jest.Mock).mockImplementation(() =>
547+
Promise.resolve([mockMatchedPath]),
548+
);
549+
536550
(PluginManager as jest.Mock).mockImplementation(() => ({
537551
install: jest.fn().mockResolvedValue(undefined),
538-
require: jest.fn().mockImplementation((codemodName: string) => {
539-
if (codemodName.startsWith('@codeshift')) {
540-
return {};
541-
}
552+
require: jest.fn(),
553+
getInfo: jest
554+
.fn()
555+
.mockReturnValue({ location: path.join(__dirname, 'path', 'to') }),
556+
uninstallAll: jest.fn().mockResolvedValue(undefined),
557+
}));
558+
});
542559

543-
return {
560+
it('should run package transform for single version', async () => {
561+
jest.mock(
562+
mockMatchedPath,
563+
() => ({
564+
__esModule: true,
565+
default: {
544566
transforms: {
545-
'18.0.0': `${codemodName}/path/to/18.js`,
567+
'18.0.0': 'mylib/path/to/18.js',
546568
},
547569
presets: {
548-
'update-formatting': `${codemodName}/path/to/update-formatting.js`,
570+
'update-formatting': 'mylib/path/to/update-formatting.js',
549571
},
550-
};
572+
},
551573
}),
552-
uninstallAll: jest.fn().mockResolvedValue(undefined),
553-
}));
554-
});
574+
{ virtual: true },
575+
);
555576

556-
it('should run package transform for single version', async () => {
557577
await main([mockPath], {
558578
packages: 'mylib@18.0.0',
559579
parser: 'babel',

packages/fetcher/src/index.spec.ts

Lines changed: 173 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,173 @@
1-
// TODO
1+
jest.mock('globby');
2+
3+
import globby from 'globby';
4+
import path from 'path';
5+
import { PluginManager } from 'live-plugin-manager';
6+
7+
import { fetchConfig, fetchPackage, fetchRemotePackage } from '.';
8+
9+
const mockBasePath = path.join(__dirname, 'path', 'to');
10+
11+
const mockConfig = {
12+
transforms: {
13+
'10.0.0': 'path/to/transform.js',
14+
},
15+
};
16+
17+
describe('fetcher', () => {
18+
let mockMatchedPaths: string[] = [];
19+
20+
beforeEach(() => {
21+
mockMatchedPaths = [
22+
path.join(mockBasePath, 'codeshift.config.js'),
23+
path.join(mockBasePath, 'src', 'codeshift.config.ts'),
24+
path.join(mockBasePath, 'codemods', 'codeshift.config.tsx'),
25+
];
26+
27+
((globby as unknown) as jest.Mock).mockImplementation(() =>
28+
Promise.resolve(mockMatchedPaths),
29+
);
30+
});
31+
32+
afterEach(() => {
33+
jest.resetAllMocks();
34+
});
35+
36+
describe('fetchConfig', () => {
37+
it('fetches config with default export', async () => {
38+
jest.mock(
39+
`${__dirname}/path/to/codeshift.config.js`,
40+
() => ({
41+
__esModule: true,
42+
default: mockConfig,
43+
}),
44+
{ virtual: true },
45+
);
46+
47+
const config = await fetchConfig(mockBasePath);
48+
49+
expect(config).toEqual(mockConfig);
50+
});
51+
52+
it('fetches config with named export', async () => {
53+
jest.mock(`${__dirname}/path/to/codeshift.config.js`, () => mockConfig, {
54+
virtual: true,
55+
});
56+
57+
const config = await fetchConfig(mockBasePath);
58+
59+
expect(config).toEqual(mockConfig);
60+
});
61+
62+
it('fetches first matched config when multiple are found', async () => {
63+
jest.mock(
64+
`${__dirname}/path/to/src/codeshift.config.ts`,
65+
() => ({
66+
__esModule: true,
67+
default: mockConfig,
68+
}),
69+
{ virtual: true },
70+
);
71+
72+
mockMatchedPaths = [
73+
path.join(mockBasePath, 'src', 'codeshift.config.ts'),
74+
path.join(mockBasePath, 'codemods', 'codeshift.config.tsx'),
75+
];
76+
77+
const config = await fetchConfig(mockBasePath);
78+
79+
expect(config).toEqual(mockConfig);
80+
});
81+
82+
it('returns undefined if no config was found', async () => {
83+
mockMatchedPaths = [];
84+
85+
const config = await fetchConfig(mockBasePath);
86+
87+
expect(config).toBe(undefined);
88+
});
89+
});
90+
91+
describe('fetchPackage', () => {
92+
it('correctly fetches package and returns a config', async () => {
93+
const mockPackageManager = {
94+
install: jest.fn(),
95+
require: jest.fn().mockReturnValue(mockConfig),
96+
};
97+
98+
const config = await fetchPackage(
99+
'fake-package',
100+
(mockPackageManager as unknown) as PluginManager,
101+
);
102+
103+
expect(config).toEqual(mockConfig);
104+
});
105+
106+
it('should throw if fetching fails', async () => {
107+
const mockPackageManager = {
108+
install: jest.fn().mockRejectedValue('Import error'),
109+
require: jest.fn().mockReturnValue(mockConfig),
110+
};
111+
112+
expect.assertions(1);
113+
114+
await expect(
115+
fetchPackage(
116+
'fake-package',
117+
(mockPackageManager as unknown) as PluginManager,
118+
),
119+
).rejects.toEqual('Import error');
120+
});
121+
});
122+
123+
describe('fetchRemotePackage', () => {
124+
it('correctly fetches package and returns a config', async () => {
125+
const mockPackageManager = {
126+
install: jest.fn(),
127+
getInfo: jest.fn().mockReturnValue({
128+
location: mockBasePath,
129+
}),
130+
};
131+
132+
const config = await fetchRemotePackage(
133+
'fake-package',
134+
(mockPackageManager as unknown) as PluginManager,
135+
);
136+
137+
expect(config).toEqual(mockConfig);
138+
});
139+
140+
it('should throw if fetching fails', async () => {
141+
const mockPackageManager = {
142+
install: jest.fn().mockRejectedValue('Import error'),
143+
};
144+
145+
expect.assertions(1);
146+
147+
await expect(
148+
fetchRemotePackage(
149+
'fake-package',
150+
(mockPackageManager as unknown) as PluginManager,
151+
),
152+
).rejects.toEqual('Import error');
153+
});
154+
155+
it('should throw if package source cannot be retrieved', async () => {
156+
const mockPackageManager = {
157+
install: jest.fn(),
158+
getInfo: () => undefined,
159+
};
160+
161+
expect.assertions(1);
162+
163+
await expect(
164+
fetchRemotePackage(
165+
'fake-package',
166+
(mockPackageManager as unknown) as PluginManager,
167+
),
168+
).rejects.toEqual(
169+
new Error(`Unable to locate package files for package: 'fake-package'`),
170+
);
171+
});
172+
});
173+
});

packages/fetcher/src/index.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,28 @@ import { PluginManager } from 'live-plugin-manager';
44

55
import { CodeshiftConfig } from '@codeshift/types';
66

7+
function resolveConfigExport(pkg: any): CodeshiftConfig {
8+
return pkg.default ? pkg.default : pkg;
9+
}
10+
711
export async function fetchConfig(
812
filePath: string,
913
): Promise<CodeshiftConfig | undefined> {
10-
let config: CodeshiftConfig | undefined;
11-
1214
const matchedPaths = await globby([
1315
path.join(filePath, 'codeshift.config.(js|ts|tsx)'),
1416
path.join(filePath, 'src', 'codeshift.config.(js|ts|tsx)'),
1517
path.join(filePath, 'codemods', 'codeshift.config.(js|ts|tsx)'),
1618
]);
1719

18-
matchedPaths.forEach(matchedPath => {
20+
for (const matchedPath of matchedPaths) {
1921
try {
2022
// eslint-disable-next-line @typescript-eslint/no-var-requires
2123
const pkg = require(matchedPath);
22-
const searchConfig = pkg.default ? pkg.default : pkg;
23-
config = searchConfig;
24+
return resolveConfigExport(pkg);
2425
} catch (e) {}
25-
});
26+
}
2627

27-
return config;
28+
return undefined;
2829
}
2930

3031
export async function fetchPackage(
@@ -33,19 +34,21 @@ export async function fetchPackage(
3334
): Promise<CodeshiftConfig | undefined> {
3435
await packageManager.install(packageName);
3536
const pkg = packageManager.require(packageName);
36-
const config: CodeshiftConfig = pkg.default ? pkg.default : pkg;
37-
return config;
37+
return resolveConfigExport(pkg);
3838
}
3939

4040
export async function fetchRemotePackage(
4141
packageName: string,
4242
packageManager: PluginManager,
4343
): Promise<CodeshiftConfig | undefined> {
44-
const config = await fetchPackage(packageName, packageManager);
45-
if (config) return config;
46-
44+
await packageManager.install(packageName);
4745
const info = packageManager.getInfo(packageName);
48-
if (!info) return undefined;
46+
47+
if (!info) {
48+
throw new Error(
49+
`Unable to locate package files for package: '${packageName}'`,
50+
);
51+
}
4952

5053
return await fetchConfig(info.location);
5154
}

0 commit comments

Comments
 (0)