Commit 7a26dd36 authored by Tom Jorquera's avatar Tom Jorquera
Browse files

Add `lib/controller`

This module allow to load all the files that must be injected into the client.
parent 10d984d0
'use strict';
/**
* This file defines a mock for the mz/fs lib.
*
* It allows us to mock filesystem access during tests.
*
* To use it, call the `__setup` method before your tests and pass it a
* dictionary of { "filepath": "content"} that represent the filesystem to mock.
*
*/
const path = require('path');
const fs = jest.genMockFromModule('mz/fs');
let mockFiles = Object.create(null);
// This is a custom function that our tests can use during setup to specify
// what the files on the "mock" filesystem should look like when any of the
// `moz/fs` APIs are used.
fs.__setup = function(newMockFiles){
mockFiles = newMockFiles;
}
fs.readFile = function(filePath, ...rest) {
if(Object.keys(mockFiles).includes(filePath)){
return Promise.resolve(mockFiles[filePath]);
} else {
return Promise.reject(new Error('no such file or directory'));
}
};
fs.readdir = function(dirPath, ...rest) {
const res = Object.keys(mockFiles)
.filter(f => path.dirname(f) == dirPath)
.map(f => path.basename(f));
if(res.length != 0) {
return Promise.resolve(res);
} else {
return Promise.reject(new Error('no such file or directory')) ;
}
};
module.exports = fs;
'use strict';
const fs = require('mz/fs');
module.exports = root => {
const controller = {
load: (module) => new Promise((resolve, reject) => {
// first we read the file with the same name than the folder
fs.readFile(root + '/' + module + '/' + module + '.js', 'utf8')
.then(content => {
// then we read all the other files in the folder
fs.readdir(root + '/' + module)
.then(files => {
// remove the file we already read
files.splice(files.indexOf(module + '.js'), 1);
Promise.all(files.map(
f => fs.readFile(root + '/' + module + '/' + f, 'utf8')
))
.then(contents => {
// concatenate all the files and resolve
resolve([content].concat(contents));
})
.catch(err => { reject(err); });
})
.catch(err => { reject(err); });
})
.catch(err => { reject(err); });
}),
loadAll: (...modules) => new Promise((resolve, reject) => {
// load all the passed modules
Promise.all(
modules.map(f => controller.load(f)))
.then(values => {
// concatenate all the arrays into a single one
resolve(Array.prototype.concat.apply([], values));
}).catch(err => {
reject(err);
});
})
};
return controller;
};
'use strict';
jest.mock('mz/fs');
describe('loadModules', () => {
const MOCK_FILES = {
'/test/controller/controller.js': '1',
'/test/controller/test.js': '2',
'/test/lib/lib.js': '3',
'/test/robot/robot.js': '4',
'/test/notavalidmodule/test.js':'5'
};
beforeEach(() => {
require('mz/fs').__setup(MOCK_FILES);
});
describe('loading a module', () => {
test('should include all (and only) files in its dir.', (done) => {
const controller = require('./controller.js')('/test');
controller.load('controller')
.then(res => {
expect(res.length).toBe(2);
expect(res.includes('1')).toBeTruthy();
expect(res.includes('2')).toBeTruthy();
done();
});
});
test('should return the files in the correct order', (done) => {
const controller = require('./controller.js')('/test');
controller.load('controller')
.then(res => {
expect(res[0]).toBe('1');
expect(res[1]).toBe('2');
done();
});
});
test('should fail for a nonexistent module', (done) => {
const controller = require('./controller.js')('/test');
controller.load('nonexistent')
.catch(() => done());
});
test('should fail for a module missing its base file', (done) => {
const controller = require('./controller.js')('/test');
controller.load('notavalidmodule')
.catch(() => done());
});
});
describe('loading several modules', () => {
test('should include all files from all modules', (done) => {
const controller = require('./controller.js')('/test');
controller.loadAll('controller', 'lib', 'robot')
.then(res => {
expect(res.length).toBe(4);
expect(res.includes('1')).toBeTruthy();
expect(res.includes('2')).toBeTruthy();
expect(res.includes('3')).toBeTruthy();
expect(res.includes('4')).toBeTruthy();
done();
});
});
test('should return files in correct order', (done) => {
const controller = require('./controller.js')('/test');
controller.loadAll('controller', 'lib', 'robot')
.then(res => {
expect(res[0]).toBe('1');
expect(res[1]).toBe('2');
expect(res[2]).toBe('3');
expect(res[3]).toBe('4');
done();
});
});
test('should fail when trying to load a non-existent module ', (done) => {
const controller = require('./controller.js')('/test');
controller.loadAll('controller', 'lib', 'robot', 'nonexistent')
.catch(() => done());
});
test('should fail when trying to load an invalid module', (done) => {
const controller = require('./controller.js')('/test');
controller.loadAll('controller', 'lib', 'robot', 'invalid')
.catch(() => done());
});
});
});
...@@ -5,10 +5,15 @@ ...@@ -5,10 +5,15 @@
"version": "0.0.1", "version": "0.0.1",
"main": "app.js", "main": "app.js",
"scripts":{ "scripts":{
"start": "node app.js" "start": "node app.js",
"test": "jest",
}, },
"dependencies":{ "dependencies":{
"webdriverio": "4.7.1" "webdriverio": "4.7.1",
"mz": "2.6.0"
},
"devDependencies":{
"jest": "20.0.0"
}, },
"author": "Linagora Folks", "author": "Linagora Folks",
"license": "AGPL-3.0" "license": "AGPL-3.0"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment