Skip to content

Commit

Permalink
more test coverage for the greater good
Browse files Browse the repository at this point in the history
  • Loading branch information
rashfael committed Jan 15, 2018
1 parent 5c0bdef commit ab60019
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 19 deletions.
23 changes: 11 additions & 12 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class QuidditchClient extends EventEmitter {
setTimeout(() => {
this.emit('reconnecting')
this._createSocket()
}, 3000) // throttle reconnect
}, this._config.reconnectDelay) // throttle reconnect
}
})
this._socket.addEventListener('message', this._processMessage.bind(this))
Expand Down Expand Up @@ -159,7 +159,6 @@ class QuidditchClient extends EventEmitter {
'ot:ack': this._handleOtAck.bind(this),
'ot:delta': this._handleOtDelta.bind(this)
}
console.log(message)
if (actionHandlers[message[0]] === undefined) {
this.emit('message', message)
} else {
Expand All @@ -177,26 +176,26 @@ class QuidditchClient extends EventEmitter {

_popPendingRequest (id) {
const req = this._openRequests[id]
if (!req) {
this.emit('error', `no saved request with id: ${id}`)
} else {
this._openRequests[id] = undefined
return req
}
this._openRequests[id] = undefined
return req
}

_handleError (message) {
const req = this._popPendingRequest(message[1])
if (req === null) {
if (req === null || req === undefined) {
this.emit('error', message[message.length - 1])
} else {
req.deferred.reject(message[2])
}
req.deferred.reject(message[2])
}

_handleCallSuccess (message) {
const req = this._popPendingRequest(message[1])
if (req === null) return // error already emitted in pop
req.deferred.resolve(message[2])
if (req === null || req === undefined) {
this.emit('error', `no saved request with id: ${message.id}`)
} else {
req.deferred.resolve(message[2])
}
}

_handlePong (message) {
Expand Down
4 changes: 4 additions & 0 deletions test/delta/ot.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ describe('Operational Transforms', () => {

expect(delta.apply('Albus P. W. B. Dumbledore')).to.equal('Albus Percival Wulfric Brian Dumbledore')
})

it('should expose static diff function', () => {
Delta.diff('a', 'b')
})
})
31 changes: 26 additions & 5 deletions test/mock-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const chai = require('chai')
const expect = chai.expect

const mock = {
silence: false,
server: null,
drop: false,
otChannels: {},
Expand All @@ -27,9 +28,21 @@ const mock = {
delta: delta.ops,
rev: 7
}]
for (let client of mock.server.clients) {
client.send(JSON.stringify(payload))
}
mock.sendToAll(payload)
},
broadcastRandomAck () {
const payload = ['ot:ack', 'test:nope', {
rev: 7
}]
mock.sendToAll(payload)
},
sendTrashSuccess () {
const payload = ['success', '9999999', {}]
mock.sendToAll(payload)
},
sendTrashError () {
const payload = ['error', '9999999', 'ALARM']
mock.sendToAll(payload)
},
handleMessage (socket, rawMessage) {
if (mock.drop) return // fall silent
Expand All @@ -41,7 +54,9 @@ const mock = {
'generic:increment': mock.handleIncrement,
'ot:delta': mock.handleOtDelta
}
handlers[message[0]](socket, message)
if (handlers[message[0]]) {
handlers[message[0]](socket, message)
}
},
handleAuth (socket, message) {
expect(message[1]).to.contain.all.keys('token')
Expand All @@ -52,6 +67,7 @@ const mock = {
socket.send(JSON.stringify(response))
},
handlePing (socket, message) {
if (mock.silence) return
const response = ['pong', message[1]]
if (socket.readyState !== 1) // socket still open?
return
Expand All @@ -61,7 +77,12 @@ const mock = {
expect(message[1]).to.contain.all.keys('project')
const response = ['joined', {
project: message[1].project,
additionalData: {}
additionalData: {},
channels: {
'initalChannel': {
last_revision: 7
}
}
}]
if (socket.readyState !== 1) // socket still open?
return
Expand Down
76 changes: 74 additions & 2 deletions test/socket.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('Quidditch Client', () => {
})

it('should connect', (done) => {
client = new QuidditchClient(WS_URL, {pingInterval: 300, token: 'hunter2'})
client = new QuidditchClient(WS_URL, {pingInterval: 300, reconnectDelay: 300, token: 'hunter2'})
client.once('open', done)
client.on('error', (error) => {
throw new Error(error) // let us hear the screams
Expand All @@ -47,8 +47,9 @@ describe('Quidditch Client', () => {
it('should join', (done) => {
client.join(42)
client.once('joined', (data) => {
expect(data).to.contain.all.keys('project', 'additionalData')
expect(data).to.contain.all.keys('project', 'additionalData', 'channels')
expect(data.project).to.equal(42)
expect(client._otChannels['initalChannel'].rev).to.equal(7)
done()
})
})
Expand Down Expand Up @@ -79,6 +80,15 @@ describe('Quidditch Client', () => {
})
})

it('should detect timouted generic calls', (done) => {
client.call('generic:invalid', {number: null}, {timeout: 200}).then(() => {
done('should not succeed')
}).catch((error) => {
expect(error.message).to.equal('call timed out')
done()
})
})

it('should send a delta and handle the ack', (done) => {
const channel = 'test:1234'
client.sendDelta(channel, new Delta([{insert: 'Hello World'}]))
Expand Down Expand Up @@ -112,6 +122,17 @@ describe('Quidditch Client', () => {
})
})

it('should receive a delta on a new channel', (done) => {
const channel = 'test:extern'
const delta = new Delta([{insert: 'Hello World'}])
server.broadcastDelta(channel, delta)
client.once('ot:delta', (returnChannel, returnDelta) => {
expect(returnChannel).to.equal(channel)
expect(returnDelta).to.deep.equal(delta)
done()
})
})

it('should receive a delta and transform', (done) => {
const channel = 'test:12345'
const deltaInFlight = new Delta([{insert: 'Hello World'}])
Expand All @@ -127,4 +148,55 @@ describe('Quidditch Client', () => {
})
})
})

it('should buffer multiple deltas', (done) => {
const channel = 'test:123456'
const deltaInFlight = new Delta([{insert: 'Hello World'}])
const moreDelta = new Delta([{retain: 11, insert: ', how'}])
const evenMoreDelta = new Delta([{retain: 16, insert: ' are you?'}])
const bufferDelta = deltaInFlight.compose(evenMoreDelta).compose(moreDelta)
const sendingDelta = new Delta([{insert: 'I AM FIRST'}])
server.broadcastDelta(channel, sendingDelta)
client.sendDelta(channel, deltaInFlight)
client.sendDelta(channel, moreDelta)
client.sendDelta(channel, evenMoreDelta)
client.once('ot:delta', (returnChannel, returnDelta) => {
expect(returnChannel).to.equal(channel)
expect(returnDelta).to.deep.equal(bufferDelta.transform(sendingDelta))
client.once('ot:ack', (returnChannel) => {
expect(returnChannel).to.equal(channel)
done()
})
})
})

it('should not accept random acks', (done) => {
client.removeAllListeners('error')
client.once('error', () => done())
server.broadcastRandomAck()
})

it('should error on unknown message id (success)', (done) => {
client.once('error', () => done())
server.sendTrashSuccess()
})

it('should error on unknown message id (error)', (done) => {
client.once('error', () => done())
server.sendTrashError()
})

it('should detect ping timeouts and reconnect', (done) => {
server.silence = true
client.once('open', () => {
server.silence = false
done()
})
})

it('should close properly', (done) => {
client.once('closed', () => done())
client.once('open', () => done('should not open again'))
client.close()
})
})

0 comments on commit ab60019

Please sign in to comment.