src/modules/observable.test.js
import Observable from './observable.js';
// eslint-disable-next-line no-console
const consoleLogFunction = console.log;
let sut;
describe('Observable', () => {
beforeEach(() => {
sut = new Observable();
// eslint-disable-next-line no-console
console.log = function() {};
});
afterEach(() => {
// eslint-disable-next-line no-console
console.log = consoleLogFunction;
});
it('on must register callback upon invocation', () =>{
const callback = jest.fn();
sut.on('test', callback);
expect(sut._observers['test']).toContain(callback);
});
it('on must fail when passing undefined callback', () =>{
expect(() => sut.on('test', null)).toThrow();
});
it('on must fail when passing undefined type', () =>{
expect(() => sut.on(null, new Function())).toThrow();
});
it('on must silently ignore registering a callback more than once', () =>{
const callback = new Function();
sut.on('test', callback);
sut.on('test', callback);
expect(sut._observers['test'].length).toBe(1);
});
it('notify must make sure callback exists', () =>{
sut.notify('test', {});
expect(sut._observers).not.toContain('test');
});
it('notify must invoke all registered callbacks', () =>{
const callback1 = jest.fn();
const callback2 = jest.fn();
sut.on('test', callback1);
sut.on('test', callback2);
sut.notify('test', {});
expect(callback1.mock.calls.length).toBe(1);
expect(callback2.mock.calls.length).toBe(1);
});
it('notify must pass data to callback', () =>{
const callback = jest.fn();
const data = {value: 'data'};
sut.on('test', callback);
sut.notify('test', data);
expect(callback.mock.calls[0][0]).toBe(data);
});
it('notify must complete notification dispatch despite exceptions in callbacks', () =>{
const callback = jest.fn();
sut.on('test', () => {
throw new Error('Forced exception');
});
sut.on('test', callback);
sut.notify('test', {});
expect(callback.mock.calls.length).toBe(1);
});
it('invoking unregister method must remove callback', () =>{
sut.on('test', jest.fn())();
expect(sut._observers['test'].length).toBe(0);
});
it('invoking unregister method twice must be silently ignored', () =>{
const remove = sut.on('test', jest.fn());
remove();
remove();
expect(sut._observers['test'].length).toBe(0);
});
});