Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
Choose a Base Repository
hypothesis/h
40a/h
AFDudley/h
BigBlueHat/h
BinaryStars/h
CCH543/h
Cinemacloud/h
Ericgood/h
FTG-003/h
Forethinker/h
GratefulTony/h
HGldJ1966/h
JJediny/h
John-Williams/h
Laurian/h
LittleFancy/h
MattyQ/h
Mishkin2015/h
RichardLitt/h
Staffan1/h
SteelWagstaff/h
TowerBR/h
VanyTang/h
abigailricarte/h
ackermann/h
alecchap/h
alesarrett/h
alexsegura/h
almereyda/h
alon/h
andzi/h
angelicxsoul/h
ansmoh/h
apurvajalit/h
arjunvasan/h
asdevor/h
bZichett/h
badgettrg/Webmarks
balmas/h
balupton/h
bbarker/h
bennlich/h
benthor/h
blakewest/h
bogste/h
bradparks/h
brittanystoroz/h
buiquangchien/h
cdchapman/h
charblanc/h
chowsamihq/h
chr7stos/Webmarks
chrber/h
chrismPssina/h
christinaphamAD/h
cmbirk/h
codeaudit/h
coolcool21/h
cove/h
csillag/h
danjimilk/h
dannyhope/h
daredream/h
davidmcclure/h
dennisplucinik/h
dezynetechnologies/h
diegodlh/h
djcun95/h
donsequitur/h
edsu/h
eiro10/h
emckean/h
ercchy/h
eshellman/h
fangang123/h
fchasen/h
fcrimins/h
fhirsch/h
ficolo/h
fragkopoulos/h
gauravkeerthi/h
geass/h
gergely-ujvari/h
gitter-badger/h
gnott/h
gobengo/h
gorinovic/h
gus3000/h
hashin/h
helemaalbigt/h
hmstepanek/h
hwasiti/h
hylhero/h
hyperstudio/h
iHDeveloper/h
imeysam/h
jackspaceBerkeley/h
jarey/h
jasdeep/h
jason790/h
jasonzou/j
jazahn/h
jccr/h
jean/h
jeka57/h
jeremydean/h
jermnelson/h
jibe-b/h
jnishiyama/h
jojksd/h
jpadilla/h
jtremback/h
judell/h
juli-so/h
kabacs/h
karissa/h
kaushikvijay/h
kaydoh/h
kill4uk/h
klopiinas/h
klrkdekira/h
koulihong311/h
krassif/h
krstnkngs/h
leoqmp/h
linhua55/h
lucadealfaro/h
lyspooner/h
lyzadanger/h
m1yag1/h
magee/h
mambocab/h
manunymous/h
maraino/h
mari-ja/h
markbarratt/h
martinq/h
mbbaig/h
mcarv63/h
meawoppl/h
meflyup/h
metasj/h
mgasner/h
mgax/h
mollycr/h
mrchrisadams/h
mrienstra/h
mshavlovsky/h
muddasani/h
nagyist/hyphothesis-h
nagyistoce/hypothesis-h
nanxio/h
neozhangthe1/h
ningyifan/h
nkingsley/h
nlholdem/h
nlisgo/h
noscripter/h
nshkuro/h
odnodn/h
oliversauter/h
openbizgit/h
opengovfoundation/h
openstax/hypothesis-server
ouroboros8/h
pablomarti/h
pamo/h
philipn/h
philschatz/h
pinballwonder/h
plainspace/h
raowl/h
rickyhan/h
rmoorman/h
rmtsukuru/h
robertknight/h
rowhit/h
rsarxiv/h
saakaifoundry/h
samrose/h
scharf/h
shepazu/h
sherah/h
shofheinz/h
soapdog/h
ssin122/test-h
st-fresh/h
stuk88/h
sylvanmist/h
tetratorus/h
tilgovi/h
tomnar/h
trivenews/h
truthadjustr/h
utngz/h
voidfiles/h
wenchen/h
yargevad/h
yumatch/h
zshen777/h
Nothing to show
Choose a Head Repository
hypothesis/h
40a/h
AFDudley/h
BigBlueHat/h
BinaryStars/h
CCH543/h
Cinemacloud/h
Ericgood/h
FTG-003/h
Forethinker/h
GratefulTony/h
HGldJ1966/h
JJediny/h
John-Williams/h
Laurian/h
LittleFancy/h
MattyQ/h
Mishkin2015/h
RichardLitt/h
Staffan1/h
SteelWagstaff/h
TowerBR/h
VanyTang/h
abigailricarte/h
ackermann/h
alecchap/h
alesarrett/h
alexsegura/h
almereyda/h
alon/h
andzi/h
angelicxsoul/h
ansmoh/h
apurvajalit/h
arjunvasan/h
asdevor/h
bZichett/h
badgettrg/Webmarks
balmas/h
balupton/h
bbarker/h
bennlich/h
benthor/h
blakewest/h
bogste/h
bradparks/h
brittanystoroz/h
buiquangchien/h
cdchapman/h
charblanc/h
chowsamihq/h
chr7stos/Webmarks
chrber/h
chrismPssina/h
christinaphamAD/h
cmbirk/h
codeaudit/h
coolcool21/h
cove/h
csillag/h
danjimilk/h
dannyhope/h
daredream/h
davidmcclure/h
dennisplucinik/h
dezynetechnologies/h
diegodlh/h
djcun95/h
donsequitur/h
edsu/h
eiro10/h
emckean/h
ercchy/h
eshellman/h
fangang123/h
fchasen/h
fcrimins/h
fhirsch/h
ficolo/h
fragkopoulos/h
gauravkeerthi/h
geass/h
gergely-ujvari/h
gitter-badger/h
gnott/h
gobengo/h
gorinovic/h
gus3000/h
hashin/h
helemaalbigt/h
hmstepanek/h
hwasiti/h
hylhero/h
hyperstudio/h
iHDeveloper/h
imeysam/h
jackspaceBerkeley/h
jarey/h
jasdeep/h
jason790/h
jasonzou/j
jazahn/h
jccr/h
jean/h
jeka57/h
jeremydean/h
jermnelson/h
jibe-b/h
jnishiyama/h
jojksd/h
jpadilla/h
jtremback/h
judell/h
juli-so/h
kabacs/h
karissa/h
kaushikvijay/h
kaydoh/h
kill4uk/h
klopiinas/h
klrkdekira/h
koulihong311/h
krassif/h
krstnkngs/h
leoqmp/h
linhua55/h
lucadealfaro/h
lyspooner/h
lyzadanger/h
m1yag1/h
magee/h
mambocab/h
manunymous/h
maraino/h
mari-ja/h
markbarratt/h
martinq/h
mbbaig/h
mcarv63/h
meawoppl/h
meflyup/h
metasj/h
mgasner/h
mgax/h
mollycr/h
mrchrisadams/h
mrienstra/h
mshavlovsky/h
muddasani/h
nagyist/hyphothesis-h
nagyistoce/hypothesis-h
nanxio/h
neozhangthe1/h
ningyifan/h
nkingsley/h
nlholdem/h
nlisgo/h
noscripter/h
nshkuro/h
odnodn/h
oliversauter/h
openbizgit/h
opengovfoundation/h
openstax/hypothesis-server
ouroboros8/h
pablomarti/h
pamo/h
philipn/h
philschatz/h
pinballwonder/h
plainspace/h
raowl/h
rickyhan/h
rmoorman/h
rmtsukuru/h
robertknight/h
rowhit/h
rsarxiv/h
saakaifoundry/h
samrose/h
scharf/h
shepazu/h
sherah/h
shofheinz/h
soapdog/h
ssin122/test-h
st-fresh/h
stuk88/h
sylvanmist/h
tetratorus/h
tilgovi/h
tomnar/h
trivenews/h
truthadjustr/h
utngz/h
voidfiles/h
wenchen/h
yargevad/h
yumatch/h
zshen777/h
Nothing to show
  • 1 commit
  • 2 files changed
  • 0 commit comments
  • 1 contributor
Showing with 193 additions and 19 deletions.
  1. +4 −9 h/static/scripts/annotation-sync.coffee
  2. +189 −10 tests/js/annotation-sync-test.coffee
@@ -106,32 +106,27 @@ class AnnotationSync
'beforeAnnotationCreated': (event, annotation) ->
return if annotation.$$tag?
this._mkCallRemotelyAndParseResults('beforeCreateAnnotation')(annotation)
this
'annotationCreated': (event, annotation) ->
return unless annotation.$$tag? and @cache[annotation.$$tag]
this._mkCallRemotelyAndParseResults('createAnnotation')(annotation)
this
'annotationUpdated': (event, annotation) ->
return unless annotation.$$tag? and @cache[annotation.$$tag]
this._mkCallRemotelyAndParseResults('updateAnnotation')(annotation)
this
'annotationDeleted': (event, annotation) ->
return unless annotation.$$tag? and @cache[annotation.$$tag]
onFailure = (err) =>
delete @cache[annotation.$$tag] unless err
this._mkCallRemotelyAndParseResults('deleteAnnotation', onFailure)(annotation)
this
'annotationsLoaded': (event, annotations) ->
annotations = (this._format a for a in annotations when not a.$$tag)
return unless annotations.length
this._notify
bodies = (this._format a for a in annotations when not a.$$tag)
return unless bodies.length
@bridge.notify
method: 'loadAnnotations'
params: annotations
this
params: bodies
_syncCache: (channel) ->
# Synchronise (here to there) the items in our cache
@@ -11,30 +11,34 @@ describe 'AnnotationSync', ->
PARENT_WINDOW = 'PARENT_WINDOW'
beforeEach module('h')
beforeEach inject (AnnotationSync) ->
beforeEach inject (AnnotationSync, $rootScope) ->
listeners = {}
publish = ({method, params}) -> listeners[method]('ctx', params)
fakeWindow = parent: PARENT_WINDOW
fakeBridge =
on: sandbox.spy((method, fn) -> listeners[method] = fn)
call: sandbox.stub()
notify: sandbox.stub()
onConnect: sandbox.stub()
links: [
{window: PARENT_WINDOW, channel: createChannel()}
{window: 'ANOTHER_WINDOW', channel: createChannel()}
{window: 'THIRD_WINDOW', channel: createChannel()}
]
# TODO: Fix this hack to remove pre-existing bound listeners.
$rootScope.$$listeners = []
options =
on: sandbox.stub()
emit: sandbox.stub()
on: sandbox.spy($rootScope.$on.bind($rootScope))
emit: sandbox.spy($rootScope.$emit.bind($rootScope))
createAnnotationSync = ->
new AnnotationSync(options, fakeBridge)
afterEach: -> sandbox.restore()
describe 'on bridge connection', ->
describe 'the bridge connection', ->
it 'sends over the current annotation cache', ->
ann = {id: 1, $$tag: 'tag1'}
annSync = createAnnotationSync()
@@ -107,23 +111,23 @@ describe 'AnnotationSync', ->
assert.equal(annSync.cache['tag1'], ann)
describe 'on "beforeCreateAnnotation" event', ->
describe 'the "beforeCreateAnnotation" event', ->
assertBroadcast('beforeCreateAnnotation', 'beforeAnnotationCreated')
assertReturnValue('beforeCreateAnnotation')
assertCacheState('beforeCreateAnnotation')
describe 'on "createAnnotation" event', ->
describe 'the "createAnnotation" event', ->
assertBroadcast('createAnnotation', 'annotationCreated')
assertReturnValue('createAnnotation')
assertCacheState('createAnnotation')
describe 'on "updateAnnotation" event', ->
describe 'the "updateAnnotation" event', ->
assertBroadcast('updateAnnotation', 'annotationUpdated')
assertBroadcast('updateAnnotation', 'beforeAnnotationUpdated')
assertReturnValue('updateAnnotation')
assertCacheState('updateAnnotation')
describe 'on "deleteAnnotation" event', ->
describe 'the "deleteAnnotation" event', ->
assertBroadcast('deleteAnnotation', 'annotationDeleted')
assertReturnValue('deleteAnnotation')
@@ -144,7 +148,7 @@ describe 'AnnotationSync', ->
assert(!annSync.cache['tag1'])
describe 'on "sync" event', ->
describe 'the "sync" event', ->
it 'returns an array of parsed and formatted annotations', ->
options.parser = sinon.spy((x) -> x)
options.formatter = sinon.spy((x) -> x)
@@ -158,7 +162,7 @@ describe 'AnnotationSync', ->
assert.called(options.parser)
assert.called(options.formatter)
describe 'on "loadAnnotations" event', ->
describe 'the "loadAnnotations" event', ->
it 'publishes the "loadAnnotations" event with parsed annotations', ->
options.parser = sinon.spy((x) -> x)
annSync = createAnnotationSync()
@@ -170,3 +174,178 @@ describe 'AnnotationSync', ->
assert.called(options.parser)
assert.calledWith(options.emit, 'loadAnnotations', annotations)
describe 'application 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, {
method: 'beforeCreateAnnotation',
params: {msg: ann, tag: ann.$$tag},
callback: 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)
describe 'the "annotationCreated" event', ->
it 'proxies the event over the bridge', ->
ann = {id: 1, $$tag: 'tag1'}
annSync = createAnnotationSync()
annSync.cache.tag1 = ann
options.emit('annotationCreated', ann)
assert.called(fakeBridge.call)
assert.calledWith(fakeBridge.call, {
method: 'createAnnotation',
params: {msg: ann, tag: ann.$$tag},
callback: sinon.match.func
})
it 'returns early if the annotation has a tag but is not cached', ->
ann = {id: 1, $$tag: 'tag1'}
annSync = createAnnotationSync()
options.emit('annotationCreated', ann)
assert.notCalled(fakeBridge.call)
it 'returns early if the annotation has no tag', ->
ann = {id: 1}
annSync = createAnnotationSync()
options.emit('annotationCreated', ann)
assert.notCalled(fakeBridge.call)
describe 'the "annotationUpdated" event', ->
it 'proxies the event over the bridge', ->
ann = {id: 1, $$tag: 'tag1'}
annSync = createAnnotationSync()
annSync.cache.tag1 = ann
options.emit('annotationUpdated', ann)
assert.called(fakeBridge.call)
assert.calledWith(fakeBridge.call, {
method: 'updateAnnotation',
params: {msg: ann, tag: ann.$$tag},
callback: sinon.match.func
})
it 'returns early if the annotation has a tag but is not cached', ->
ann = {id: 1, $$tag: 'tag1'}
annSync = createAnnotationSync()
options.emit('annotationUpdated', ann)
assert.notCalled(fakeBridge.call)
it 'returns early if the annotation has no tag', ->
ann = {id: 1}
annSync = createAnnotationSync()
options.emit('annotationUpdated', ann)
assert.notCalled(fakeBridge.call)
describe 'the "annotationDeleted" event', ->
it 'proxies the event over the bridge', ->
ann = {id: 1, $$tag: 'tag1'}
annSync = createAnnotationSync()
annSync.cache.tag1 = ann
options.emit('annotationDeleted', ann)
assert.called(fakeBridge.call)
assert.calledWith(fakeBridge.call, {
method: 'deleteAnnotation',
params: {msg: ann, tag: ann.$$tag},
callback: sinon.match.func
})
it 'parses the result returned by the call', ->
ann = {id: 1, $$tag: 'tag1'}
options.parser = sinon.spy((x) -> x)
annSync = createAnnotationSync()
annSync.cache.tag1 = ann
options.emit('annotationDeleted', ann)
body = {msg: {}, tag: 'tag1'}
fakeBridge.call.yieldTo('callback', null, [body])
assert.called(options.parser)
assert.calledWith(options.parser, {})
it 'removes the annotation from the cache on success', ->
ann = {id: 1, $$tag: 'tag1'}
annSync = createAnnotationSync()
annSync.cache.tag1 = ann
options.emit('annotationDeleted', ann)
fakeBridge.call.yieldTo('callback', null, [])
assert.isUndefined(annSync.cache.tag1)
it 'does not remove the annotation from the cache if an error occurs', ->
ann = {id: 1, $$tag: 'tag1'}
annSync = createAnnotationSync()
annSync.cache.tag1 = ann
options.emit('annotationDeleted', ann)
fakeBridge.call.yieldTo('callback', new Error('Error'), [])
assert.equal(annSync.cache.tag1, ann)
it 'returns early if the annotation has a tag but is not cached', ->
ann = {id: 1, $$tag: 'tag1'}
annSync = createAnnotationSync()
options.emit('annotationDeleted', ann)
assert.notCalled(fakeBridge.call)
it 'returns early if the annotation has no tag', ->
ann = {id: 1}
annSync = createAnnotationSync()
options.emit('annotationDeleted', ann)
assert.notCalled(fakeBridge.call)
describe 'the "annotationsLoaded" event', ->
it 'formats the provided annotations', ->
annotations = [{id: 1}, {id: 2}, {id: 3}]
options.formatter = sinon.spy((x) -> x)
annSync = createAnnotationSync()
options.emit('annotationsLoaded', annotations)
assert.calledWith(options.formatter, {id: 1})
assert.calledWith(options.formatter, {id: 2})
assert.calledWith(options.formatter, {id: 3})
it 'sends the annotations over the bridge', ->
annotations = [{id: 1}, {id: 2}, {id: 3}]
options.formatter = sinon.spy((x) -> x)
annSync = createAnnotationSync()
options.emit('annotationsLoaded', annotations)
assert.called(fakeBridge.notify)
assert.calledWith(fakeBridge.notify, {
method: 'loadAnnotations',
params: {msg: a, tag: a.$$tag} for a in annotations
})
it 'does not send annotations that have already been tagged', ->
annotations = [{id: 1, $$tag: 'tag1'}, {id: 2, $$tag: 'tag2'}, {id: 3}]
options.formatter = sinon.spy((x) -> x)
annSync = createAnnotationSync()
options.emit('annotationsLoaded', annotations)
assert.called(fakeBridge.notify)
assert.calledWith(fakeBridge.notify, {
method: 'loadAnnotations',
params: [{msg: annotations[2], tag: annotations[2].$$tag}]
})
it 'returns early if no annotations are loaded', ->
annSync = createAnnotationSync()
options.emit('annotationsLoaded', [])
assert.notCalled(fakeBridge.notify)

No commit comments for this range