Files
react-native/packager/react-packager/src/Cache/__tests__/Cache-test.js
Christoph Pojer d088750163 Fix tests + enable inline requires on react-native
Reviewed By: @sahrens, @vjeux

Differential Revision: D2456607
2015-09-21 14:39:44 -07:00

297 lines
7.3 KiB
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
.dontMock('underscore')
.dontMock('absolute-path')
.dontMock('../')
.dontMock('../../lib/loadCacheSync')
.dontMock('../../lib/getCacheFilePath');
jest
.mock('os')
.mock('fs');
var Promise = require('promise');
var fs = require('fs');
var os = require('os');
var _ = require('underscore');
var Cache = require('../');
describe('JSTransformer Cache', () => {
beforeEach(() => {
os.tmpDir.mockImpl(() => 'tmpDir');
});
describe('getting/setting', () => {
pit('calls loader callback for uncached file', () => {
fs.stat.mockImpl((file, callback) => {
callback(null, {
mtime: {
getTime: () => {}
}
});
});
var cache = new Cache({
projectRoots: ['/rootDir'],
transformModulePath: 'x.js',
});
var loaderCb = jest.genMockFn().mockImpl(() => Promise.resolve());
return cache
.get('/rootDir/someFile', 'field', loaderCb)
.then($ =>
expect(loaderCb).toBeCalledWith('/rootDir/someFile')
);
});
pit('supports storing multiple fields', () => {
fs.stat.mockImpl((file, callback) => {
callback(null, {
mtime: {
getTime: () => {}
}
});
});
var cache = new Cache({
projectRoots: ['/rootDir'],
transformModulePath: 'x.js',
});
var index = 0;
var loaderCb = jest.genMockFn().mockImpl(() =>
Promise.resolve(index++)
);
return cache
.get('/rootDir/someFile', 'field1', loaderCb)
.then(value => {
expect(value).toBe(0);
return cache
.get('/rootDir/someFile', 'field2', loaderCb)
.then(value2 => expect(value2).toBe(1));
});
});
pit('gets the value from the loader callback', () => {
fs.stat.mockImpl((file, callback) =>
callback(null, {
mtime: {
getTime: () => {}
}
})
);
var cache = new Cache({
projectRoots: ['/rootDir'],
transformModulePath: 'x.js',
});
var loaderCb = jest.genMockFn().mockImpl(() =>
Promise.resolve('lol')
);
return cache
.get('/rootDir/someFile', 'field', loaderCb)
.then(value => expect(value).toBe('lol'));
});
pit('caches the value after the first call', () => {
fs.stat.mockImpl((file, callback) => {
callback(null, {
mtime: {
getTime: () => {}
}
});
});
var cache = new Cache({
projectRoots: ['/rootDir'],
transformModulePath: 'x.js',
});
var loaderCb = jest.genMockFn().mockImpl(() =>
Promise.resolve('lol')
);
return cache
.get('/rootDir/someFile', 'field', loaderCb)
.then(() => {
var shouldNotBeCalled = jest.genMockFn();
return cache.get('/rootDir/someFile', 'field', shouldNotBeCalled)
.then(value => {
expect(shouldNotBeCalled).not.toBeCalled();
expect(value).toBe('lol');
});
});
});
pit('clears old field when getting new field and mtime changed', () => {
var mtime = 0;
fs.stat.mockImpl((file, callback) => {
callback(null, {
mtime: {
getTime: () => mtime++
}
});
});
var cache = new Cache({
projectRoots: ['/rootDir'],
transformModulePath: 'x.js',
});
var loaderCb = jest.genMockFn().mockImpl(() =>
Promise.resolve('lol' + mtime)
);
return cache
.get('/rootDir/someFile', 'field1', loaderCb)
.then(value => cache
.get('/rootDir/someFile', 'field2', loaderCb)
.then(value2 => cache
.get('/rootDir/someFile', 'field1', loaderCb)
.then(value3 => expect(value3).toBe('lol2'))
)
);
});
});
describe('loading cache from disk', () => {
var fileStats;
beforeEach(() => {
fileStats = {
'/rootDir/someFile': {
mtime: {
getTime: () => 22
}
},
'/rootDir/foo': {
mtime: {
getTime: () => 11
}
}
};
fs.existsSync.mockImpl(() => true);
fs.statSync.mockImpl(filePath => fileStats[filePath]);
fs.readFileSync.mockImpl(() => JSON.stringify({
'/rootDir/someFile': {
metadata: {mtime: 22},
data: {field: 'oh hai'},
},
'/rootDir/foo': {
metadata: {mtime: 11},
data: {field: 'lol wat'},
}
}));
});
pit('should load cache from disk', () => {
var cache = new Cache({
projectRoots: ['/rootDir'],
transformModulePath: 'x.js',
});
var loaderCb = jest.genMockFn();
return cache
.get('/rootDir/someFile', 'field', loaderCb)
.then(value => {
expect(loaderCb).not.toBeCalled();
expect(value).toBe('oh hai');
return cache
.get('/rootDir/foo', 'field', loaderCb)
.then(val => {
expect(loaderCb).not.toBeCalled();
expect(val).toBe('lol wat');
});
});
});
pit('should not load outdated cache', () => {
fs.stat.mockImpl((file, callback) =>
callback(null, {
mtime: {
getTime: () => {}
}
})
);
fileStats['/rootDir/foo'].mtime.getTime = () => 123;
var cache = new Cache({
projectRoots: ['/rootDir'],
transformModulePath: 'x.js',
});
var loaderCb = jest.genMockFn().mockImpl(() =>
Promise.resolve('new value')
);
return cache
.get('/rootDir/someFile', 'field', loaderCb)
.then(value => {
expect(loaderCb).not.toBeCalled();
expect(value).toBe('oh hai');
return cache
.get('/rootDir/foo', 'field', loaderCb)
.then(val => {
expect(loaderCb).toBeCalled();
expect(val).toBe('new value');
});
});
});
});
describe('writing cache to disk', () => {
it('should write cache to disk', () => {
var index = 0;
var mtimes = [10, 20, 30];
var debounceIndex = 0;
_.debounce = callback => {
return () => {
if (++debounceIndex === 3) {
callback();
}
};
};
fs.stat.mockImpl((file, callback) =>
callback(null, {
mtime: {
getTime: () => mtimes[index++]
}
})
);
var cache = new Cache({
projectRoots: ['/rootDir'],
transformModulePath: 'x.js',
});
cache.get('/rootDir/bar', 'field', () =>
Promise.resolve('bar value')
);
cache.get('/rootDir/foo', 'field', () =>
Promise.resolve('foo value')
);
cache.get('/rootDir/baz', 'field', () =>
Promise.resolve('baz value')
);
jest.runAllTicks();
expect(fs.writeFile).toBeCalled();
});
});
});