diff --git a/spec/core/formatErrorMsgSpec.js b/spec/core/formatErrorMsgSpec.js new file mode 100644 index 00000000..fd72190d --- /dev/null +++ b/spec/core/formatErrorMsgSpec.js @@ -0,0 +1,69 @@ +describe('formatErrorMsg', function () { + + it('should return a factory', function() { + expect(typeof jasmineUnderTest.formatErrorMsg).toBe('function'); + }); + + + describe('Format an error with a domain', function() { + + var formator; + + beforeEach(function() { + formator = jasmineUnderTest.formatErrorMsg('api'); + }); + + it('should format the output', function() { + expect(formator('message').trim()).toBe('api : message'); + expect(formator('message2').trim()).toBe('api : message2'); + }); + + }); + + + describe('Format an error with a domain and usage', function() { + + var formator; + + beforeEach(function() { + formator = jasmineUnderTest.formatErrorMsg('api', 'with a param'); + }); + + it('should format the output', function() { + expect(formator('message').trim()).toBe('api : message\nUsage: with a param'); + expect(formator('message2').trim()).toBe('api : message2\nUsage: with a param'); + }); + + }); + + describe('Format an error with a domain, usage, Tips', function() { + + var formator; + + beforeEach(function() { + formator = jasmineUnderTest.formatErrorMsg('api', 'with a param', 'you can do it'); + }); + + it('should format the output', function() { + expect(formator('message').trim()).toBe('api : message\nUsage: with a param\nTips: you can do it'); + expect(formator('message2').trim()).toBe('api : message2\nUsage: with a param\nTips: you can do it'); + }); + + }); + + describe('Format an error with a domain no usage and Tips', function() { + + var formator; + + beforeEach(function() { + formator = jasmineUnderTest.formatErrorMsg('api', null, 'you can do it'); + }); + + it('should format the output', function() { + expect(formator('message').trim()).toBe('api : message\nTips: you can do it'); + expect(formator('message2').trim()).toBe('api : message2\nTips: you can do it'); + }); + + }); + +}); diff --git a/spec/core/matchers/toHaveBeenCalledSpec.js b/spec/core/matchers/toHaveBeenCalledSpec.js index be4c89fa..6a0e5b94 100644 --- a/spec/core/matchers/toHaveBeenCalledSpec.js +++ b/spec/core/matchers/toHaveBeenCalledSpec.js @@ -24,14 +24,14 @@ describe("toHaveBeenCalled", function() { var matcher = jasmineUnderTest.matchers.toHaveBeenCalled(), fn = function() {}; - expect(function() { matcher.compare(fn) }).toThrow(new Error("Expected a spy, but got Function.")); + expect(function() { matcher.compare(fn) }).toThrowError(Error, /Expected a spy, but got Function./); }); it("throws an exception when invoked with any arguments", function() { var matcher = jasmineUnderTest.matchers.toHaveBeenCalled(), spy = jasmineUnderTest.createSpy('sample spy'); - expect(function() { matcher.compare(spy, 'foo') }).toThrow(new Error("toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith")); + expect(function() { matcher.compare(spy, 'foo') }).toThrowError(Error, /It does not take arguments, use toHaveBeenCalledWith/); }); it("has a custom message on failure", function() { diff --git a/spec/core/matchers/toHaveBeenCalledTimesSpec.js b/spec/core/matchers/toHaveBeenCalledTimesSpec.js index 55a4a3ba..6a12e779 100644 --- a/spec/core/matchers/toHaveBeenCalledTimesSpec.js +++ b/spec/core/matchers/toHaveBeenCalledTimesSpec.js @@ -24,7 +24,7 @@ describe("toHaveBeenCalledTimes", function() { spy(); expect(function() { matcher.compare(spy); - }).toThrowError('The expected times failed is a required argument and must be a number.'); + }).toThrowError(/The expected times failed is a required argument and must be a number./); }); it("fails when the actual was called less than the expected", function() { @@ -54,7 +54,7 @@ describe("toHaveBeenCalledTimes", function() { expect(function() { matcher.compare(fn); - }).toThrowError("Expected a spy, but got Function."); + }).toThrowError(/Expected a spy, but got Function./); }); it("has a custom message on failure that tells it was called only once", function() { diff --git a/spec/core/matchers/toHaveBeenCalledWithSpec.js b/spec/core/matchers/toHaveBeenCalledWithSpec.js index 15d0aec0..fa39fc0a 100644 --- a/spec/core/matchers/toHaveBeenCalledWithSpec.js +++ b/spec/core/matchers/toHaveBeenCalledWithSpec.js @@ -1,4 +1,5 @@ describe("toHaveBeenCalledWith", function() { + it("passes when the actual was called with matching parameters", function() { var util = { contains: jasmine.createSpy('delegated-contains').and.returnValue(true) @@ -61,6 +62,6 @@ describe("toHaveBeenCalledWith", function() { var matcher = jasmineUnderTest.matchers.toHaveBeenCalledWith(), fn = function() {}; - expect(function() { matcher.compare(fn) }).toThrow(new Error("Expected a spy, but got Function.")); + expect(function() { matcher.compare(fn) }).toThrowError(/Expected a spy, but got Function./); }); }); diff --git a/spec/core/matchers/toMatchSpec.js b/spec/core/matchers/toMatchSpec.js index 85cfd05f..b245e34d 100644 --- a/spec/core/matchers/toMatchSpec.js +++ b/spec/core/matchers/toMatchSpec.js @@ -1,4 +1,5 @@ describe("toMatch", function() { + it("passes when RegExps are equivalent", function() { var matcher = jasmineUnderTest.matchers.toMatch(), result; @@ -36,7 +37,7 @@ describe("toMatch", function() { expect(function() { matcher.compare('foo', { bar: 'baz' }); - }).toThrowError('Expected is not a String or a RegExp'); + }).toThrowError(/Expected is not a String or a RegExp/); }); }); diff --git a/spec/core/matchers/toThrowErrorSpec.js b/spec/core/matchers/toThrowErrorSpec.js index 8af0b343..c15e7129 100644 --- a/spec/core/matchers/toThrowErrorSpec.js +++ b/spec/core/matchers/toThrowErrorSpec.js @@ -4,7 +4,7 @@ describe("toThrowError", function() { expect(function() { matcher.compare({}); - }).toThrowError("Actual is not a Function"); + }).toThrowError(/Actual is not a Function/); }); it("throws an error when the expected is not an Error, string, or RegExp", function() { @@ -15,7 +15,7 @@ describe("toThrowError", function() { expect(function() { matcher.compare(fn, 1); - }).toThrowError("Expected is not an Error, string, or RegExp."); + }).toThrowError(/Expected is not an Error, string, or RegExp./); }); it("throws an error when the expected error type is not an Error", function() { @@ -26,7 +26,7 @@ describe("toThrowError", function() { expect(function() { matcher.compare(fn, void 0, "foo"); - }).toThrowError("Expected error type is not an Error."); + }).toThrowError(/Expected error type is not an Error./); }); it("throws an error when the expected error message is not a string or RegExp", function() { @@ -37,7 +37,7 @@ describe("toThrowError", function() { expect(function() { matcher.compare(fn, Error, 1); - }).toThrowError("Expected error message is not a string or RegExp."); + }).toThrowError(/Expected error message is not a string or RegExp./); }); it("fails if actual does not throw at all", function() { diff --git a/spec/core/matchers/toThrowSpec.js b/spec/core/matchers/toThrowSpec.js index e232156b..03e11b38 100644 --- a/spec/core/matchers/toThrowSpec.js +++ b/spec/core/matchers/toThrowSpec.js @@ -1,11 +1,12 @@ describe("toThrow", function() { + it("throws an error when the actual is not a function", function() { var matcher = jasmineUnderTest.matchers.toThrow(); expect(function() { matcher.compare({}); matcherComparator({}); - }).toThrowError("Actual is not a Function"); + }).toThrowError(/Actual is not a Function/); }); it("fails if actual does not throw", function() { diff --git a/src/core/SpyRegistry.js b/src/core/SpyRegistry.js index 15c31905..eb0a2acd 100644 --- a/src/core/SpyRegistry.js +++ b/src/core/SpyRegistry.js @@ -1,5 +1,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) { + var getErrorMsg = j$.formatErrorMsg('', 'spyOn(, )'); + function SpyRegistry(options) { options = options || {}; var currentSpies = options.currentSpies || function() { return []; }; @@ -9,23 +11,24 @@ getJasmineRequireObj().SpyRegistry = function(j$) { }; this.spyOn = function(obj, methodName) { + if (j$.util.isUndefined(obj)) { - throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()'); + throw new Error(getErrorMsg('could not find an object to spy upon for ' + methodName + '()')); } if (j$.util.isUndefined(methodName)) { - throw new Error('No method name supplied'); + throw new Error(getErrorMsg('No method name supplied the second parameter is required')); } if (j$.util.isUndefined(obj[methodName])) { - throw new Error(methodName + '() method does not exist'); + throw new Error(getErrorMsg(methodName + '() method does not exist')); } if (obj[methodName] && j$.isSpy(obj[methodName]) ) { if ( !!this.respy ){ return obj[methodName]; }else { - throw new Error(methodName + ' has already been spied upon'); + throw new Error(getErrorMsg(methodName + ' has already been spied upon')); } } @@ -37,7 +40,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) { } if (descriptor && !(descriptor.writable || descriptor.set)) { - throw new Error(methodName + ' is not declared writable or has no setter'); + throw new Error(getErrorMsg(methodName + ' is not declared writable or has no setter')); } var originalMethod = obj[methodName], diff --git a/src/core/formatErrorMsg.js b/src/core/formatErrorMsg.js new file mode 100644 index 00000000..f4050217 --- /dev/null +++ b/src/core/formatErrorMsg.js @@ -0,0 +1,14 @@ +getJasmineRequireObj().formatErrorMsg = function() { + + function generateErrorMsg(domain, usage, reco) { + + var usageDefinition = usage ? 'Usage: ' + usage + '\n' : ''; + var recoDefinition = reco ? 'Tips: ' + reco + '\n' : ''; + + return function errorMsg(msg) { + return domain + ' : ' + msg + '\n' + usageDefinition + recoDefinition; + }; + } + + return generateErrorMsg; +}; \ No newline at end of file diff --git a/src/core/matchers/toHaveBeenCalled.js b/src/core/matchers/toHaveBeenCalled.js index 5c7a1a99..ce900d75 100644 --- a/src/core/matchers/toHaveBeenCalled.js +++ b/src/core/matchers/toHaveBeenCalled.js @@ -1,16 +1,18 @@ getJasmineRequireObj().toHaveBeenCalled = function(j$) { + var getErrorMsg = j$.formatErrorMsg('', 'expect().toHaveBeenCalled()', 'To test with arguments, you can use '); + function toHaveBeenCalled() { return { compare: function(actual) { var result = {}; if (!j$.isSpy(actual)) { - throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.')); } if (arguments.length > 1) { - throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); + throw new Error(getErrorMsg('It does not take arguments, use toHaveBeenCalledWith')); } result.pass = actual.calls.any(); diff --git a/src/core/matchers/toHaveBeenCalledTimes.js b/src/core/matchers/toHaveBeenCalledTimes.js index 597968fd..a547a2df 100644 --- a/src/core/matchers/toHaveBeenCalledTimes.js +++ b/src/core/matchers/toHaveBeenCalledTimes.js @@ -1,17 +1,19 @@ getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) { + var getErrorMsg = j$.formatErrorMsg('', 'expect().toHaveBeenCalledTimes()'); + function toHaveBeenCalledTimes() { return { compare: function(actual, expected) { if (!j$.isSpy(actual)) { - throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.')); } var args = Array.prototype.slice.call(arguments, 0), result = { pass: false }; if (!j$.isNumber_(expected)){ - throw new Error('The expected times failed is a required argument and must be a number.'); + throw new Error(getErrorMsg('The expected times failed is a required argument and must be a number.')); } actual = args[0]; @@ -27,4 +29,4 @@ getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) { } return toHaveBeenCalledTimes; -}; \ No newline at end of file +}; diff --git a/src/core/matchers/toHaveBeenCalledWith.js b/src/core/matchers/toHaveBeenCalledWith.js index 18a6c5b3..ac3bcea9 100644 --- a/src/core/matchers/toHaveBeenCalledWith.js +++ b/src/core/matchers/toHaveBeenCalledWith.js @@ -1,5 +1,7 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) { + var getErrorMsg = j$.formatErrorMsg('', 'expect().toHaveBeenCalledWith(...arguments)'); + function toHaveBeenCalledWith(util, customEqualityTesters) { return { compare: function() { @@ -9,7 +11,7 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) { result = { pass: false }; if (!j$.isSpy(actual)) { - throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.')); } if (!actual.calls.any()) { diff --git a/src/core/matchers/toMatch.js b/src/core/matchers/toMatch.js index df7ded5e..898219d4 100644 --- a/src/core/matchers/toMatch.js +++ b/src/core/matchers/toMatch.js @@ -1,10 +1,12 @@ getJasmineRequireObj().toMatch = function(j$) { + var getErrorMsg = j$.formatErrorMsg('', 'expect().toMatch( || )'); + function toMatch() { return { compare: function(actual, expected) { if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { - throw new Error('Expected is not a String or a RegExp'); + throw new Error(getErrorMsg('Expected is not a String or a RegExp')); } var regexp = new RegExp(expected); diff --git a/src/core/matchers/toThrow.js b/src/core/matchers/toThrow.js index ae0ea129..2130a417 100644 --- a/src/core/matchers/toThrow.js +++ b/src/core/matchers/toThrow.js @@ -1,5 +1,7 @@ getJasmineRequireObj().toThrow = function(j$) { + var getErrorMsg = j$.formatErrorMsg('', 'expect(function() {}).toThrow()', 'You can match a specific exception with '); + function toThrow(util) { return { compare: function(actual, expected) { @@ -8,7 +10,7 @@ getJasmineRequireObj().toThrow = function(j$) { thrown; if (typeof actual != 'function') { - throw new Error('Actual is not a Function'); + throw new Error(getErrorMsg('Actual is not a Function')); } try { diff --git a/src/core/matchers/toThrowError.js b/src/core/matchers/toThrowError.js index 7118dc3e..a80a1427 100644 --- a/src/core/matchers/toThrowError.js +++ b/src/core/matchers/toThrowError.js @@ -1,4 +1,7 @@ getJasmineRequireObj().toThrowError = function(j$) { + + var getErrorMsg = j$.formatErrorMsg('', 'expect(function() {' + '\n' + '\t' + '' + '\n' + '}).toThrowError(, )'); + function toThrowError () { return { compare: function(actual) { @@ -8,7 +11,7 @@ getJasmineRequireObj().toThrowError = function(j$) { thrown; if (typeof actual != 'function') { - throw new Error('Actual is not a Function'); + throw new Error(getErrorMsg('Actual is not a Function')); } var errorMatcher = getMatcher.apply(null, arguments); @@ -64,15 +67,15 @@ getJasmineRequireObj().toThrowError = function(j$) { errorType = arguments[1]; expected = arguments[2]; if (!isAnErrorType(errorType)) { - throw new Error('Expected error type is not an Error.'); + throw new Error(getErrorMsg('Expected error type is not an Error.')); } } if (expected && !isStringOrRegExp(expected)) { if (errorType) { - throw new Error('Expected error message is not a string or RegExp.'); + throw new Error(getErrorMsg('Expected error message is not a string or RegExp.')); } else { - throw new Error('Expected is not an Error, string, or RegExp.'); + throw new Error(getErrorMsg('Expected is not an Error, string, or RegExp.')); } } diff --git a/src/core/requireCore.js b/src/core/requireCore.js index 51c82285..8da77e32 100644 --- a/src/core/requireCore.js +++ b/src/core/requireCore.js @@ -25,6 +25,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) { jRequire.base(j$, jasmineGlobal); j$.util = jRequire.util(); j$.errors = jRequire.errors(); + j$.formatErrorMsg = jRequire.formatErrorMsg(); j$.Any = jRequire.Any(j$); j$.Anything = jRequire.Anything(j$); j$.CallTracker = jRequire.CallTracker(j$);