diff --git a/packages/metro-bundler/src/ModuleGraph/__tests__/Graph-test.js b/packages/metro-bundler/src/ModuleGraph/__tests__/Graph-test.js index a5689e6f..288e5550 100644 --- a/packages/metro-bundler/src/ModuleGraph/__tests__/Graph-test.js +++ b/packages/metro-bundler/src/ModuleGraph/__tests__/Graph-test.js @@ -5,12 +5,13 @@ * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. + * + * @emails oncall+javascript_foundation + * @format */ 'use strict'; -jest - .useRealTimers() - .mock('console'); +jest.useRealTimers().mock('console'); const {Console} = require('console'); const Graph = require('../Graph'); @@ -45,7 +46,11 @@ describe('Graph:', () => { const entryPoint = '/arbitrary/path'; graph([entryPoint], anyPlatform, noOpts, () => { expect(resolve).toBeCalledWith( - entryPoint, null, any(String), any(Object)); + entryPoint, + null, + any(String), + any(Object), + ); done(); }); }); @@ -54,12 +59,19 @@ describe('Graph:', () => { const entryPoints = ['Arbitrary', '../entry.js']; graph(entryPoints, anyPlatform, noOpts, () => { expect(resolve).toBeCalledWith( - entryPoints[0], null, any(String), any(Object)); + entryPoints[0], + null, + any(String), + any(Object), + ); expect(resolve).toBeCalledWith( - entryPoints[1], null, any(String), any(Object)); + entryPoints[1], + null, + any(String), + any(Object), + ); done(); }); - }); it('calls back with an error when called without `platform` option', done => { @@ -72,8 +84,7 @@ describe('Graph:', () => { it('forwards a passed-in `platform` to `resolve`', done => { const platform = 'any'; graph(anyEntry, platform, noOpts, () => { - expect(resolve).toBeCalledWith( - any(String), null, platform, any(Object)); + expect(resolve).toBeCalledWith(any(String), null, platform, any(Object)); done(); }); }); @@ -82,7 +93,11 @@ describe('Graph:', () => { const log = new Console(); graph(anyEntry, anyPlatform, {log}, () => { expect(resolve).toBeCalledWith( - any(String), null, any(String), objectContaining({log})); + any(String), + null, + any(String), + objectContaining({log}), + ); done(); }); }); @@ -99,11 +114,13 @@ describe('Graph:', () => { it('only calls back once if two parallel invocations of `resolve` fail', done => { load.stub.returns({ file: createFile('with two deps'), - dependencies: ['depA', 'depB']}, - ); + dependencies: ['depA', 'depB'], + }); resolve.stub - .withArgs('depA').throws(new Error()) - .withArgs('depB').throws(new Error()); + .withArgs('depA') + .throws(new Error()) + .withArgs('depB') + .throws(new Error()); let calls = 0; function callback() { @@ -139,7 +156,9 @@ describe('Graph:', () => { it('passes the `optimize` flag on to `load`', done => { graph(anyEntry, anyPlatform, {optimize: true}, () => { expect(load).toBeCalledWith( - any(String), objectContaining({optimize: true})); + any(String), + objectContaining({optimize: true}), + ); done(); }); }); @@ -147,7 +166,9 @@ describe('Graph:', () => { it('uses `false` as the default for the `optimize` flag', done => { graph(anyEntry, anyPlatform, noOpts, () => { expect(load).toBeCalledWith( - any(String), objectContaining({optimize: false})); + any(String), + objectContaining({optimize: false}), + ); done(); }); }); @@ -155,8 +176,7 @@ describe('Graph:', () => { it('forwards a passed-in `log` to `load`', done => { const log = new Console(); graph(anyEntry, anyPlatform, {log}, () => { - expect(load) - .toBeCalledWith(any(String), objectContaining({log})); + expect(load).toBeCalledWith(any(String), objectContaining({log})); done(); }); }); @@ -181,10 +201,8 @@ describe('Graph:', () => { }); graph(['entry'], anyPlatform, noOpts, () => { - expect(resolve).toBeCalledWith( - id1, entryPath, any(String), any(Object)); - expect(resolve).toBeCalledWith( - id2, entryPath, any(String), any(Object)); + expect(resolve).toBeCalledWith(id1, entryPath, any(String), any(Object)); + expect(resolve).toBeCalledWith(id2, entryPath, any(String), any(Object)); done(); }); }); @@ -197,12 +215,17 @@ describe('Graph:', () => { const path2 = '/path/to/dep/2'; resolve.stub - .withArgs(id1).returns(path1) - .withArgs(id2).returns(path2) - .withArgs('entry').returns(entryPath); + .withArgs(id1) + .returns(path1) + .withArgs(id2) + .returns(path2) + .withArgs('entry') + .returns(entryPath); load.stub - .withArgs(entryPath).returns({file: {path: entryPath}, dependencies: [id1]}) - .withArgs(path1).returns({file: {path: path1}, dependencies: [id2]}); + .withArgs(entryPath) + .returns({file: {path: entryPath}, dependencies: [id1]}) + .withArgs(path1) + .returns({file: {path: path1}, dependencies: [id2]}); graph(['entry'], anyPlatform, noOpts, () => { expect(resolve).toBeCalledWith(id2, path1, any(String), any(Object)); @@ -212,69 +235,75 @@ describe('Graph:', () => { }); }); - it('resolves modules in depth-first traversal order, regardless of the order of loading', - done => { - load.stub.reset(); - resolve.stub.reset(); + it('resolves modules in depth-first traversal order, regardless of the order of loading', done => { + load.stub.reset(); + resolve.stub.reset(); - const ids = [ - 'a', - 'b', - 'c', 'd', - 'e', - 'f', 'g', - 'h', - ]; - ids.forEach(id => { - const path = idToPath(id); - resolve.stub.withArgs(id).returns(path); - load.stub.withArgs(path).returns({file: createFile(id), dependencies: []}); - }); - load.stub.withArgs(idToPath('a')).returns({file: createFile('a'), dependencies: ['b', 'e', 'h']}); - - // load certain files later - const b = deferred({file: createFile('b'), dependencies: ['c', 'd']}); - const e = deferred({file: createFile('e'), dependencies: ['f', 'g']}); + const ids = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']; + ids.forEach(id => { + const path = idToPath(id); + resolve.stub.withArgs(id).returns(path); load.stub - .withArgs(idToPath('b')).returns(b.promise) - .withArgs(idToPath('e')).returns(e.promise) - .withArgs(idToPath('h')).func = (f, o) => { - process.nextTick(() => { - // `e` loads after `h` - e.resolve(); - // `b` loads after `a` - process.nextTick(b.resolve); - }); - return {file: createFile('h'), dependencies: []}; - }; + .withArgs(path) + .returns({file: createFile(id), dependencies: []}); + }); + load.stub + .withArgs(idToPath('a')) + .returns({file: createFile('a'), dependencies: ['b', 'e', 'h']}); - graph(['a'], anyPlatform, noOpts, (error, result) => { - expect(error).toEqual(null); - expect(result.modules).toEqual([ - createModule('a', ['b', 'e', 'h']), - createModule('b', ['c', 'd']), - createModule('c'), - createModule('d'), - createModule('e', ['f', 'g']), - createModule('f'), - createModule('g'), - createModule('h'), - ]); - done(); + // load certain files later + const b = deferred({file: createFile('b'), dependencies: ['c', 'd']}); + const e = deferred({file: createFile('e'), dependencies: ['f', 'g']}); + load.stub + .withArgs(idToPath('b')) + .returns(b.promise) + .withArgs(idToPath('e')) + .returns(e.promise) + .withArgs(idToPath('h')).func = (f, o) => { + process.nextTick(() => { + // `e` loads after `h` + e.resolve(); + // `b` loads after `a` + process.nextTick(b.resolve); }); - }, - ); + return {file: createFile('h'), dependencies: []}; + }; + + graph(['a'], anyPlatform, noOpts, (error, result) => { + expect(error).toEqual(null); + expect(result.modules).toEqual([ + createModule('a', ['b', 'e', 'h']), + createModule('b', ['c', 'd']), + createModule('c'), + createModule('d'), + createModule('e', ['f', 'g']), + createModule('f'), + createModule('g'), + createModule('h'), + ]); + done(); + }); + }); it('calls back with the resolved modules of the entry points', done => { load.stub.reset(); resolve.stub.reset(); - load.stub.withArgs(idToPath('a')).returns({file: createFile('a'), dependencies: ['b']}); - load.stub.withArgs(idToPath('b')).returns({file: createFile('b'), dependencies: []}); - load.stub.withArgs(idToPath('c')).returns({file: createFile('c'), dependencies: ['d']}); - load.stub.withArgs(idToPath('d')).returns({file: createFile('d'), dependencies: []}); + load.stub + .withArgs(idToPath('a')) + .returns({file: createFile('a'), dependencies: ['b']}); + load.stub + .withArgs(idToPath('b')) + .returns({file: createFile('b'), dependencies: []}); + load.stub + .withArgs(idToPath('c')) + .returns({file: createFile('c'), dependencies: ['d']}); + load.stub + .withArgs(idToPath('d')) + .returns({file: createFile('d'), dependencies: []}); - 'abcd'.split('') + 'abcd' + .split('') .forEach(id => resolve.stub.withArgs(id).returns(idToPath(id))); graph(['a', 'c'], anyPlatform, noOpts, (error, result) => { @@ -290,10 +319,15 @@ describe('Graph:', () => { load.stub.reset(); resolve.stub.reset(); - load.stub.withArgs(idToPath('a')).returns({file: createFile('a'), dependencies: ['b']}); - load.stub.withArgs(idToPath('b')).returns({file: createFile('b'), dependencies: []}); + load.stub + .withArgs(idToPath('a')) + .returns({file: createFile('a'), dependencies: ['b']}); + load.stub + .withArgs(idToPath('b')) + .returns({file: createFile('b'), dependencies: []}); - 'ab'.split('') + 'ab' + .split('') .forEach(id => resolve.stub.withArgs(id).returns(idToPath(id))); graph(['a', 'b'], anyPlatform, noOpts, (error, result) => { @@ -310,11 +344,15 @@ describe('Graph:', () => { ids.forEach(id => { const path = idToPath(id); resolve.stub.withArgs(id).returns(path); - load.stub.withArgs(path).returns({file: createFile(id), dependencies: []}); + load.stub + .withArgs(path) + .returns({file: createFile(id), dependencies: []}); }); ['a', 'd'].forEach(id => load.stub - .withArgs(idToPath(id)).returns({file: createFile(id), dependencies: ['b', 'c']})); + .withArgs(idToPath(id)) + .returns({file: createFile(id), dependencies: ['b', 'c']}), + ); graph(['a', 'd', 'b'], anyPlatform, noOpts, (error, result) => { expect(error).toEqual(null); @@ -330,13 +368,19 @@ describe('Graph:', () => { it('handles dependency cycles', done => { resolve.stub - .withArgs('a').returns(idToPath('a')) - .withArgs('b').returns(idToPath('b')) - .withArgs('c').returns(idToPath('c')); + .withArgs('a') + .returns(idToPath('a')) + .withArgs('b') + .returns(idToPath('b')) + .withArgs('c') + .returns(idToPath('c')); load.stub - .withArgs(idToPath('a')).returns({file: createFile('a'), dependencies: ['b']}) - .withArgs(idToPath('b')).returns({file: createFile('b'), dependencies: ['c']}) - .withArgs(idToPath('c')).returns({file: createFile('c'), dependencies: ['a']}); + .withArgs(idToPath('a')) + .returns({file: createFile('a'), dependencies: ['b']}) + .withArgs(idToPath('b')) + .returns({file: createFile('b'), dependencies: ['c']}) + .withArgs(idToPath('c')) + .returns({file: createFile('c'), dependencies: ['a']}); graph(['a'], anyPlatform, noOpts, (error, result) => { expect(result.modules).toEqual([ @@ -349,13 +393,19 @@ describe('Graph:', () => { }); it('can skip files', done => { - ['a', 'b', 'c', 'd', 'e'].forEach( - id => resolve.stub.withArgs(id).returns(idToPath(id))); + ['a', 'b', 'c', 'd', 'e'].forEach(id => + resolve.stub.withArgs(id).returns(idToPath(id)), + ); load.stub - .withArgs(idToPath('a')).returns({file: createFile('a'), dependencies: ['b', 'c', 'd']}) - .withArgs(idToPath('b')).returns({file: createFile('b'), dependencies: ['e']}); + .withArgs(idToPath('a')) + .returns({file: createFile('a'), dependencies: ['b', 'c', 'd']}) + .withArgs(idToPath('b')) + .returns({file: createFile('b'), dependencies: ['e']}); ['c', 'd', 'e'].forEach(id => - load.stub.withArgs(idToPath(id)).returns({file: createFile(id), dependencies: []})); + load.stub + .withArgs(idToPath(id)) + .returns({file: createFile(id), dependencies: []}), + ); const skip = new Set([idToPath('b'), idToPath('c')]); graph(['a'], anyPlatform, {skip}, (error, result) => { @@ -389,6 +439,6 @@ function idToPath(id) { function deferred(value) { let resolve; - const promise = new Promise(res => resolve = res); + const promise = new Promise(res => (resolve = res)); return {promise, resolve: () => resolve(value)}; }