react-native
Version:
A framework for building native apps using React
1,763 lines (1,679 loc) • 159 kB
JavaScript
/**
* 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 + '")', () => {