From edd7dd8492c9795461216b4edad215480dbede6a Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Wed, 9 Mar 2016 14:33:45 -0500 Subject: [PATCH] Ugly progress commit --- app/Container.js | 36 ++++++++++-- app/base/DBModel.js | 10 ++++ app/models/User.js | 4 ++ gulpfile.js | 2 +- package.json | 2 + test/mocha.opts | 2 +- test/unit/.gitkeep | 0 test/unit/{base => }/Container_test.js | 21 ++++++- test/unit/test-base.js | 76 ++++++++++++++++++++++++++ 9 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 app/base/DBModel.js create mode 100644 app/models/User.js delete mode 100644 test/unit/.gitkeep rename test/unit/{base => }/Container_test.js (73%) create mode 100644 test/unit/test-base.js diff --git a/app/Container.js b/app/Container.js index 637d65c..0f8a70c 100644 --- a/app/Container.js +++ b/app/Container.js @@ -80,11 +80,37 @@ class Container { return this._container.get(name); } - try { - return this._require(name); - } catch (e) { - return; - } + return this._require(name); + } + + + /** + * Get a base library instance + * + * @param {string} name - name of the base module + * @returns {*} - the base module + */ + getBase(name) { + return this.get(`base/${name}`); + } + + /** + * Get a helper library instance + * + * @param {string} name - name of the helper module + * @return {*} - the helper instance + */ + getHelper(name) { + return this.get(`helpers/${name}`); + } + + /** + * Get a model + * @param {string} name - the name of the model module + * @returns {*} - the model + */ + getModel(name) { + return this.get(`models/${name}`); } /** diff --git a/app/base/DBModel.js b/app/base/DBModel.js new file mode 100644 index 0000000..df7874e --- /dev/null +++ b/app/base/DBModel.js @@ -0,0 +1,10 @@ +'use strict'; + +const container = require('../Container'); +const Model = container.getBase('Model'); + +class DBModel extends Model { + +} + +module.exports = DBModel; \ No newline at end of file diff --git a/app/models/User.js b/app/models/User.js new file mode 100644 index 0000000..2a28deb --- /dev/null +++ b/app/models/User.js @@ -0,0 +1,4 @@ +'use strict'; + +const container = require('../Container'); + diff --git a/gulpfile.js b/gulpfile.js index e91ef4a..4752381 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -219,7 +219,7 @@ gulp.task('coverage', ['lint', 'pre-coverage'], () => { mocha(MOCHA_SETTINGS), istanbul.writeReports({ dir: 'public/generated/coverage', - reporters:['lcov', 'lcovonly', 'html', 'text'], + reporters:['clover', 'lcov', 'lcovonly', 'html', 'text'], }), ]); }); diff --git a/package.json b/package.json index 96eea97..03c01f4 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,8 @@ "istanbul": "0.4.*", "mocha": "2.3.*", "pre-commit": "^1.1.2", + "sinon": "^1.17.3", + "sinon-chai": "^2.8.0", "supertest": "^1.1.0" }, "engines": { diff --git a/test/mocha.opts b/test/mocha.opts index 6226de3..ab55d9d 100644 --- a/test/mocha.opts +++ b/test/mocha.opts @@ -1,4 +1,4 @@ -test/**/*.js +test/**/*_test.js --ui tdd --reporter spec --slow 1000 diff --git a/test/unit/.gitkeep b/test/unit/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/test/unit/base/Container_test.js b/test/unit/Container_test.js similarity index 73% rename from test/unit/base/Container_test.js rename to test/unit/Container_test.js index 2d8b0d9..bc5d7a7 100644 --- a/test/unit/base/Container_test.js +++ b/test/unit/Container_test.js @@ -1,6 +1,6 @@ 'use strict'; -const testBase = require('../../test-base'); +const testBase = require('../test-base'); const expect = testBase.expect; suite('Dependency Container tests', () => { @@ -54,8 +54,9 @@ suite('Dependency Container tests', () => { expect(actual).to.be.equal(obj); }); - test('Attempt to get non-existent item returns undefined', () => { - expect(container.get('aseiutj')).to.be.undefined; + test('Attempt to get non-existent item throws error', () => { + let fn = () => container.get('aseiutj'); + expect(fn).to.throw(Error, `Cannot find module 'aseiutj'`); }); }); @@ -73,5 +74,19 @@ suite('Dependency Container tests', () => { expect(containerFile).to.be.equal(nativeRequire); }); + + test('getHelper(foo) returns same object as get(helpers/foo)', () => { + let expected = container.get('helpers/promisify'); + let actual = container.getHelper('promisify'); + + expect(expected).to.deep.equal(actual); + }); + + test('getBase(foo) returns same object as get(base/foo)', () => { + let expected = container.get('base/Model'); + let actual = container.getBase('Model'); + + expect(expected).to.deep.equal(actual); + }); }); }); \ No newline at end of file diff --git a/test/unit/test-base.js b/test/unit/test-base.js new file mode 100644 index 0000000..6d5ad05 --- /dev/null +++ b/test/unit/test-base.js @@ -0,0 +1,76 @@ +'use strict'; + +const path = require('path'); +const sinon = require('sinon'); + +// Set up chai as promised to allow for +// better testing of promises, +// set up sinon-chai for better integration +// of sinon for spies, stubs and mocks +const chai = require('chai'); +const chaiAsPromised = require('chai-as-promised'); +const sinonChai = require('sinon-chai'); +chai.use(chaiAsPromised); +chai.use(sinonChai); + +/** + * Base Object for unit test utilities + */ +const testBase = { + + /** + * Chai expect assertion library + */ + expect: chai.expect, + + /** + * Sinon library for spies, stubs, and mocks + */ + sinon: sinon, + + /** + * Determine the appropriate path to a module relative to the root folder + * + * @param {String} modulePath - the raw path to the module + * @return {String} - the normalized path to the module + */ + _normalizeIncludePath(modulePath) { + const basePath = path.resolve(path.join(__dirname, '../')); + + let includePath = modulePath; + + // Allow referencing local modules without using a ./ + // eg. util/route-loader instead of ./util/route-loader + if (modulePath.includes('/') && ! modulePath.startsWith('./')) { + includePath = path.join(basePath, modulePath); + } + + return includePath; + }, + + /** + * Load a module relative to the root folder + * + * @param {String} modulePath - path to the module, relative to the tests/ folder + * @return {mixed} - whatever the module returns + */ + require(modulePath) { + const includePath = testBase._normalizeIncludePath(modulePath); + return require(includePath); + }, + + /** + * Load a module relative to the root folder, but first delete + * the module from the require cache + * + * @param {String} modulePath - path to the module, relative to the tests/ folder + * @return {mixed} - whatever the module returns + */ + requireNoCache(modulePath) { + const includePath = testBase._normalizeIncludePath(modulePath); + delete require.cache[includePath]; + return require(includePath); + }, +}; + +module.exports = testBase; \ No newline at end of file