Skip to content

Commit

Permalink
create ProtectedMethodError
Browse files Browse the repository at this point in the history
  • Loading branch information
Rémi Becheras committed Jan 2, 2017
1 parent d8b2e66 commit 7b45832
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 34 deletions.
27 changes: 18 additions & 9 deletions lib/errors/CustomError.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
'use strict'

var path = require('path')
var PrivateMethodError = require('./PrivateMethodError')

module.exports = CustomError

CustomError.prototype = Object.create(Error.prototype)
CustomError.prototype.constructor = CustomError
CustomError.prototype.setMessage = setMessage
CustomError.prototype.createStackTrace = createStackTrace
CustomError.prototype.protect = protect
CustomError.prototype.privatize = privatize

/**
* CustomError
* @class
Expand All @@ -17,22 +23,25 @@ module.exports = CustomError
*/
function CustomError (msg) {
// Error.call(this, msg)
this.setMessage(msg)
this.createStackTrace()
}

/**
* Set the error message from the given argument or from the class property DEFAULT_ERROR_MESSAGE
* @method
*/
function setMessage (msg) {
privatize()
if (msg && typeof msg === 'string') {
this.message = msg
} else if (this.constructor.name !== 'CustomError') {
this.message = global[this.constructor.name].DEFAULT_ERROR_MESSAGE
this.message = this.constructor.DEFAULT_ERROR_MESSAGE
} else {
this.message = undefined
}
this.createStackTrace()
}

CustomError.prototype = Object.create(Error.prototype)
CustomError.prototype.constructor = CustomError
CustomError.prototype.createStackTrace = createStackTrace
CustomError.prototype.protect = protect
CustomError.prototype.privatize = privatize

/**
* Set the the correct stack trace for this error
* @method
Expand Down
23 changes: 23 additions & 0 deletions lib/errors/ProtectedMethodError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict'

var CustomError = require('./CustomError')

module.exports = ProtectedMethodError

ProtectedMethodError.DEFAULT_ERROR_MESSAGE = 'This is a protected method'

ProtectedMethodError.prototype = Object.create(CustomError.prototype)
ProtectedMethodError.prototype.constructor = ProtectedMethodError

/**
* ProtectedMethodError
* @class
* @property {String} message The error message
* @property {String} stack The error stack trace
*
* @constructor
* @param {String} msg A custom error message
*/
function ProtectedMethodError (msg) {
CustomError.call(this, msg)
}
91 changes: 66 additions & 25 deletions tests/errors/CustomError.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

var path = require('path')
var chai = require('chai')
var PrivateMethodError = require(path.resolve('./lib/errors/PrivateMethodError'))
var ProtectedMethodError = require(path.resolve('./lib/errors/ProtectedMethodError'))

var CustomError = require(path.resolve('./lib/errors/CustomError'))

var describe = global.describe
Expand All @@ -13,7 +16,7 @@ describe('CustomError', function () {
expect(CustomError).to.be.a('function')
})

it("should not have a 'DEFAULT_ERROR_MESSAGE' static constant property (child classes should have one)", function () {
it("should not have a 'DEFAULT_ERROR_MESSAGE' static constant property (child classes should)", function () {
expect(CustomError).to.not.have.a.property('DEFAULT_ERROR_MESSAGE')
})

Expand Down Expand Up @@ -73,40 +76,78 @@ describe('CustomError', function () {
expect(err.protect).to.be.a('function')
})

it('should not fail if an bad type is given instead of a string as first argument', function () {
var err
var func = function () { err = new CustomError(func) }
var obj = function () { err = new CustomError({ foo: 'bar' }) }
var arr = function () { err = new CustomError([ 'foo', 'baz' ]) }
describe('when giving a non-string argument', function () {
it('should not fail', function () {
var func = function () { return new CustomError(func) }
var obj = function () { return new CustomError({ foo: 'bar' }) }
var arr = function () { return new CustomError([ 'foo', 'baz' ]) }

expect(func).to.not.throw()
expect(obj).to.not.throw()
expect(arr).to.not.throw()
})
})

expect(func).to.not.throw('TypeError')
expect(obj).to.not.throw('TypeError')
expect(arr).to.not.throw('TypeError')
describe('when called without argument', function () {
it('should not have a default error message (child classes should)', function () {
var err = new CustomError()
expect(err.message).to.not.be.a('String')
expect(err.message).to.be.undefined
})
})

it('should fails if we call the private createStackTrace method', function () {
var func = function () {
describe('when called without argument from a child class', function () {
it('should set the child class DEFAULT_ERROR_MESSAGE', function () {
var err
var ChildError = function ChildError (msg) {
CustomError.call(this, msg)
}
ChildError.prototype = Object.create(CustomError.prototype)
ChildError.prototype.constructor = ChildError
ChildError.DEFAULT_ERROR_MESSAGE = 'child error'
err = new ChildError()
expect(err).to.be.an('object')
expect(err).to.be.an.instanceof(ChildError)
expect(err.message).to.be.a('string')
expect(err.message).to.equal(ChildError.DEFAULT_ERROR_MESSAGE)
})
})
})

describe('#setMessage()', function () {
describe('when called from outside', function () {
it('should thow PrivateMethodError', function () {
var err = new CustomError(func)
var t = err.createStackTrace()
console.log(t)
}
expect(func).to.throw(Error)
var func = function () {
return err.setMessage()
}
expect(func).to.throw(PrivateMethodError)
})
})
})

it('should fails if a child class call the protected createStackTrace method', function () {
var func = function () {
describe('#createStackTrace()', function () {
describe('when called from outside', function () {
it('should thow PrivateMethodError', function () {
var err = new CustomError(func)
var t = err.createStackTrace()
console.log(t)
}
expect(func).to.throw(Error)
var func = function () {
return err.createStackTrace()
}
expect(func).to.throw(PrivateMethodError)
})
})

it('should not have a default error message if no argument is given (child class should have)', function () {
var err = new CustomError()
expect(err.message).to.not.be.a('String')
expect(err.message).to.be.undefined
describe.skip('when called from a child class', function () {
it('should throw ProtectedMethodError', function () {
var func = function () {
var err = new CustomError(func)
var t = err.createStackTrace()
console.log(t)
}
expect(func).to.throw(ProtectedMethodError)
})
})
})

})
})
117 changes: 117 additions & 0 deletions tests/errors/ProtectedMethodError.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
'use strict'

var path = require('path')
var chai = require('chai')
var CustomError = require(path.resolve('./lib/errors/CustomError'))
var ProtectedMethodError = require(path.resolve('./lib/errors/ProtectedMethodError'))
var PrivateMethodError = require(path.resolve('./lib/errors/PrivateMethodError'))

var describe = global.describe
var beforeEach = global.beforeEach
var it = global.it
var expect = chai.expect

describe('ProtectedMethodError', function () {
it('should be a function', function () {
expect(ProtectedMethodError).to.be.a('function')
})

it("should have a 'DEFAULT_ERROR_MESSAGE' static constant property", function () {
expect(ProtectedMethodError).to.be.a.property('DEFAULT_ERROR_MESSAGE')
})

describe('.prototype', function () {
it('should be an object', function () {
expect(ProtectedMethodError.prototype).to.be.a('object')
})

it('should be an instance of CustomError', function () {
expect(ProtectedMethodError.prototype).to.be.an.instanceof(CustomError)
})

describe('.constructor', function () {
it('should be a function', function () {
expect(ProtectedMethodError.prototype.constructor).to.be.a('function')
})

it("should have a 'name' property w/ the value 'ProtectedMethodError'", function () {
expect(ProtectedMethodError.prototype.constructor).to.be.a.property('name')
expect(ProtectedMethodError.prototype.constructor.name).to.equal('ProtectedMethodError')
})
})

describe('.constructor()', function () {
it('should be an instance of ProtectedMethodError', function () {
var err = new ProtectedMethodError()
expect(err).to.be.an.instanceof(ProtectedMethodError)
})

it("should have a 'message' property of type 'String'", function () {
var msg = 'i am private'
var err = new ProtectedMethodError(msg)
expect(err).to.be.a.property('message')
expect(err.message).to.be.a('String')
})

it("should have a 'stack' property of type 'String'", function () {
var msg = 'i am private'
var err = new ProtectedMethodError(msg)
expect(err).to.be.a.property('stack')
expect(err.stack).to.be.a('String')
})

describe('when a non-string argument is given', function () {
var err0, err1, err2
var func, obj, arr

beforeEach(function () {
func = function () { err0 = new ProtectedMethodError(func) }
obj = function () { err1 = new ProtectedMethodError({ foo: 'bar' }) }
arr = function () { err2 = new ProtectedMethodError([ 'foo', 'baz' ]) }
})

it('should not fail', function () {
expect(func).to.not.throw()
expect(obj).to.not.throw()
expect(arr).to.not.throw()
})

it('should define the "message" property as a String', function () {
expect(err0.message).to.be.a('String')
expect(err1.message).to.be.a('String')
expect(err2.message).to.be.a('String')
})
})

describe('when no argument is given', function () {
it('should set the default error message', function () {
var err = new ProtectedMethodError()
expect(err.message).to.be.a('String')
expect(err.message).to.be.equal(ProtectedMethodError.DEFAULT_ERROR_MESSAGE)
})
})
})

describe('#setMessage()', function () {
describe('when called from outside', function () {
it('should throw "PrivateMethodError"', function () {
var func = function () {
var err = new ProtectedMethodError(func)
return err.setMessage('foo')
}
expect(func).to.throw(Error)
})
})
})

describe('#createStackTrace()', function () {
describe('when called from outside', function () {
it('should throw "PrivateMethodError"', function () {
expect(function () {
return new ProtectedMethodError('foo').createStackTrace()
}).to.throw(PrivateMethodError)
})
})
})
})
})

0 comments on commit 7b45832

Please sign in to comment.