Refactor mocking in GlobalErrorsSpec

This commit is contained in:
Steve Gravrock
2025-07-12 09:22:54 -07:00
parent 495e5fcd50
commit adfbd00c75

View File

@@ -1,14 +1,14 @@
describe('GlobalErrors', function() { describe('GlobalErrors', function() {
it('calls the added handler on error', function() { it('calls the added handler on error', function() {
const fakeGlobal = browserGlobal(); const globals = browserGlobals();
const handler = jasmine.createSpy('errorHandler'); const handler = jasmine.createSpy('errorHandler');
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal); const errors = new jasmineUnderTest.GlobalErrors(globals.global);
errors.install(); errors.install();
errors.pushListener(handler); errors.pushListener(handler);
const error = new Error('nope'); const error = new Error('nope');
dispatchErrorEvent(fakeGlobal, { error }); dispatchEvent(globals.listeners, 'error', { error });
expect(handler).toHaveBeenCalledWith( expect(handler).toHaveBeenCalledWith(
jasmine.is(error), jasmine.is(error),
@@ -17,17 +17,17 @@ describe('GlobalErrors', function() {
}); });
it('is not affected by overriding global.onerror', function() { it('is not affected by overriding global.onerror', function() {
const fakeGlobal = browserGlobal(); const globals = browserGlobals();
const handler = jasmine.createSpy('errorHandler'); const handler = jasmine.createSpy('errorHandler');
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal); const errors = new jasmineUnderTest.GlobalErrors(globals.global);
errors.install(); errors.install();
errors.pushListener(handler); errors.pushListener(handler);
fakeGlobal.onerror = () => {}; globals.global.onerror = () => {};
const error = new Error('nope'); const error = new Error('nope');
dispatchErrorEvent(fakeGlobal, { error }); dispatchEvent(globals.listeners, 'error', { error });
expect(handler).toHaveBeenCalledWith( expect(handler).toHaveBeenCalledWith(
jasmine.is(error), jasmine.is(error),
@@ -36,17 +36,17 @@ describe('GlobalErrors', function() {
}); });
it('only calls the most recent handler', function() { it('only calls the most recent handler', function() {
const fakeGlobal = browserGlobal(); const globals = browserGlobals();
const handler1 = jasmine.createSpy('errorHandler1'); const handler1 = jasmine.createSpy('errorHandler1');
const handler2 = jasmine.createSpy('errorHandler2'); const handler2 = jasmine.createSpy('errorHandler2');
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal); const errors = new jasmineUnderTest.GlobalErrors(globals.global);
errors.install(); errors.install();
errors.pushListener(handler1); errors.pushListener(handler1);
errors.pushListener(handler2); errors.pushListener(handler2);
const error = new Error('nope'); const error = new Error('nope');
dispatchErrorEvent(fakeGlobal, { error }); dispatchEvent(globals.listeners, 'error', { error });
expect(handler1).not.toHaveBeenCalled(); expect(handler1).not.toHaveBeenCalled();
expect(handler2).toHaveBeenCalledWith( expect(handler2).toHaveBeenCalledWith(
@@ -56,10 +56,10 @@ describe('GlobalErrors', function() {
}); });
it('calls previous handlers when one is removed', function() { it('calls previous handlers when one is removed', function() {
const fakeGlobal = browserGlobal(); const globals = browserGlobals();
const handler1 = jasmine.createSpy('errorHandler1'); const handler1 = jasmine.createSpy('errorHandler1');
const handler2 = jasmine.createSpy('errorHandler2'); const handler2 = jasmine.createSpy('errorHandler2');
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal); const errors = new jasmineUnderTest.GlobalErrors(globals.global);
errors.install(); errors.install();
errors.pushListener(handler1); errors.pushListener(handler1);
@@ -68,7 +68,7 @@ describe('GlobalErrors', function() {
errors.popListener(handler2); errors.popListener(handler2);
const error = new Error('nope'); const error = new Error('nope');
dispatchErrorEvent(fakeGlobal, { error }); dispatchEvent(globals.listeners, 'error', { error });
expect(handler1).toHaveBeenCalledWith( expect(handler1).toHaveBeenCalledWith(
jasmine.is(error), jasmine.is(error),
@@ -85,26 +85,26 @@ describe('GlobalErrors', function() {
}); });
it('uninstalls itself', function() { it('uninstalls itself', function() {
const fakeGlobal = browserGlobal(); const globals = browserGlobals();
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal); const errors = new jasmineUnderTest.GlobalErrors(globals.global);
function unrelatedListener() {} function unrelatedListener() {}
errors.install(); errors.install();
fakeGlobal.addEventListener('error', unrelatedListener); globals.global.addEventListener('error', unrelatedListener);
errors.uninstall(); errors.uninstall();
expect(fakeGlobal.listeners_.error).toEqual([unrelatedListener]); expect(globals.listeners.error).toEqual([unrelatedListener]);
}); });
it('rethrows the original error when there is no handler', function() { it('rethrows the original error when there is no handler', function() {
const fakeGlobal = browserGlobal(); const globals = browserGlobals();
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal); const errors = new jasmineUnderTest.GlobalErrors(globals.global);
const originalError = new Error('nope'); const originalError = new Error('nope');
errors.install(); errors.install();
try { try {
dispatchErrorEvent(fakeGlobal, { error: originalError }); dispatchEvent(globals.listeners, 'error', { error: originalError });
} catch (e) { } catch (e) {
expect(e).toBe(originalError); expect(e).toBe(originalError);
} }
@@ -113,35 +113,23 @@ describe('GlobalErrors', function() {
}); });
it('reports uncaught exceptions in node.js', function() { it('reports uncaught exceptions in node.js', function() {
const fakeGlobal = { const globals = nodeGlobals();
process: { const errors = new jasmineUnderTest.GlobalErrors(globals.global);
on: jasmine.createSpy('process.on'), const handler = jasmine.createSpy('errorHandler');
removeListener: jasmine.createSpy('process.removeListener'), function originalHandler() {}
listeners: jasmine globals.listeners.uncaughtException = [originalHandler];
.createSpy('process.listeners')
.and.returnValue(['foo']),
removeAllListeners: jasmine.createSpy('process.removeAllListeners')
}
},
handler = jasmine.createSpy('errorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install(); errors.install();
expect(fakeGlobal.process.on).toHaveBeenCalledWith( expect(globals.listeners.uncaughtException).toEqual([
'uncaughtException',
jasmine.any(Function) jasmine.any(Function)
); ]);
expect(fakeGlobal.process.listeners).toHaveBeenCalledWith( expect(globals.listeners.uncaughtException).not.toEqual([
'uncaughtException' originalHandler()
); ]);
expect(fakeGlobal.process.removeAllListeners).toHaveBeenCalledWith(
'uncaughtException'
);
errors.pushListener(handler); errors.pushListener(handler);
const addedListener = fakeGlobal.process.on.calls.argsFor(0)[1]; dispatchEvent(globals.listeners, 'uncaughtException', new Error('bar'));
addedListener(new Error('bar'));
expect(handler).toHaveBeenCalledWith(new Error('bar')); expect(handler).toHaveBeenCalledWith(new Error('bar'));
expect(handler.calls.argsFor(0)[0].jasmineMessage).toBe( expect(handler.calls.argsFor(0)[0].jasmineMessage).toBe(
@@ -150,47 +138,28 @@ describe('GlobalErrors', function() {
errors.uninstall(); errors.uninstall();
expect(fakeGlobal.process.removeListener).toHaveBeenCalledWith( expect(globals.listeners.uncaughtException).toEqual([originalHandler]);
'uncaughtException',
addedListener
);
expect(fakeGlobal.process.on).toHaveBeenCalledWith(
'uncaughtException',
'foo'
);
}); });
describe('Reporting unhandled promise rejections in node.js', function() { describe('Reporting unhandled promise rejections in node.js', function() {
it('reports rejections with `Error` reasons', function() { it('reports rejections with `Error` reasons', function() {
const fakeGlobal = { const globals = nodeGlobals();
process: { const errors = new jasmineUnderTest.GlobalErrors(globals.global);
on: jasmine.createSpy('process.on'), const handler = jasmine.createSpy('errorHandler');
removeListener: jasmine.createSpy('process.removeListener'), function originalHandler() {}
listeners: jasmine globals.listeners.unhandledRejection = [originalHandler];
.createSpy('process.listeners')
.and.returnValue(['foo']),
removeAllListeners: jasmine.createSpy('process.removeAllListeners')
}
},
handler = jasmine.createSpy('errorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install(); errors.install();
expect(fakeGlobal.process.on).toHaveBeenCalledWith( expect(globals.listeners.unhandledRejection).toEqual([
'unhandledRejection',
jasmine.any(Function) jasmine.any(Function)
); ]);
expect(fakeGlobal.process.listeners).toHaveBeenCalledWith( expect(globals.listeners.unhandledRejection).not.toEqual([
'unhandledRejection' originalHandler()
); ]);
expect(fakeGlobal.process.removeAllListeners).toHaveBeenCalledWith(
'unhandledRejection'
);
errors.pushListener(handler); errors.pushListener(handler);
const addedListener = fakeGlobal.process.on.calls.argsFor(1)[1]; dispatchEvent(globals.listeners, 'unhandledRejection', new Error('bar'));
addedListener(new Error('bar'));
expect(handler).toHaveBeenCalledWith(new Error('bar')); expect(handler).toHaveBeenCalledWith(new Error('bar'));
expect(handler.calls.argsFor(0)[0].jasmineMessage).toBe( expect(handler.calls.argsFor(0)[0].jasmineMessage).toBe(
@@ -199,38 +168,18 @@ describe('GlobalErrors', function() {
errors.uninstall(); errors.uninstall();
expect(fakeGlobal.process.removeListener).toHaveBeenCalledWith( expect(globals.listeners.unhandledRejection).toEqual([originalHandler]);
'unhandledRejection',
addedListener
);
expect(fakeGlobal.process.on).toHaveBeenCalledWith(
'unhandledRejection',
'foo'
);
}); });
it('reports rejections with non-`Error` reasons', function() { it('reports rejections with non-`Error` reasons', function() {
const fakeGlobal = { const globals = nodeGlobals();
process: { const errors = new jasmineUnderTest.GlobalErrors(globals.global);
on: jasmine.createSpy('process.on'), const handler = jasmine.createSpy('errorHandler');
removeListener: function() {},
listeners: function() {
return [];
},
removeAllListeners: function() {}
}
},
handler = jasmine.createSpy('errorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install(); errors.install();
errors.pushListener(handler); errors.pushListener(handler);
expect(fakeGlobal.process.on.calls.argsFor(1)[0]).toEqual( dispatchEvent(globals.listeners, 'unhandledRejection', 17);
'unhandledRejection'
);
const addedListener = fakeGlobal.process.on.calls.argsFor(1)[1];
addedListener(17);
expect(handler).toHaveBeenCalledWith( expect(handler).toHaveBeenCalledWith(
new Error( new Error(
@@ -242,27 +191,14 @@ describe('GlobalErrors', function() {
}); });
it('reports rejections with no reason provided', function() { it('reports rejections with no reason provided', function() {
const fakeGlobal = { const globals = nodeGlobals();
process: { const errors = new jasmineUnderTest.GlobalErrors(globals.global);
on: jasmine.createSpy('process.on'), const handler = jasmine.createSpy('errorHandler');
removeListener: function() {},
listeners: function() {
return [];
},
removeAllListeners: function() {}
}
},
handler = jasmine.createSpy('errorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install(); errors.install();
errors.pushListener(handler); errors.pushListener(handler);
expect(fakeGlobal.process.on.calls.argsFor(1)[0]).toEqual( dispatchEvent(globals.listeners, 'unhandledRejection', undefined);
'unhandledRejection'
);
const addedListener = fakeGlobal.process.on.calls.argsFor(1)[1];
addedListener(undefined);
expect(handler).toHaveBeenCalledWith( expect(handler).toHaveBeenCalledWith(
new Error( new Error(
@@ -276,28 +212,28 @@ describe('GlobalErrors', function() {
describe('Reporting unhandled promise rejections in the browser', function() { describe('Reporting unhandled promise rejections in the browser', function() {
it('subscribes and unsubscribes from the unhandledrejection event', function() { it('subscribes and unsubscribes from the unhandledrejection event', function() {
const fakeGlobal = browserGlobal(); const globals = browserGlobals();
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal); const errors = new jasmineUnderTest.GlobalErrors(globals.global);
errors.install(); errors.install();
expect(fakeGlobal.listeners_.unhandledrejection).toEqual([ expect(globals.listeners.unhandledrejection).toEqual([
jasmine.any(Function) jasmine.any(Function)
]); ]);
errors.uninstall(); errors.uninstall();
expect(fakeGlobal.listeners_.unhandledrejection).toEqual([]); expect(globals.listeners.unhandledrejection).toEqual([]);
}); });
it('reports rejections whose reason is a string', function() { it('reports rejections whose reason is a string', function() {
const fakeGlobal = browserGlobal(); const globals = browserGlobals();
const handler = jasmine.createSpy('errorHandler'); const handler = jasmine.createSpy('errorHandler');
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal); const errors = new jasmineUnderTest.GlobalErrors(globals.global);
errors.install(); errors.install();
errors.pushListener(handler); errors.pushListener(handler);
const event = { reason: 'nope' }; const event = { reason: 'nope' };
dispatchUnhandledRejectionEvent(fakeGlobal, event); dispatchEvent(globals.listeners, 'unhandledrejection', event);
expect(handler).toHaveBeenCalledWith( expect(handler).toHaveBeenCalledWith(
'Unhandled promise rejection: nope', 'Unhandled promise rejection: nope',
@@ -306,16 +242,16 @@ describe('GlobalErrors', function() {
}); });
it('reports rejections whose reason is an Error', function() { it('reports rejections whose reason is an Error', function() {
const fakeGlobal = browserGlobal(); const globals = browserGlobals();
const handler = jasmine.createSpy('errorHandler'); const handler = jasmine.createSpy('errorHandler');
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal); const errors = new jasmineUnderTest.GlobalErrors(globals.global);
errors.install(); errors.install();
errors.pushListener(handler); errors.pushListener(handler);
const reason = new Error('bar'); const reason = new Error('bar');
const event = { reason }; const event = { reason };
dispatchUnhandledRejectionEvent(fakeGlobal, event); dispatchEvent(globals.listeners, 'unhandledrejection', event);
expect(handler).toHaveBeenCalledWith( expect(handler).toHaveBeenCalledWith(
jasmine.objectContaining({ jasmine.objectContaining({
@@ -330,73 +266,47 @@ describe('GlobalErrors', function() {
describe('Reporting uncaught exceptions in node.js', function() { describe('Reporting uncaught exceptions in node.js', function() {
it('prepends a descriptive message when the error is not an `Error`', function() { it('prepends a descriptive message when the error is not an `Error`', function() {
const fakeGlobal = { const globals = nodeGlobals();
process: { const errors = new jasmineUnderTest.GlobalErrors(globals.global);
on: jasmine.createSpy('process.on'),
removeListener: function() {},
listeners: function() {
return [];
},
removeAllListeners: function() {}
}
};
const handler = jasmine.createSpy('errorHandler'); const handler = jasmine.createSpy('errorHandler');
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install(); errors.install();
errors.pushListener(handler); errors.pushListener(handler);
uncaughtExceptionListener(fakeGlobal)(17); dispatchEvent(globals.listeners, 'uncaughtException', 17);
expect(handler).toHaveBeenCalledWith(new Error('Uncaught exception: 17')); expect(handler).toHaveBeenCalledWith(new Error('Uncaught exception: 17'));
}); });
it('substitutes a descriptive message when the error is falsy', function() { it('substitutes a descriptive message when the error is falsy', function() {
const fakeGlobal = { const globals = nodeGlobals();
process: { const errors = new jasmineUnderTest.GlobalErrors(globals.global);
on: jasmine.createSpy('process.on'),
removeListener: function() {},
listeners: function() {
return [];
},
removeAllListeners: function() {}
}
};
const handler = jasmine.createSpy('errorHandler'); const handler = jasmine.createSpy('errorHandler');
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install(); errors.install();
errors.pushListener(handler); errors.pushListener(handler);
uncaughtExceptionListener(fakeGlobal)(); dispatchEvent(globals.listeners, 'uncaughtException', undefined);
expect(handler).toHaveBeenCalledWith( expect(handler).toHaveBeenCalledWith(
new Error('Uncaught exception with no error or message') new Error('Uncaught exception with no error or message')
); );
}); });
function uncaughtExceptionListener(global) {
// Grab the right listener
expect(global.process.on.calls.argsFor(0)[0]).toEqual(
'uncaughtException'
);
return global.process.on.calls.argsFor(0)[1];
}
}); });
describe('#setOverrideListener', function() { describe('#setOverrideListener', function() {
it('overrides the existing handlers in browsers until removed', function() { it('overrides the existing handlers in browsers until removed', function() {
const fakeGlobal = browserGlobal(); const globals = browserGlobals();
const handler0 = jasmine.createSpy('handler0'); const handler0 = jasmine.createSpy('handler0');
const handler1 = jasmine.createSpy('handler1'); const handler1 = jasmine.createSpy('handler1');
const overrideHandler = jasmine.createSpy('overrideHandler'); const overrideHandler = jasmine.createSpy('overrideHandler');
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal); const errors = new jasmineUnderTest.GlobalErrors(globals.global);
errors.install(); errors.install();
errors.pushListener(handler0); errors.pushListener(handler0);
errors.setOverrideListener(overrideHandler, () => {}); errors.setOverrideListener(overrideHandler, () => {});
errors.pushListener(handler1); errors.pushListener(handler1);
dispatchErrorEvent(fakeGlobal, { error: 'foo' }); dispatchEvent(globals.listeners, 'error', { error: 'foo' });
expect(overrideHandler).toHaveBeenCalledWith('foo'); expect(overrideHandler).toHaveBeenCalledWith('foo');
expect(handler0).not.toHaveBeenCalled(); expect(handler0).not.toHaveBeenCalled();
@@ -405,55 +315,42 @@ describe('GlobalErrors', function() {
errors.removeOverrideListener(); errors.removeOverrideListener();
const event = { error: 'baz' }; const event = { error: 'baz' };
dispatchErrorEvent(fakeGlobal, event); dispatchEvent(globals.listeners, 'error', event);
expect(overrideHandler).not.toHaveBeenCalledWith('baz'); expect(overrideHandler).not.toHaveBeenCalledWith('baz');
expect(handler1).toHaveBeenCalledWith('baz', event); expect(handler1).toHaveBeenCalledWith('baz', event);
}); });
it('overrides the existing handlers in Node until removed', function() { it('overrides the existing handlers in Node until removed', function() {
const globalEventListeners = {}; const globals = nodeGlobals();
const fakeGlobal = {
process: {
on: (name, listener) => (globalEventListeners[name] = listener),
removeListener: () => {},
listeners: name => globalEventListeners[name],
removeAllListeners: name => (globalEventListeners[name] = [])
}
};
const handler0 = jasmine.createSpy('handler0'); const handler0 = jasmine.createSpy('handler0');
const handler1 = jasmine.createSpy('handler1'); const handler1 = jasmine.createSpy('handler1');
const overrideHandler = jasmine.createSpy('overrideHandler'); const overrideHandler = jasmine.createSpy('overrideHandler');
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal); const errors = new jasmineUnderTest.GlobalErrors(globals.global);
errors.install(); errors.install();
errors.pushListener(handler0); errors.pushListener(handler0);
errors.setOverrideListener(overrideHandler); errors.setOverrideListener(overrideHandler);
errors.pushListener(handler1); errors.pushListener(handler1);
globalEventListeners['uncaughtException'](new Error('foo')); dispatchEvent(globals.listeners, 'uncaughtException', new Error('foo'));
expect(overrideHandler).toHaveBeenCalledWith(new Error('foo')); expect(overrideHandler).toHaveBeenCalledWith(new Error('foo'));
expect(handler0).not.toHaveBeenCalled(); expect(handler0).not.toHaveBeenCalled();
expect(handler1).not.toHaveBeenCalled(); expect(handler1).not.toHaveBeenCalled();
overrideHandler.calls.reset();
errors.removeOverrideListener(); errors.removeOverrideListener();
globalEventListeners['uncaughtException'](new Error('bar')); dispatchEvent(globals.listeners, 'uncaughtException', new Error('bar'));
expect(overrideHandler).not.toHaveBeenCalledWith(new Error('bar')); expect(overrideHandler).not.toHaveBeenCalled();
expect(handler1).toHaveBeenCalledWith(new Error('bar')); expect(handler1).toHaveBeenCalledWith(new Error('bar'));
}); });
it('handles unhandled promise rejections in browsers', function() { it('handles unhandled promise rejections in browsers', function() {
const globalEventListeners = {}; const globals = browserGlobals();
const fakeGlobal = {
addEventListener(name, listener) {
globalEventListeners[name] = listener;
},
removeEventListener() {}
};
const handler = jasmine.createSpy('handler'); const handler = jasmine.createSpy('handler');
const overrideHandler = jasmine.createSpy('overrideHandler'); const overrideHandler = jasmine.createSpy('overrideHandler');
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal); const errors = new jasmineUnderTest.GlobalErrors(globals.global);
errors.install(); errors.install();
errors.pushListener(handler); errors.pushListener(handler);
@@ -461,7 +358,7 @@ describe('GlobalErrors', function() {
const reason = new Error('bar'); const reason = new Error('bar');
globalEventListeners['unhandledrejection']({ reason: reason }); dispatchEvent(globals.listeners, 'unhandledrejection', { reason });
expect(overrideHandler).toHaveBeenCalledWith( expect(overrideHandler).toHaveBeenCalledWith(
jasmine.objectContaining({ jasmine.objectContaining({
@@ -474,32 +371,18 @@ describe('GlobalErrors', function() {
}); });
it('handles unhandled promise rejections in Node', function() { it('handles unhandled promise rejections in Node', function() {
const globalEventListeners = {}; const globals = nodeGlobals();
const fakeGlobal = {
process: {
on(name, listener) {
globalEventListeners[name] = listener;
},
removeListener() {},
listeners(name) {
return globalEventListeners[name];
},
removeAllListeners(name) {
globalEventListeners[name] = null;
}
}
};
const handler0 = jasmine.createSpy('handler0'); const handler0 = jasmine.createSpy('handler0');
const handler1 = jasmine.createSpy('handler1'); const handler1 = jasmine.createSpy('handler1');
const overrideHandler = jasmine.createSpy('overrideHandler'); const overrideHandler = jasmine.createSpy('overrideHandler');
const errors = new jasmineUnderTest.GlobalErrors(fakeGlobal); const errors = new jasmineUnderTest.GlobalErrors(globals.global);
errors.install(); errors.install();
errors.pushListener(handler0); errors.pushListener(handler0);
errors.setOverrideListener(overrideHandler, () => {}); errors.setOverrideListener(overrideHandler, () => {});
errors.pushListener(handler1); errors.pushListener(handler1);
globalEventListeners['unhandledRejection'](new Error('nope')); dispatchEvent(globals.listeners, 'unhandledRejection', new Error('nope'));
expect(overrideHandler).toHaveBeenCalledWith(new Error('nope')); expect(overrideHandler).toHaveBeenCalledWith(new Error('nope'));
expect(handler0).not.toHaveBeenCalled(); expect(handler0).not.toHaveBeenCalled();
@@ -507,7 +390,7 @@ describe('GlobalErrors', function() {
}); });
it('throws if there is already an override handler', function() { it('throws if there is already an override handler', function() {
const errors = new jasmineUnderTest.GlobalErrors(browserGlobal()); const errors = new jasmineUnderTest.GlobalErrors(browserGlobals().global);
errors.setOverrideListener(() => {}, () => {}); errors.setOverrideListener(() => {}, () => {});
expect(function() { expect(function() {
@@ -519,7 +402,7 @@ describe('GlobalErrors', function() {
describe('#removeOverrideListener', function() { describe('#removeOverrideListener', function() {
it("calls the handler's onRemove callback", function() { it("calls the handler's onRemove callback", function() {
const onRemove = jasmine.createSpy('onRemove'); const onRemove = jasmine.createSpy('onRemove');
const errors = new jasmineUnderTest.GlobalErrors(browserGlobal()); const errors = new jasmineUnderTest.GlobalErrors(browserGlobals().global);
errors.setOverrideListener(() => {}, onRemove); errors.setOverrideListener(() => {}, onRemove);
errors.removeOverrideListener(); errors.removeOverrideListener();
@@ -528,42 +411,60 @@ describe('GlobalErrors', function() {
}); });
it('does not throw if there is no handler', function() { it('does not throw if there is no handler', function() {
const errors = new jasmineUnderTest.GlobalErrors(browserGlobal()); const errors = new jasmineUnderTest.GlobalErrors(browserGlobals().global);
expect(() => errors.removeOverrideListener()).not.toThrow(); expect(() => errors.removeOverrideListener()).not.toThrow();
}); });
}); });
function browserGlobal() { function browserGlobals() {
const listeners = { error: [], unhandledrejection: [] };
return { return {
listeners_: { error: [], unhandledrejection: [] }, listeners,
addEventListener(eventName, listener) { global: {
this.listeners_[eventName].push(listener); addEventListener(eventName, listener) {
}, listeners[eventName].push(listener);
removeEventListener(eventName, listener) { },
this.listeners_[eventName] = this.listeners_[eventName].filter( removeEventListener(eventName, listener) {
l => l !== listener listeners[eventName] = listeners[eventName].filter(
); l => l !== listener
);
}
} }
}; };
} }
function dispatchErrorEvent(global, event) { function nodeGlobals() {
expect(global.listeners_.error.length) const listeners = { uncaughtException: [], unhandledRejection: [] };
.withContext('number of error listeners') return {
.toBeGreaterThan(0); listeners,
global: {
for (const l of global.listeners_.error) { process: {
l(event); on(eventName, listener) {
} listeners[eventName].push(listener);
},
removeListener(eventName, listener) {
listeners[eventName] = listeners[eventName].filter(
l => l !== listener
);
},
removeAllListeners(eventName) {
listeners[eventName] = [];
},
listeners(eventName) {
return listeners[eventName];
}
}
}
};
} }
function dispatchUnhandledRejectionEvent(global, event) { function dispatchEvent(listeners, eventName, event) {
expect(global.listeners_.unhandledrejection.length) expect(listeners[eventName].length)
.withContext('number of unhandledrejection listeners') .withContext(`number of ${eventName} listeners`)
.toBeGreaterThan(0); .toBeGreaterThan(0);
for (const l of global.listeners_.unhandledrejection) { for (const l of listeners[eventName]) {
l(event); l(event);
} }
} }