UNPKG

react-native

Version:

A framework for building native apps using React

1,763 lines (1,679 loc) • 159 kB
/** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * 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. */ 'use strict'; jest.disableAutomock(); jest.useRealTimers(); jest .mock('fs') .mock('../../Logger') .mock('../../lib/TransformCache') // It's noticeably faster to prevent running watchman from FileWatcher. .mock('child_process', () => ({})) ; // This doesn't have state, and it's huge (Babel) so it's much faster to // require it only once. const extractDependencies = require('../../JSTransformer/worker/extract-dependencies'); jest.mock('../../JSTransformer/worker/extract-dependencies', () => extractDependencies); jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; const path = require('path'); const mockStat = { isDirectory: () => false, }; beforeEach(() => { jest.resetModules(); jest.mock('path', () => path); }); describe('DependencyGraph', function() { let Module; let ResolutionRequest; let defaults; function getOrderedDependenciesAsJSON(dgraph, entryPath, platform, recursive = true) { return dgraph.getDependencies({entryPath, platform, recursive}) .then(response => response.finalize()) .then(({ dependencies }) => Promise.all(dependencies.map(dep => Promise.all([ dep.getName(), dep.getDependencies(), ]).then(([name, moduleDependencies]) => ({ path: dep.path, isJSON: dep.isJSON(), isAsset: dep.isAsset(), isPolyfill: dep.isPolyfill(), resolution: dep.resolution, id: name, dependencies: moduleDependencies, }))) )); } beforeEach(function() { jest.resetModules(); Module = require('../Module'); ResolutionRequest = require('../DependencyGraph/ResolutionRequest'); const Cache = jest.genMockFn().mockImplementation(function() { this._maps = Object.create(null); }); Cache.prototype.has = jest.genMockFn() .mockImplementation(function(filepath, field) { if (!(filepath in this._maps)) { return false; } return !field || field in this._maps[filepath]; }); Cache.prototype.get = jest.genMockFn() .mockImplementation(function(filepath, field, factory) { let cacheForPath = this._maps[filepath]; if (this.has(filepath, field)) { return field ? cacheForPath[field] : cacheForPath; } if (!cacheForPath) { cacheForPath = this._maps[filepath] = Object.create(null); } const value = cacheForPath[field] = factory(); return value; }); Cache.prototype.invalidate = jest.genMockFn() .mockImplementation(function(filepath, field) { if (!this.has(filepath, field)) { return; } if (field) { delete this._maps[filepath][field]; } else { delete this._maps[filepath]; } }); Cache.prototype.end = jest.genMockFn(); const transformCacheKey = 'abcdef'; defaults = { assetExts: ['png', 'jpg'], cache: new Cache(), forceNodeFilesystemAPI: true, providesModuleNodeModules: [ 'haste-fbjs', 'react-haste', 'react-native', ], platforms: ['ios', 'android'], useWatchman: false, maxWorkers: 1, resetCache: true, transformCode: (module, sourceCode, transformOptions) => { return new Promise(resolve => { let deps = {dependencies: [], dependencyOffsets: []}; if (!module.path.endsWith('.json')) { deps = extractDependencies(sourceCode); } resolve({...deps, code: sourceCode}); }); }, transformCacheKey, }; }); describe('get sync dependencies (posix)', function() { let DependencyGraph; const consoleWarn = console.warn; const realPlatform = process.platform; beforeEach(function() { process.platform = 'linux'; DependencyGraph = require('../index'); }); afterEach(function() { console.warn = consoleWarn; process.platform = realPlatform; }); it('should get dependencies', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("a")', ].join('\n'), 'a.js': [ '/**', ' * @providesModule a', ' */', 'require("b")', ].join('\n'), 'b.js': [ '/**', ' * @providesModule b', ' */', ].join('\n'), }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['a'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, { id: 'a', path: '/root/a.js', dependencies: ['b'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, { id: 'b', path: '/root/b.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, ]); }); }); it('should resolve relative entry path', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', ].join('\n'), }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, 'index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should get shallow dependencies', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("a")', ].join('\n'), 'a.js': [ '/**', ' * @providesModule a', ' */', 'require("b")', ].join('\n'), 'b.js': [ '/**', ' * @providesModule b', ' */', ].join('\n'), }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js', null, false).then((deps) => { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['a'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'a', path: '/root/a.js', dependencies: ['b'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should get dependencies with the correct extensions', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("a")', ].join('\n'), 'a.js': [ '/**', ' * @providesModule a', ' */', ].join('\n'), 'a.js.orig': [ '/**', ' * @providesModule a', ' */', ].join('\n'), }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['a'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'a', path: '/root/a.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should get json dependencies', function() { var root = '/root'; setMockFileSystem({ 'root': { 'package.json': JSON.stringify({ name: 'package', }), 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("./a.json")', 'require("./b")', ].join('\n'), 'a.json': JSON.stringify({}), 'b.json': JSON.stringify({}), }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['./a.json', './b'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'package/a.json', isJSON: true, path: '/root/a.json', dependencies: [], isAsset: false, isPolyfill: false, resolution: undefined, }, { id: 'package/b.json', isJSON: true, path: '/root/b.json', dependencies: [], isAsset: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should get package json as a dep', () => { var root = '/root'; setMockFileSystem({ 'root': { 'package.json': JSON.stringify({ name: 'package', }), 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("./package.json")', ].join('\n'), }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(deps => { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['./package.json'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'package/package.json', isJSON: true, path: '/root/package.json', dependencies: [], isAsset: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should get dependencies with relative assets', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("./imgs/a.png")', ].join('\n'), 'imgs': { 'a.png': '', }, 'package.json': JSON.stringify({ name: 'rootPackage', }), }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['./imgs/a.png'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'rootPackage/imgs/a.png', path: '/root/imgs/a.png', dependencies: [], isAsset: true, resolution: 1, isJSON: false, isPolyfill: false, }, ]); }); }); it('should get dependencies with assets and resolution', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("./imgs/a.png");', 'require("./imgs/b.png");', 'require("./imgs/c.png");', ].join('\n'), 'imgs': { 'a@1.5x.png': '', 'b@.7x.png': '', 'c.png': '', 'c@2x.png': '', }, 'package.json': JSON.stringify({ name: 'rootPackage', }), }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: [ './imgs/a.png', './imgs/b.png', './imgs/c.png', ], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'rootPackage/imgs/a.png', path: '/root/imgs/a@1.5x.png', resolution: 1.5, dependencies: [], isAsset: true, isJSON: false, isPolyfill: false, }, { id: 'rootPackage/imgs/b.png', path: '/root/imgs/b@.7x.png', resolution: 0.7, dependencies: [], isAsset: true, isJSON: false, isPolyfill: false, }, { id: 'rootPackage/imgs/c.png', path: '/root/imgs/c.png', resolution: 1, dependencies: [], isAsset: true, isJSON: false, isPolyfill: false, }, ]); }); }); it('should respect platform extension in assets', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("./imgs/a.png");', 'require("./imgs/b.png");', 'require("./imgs/c.png");', ].join('\n'), 'imgs': { 'a@1.5x.ios.png': '', 'b@.7x.ios.png': '', 'c.ios.png': '', 'c@2x.ios.png': '', }, 'package.json': JSON.stringify({ name: 'rootPackage', }), }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js', 'ios').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: [ './imgs/a.png', './imgs/b.png', './imgs/c.png', ], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'rootPackage/imgs/a.png', path: '/root/imgs/a@1.5x.ios.png', resolution: 1.5, dependencies: [], isAsset: true, isJSON: false, isPolyfill: false, }, { id: 'rootPackage/imgs/b.png', path: '/root/imgs/b@.7x.ios.png', resolution: 0.7, dependencies: [], isAsset: true, isJSON: false, isPolyfill: false, }, { id: 'rootPackage/imgs/c.png', path: '/root/imgs/c.ios.png', resolution: 1, dependencies: [], isAsset: true, isJSON: false, isPolyfill: false, }, ]); }); }); it('should get recursive dependencies', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("a")', ].join('\n'), 'a.js': [ '/**', ' * @providesModule a', ' */', 'require("index")', ].join('\n'), }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['a'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'a', path: '/root/a.js', dependencies: ['index'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should work with packages', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("aPackage")', ].join('\n'), 'aPackage': { 'package.json': JSON.stringify({ name: 'aPackage', main: 'main.js', }), 'main.js': 'lol', }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['aPackage'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'aPackage/main.js', path: '/root/aPackage/main.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should work with packages', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("aPackage/")', ].join('\n'), 'aPackage': { 'package.json': JSON.stringify({ name: 'aPackage', main: 'main.js', }), 'main.js': 'lol', }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['aPackage/'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'aPackage/main.js', path: '/root/aPackage/main.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should work with packages with a dot in the name', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("sha.js")', 'require("x.y.z")', ].join('\n'), 'sha.js': { 'package.json': JSON.stringify({ name: 'sha.js', main: 'main.js', }), 'main.js': 'lol', }, 'x.y.z': { 'package.json': JSON.stringify({ name: 'x.y.z', main: 'main.js', }), 'main.js': 'lol', }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['sha.js', 'x.y.z'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'sha.js/main.js', path: '/root/sha.js/main.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'x.y.z/main.js', path: '/root/x.y.z/main.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should default main package to index.js', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': 'require("aPackage")', 'aPackage': { 'package.json': JSON.stringify({ name: 'aPackage', }), 'index.js': 'lol', }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: '/root/index.js', path: '/root/index.js', dependencies: ['aPackage'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'aPackage/index.js', path: '/root/aPackage/index.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should resolve using alternative ids', () => { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': 'require("aPackage")', 'aPackage': { 'package.json': JSON.stringify({ name: 'aPackage', }), 'index.js': [ '/**', ' * @providesModule EpicModule', ' */', ].join('\n'), }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: '/root/index.js', path: '/root/index.js', dependencies: ['aPackage'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'EpicModule', path: '/root/aPackage/index.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should default use index.js if main is a dir', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': 'require("aPackage")', 'aPackage': { 'package.json': JSON.stringify({ name: 'aPackage', main: 'lib', }), lib: { 'index.js': 'lol', }, }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: '/root/index.js', path: '/root/index.js', dependencies: ['aPackage'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'aPackage/lib/index.js', path: '/root/aPackage/lib/index.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should resolve require to index if it is a dir', function() { var root = '/root'; setMockFileSystem({ 'root': { 'package.json': JSON.stringify({ name: 'test', }), 'index.js': 'require("./lib/")', lib: { 'index.js': 'lol', }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'test/index.js', path: '/root/index.js', dependencies: ['./lib/'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'test/lib/index.js', path: '/root/lib/index.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should resolve require to main if it is a dir w/ a package.json', function() { var root = '/root'; setMockFileSystem({ 'root': { 'package.json': JSON.stringify({ name: 'test', }), 'index.js': 'require("./lib/")', lib: { 'package.json': JSON.stringify({ 'main': 'main.js', }), 'index.js': 'lol', 'main.js': 'lol', }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'test/index.js', path: '/root/index.js', dependencies: ['./lib/'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: '/root/lib/main.js', path: '/root/lib/main.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should ignore malformed packages', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', ].join('\n'), 'aPackage': { 'package.json': 'lol', 'main.js': 'lol', }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should fatal on multiple modules with the same name', function() { const root = '/root'; console.warn = jest.fn(); setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', ].join('\n'), 'b.js': [ '/**', ' * @providesModule index', ' */', ].join('\n'), }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return dgraph.load().catch(err => { expect(err.message).toEqual( `Failed to build DependencyGraph: @providesModule naming collision:\n` + ` Duplicate module name: index\n` + ` Paths: /root/b.js collides with /root/index.js\n\n` + 'This error is caused by a @providesModule declaration ' + 'with the same name across two different files.' ); expect(err.type).toEqual('DependencyGraphError'); expect(console.warn).toBeCalled(); }); }); it('throws when a module is missing', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("lolomg")', ].join('\n'), }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').catch( error => { expect(error.type).toEqual('UnableToResolveError'); } ); }); it('should work with packages with subdirs', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("aPackage/subdir/lolynot")', ].join('\n'), 'aPackage': { 'package.json': JSON.stringify({ name: 'aPackage', main: 'main.js', }), 'main.js': 'lol', 'subdir': { 'lolynot.js': 'lolynot', }, }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['aPackage/subdir/lolynot'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, { id: 'aPackage/subdir/lolynot.js', path: '/root/aPackage/subdir/lolynot.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, ]); }); }); it('should work with packages with symlinked subdirs', function() { var root = '/root'; setMockFileSystem({ 'symlinkedPackage': { 'package.json': JSON.stringify({ name: 'aPackage', main: 'main.js', }), 'main.js': 'lol', 'subdir': { 'lolynot.js': 'lolynot', }, }, 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("aPackage/subdir/lolynot")', ].join('\n'), 'aPackage': { SYMLINK: '/symlinkedPackage' }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['aPackage/subdir/lolynot'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, { id: 'aPackage/subdir/lolynot.js', path: '/root/aPackage/subdir/lolynot.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, ]); }); }); it('should work with relative modules in packages', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("aPackage")', ].join('\n'), 'aPackage': { 'package.json': JSON.stringify({ name: 'aPackage', main: 'main.js', }), 'main.js': 'require("./subdir/lolynot")', 'subdir': { 'lolynot.js': 'require("../other")', }, 'other.js': '/* some code */', }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['aPackage'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, { id: 'aPackage/main.js', path: '/root/aPackage/main.js', dependencies: ['./subdir/lolynot'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, { id: 'aPackage/subdir/lolynot.js', path: '/root/aPackage/subdir/lolynot.js', dependencies: ['../other'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, { id: 'aPackage/other.js', path: '/root/aPackage/other.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, ]); }); }); testBrowserField('browser'); testBrowserField('react-native'); function replaceBrowserField(json, fieldName) { if (fieldName !== 'browser') { json[fieldName] = json.browser; delete json.browser; } return json; } function testBrowserField(fieldName) { it('should support simple browser field in packages ("' + fieldName + '")', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("aPackage")', ].join('\n'), 'aPackage': { 'package.json': JSON.stringify(replaceBrowserField({ name: 'aPackage', main: 'main.js', browser: 'client.js', }, fieldName)), 'main.js': 'some other code', 'client.js': '/* some code */', }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['aPackage'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, { id: 'aPackage/client.js', path: '/root/aPackage/client.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, ]); }); }); it('should support browser field in packages w/o .js ext ("' + fieldName + '")', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("aPackage")', ].join('\n'), 'aPackage': { 'package.json': JSON.stringify(replaceBrowserField({ name: 'aPackage', main: 'main.js', browser: 'client', }, fieldName)), 'main.js': 'some other code', 'client.js': '/* some code */', }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['aPackage'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'aPackage/client.js', path: '/root/aPackage/client.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should support mapping main in browser field json ("' + fieldName + '")', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("aPackage")', ].join('\n'), 'aPackage': { 'package.json': JSON.stringify(replaceBrowserField({ name: 'aPackage', main: './main.js', browser: { './main.js': './client.js', }, }, fieldName)), 'main.js': 'some other code', 'client.js': '/* some code */', }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], assetExts: ['png', 'jpg'], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['aPackage'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'aPackage/client.js', path: '/root/aPackage/client.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, ]); }); }); it('should work do correct browser mapping w/o js ext ("' + fieldName + '")', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("aPackage")', ].join('\n'), 'aPackage': { 'package.json': JSON.stringify(replaceBrowserField({ name: 'aPackage', main: './main.js', browser: { './main': './client.js', }, }, fieldName)), 'main.js': 'some other code', 'client.js': '/* some code */', }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], assetExts: ['png', 'jpg'], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['aPackage'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, { id: 'aPackage/client.js', path: '/root/aPackage/client.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, resolveDependency: undefined, }, ]); }); }); it('should support browser mapping of files ("' + fieldName + '")', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("aPackage")', ].join('\n'), 'aPackage': { 'package.json': JSON.stringify(replaceBrowserField({ name: 'aPackage', main: './main.js', browser: { './main': './client.js', './node.js': './not-node.js', './not-browser': './browser.js', './dir/server.js': './dir/client', './hello.js': './bye.js', }, }, fieldName)), 'main.js': '/* some other code */', 'client.js': 'require("./node")\nrequire("./dir/server.js")', 'not-node.js': 'require("./not-browser")', 'not-browser.js': 'require("./dir/server")', 'browser.js': '/* some browser code */', 'dir': { 'server.js': '/* some node code */', 'client.js': 'require("../hello")', }, 'hello.js': '/* hello */', 'bye.js': '/* bye */', }, }, }); const dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['aPackage'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'aPackage/client.js', path: '/root/aPackage/client.js', dependencies: ['./node', './dir/server.js'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'aPackage/not-node.js', path: '/root/aPackage/not-node.js', dependencies: ['./not-browser'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'aPackage/browser.js', path: '/root/aPackage/browser.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'aPackage/dir/client.js', path: '/root/aPackage/dir/client.js', dependencies: ['../hello'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'aPackage/bye.js', path: '/root/aPackage/bye.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should support browser mapping for packages ("' + fieldName + '")', function() { var root = '/root'; setMockFileSystem({ 'root': { 'index.js': [ '/**', ' * @providesModule index', ' */', 'require("aPackage")', ].join('\n'), 'aPackage': { 'package.json': JSON.stringify(replaceBrowserField({ name: 'aPackage', browser: { 'node-package': 'browser-package', }, }, fieldName)), 'index.js': 'require("node-package")', 'node-package': { 'package.json': JSON.stringify({ 'name': 'node-package', }), 'index.js': '/* some node code */', }, 'browser-package': { 'package.json': JSON.stringify({ 'name': 'browser-package', }), 'index.js': '/* some browser code */', }, }, }, }); var dgraph = new DependencyGraph({ ...defaults, roots: [root], }); return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(function(deps) { expect(deps) .toEqual([ { id: 'index', path: '/root/index.js', dependencies: ['aPackage'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'aPackage/index.js', path: '/root/aPackage/index.js', dependencies: ['node-package'], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, { id: 'browser-package/index.js', path: '/root/aPackage/browser-package/index.js', dependencies: [], isAsset: false, isJSON: false, isPolyfill: false, resolution: undefined, }, ]); }); }); it('should support browser mapping of a package to a file ("' + fieldName + '")', () => {