Commit 6a8af948 authored by Sean Hammond's avatar Sean Hammond Committed by GitHub

Merge pull request #305 from hypothesis/annotation-sync-test-to-js

Translate AnnotationSync tests to JavaScript
parents eb22b50b 725cbfcc
EventEmitter = require('tiny-emitter')
AnnotationSync = require('../annotation-sync')
describe 'AnnotationSync', ->
sandbox = sinon.sandbox.create()
publish = null
fakeBridge = null
createAnnotationSync = null
createChannel = -> {call: sandbox.stub()}
options = null
PARENT_WINDOW = 'PARENT_WINDOW'
beforeEach ->
listeners = {}
publish = (method, args...) -> listeners[method](args...)
fakeWindow = parent: PARENT_WINDOW
fakeBridge =
on: sandbox.spy((method, fn) -> listeners[method] = fn)
call: sandbox.stub()
onConnect: sandbox.stub()
links: []
emitter = new EventEmitter();
options =
on: emitter.on.bind(emitter)
emit: emitter.emit.bind(emitter)
createAnnotationSync = ->
new AnnotationSync(fakeBridge, options)
afterEach: -> sandbox.restore()
describe 'channel event handlers', ->
assertBroadcast = (channelEvent, publishEvent) ->
it 'broadcasts the "' + publishEvent + '" event over the local event bus', ->
ann = {id: 1, $tag: 'tag1'}
annSync = createAnnotationSync()
eventStub = sinon.stub()
options.on(publishEvent, eventStub)
publish(channelEvent, {msg: ann}, ->)
assert.calledWith(eventStub, ann)
assertReturnValue = (channelEvent) ->
it 'calls back with a formatted annotation', (done) ->
ann = {id: 1, $tag: 'tag1'}
annSync = createAnnotationSync()
callback = (err, ret) ->
assert.isNull(err)
assert.deepEqual(ret, {tag: 'tag1', msg: ann})
done()
publish(channelEvent, {msg: ann}, callback)
assertCacheState = (channelEvent) ->
it 'removes an existing entry from the cache before the event is triggered', ->
options.emit = -> assert(!annSync.cache['tag1'])
ann = {id: 1, $tag: 'tag1'}
annSync = createAnnotationSync()
annSync.cache['tag1'] = ann
publish(channelEvent, {msg: ann}, ->)
it 'ensures the annotation is inserted in the cache', ->
ann = {id: 1, $tag: 'tag1'}
annSync = createAnnotationSync()
publish(channelEvent, {msg: ann}, ->)
assert.equal(annSync.cache['tag1'], ann)
describe 'the "deleteAnnotation" event', ->
assertBroadcast('deleteAnnotation', 'annotationDeleted')
assertReturnValue('deleteAnnotation')
it 'removes an existing entry from the cache before the event is triggered', ->
options.emit = -> assert(!annSync.cache['tag1'])
ann = {id: 1, $tag: 'tag1'}
annSync = createAnnotationSync()
annSync.cache['tag1'] = ann
publish('deleteAnnotation', {msg: ann}, ->)
it 'removes the annotation from the cache', ->
ann = {id: 1, $tag: 'tag1'}
annSync = createAnnotationSync()
publish('deleteAnnotation', {msg: ann}, ->)
assert(!annSync.cache['tag1'])
describe 'the "loadAnnotations" event', ->
it 'publishes the "annotationsLoaded" event', ->
loadedStub = sinon.stub()
options.on('annotationsLoaded', loadedStub)
annSync = createAnnotationSync()
annotations = [{id: 1, $tag: 'tag1'}, {id: 2, $tag: 'tag2'}, {id: 3, $tag: 'tag3'}]
bodies = ({msg: ann, tag: ann.$tag} for ann in annotations)
publish('loadAnnotations', bodies, ->)
assert.calledWith(loadedStub, annotations)
describe 'event handlers', ->
describe 'the "beforeAnnotationCreated" event', ->
it 'proxies the event over the bridge', ->
ann = {id: 1}
annSync = createAnnotationSync()
options.emit('beforeAnnotationCreated', ann)
assert.called(fakeBridge.call)
assert.calledWith(fakeBridge.call, 'beforeCreateAnnotation',
{msg: ann, tag: ann.$tag}, sinon.match.func)
it 'returns early if the annotation has a tag', ->
ann = {id: 1, $tag: 'tag1'}
annSync = createAnnotationSync()
options.emit('beforeAnnotationCreated', ann)
assert.notCalled(fakeBridge.call)
'use strict';
var EventEmitter = require('tiny-emitter');
var AnnotationSync = require('../annotation-sync');
describe('AnnotationSync', function() {
var createAnnotationSync;
var fakeBridge;
var options;
var publish;
var sandbox = sinon.sandbox.create();
beforeEach(function() {
var emitter = new EventEmitter();
var listeners = {};
createAnnotationSync = function() {
return new AnnotationSync(fakeBridge, options);
};
fakeBridge = {
on: sandbox.spy(function(method, fn) {
listeners[method] = fn;
}),
call: sandbox.stub(),
onConnect: sandbox.stub(),
links: [],
};
options = {
on: emitter.on.bind(emitter),
emit: emitter.emit.bind(emitter),
};
publish = function() {
var method = arguments[0];
var args = [].slice.call(arguments, 1);
listeners[method].apply(listeners, args);
};
});
afterEach(function() {
sandbox.restore();
});
describe('channel event handlers', function() {
describe('the "deleteAnnotation" event', function() {
it('broadcasts the "annotationDeleted" event over the local event bus', function() {
var ann = {id: 1, $tag: 'tag1'};
var eventStub = sinon.stub();
options.on('annotationDeleted', eventStub);
createAnnotationSync();
publish('deleteAnnotation', {msg: ann}, function() {});
assert.calledWith(eventStub, ann);
});
it('calls back with a formatted annotation', function(done) {
var ann = {id: 1, $tag: 'tag1'};
var callback = function(err, ret) {
assert.isNull(err);
assert.deepEqual(ret, {tag: 'tag1', msg: ann});
done();
};
createAnnotationSync();
publish('deleteAnnotation', {msg: ann}, callback);
});
it('removes an existing entry from the cache before the event is triggered', function() {
var ann = {id: 1, $tag: 'tag1'};
var annSync = createAnnotationSync();
annSync.cache.tag1 = ann;
options.emit = function() { assert(!annSync.cache.tag1); };
publish('deleteAnnotation', {msg: ann}, function() {});
});
it('removes the annotation from the cache', function() {
var ann = {id: 1, $tag: 'tag1'};
var annSync = createAnnotationSync();
annSync.cache.tag1 = ann;
publish('deleteAnnotation', {msg: ann}, function() {});
assert(!annSync.cache.tag1);
});
});
describe('the "loadAnnotations" event', function() {
it('publishes the "annotationsLoaded" event', function() {
var annotations = [
{id: 1, $tag: 'tag1'},
{id: 2, $tag: 'tag2'},
{id: 3, $tag: 'tag3'},
];
var bodies = [
{msg: annotations[0], tag: annotations[0].$tag},
{msg: annotations[1], tag: annotations[1].$tag},
{msg: annotations[2], tag: annotations[2].$tag},
];
var loadedStub = sinon.stub();
options.on('annotationsLoaded', loadedStub);
createAnnotationSync();
publish('loadAnnotations', bodies, function() {});
assert.calledWith(loadedStub, annotations);
});
});
});
describe('event handlers', function() {
describe('the "beforeAnnotationCreated" event', function() {
it('proxies the event over the bridge', function() {
var ann = {id: 1};
createAnnotationSync();
options.emit('beforeAnnotationCreated', ann);
assert.called(fakeBridge.call);
assert.calledWith(
fakeBridge.call, 'beforeCreateAnnotation', {msg: ann, tag: ann.$tag},
sinon.match.func);
});
it('returns early if the annotation has a tag', function() {
var ann = {id: 1, $tag: 'tag1'};
createAnnotationSync();
options.emit('beforeAnnotationCreated', ann);
assert.notCalled(fakeBridge.call);
});
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment