portfolio/packages/pouchorm/spec/watcher.spec.js

149 lines
3.7 KiB
JavaScript

import { Watcher } from '../src/watcher.js';
describe('A watcher', () => {
const selector = {};
const opts = {};
it('initially does nothing.', () => {
const db = {
changes: () => fail('Watcher should not call changes until the first subscription.')
};
const w = Watcher(db, selector, opts);
expect().nothing();
});
it('calls PouchDB.change API on the first subscription.', () => {
let state = 0;
const db = {
changes: options => {
expect(state).toEqual(1);
expect(options.live).toEqual(true);
expect(options.since).toEqual('now');
expect(options.selector).toBe(selector);
return db;
},
on: (eventName, callback) => {
expect(['change', 'error'].indexOf(eventName) !== -1).toBeTruthy();
return db;
},
cancel: () => {}
};
const w = Watcher(db, selector, opts);
state = 1;
w(() => fail('Subscription callback should not be called until data changes.'));
});
it('cancels change subscription when the last subscriber unsubscribes', () => {
let state = 0;
const db = {
changes: options => {
expect(state).toEqual(1);
expect(options.live).toEqual(true);
expect(options.since).toEqual('now');
expect(options.selector).toBe(selector);
return db;
},
on: (eventName, callback) => {
expect(['change', 'error'].indexOf(eventName) !== -1).toBeTruthy();
return db;
},
cancel: () => {
expect(state).toEqual(2);
state = 3;
}
};
const w = Watcher(db, selector, opts);
state = 1;
const unsub = w(() => fail('Subscription callback should not be called until data changes.'));
state = 2;
unsub();
expect(state).toEqual(3);
});
it('passes change events to subscribers.', () => {
let state = 0;
const changes = {
234: { id: 234, deleted: false, doc: { _id: 234 } },
34: { id: 34, deleted: true, doc: { _id: 34 } },
4564565: { id: 4564565, deleted: false, doc: { _id: 4564565 } }
};
let sub = null;
const db = {
changes: options => {
expect(state).toEqual(1);
expect(options.live).toEqual(true);
expect(options.since).toEqual('now');
expect(options.selector).toBe(selector);
return db;
},
on: (eventName, callback) => {
if (eventName == 'change') {
sub = callback;
}
expect(['change', 'error'].indexOf(eventName) !== -1).toBeTruthy();
return db;
},
cancel: () => (sub = null)
};
const w = Watcher(db, selector, opts);
state = 1;
w((id, deleted, doc) => {
expect(changes.hasOwnProperty(id)).toBeTruthy();
expect(changes[id].doc).toBe(doc);
expect(changes[id].deleted).toEqual(deleted);
});
Object.values(changes).forEach(sub);
});
it('dumps subscribers when an error event happens.', () => {
let state = 0;
const changes = {
234: { id: 234, deleted: false, doc: { _id: 234 } },
34: { id: 34, deleted: true, doc: { _id: 34 } },
4564565: { id: 4564565, deleted: false, doc: { _id: 4564565 } }
};
let sub = null;
let errorSub = null;
const db = {
changes: options => {
expect(state).toEqual(1);
expect(options.live).toEqual(true);
expect(options.since).toEqual('now');
expect(options.selector).toBe(selector);
return db;
},
on: (eventName, callback) => {
if (eventName == 'change') {
sub = callback;
}
if (eventName == 'error') {
errorSub = callback;
}
expect(['change', 'error'].indexOf(eventName) !== -1).toBeTruthy();
return db;
},
cancel: () => {
sub = null;
errorSub = null;
}
};
const w = Watcher(db, selector, opts);
state = 1;
w(() => fail('Subscription callback should not be called until data changes.'));
const error = new Error('TestError');
try {
errorSub(error);
} catch (e) {
expect(e).toBe(error);
}
Object.values(changes).forEach(sub);
});
});