Skip to content

Commit 922ee8b

Browse files
robhoganmeta-codesync[bot]
authored andcommitted
Resolver tests: Refactor to test observable "browser"-spec redirection rather than calls to redirectModulePath
Summary: Currently, `metro-resolver` tests assert on and mock calls to `redirectModulePath`, which since [5e96d17](5e96d17) (v0.81.0) is a fixed implementation detail, rather than a user-configurable context method. Refactor tests to assert on observable behaviour by creating mock `package.json`s, which makes these tests more robust to upcoming internal optimisations. Changelog: [Internal] ___ Differential Revision: D102514698 fbshipit-source-id: 05c47b37ea07d2d42128b20c4d15148a8f35a634
1 parent 76b6ca8 commit 922ee8b

1 file changed

Lines changed: 104 additions & 116 deletions

File tree

packages/metro-resolver/src/__tests__/index-test.js

Lines changed: 104 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import type {ResolutionContext} from '../index';
1515

1616
import {createResolutionContext} from './utils';
1717

18-
let Resolver = require('../index');
18+
const Resolver = require('../index');
1919

2020
const fileMap = {
2121
'/root/project/foo.js': '',
@@ -396,165 +396,137 @@ test('throws a descriptive error when a file inside a Haste package cannot be re
396396
`);
397397
});
398398

399-
describe('redirectModulePath', () => {
400-
const mockRedirectModulePath = jest.fn();
401-
const context = CONTEXT;
402-
403-
beforeEach(() => {
404-
mockRedirectModulePath.mockReset();
405-
mockRedirectModulePath.mockImplementation(filePath => false);
406-
407-
jest.resetModules();
408-
jest.mock('../PackageResolve', () => {
409-
return {
410-
...jest.requireActual('../PackageResolve'),
411-
redirectModulePath: (_ctx, specifier) =>
412-
mockRedirectModulePath(specifier),
413-
};
414-
});
415-
416-
Resolver = require('../index');
417-
});
418-
419-
afterEach(() => {
420-
jest.unmock('../PackageResolve');
421-
jest.resetModules();
422-
Resolver = require('../index');
423-
});
424-
399+
describe('browser spec redirection', () => {
425400
test('is used for relative path requests', () => {
401+
const testFileMap = {
402+
...fileMap,
403+
'/root/project/package.json': JSON.stringify({
404+
name: 'project',
405+
browser: {
406+
'./bar': false,
407+
},
408+
}),
409+
};
410+
const context = {
411+
...createResolutionContext(testFileMap),
412+
originModulePath: '/root/project/foo.js',
413+
};
426414
expect(Resolver.resolve(context, './bar', null)).toMatchInlineSnapshot(`
427415
Object {
428416
"type": "empty",
429417
}
430418
`);
431-
expect(mockRedirectModulePath).toBeCalledTimes(1);
432-
expect(mockRedirectModulePath).toBeCalledWith('/root/project/bar');
433419
});
434420

435421
test('is used for absolute path requests', () => {
436-
expect(Resolver.resolve(context, '/bar', null)).toMatchInlineSnapshot(`
422+
// browser field redirects the specifier to false
423+
const testFileMap = {
424+
'/root/bar.js': '',
425+
'/root/package.json': JSON.stringify({
426+
browser: {
427+
'./bar': false,
428+
},
429+
}),
430+
};
431+
const context = {
432+
...createResolutionContext(testFileMap),
433+
originModulePath: '/other/project/foo.js',
434+
};
435+
expect(Resolver.resolve(context, '/root/bar', null)).toMatchInlineSnapshot(`
437436
Object {
438437
"type": "empty",
439438
}
440439
`);
441-
expect(mockRedirectModulePath).toBeCalledTimes(1);
442-
expect(mockRedirectModulePath).toBeCalledWith('/bar');
443440
});
444441

445442
test('is used for non-Haste package requests', () => {
443+
const testFileMap = {
444+
...fileMap,
445+
'/root/project/package.json': JSON.stringify({
446+
name: 'project',
447+
browser: {
448+
'does-not-exist': false,
449+
},
450+
}),
451+
};
452+
const context = {
453+
...createResolutionContext(testFileMap),
454+
originModulePath: '/root/project/foo.js',
455+
};
446456
expect(Resolver.resolve(context, 'does-not-exist', null))
447457
.toMatchInlineSnapshot(`
448458
Object {
449459
"type": "empty",
450460
}
451461
`);
452-
expect(mockRedirectModulePath).toBeCalledTimes(1);
453-
expect(mockRedirectModulePath).toBeCalledWith('does-not-exist');
454462
});
455463

456464
test('can redirect to an arbitrary relative module', () => {
457-
mockRedirectModulePath
458-
.mockImplementationOnce(filePath => '../smth/beep')
459-
.mockImplementation(filePath => filePath);
465+
const testFileMap = {
466+
...fileMap,
467+
'/root/project/package.json': JSON.stringify({
468+
browser: {
469+
'does-not-exist': '../smth/beep',
470+
},
471+
}),
472+
};
473+
const context = {
474+
...createResolutionContext(testFileMap),
475+
originModulePath: '/root/project/foo.js',
476+
};
460477
expect(Resolver.resolve(context, 'does-not-exist', null))
461478
.toMatchInlineSnapshot(`
462479
Object {
463480
"filePath": "/root/smth/beep.js",
464481
"type": "sourceFile",
465482
}
466483
`);
467-
expect(mockRedirectModulePath.mock.calls).toMatchInlineSnapshot(`
468-
Array [
469-
Array [
470-
"does-not-exist",
471-
],
472-
Array [
473-
"/root/smth/beep",
474-
],
475-
Array [
476-
"/root/smth/beep.js",
477-
],
478-
]
479-
`);
480484
});
481485

482-
test("is called for source extension candidates that don't exist on disk", () => {
483-
mockRedirectModulePath.mockImplementation(filePath =>
484-
filePath.replace('.another-fake-ext', '.js'),
485-
);
486-
expect(
487-
Resolver.resolve(
488-
{...context, sourceExts: ['fake-ext', 'another-fake-ext']},
489-
'../smth/beep',
490-
null,
491-
),
492-
).toMatchInlineSnapshot(`
486+
test('resolves source extension candidates to relative paths', () => {
487+
const testFileMap = {
488+
...fileMap,
489+
'/root/project/package.json': JSON.stringify({
490+
name: 'project',
491+
browser: {
492+
'./beep.another-fake-ext': '../smth/beep.js',
493+
},
494+
}),
495+
'/root/project/beep.js': '',
496+
};
497+
const context = {
498+
...createResolutionContext(testFileMap),
499+
originModulePath: '/root/project/foo.js',
500+
sourceExts: ['fake-ext', 'another-fake-ext'],
501+
};
502+
expect(Resolver.resolve(context, './beep', null)).toMatchInlineSnapshot(`
493503
Object {
494504
"filePath": "/root/smth/beep.js",
495505
"type": "sourceFile",
496506
}
497507
`);
498-
expect(mockRedirectModulePath.mock.calls).toMatchInlineSnapshot(`
499-
Array [
500-
Array [
501-
"/root/smth/beep",
502-
],
503-
Array [
504-
"/root/smth/beep.fake-ext",
505-
],
506-
Array [
507-
"/root/smth/beep.another-fake-ext",
508-
],
509-
]
510-
`);
511508
});
512509

513510
test('can resolve to empty from a candidate with an added source extension', () => {
514-
mockRedirectModulePath.mockImplementation(filePath =>
515-
filePath.endsWith('.fake-ext') ? false : filePath,
516-
);
517-
expect(
518-
Resolver.resolve(
519-
{...context, sourceExts: ['fake-ext', 'js']},
520-
'../smth/beep',
521-
null,
522-
),
523-
).toMatchInlineSnapshot(`
511+
const testFileMap = {
512+
...fileMap,
513+
'/root/project/package.json': JSON.stringify({
514+
name: 'project',
515+
browser: {
516+
'./beep.fake-ext': false,
517+
},
518+
}),
519+
};
520+
const context = {
521+
...createResolutionContext(testFileMap),
522+
originModulePath: '/root/project/foo.js',
523+
sourceExts: ['fake-ext', 'js'],
524+
};
525+
expect(Resolver.resolve(context, './beep', null)).toMatchInlineSnapshot(`
524526
Object {
525527
"type": "empty",
526528
}
527529
`);
528-
expect(mockRedirectModulePath.mock.calls).toMatchInlineSnapshot(`
529-
Array [
530-
Array [
531-
"/root/smth/beep",
532-
],
533-
Array [
534-
"/root/smth/beep.fake-ext",
535-
],
536-
]
537-
`);
538-
});
539-
540-
test('is not called redundantly for a candidate that does exist on disk', () => {
541-
mockRedirectModulePath.mockImplementation(filePath => filePath);
542-
expect(Resolver.resolve(context, './bar', null)).toMatchInlineSnapshot(`
543-
Object {
544-
"filePath": "/root/project/bar.js",
545-
"type": "sourceFile",
546-
}
547-
`);
548-
expect(mockRedirectModulePath.mock.calls).toMatchInlineSnapshot(`
549-
Array [
550-
Array [
551-
"/root/project/bar",
552-
],
553-
Array [
554-
"/root/project/bar.js",
555-
],
556-
]
557-
`);
558530
});
559531
});
560532

@@ -643,9 +615,17 @@ describe('resolveRequest', () => {
643615
});
644616

645617
test('is called with the platform and non-redirected module path', () => {
618+
const testFileMap = {
619+
...fileMap,
620+
'/root/project/package.json': JSON.stringify({
621+
browser: {
622+
'does-not-exist': './redirected',
623+
},
624+
}),
625+
};
646626
const contextWithRedirect = {
647627
...context,
648-
redirectModulePath: (filePath: string) => filePath + '.redirected',
628+
...createResolutionContext(testFileMap),
649629
};
650630
expect(Resolver.resolve(contextWithRedirect, 'does-not-exist', 'android'))
651631
.toMatchInlineSnapshot(`
@@ -666,9 +646,17 @@ describe('resolveRequest', () => {
666646
type: 'sourceFile',
667647
filePath: '/some/fake/path',
668648
}));
649+
const testFileMap = {
650+
...fileMap,
651+
'/root/project/package.json': JSON.stringify({
652+
browser: {
653+
'does-not-exist': false,
654+
},
655+
}),
656+
};
669657
const contextWithRedirect = {
670658
...context,
671-
redirectModulePath: (filePath: string) => false as const,
659+
...createResolutionContext(testFileMap),
672660
};
673661
expect(Resolver.resolve(contextWithRedirect, 'does-not-exist', 'android'))
674662
.toMatchInlineSnapshot(`

0 commit comments

Comments
 (0)