diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index b7188584..0a679f7c 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -3843,7 +3843,7 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) { return message; }; - this.stack = function(error) { + this.stack = function(error, { omitMessage } = {}) { if (!error || !error.stack) { return null; } @@ -3852,7 +3852,7 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) { var lines = filterJasmine(stackTrace); var result = ''; - if (stackTrace.message) { + if (stackTrace.message && !omitMessage) { lines.unshift(stackTrace.message); } @@ -4302,7 +4302,9 @@ getJasmineRequireObj().buildExpectationResult = function(j$) { } } } - return stackFormatter(error); + // Omit the message from the stack trace because it will be + // included elsewhere. + return stackFormatter(error, { omitMessage: true }); } } diff --git a/spec/core/ExceptionFormatterSpec.js b/spec/core/ExceptionFormatterSpec.js index 1c4a1c62..f4f15700 100644 --- a/spec/core/ExceptionFormatterSpec.js +++ b/spec/core/ExceptionFormatterSpec.js @@ -225,5 +225,61 @@ describe('ExceptionFormatter', function() { expect(result).toMatch(/error properties:.*someProperty.*hello there/); }); + + describe('When omitMessage is true', function() { + it('filters the message from V8-style stack traces', function() { + const error = { + message: 'nope', + stack: + 'Error: nope\n' + + ' at fn1 (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' + + ' at fn2 (http://localhost:8888/__jasmine__/jasmine.js:4320:20)\n' + + ' at fn3 (http://localhost:8888/__jasmine__/jasmine.js:4320:20)\n' + + ' at fn4 (http://localhost:8888/__spec__/core/UtilSpec.js:110:19)\n' + }; + const subject = new jasmineUnderTest.ExceptionFormatter({ + jasmineFile: 'http://localhost:8888/__jasmine__/jasmine.js' + }); + const result = subject.stack(error, { omitMessage: true }); + expect(result).toEqual( + ' at fn1 (http://localhost:8888/__spec__/core/UtilSpec.js:115:19)\n' + + ' at \n' + + ' at fn4 (http://localhost:8888/__spec__/core/UtilSpec.js:110:19)' + ); + }); + + it('handles Webkit style traces that do not include a message', function() { + const error = { + stack: + 'http://localhost:8888/__spec__/core/UtilSpec.js:115:28\n' + + 'fn1@http://localhost:8888/__jasmine__/jasmine.js:4320:27\n' + + 'fn2@http://localhost:8888/__jasmine__/jasmine.js:4320:27\n' + + 'http://localhost:8888/__spec__/core/UtilSpec.js:115:28' + }; + const subject = new jasmineUnderTest.ExceptionFormatter({ + jasmineFile: 'http://localhost:8888/__jasmine__/jasmine.js' + }); + const result = subject.stack(error, { omitMessage: true }); + expect(result).toEqual( + 'http://localhost:8888/__spec__/core/UtilSpec.js:115:28\n' + + '\n' + + 'http://localhost:8888/__spec__/core/UtilSpec.js:115:28' + ); + }); + + it('ensures that stack traces do not include the message in this environment', function() { + let error; + try { + throw new Error('an error'); + } catch (e) { + error = e; + } + const subject = new jasmineUnderTest.ExceptionFormatter({ + jasmineFile: jasmine.util.jasmineFile() + }); + const result = subject.stack(error, { omitMessage: true }); + expect(result).not.toContain('an error'); + }); + }); }); }); diff --git a/spec/core/ExpectationResultSpec.js b/spec/core/ExpectationResultSpec.js index b28818aa..d68b1655 100644 --- a/spec/core/ExpectationResultSpec.js +++ b/spec/core/ExpectationResultSpec.js @@ -50,7 +50,9 @@ describe('buildExpectationResult', function() { stackFormatter: stackFormatter }); - expect(stackFormatter).toHaveBeenCalledWith(fakeError); + expect(stackFormatter).toHaveBeenCalledWith(fakeError, { + omitMessage: true + }); expect(result.stack).toEqual('foo'); }); @@ -66,7 +68,9 @@ describe('buildExpectationResult', function() { stackFormatter: stackFormatter }); - expect(stackFormatter).toHaveBeenCalledWith(fakeError); + expect(stackFormatter).toHaveBeenCalledWith(fakeError, { + omitMessage: true + }); expect(result.stack).toEqual('foo'); }); diff --git a/spec/core/integration/EnvSpec.js b/spec/core/integration/EnvSpec.js index 2d0b0072..45846e4f 100644 --- a/spec/core/integration/EnvSpec.js +++ b/spec/core/integration/EnvSpec.js @@ -2839,7 +2839,7 @@ describe('Env integration', function() { expect(result.deprecationWarnings).toEqual([ jasmine.objectContaining({ message: topLevelError.message, - stack: exceptionFormatter.stack(topLevelError) + stack: exceptionFormatter.stack(topLevelError, { omitMessage: true }) }) ]); @@ -2849,7 +2849,9 @@ describe('Env integration', function() { deprecationWarnings: [ jasmine.objectContaining({ message: suiteLevelError.message, - stack: exceptionFormatter.stack(suiteLevelError) + stack: exceptionFormatter.stack(suiteLevelError, { + omitMessage: true + }) }) ] }) @@ -2861,7 +2863,9 @@ describe('Env integration', function() { deprecationWarnings: [ jasmine.objectContaining({ message: specLevelError.message, - stack: exceptionFormatter.stack(specLevelError) + stack: exceptionFormatter.stack(specLevelError, { + omitMessage: true + }) }) ] }) diff --git a/src/core/ExceptionFormatter.js b/src/core/ExceptionFormatter.js index 113f7af7..a36d1422 100644 --- a/src/core/ExceptionFormatter.js +++ b/src/core/ExceptionFormatter.js @@ -38,7 +38,7 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) { return message; }; - this.stack = function(error) { + this.stack = function(error, { omitMessage } = {}) { if (!error || !error.stack) { return null; } @@ -47,7 +47,7 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) { var lines = filterJasmine(stackTrace); var result = ''; - if (stackTrace.message) { + if (stackTrace.message && !omitMessage) { lines.unshift(stackTrace.message); } diff --git a/src/core/ExpectationResult.js b/src/core/ExpectationResult.js index 8834b3e0..23c91013 100644 --- a/src/core/ExpectationResult.js +++ b/src/core/ExpectationResult.js @@ -76,7 +76,9 @@ getJasmineRequireObj().buildExpectationResult = function(j$) { } } } - return stackFormatter(error); + // Omit the message from the stack trace because it will be + // included elsewhere. + return stackFormatter(error, { omitMessage: true }); } }