Skip to content

Commit

Permalink
Merge pull request #162 from raveljs/feature/161
Browse files Browse the repository at this point in the history
Adding hooks for pre/post param load. app.get() now throws an exception if called before param load.
  • Loading branch information
Ghnuberath authored Sep 13, 2016
2 parents 3547092 + e946019 commit 766a1af
Show file tree
Hide file tree
Showing 10 changed files with 46 additions and 6 deletions.
6 changes: 5 additions & 1 deletion lib/core/params.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ module.exports = function(Ravel) {
Object.assign(defaults, this[symbols.params]);
// now defaults contains what we want, so make it this[symbols.params]
this[symbols.params] = defaults;
// done!
this[symbols.parametersLoaded] = true;
};

/**
Expand Down Expand Up @@ -91,7 +93,9 @@ module.exports = function(Ravel) {
* @return {Object} the parameter value, or undefined if it is not required and not set
*/
Ravel.prototype.get = function(key) {
if (!this[symbols.knownParameters][key]) {
if (!this[symbols.parametersLoaded]) {
throw new this.ApplicationError.General('Cannot get() parameters until after app.init()');
} else if (!this[symbols.knownParameters][key]) {
throw new this.ApplicationError.NotFound(`Parameter ${key} was requested, but is unknown.`);
} else if (this[symbols.knownParameters][key].required && this[symbols.params][key] === undefined) {
throw new this.ApplicationError.NotFound(
Expand Down
1 change: 1 addition & 0 deletions lib/core/symbols.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module.exports = {

// methods
loadParameters: Symbol.for('_loadParameters()'),
parametersLoaded: Symbol.for('_parametersLoaded()'),
moduleInit: Symbol.for('_moduleInit'),
resourceInit: Symbol.for('_resourceInit'),
routesInit: Symbol.for('_routesInit'),
Expand Down
2 changes: 2 additions & 0 deletions lib/ravel.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ class Ravel extends EventEmitter {
});

// load parameters from .ravelrc file, if any
this.emit('pre load parameters');
this[coreSymbols.loadParameters]();
this.emit('post load parameters');

this[sInitialized] = true;

Expand Down
2 changes: 1 addition & 1 deletion lib/util/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class Log extends Logger {
ravelInstance.registerParameter('log level', true);
ravelInstance.set('log level', this.DEBUG); //default log level

ravelInstance.once('pre init', function() {
ravelInstance.once('post load parameters', function() {
intel.setLevel(logLevels[ravelInstance.get('log level')]);
});
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ravel",
"version": "0.17.12",
"version": "0.17.13",
"author": "Sean McIntyre <[email protected]>",
"description": "Ravel Rapid Application Development Framework",
"engines": {
Expand Down
1 change: 1 addition & 0 deletions test/auth/test-authenticate-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ describe('util/authenticate_request', function() {
Ravel.log.setLevel('NONE');
app = koa();
Ravel.kvstore = {}; // mock Ravel.kvstore, since we're not actually starting Ravel.
Ravel[coreSymbols.parametersLoaded] = true;
done();
});

Expand Down
5 changes: 4 additions & 1 deletion test/auth/test-authenticate-token.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ chai.use(require('sinon-chai'));
const mockery = require('mockery');
const sinon = require('sinon');

let Ravel, tokenAuth, profile, testProvider;
let Ravel, tokenAuth, profile, testProvider, coreSymbols;

describe('auth/authenticate_token', function() {
beforeEach((done) => {
Expand All @@ -31,10 +31,12 @@ describe('auth/authenticate_token', function() {
mockery.registerMock('redis', redisMock);

Ravel = new (require('../../lib/ravel'))();
coreSymbols = require('../../lib/core/symbols');
Ravel.log.setLevel(Ravel.log.NONE);
Ravel.set('redis port', 0);
Ravel.set('redis host', 'localhost');
Ravel.set('redis password', 'password');
Ravel[coreSymbols.parametersLoaded] = true;
Ravel.kvstore = require('../../lib/util/kvstore')(Ravel);

tokenAuth = new (require('../../lib/auth/authenticate_token'))(Ravel);
Expand Down Expand Up @@ -67,6 +69,7 @@ describe('auth/authenticate_token', function() {

afterEach((done) => {
Ravel = undefined;
coreSymbols = undefined;
tokenAuth = undefined;
mockery.deregisterAll();
mockery.disable();
Expand Down
17 changes: 17 additions & 0 deletions test/core/test-params.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe('Ravel', function() {
it('should allow clients to set the value of a parameter', (done) => {
Ravel.registerParameter('test param', false);
Ravel.set('test param', 'test value');
Ravel[coreSymbols.parametersLoaded] = true;
expect(Ravel.get('test param')).to.equal('test value');
done();
});
Expand All @@ -59,25 +60,40 @@ describe('Ravel', function() {
it('should allow clients to retrieve the value of a set optional parameter', (done) => {
Ravel.registerParameter('test param', false);
Ravel.set('test param', 'test value');
Ravel[coreSymbols.parametersLoaded] = true;
expect(Ravel.get('test param')).to.equal('test value');
done();
});

it('should return undefined when clients attempt to retrieve the value of an unset optional parameter', (done) => {
Ravel.registerParameter('test param', false);
Ravel[coreSymbols.parametersLoaded] = true;
expect(Ravel.get('test param')).to.equal(undefined);
done();
});

it('should allow clients to retrieve the value of a set required parameter', (done) => {
Ravel.registerParameter('test param', true);
Ravel.set('test param', 'test value');
Ravel[coreSymbols.parametersLoaded] = true;
expect(Ravel.get('test param')).to.equal('test value');
done();
});

it('should throw a Ravel.ApplicationError.General error when clients attempt to retrieve a parameter before loading', (done) => {
try {
Ravel[coreSymbols.parametersLoaded] = false;
Ravel.get('test param');
done(new Error('Should never reach this line.'));
} catch (err) {
expect(err).to.be.instanceof(Ravel.ApplicationError.General);
done();
}
});

it('should throw a Ravel.ApplicationError.NotFound error when clients attempt to retrieve an unregistered parameter', (done) => {
try {
Ravel[coreSymbols.parametersLoaded] = true;
Ravel.get('test param');
done(new Error('Should never reach this line.'));
} catch (err) {
Expand All @@ -89,6 +105,7 @@ describe('Ravel', function() {
it('should throw a Ravel.ApplicationError.NotFound error when clients attempt to retrieve the value of an unset required parameter', (done) => {
try {
Ravel.registerParameter('test param', true);
Ravel[coreSymbols.parametersLoaded] = true;
Ravel.get('test param');
done(new Error('Should never reach this line.'));
} catch (err) {
Expand Down
6 changes: 5 additions & 1 deletion test/util/test-kvstore.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const expect = chai.expect;
chai.use(require('chai-things'));
const mockery = require('mockery');

let Ravel, redisClientStub, redisMock;
let Ravel, redisClientStub, redisMock, coreSymbols;

describe('Ravel', function() {

Expand All @@ -26,6 +26,7 @@ describe('Ravel', function() {
};
mockery.registerMock('redis', redisMock);
Ravel = new (require('../../lib/ravel'))();
coreSymbols = require('../../lib/core/symbols');
Ravel.log.setLevel(Ravel.log.NONE);
Ravel.set('redis port', 0);
Ravel.set('redis host', 'localhost');
Expand All @@ -35,6 +36,7 @@ describe('Ravel', function() {

afterEach((done) => {
Ravel = undefined;
coreSymbols = undefined;
mockery.deregisterAll();mockery.disable();
done();
});
Expand All @@ -52,6 +54,7 @@ describe('Ravel', function() {
const retryStrategy = require('../../lib/util/kvstore').retryStrategy(Ravel);
expect(retryStrategy).to.be.a('function');
Ravel.set('redis max retries', 10);
Ravel[coreSymbols.parametersLoaded] = true;
const options = {
error:{code:'something'},
attempt: Ravel.get('redis max retries') + 1
Expand All @@ -64,6 +67,7 @@ describe('Ravel', function() {
const retryStrategy = require('../../lib/util/kvstore').retryStrategy(Ravel);
expect(retryStrategy).to.be.a('function');
Ravel.set('redis max retries', 10);
Ravel[coreSymbols.parametersLoaded] = true;
const options = {
error:{code:'something'},
attempt: 1
Expand Down
10 changes: 9 additions & 1 deletion test/util/test-log.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ chai.use(require('sinon-chai'));
const sinon = require('sinon');
const mockery = require('mockery');

let Ravel, intel, intelLogger;
let Ravel, intel, intelLogger, coreSymbols;

describe('Ravel.Log', function() {
beforeEach((done) => {
Expand Down Expand Up @@ -55,11 +55,13 @@ describe('Ravel.Log', function() {
};
mockery.registerMock('intel', intel);
Ravel = new (require('../../lib/ravel'))();
coreSymbols = require('../../lib/core/symbols');
done();
});

afterEach((done) => {
Ravel = undefined;
coreSymbols = undefined;
mockery.deregisterAll();mockery.disable();
done();
});
Expand Down Expand Up @@ -210,6 +212,9 @@ describe('Ravel.Log', function() {
it('should set the default log level on \'start\' if none was specified via Ravel.set(\'log level\')', (done) => {
const stub = sinon.stub(intel, 'setLevel');
Ravel.emit('pre init');
Ravel.emit('pre load parameters');
Ravel[coreSymbols.parametersLoaded] = true;
Ravel.emit('post load parameters');
expect(stub).to.have.been.calledOnce;
expect(stub).to.have.been.calledWith(intel.DEBUG);
done();
Expand All @@ -219,6 +224,9 @@ describe('Ravel.Log', function() {
const stub = sinon.stub(intel, 'setLevel');
Ravel.set('log level', Ravel.log.ERROR);
Ravel.emit('pre init');
Ravel.emit('pre load parameters');
Ravel[coreSymbols.parametersLoaded] = true;
Ravel.emit('post load parameters');
expect(stub).to.have.been.calledOnce;
expect(stub).to.have.been.calledWith(intel.ERROR);
done();
Expand Down

0 comments on commit 766a1af

Please sign in to comment.