diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fs/__tests__/mock.js | 83 | ||||
-rw-r--r-- | lib/fs/mock.js | 101 | ||||
-rw-r--r-- | lib/models/fs.js | 3 | ||||
-rw-r--r-- | lib/plugins/__tests__/findInstalled.js | 1 |
4 files changed, 187 insertions, 1 deletions
diff --git a/lib/fs/__tests__/mock.js b/lib/fs/__tests__/mock.js new file mode 100644 index 0000000..7842011 --- /dev/null +++ b/lib/fs/__tests__/mock.js @@ -0,0 +1,83 @@ +jest.autoMockOff(); + +describe('MockFS', function() { + var createMockFS = require('../mock'); + var fs = createMockFS({ + 'README.md': 'Hello World', + 'SUMMARY.md': '# Summary', + 'folder': { + 'test.md': 'Cool', + 'folder2': { + 'hello.md': 'Hello', + 'world.md': 'World' + } + } + }); + + describe('exists', function() { + pit('must return true for a file', function() { + return fs.exists('README.md') + .then(function(result) { + expect(result).toBeTruthy(); + }); + }); + + pit('must return false for a non existing file', function() { + return fs.exists('README_NOTEXISTS.md') + .then(function(result) { + expect(result).toBeFalsy(); + }); + }); + + pit('must return true for a directory', function() { + return fs.exists('folder') + .then(function(result) { + expect(result).toBeTruthy(); + }); + }); + + pit('must return true for a deep file', function() { + return fs.exists('folder/test.md') + .then(function(result) { + expect(result).toBeTruthy(); + }); + }); + + pit('must return true for a deep file (2)', function() { + return fs.exists('folder/folder2/hello.md') + .then(function(result) { + expect(result).toBeTruthy(); + }); + }); + }); + + describe('readAsString', function() { + pit('must return content for a file', function() { + return fs.readAsString('README.md') + .then(function(result) { + expect(result).toBe('Hello World'); + }); + }); + + pit('must return content for a deep file', function() { + return fs.readAsString('folder/test.md') + .then(function(result) { + expect(result).toBe('Cool'); + }); + }); + }); + + describe('readDir', function() { + pit('must return content for a directory', function() { + return fs.readDir('./') + .then(function(files) { + expect(files.size).toBe(3); + expect(files.includes('README.md')).toBeTruthy(); + expect(files.includes('SUMMARY.md')).toBeTruthy(); + expect(files.includes('folder/')).toBeTruthy(); + }); + }); + }); +}); + + diff --git a/lib/fs/mock.js b/lib/fs/mock.js new file mode 100644 index 0000000..6c2670b --- /dev/null +++ b/lib/fs/mock.js @@ -0,0 +1,101 @@ +var path = require('path'); +var is = require('is'); +var Buffer = require('buffer').Buffer; +var Immutable = require('immutable'); + +var FS = require('../models/fs'); +var error = require('../utils/error'); + +/** + Create a fake filesystem for testing books + + @param {Map<String:File>} +*/ +function createMockFS(files) { + files = Immutable.fromJS(files); + var mtime = new Date(); + + /** + Get a file by resolving its path + + @param {String} + @return {String|Map|null} + */ + function getFile(filePath) { + var parts = path.normalize(filePath).split('/'); + return parts.reduce(function(list, part, i) { + if (!list) return null; + + var file; + + if (!part || part === '.') file = list; + else file = list.get(part); + + if (!file) return null; + + if (is.string(file)) { + if (i === (parts.length - 1)) return file; + else return null; + } + + return file; + }, files); + } + + function fsExists(filePath) { + return Boolean(getFile(filePath) !== null); + } + + function fsReadFile(filePath) { + var file = getFile(filePath); + if (!is.string(file)) { + throw error.FileNotFoundError({ + filename: filePath + }); + } + + return new Buffer(file, 'utf8'); + } + + function fsStatFile(filePath) { + var file = getFile(filePath); + if (!file) { + throw error.FileNotFoundError({ + filename: filePath + }); + } + + return { + mtime: mtime + }; + } + + function fsReadDir(filePath) { + var dir = getFile(filePath); + if (!dir || is.string(dir)) { + throw error.FileNotFoundError({ + filename: filePath + }); + } + + return dir + .map(function(content, name) { + if (!is.string(content)) { + name = name + '/'; + } + + return name; + }) + .valueSeq(); + } + + return FS.create({ + root: '', + fsExists: fsExists, + fsReadFile: fsReadFile, + fsStatFile: fsStatFile, + fsReadDir: fsReadDir + }); +} + +module.exports = createMockFS; diff --git a/lib/models/fs.js b/lib/models/fs.js index c74f3cd..f124da8 100644 --- a/lib/models/fs.js +++ b/lib/models/fs.js @@ -46,7 +46,8 @@ FS.prototype.isInScope = function(filename) { FS.prototype.resolve = function() { var rootPath = this.getRoot(); var args = Array.prototype.slice.call(arguments); - var filename = path.resolve.apply(path, [rootPath].concat(args)); + var filename = path.join.apply(path, [rootPath].concat(args)); + filename = path.normalize(filename); if (!this.isInScope(filename)) { throw error.FileOutOfScopeError({ diff --git a/lib/plugins/__tests__/findInstalled.js b/lib/plugins/__tests__/findInstalled.js index 956e73f..fca8295 100644 --- a/lib/plugins/__tests__/findInstalled.js +++ b/lib/plugins/__tests__/findInstalled.js @@ -1,4 +1,5 @@ jest.autoMockOff(); +jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; var path = require('path'); |