summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/fs/__tests__/mock.js83
-rw-r--r--lib/fs/mock.js101
-rw-r--r--lib/models/fs.js3
-rw-r--r--lib/plugins/__tests__/findInstalled.js1
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');