diff --git a/src/raven.js b/src/raven.js index e5f8780c3a4e..01cd5fe85281 100644 --- a/src/raven.js +++ b/src/raven.js @@ -21,7 +21,8 @@ var _Raven = window.Raven, tags: {}, extra: {} }, - authQueryString; + authQueryString, + isRavenInstalled = false; /* * The core Raven singleton @@ -52,6 +53,10 @@ var Raven = { * @return {Raven} */ config: function(dsn, options) { + if (globalServer) { + logDebug('error', 'Error: Raven has already been configured'); + return Raven; + } if (!dsn) return Raven; var uri = parseDSN(dsn), @@ -117,8 +122,9 @@ var Raven = { * @return {Raven} */ install: function() { - if (isSetup()) { + if (isSetup() && !isRavenInstalled) { TraceKit.report.subscribe(handleStackInfo); + isRavenInstalled = true; } return Raven; @@ -212,6 +218,7 @@ var Raven = { */ uninstall: function() { TraceKit.report.uninstall(); + isRavenInstalled = false; return Raven; }, @@ -681,9 +688,7 @@ function makeRequest(data) { function isSetup() { if (!hasJSON) return false; // needs JSON support if (!globalServer) { - if (window.console && console.error && Raven.debug) { - console.error("Error: Raven has not been configured."); - } + logDebug('error', 'Error: Raven has not been configured.'); return false; } return true; @@ -720,6 +725,12 @@ function uuid4() { }); } +function logDebug(level, message) { + if (window.console && console[level] && Raven.debug) { + console[level](message); + } +} + function afterLoad() { // Attempt to initialize Raven on load var RavenConfig = window.RavenConfig; diff --git a/test/raven.test.js b/test/raven.test.js index 74b43777dbf7..ca352e4d4bda 100644 --- a/test/raven.test.js +++ b/test/raven.test.js @@ -218,31 +218,32 @@ describe('globals', function() { it('should return false when Raven is not configured', function() { hasJSON = true; // be explicit globalServer = undefined; - this.sinon.stub(console, 'error'); + this.sinon.stub(window, 'logDebug'); assert.isFalse(isSetup()); }); - it('should not write to console.error when Raven is not configured and Raven.debug is false', function() { - hasJSON = true; // be explicit - globalServer = undefined; - Raven.debug = false; - this.sinon.stub(console, 'error'); - isSetup(); - assert.isFalse(console.error.calledOnce); + it('should return true when everything is all gravy', function() { + hasJSON = true; + assert.isTrue(isSetup()); }); + }); - it('should write to console.error when Raven is not configured and Raven.debug is true', function() { - hasJSON = true; // be explicit - globalServer = undefined; - Raven.debug = true; - this.sinon.stub(console, 'error'); - isSetup(); - assert.isTrue(console.error.calledOnce); + describe('logDebug', function() { + var level = 'error', + message = 'foobar'; + + it('should not write to console when Raven.debug is false', function() { + Raven.debug = false; + this.sinon.stub(console, level); + logDebug(level, message); + assert.isFalse(console[level].called); }); - it('should return true when everything is all gravy', function() { - hasJSON = true; - assert.isTrue(isSetup()); + it('should write to console when Raven.debug is true', function() { + Raven.debug = true; + this.sinon.stub(console, level); + logDebug(level, message); + assert.isTrue(console[level].calledOnce); }); }); @@ -1168,6 +1169,15 @@ describe('Raven (public API)', function() { assert.equal(Raven.config(''), Raven); }); + it('should not set global options more than once', function() { + this.sinon.spy(window, 'parseDSN'); + this.sinon.stub(window, 'logDebug'); + setupRaven(); + setupRaven(); + assert.isTrue(parseDSN.calledOnce); + assert.isTrue(logDebug.called); + }); + describe('whitelistUrls', function() { it('should be false if none are passed', function() { Raven.config('//abc@example.com/2'); @@ -1237,6 +1247,14 @@ describe('Raven (public API)', function() { assert.isTrue(TraceKit.report.subscribe.calledOnce); assert.equal(TraceKit.report.subscribe.lastCall.args[0], handleStackInfo); }); + + it('should not register itself more than once', function() { + this.sinon.stub(window, 'isSetup').returns(true); + this.sinon.stub(TraceKit.report, 'subscribe'); + Raven.install(); + Raven.install(); + assert.isTrue(TraceKit.report.subscribe.calledOnce); + }); }); describe('.wrap', function() { @@ -1382,6 +1400,13 @@ describe('Raven (public API)', function() { Raven.uninstall(); assert.isTrue(TraceKit.report.uninstall.calledOnce); }); + + it('should set isRavenInstalled flag to false', function() { + isRavenInstalled = true; + this.sinon.stub(TraceKit.report, 'uninstall'); + Raven.uninstall(); + assert.isFalse(isRavenInstalled); + }); }); describe('.setUserContext', function() {