|
|
|
@ -13,7 +13,7 @@ describe('Websock', function () {
|
|
|
|
|
beforeEach(function () {
|
|
|
|
|
sock = new Websock();
|
|
|
|
|
// skip init
|
|
|
|
|
sock._allocate_buffers();
|
|
|
|
|
sock._allocateBuffers();
|
|
|
|
|
sock._rQ.set(RQ_TEMPLATE);
|
|
|
|
|
sock._rQlen = RQ_TEMPLATE.length;
|
|
|
|
|
});
|
|
|
|
@ -33,51 +33,51 @@ describe('Websock', function () {
|
|
|
|
|
|
|
|
|
|
describe('rQpeek8', function () {
|
|
|
|
|
it('should peek at the next byte without poping it off the queue', function () {
|
|
|
|
|
const bef_len = sock.rQlen;
|
|
|
|
|
const befLen = sock.rQlen;
|
|
|
|
|
const peek = sock.rQpeek8();
|
|
|
|
|
expect(sock.rQpeek8()).to.equal(peek);
|
|
|
|
|
expect(sock.rQlen).to.equal(bef_len);
|
|
|
|
|
expect(sock.rQlen).to.equal(befLen);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('rQshift8()', function () {
|
|
|
|
|
it('should pop a single byte from the receive queue', function () {
|
|
|
|
|
const peek = sock.rQpeek8();
|
|
|
|
|
const bef_len = sock.rQlen;
|
|
|
|
|
const befLen = sock.rQlen;
|
|
|
|
|
expect(sock.rQshift8()).to.equal(peek);
|
|
|
|
|
expect(sock.rQlen).to.equal(bef_len - 1);
|
|
|
|
|
expect(sock.rQlen).to.equal(befLen - 1);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('rQshift16()', function () {
|
|
|
|
|
it('should pop two bytes from the receive queue and return a single number', function () {
|
|
|
|
|
const bef_len = sock.rQlen;
|
|
|
|
|
const befLen = sock.rQlen;
|
|
|
|
|
const expected = (RQ_TEMPLATE[0] << 8) + RQ_TEMPLATE[1];
|
|
|
|
|
expect(sock.rQshift16()).to.equal(expected);
|
|
|
|
|
expect(sock.rQlen).to.equal(bef_len - 2);
|
|
|
|
|
expect(sock.rQlen).to.equal(befLen - 2);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('rQshift32()', function () {
|
|
|
|
|
it('should pop four bytes from the receive queue and return a single number', function () {
|
|
|
|
|
const bef_len = sock.rQlen;
|
|
|
|
|
const befLen = sock.rQlen;
|
|
|
|
|
const expected = (RQ_TEMPLATE[0] << 24) +
|
|
|
|
|
(RQ_TEMPLATE[1] << 16) +
|
|
|
|
|
(RQ_TEMPLATE[2] << 8) +
|
|
|
|
|
RQ_TEMPLATE[3];
|
|
|
|
|
expect(sock.rQshift32()).to.equal(expected);
|
|
|
|
|
expect(sock.rQlen).to.equal(bef_len - 4);
|
|
|
|
|
expect(sock.rQlen).to.equal(befLen - 4);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('rQshiftStr', function () {
|
|
|
|
|
it('should shift the given number of bytes off of the receive queue and return a string', function () {
|
|
|
|
|
const bef_len = sock.rQlen;
|
|
|
|
|
const bef_rQi = sock.rQi;
|
|
|
|
|
const befLen = sock.rQlen;
|
|
|
|
|
const befRQi = sock.rQi;
|
|
|
|
|
const shifted = sock.rQshiftStr(3);
|
|
|
|
|
expect(shifted).to.be.a('string');
|
|
|
|
|
expect(shifted).to.equal(String.fromCharCode.apply(null, Array.prototype.slice.call(new Uint8Array(RQ_TEMPLATE.buffer, bef_rQi, 3))));
|
|
|
|
|
expect(sock.rQlen).to.equal(bef_len - 3);
|
|
|
|
|
expect(shifted).to.equal(String.fromCharCode.apply(null, Array.prototype.slice.call(new Uint8Array(RQ_TEMPLATE.buffer, befRQi, 3))));
|
|
|
|
|
expect(sock.rQlen).to.equal(befLen - 3);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should shift the entire rest of the queue off if no length is given', function () {
|
|
|
|
@ -112,12 +112,12 @@ describe('Websock', function () {
|
|
|
|
|
|
|
|
|
|
describe('rQshiftBytes', function () {
|
|
|
|
|
it('should shift the given number of bytes of the receive queue and return an array', function () {
|
|
|
|
|
const bef_len = sock.rQlen;
|
|
|
|
|
const bef_rQi = sock.rQi;
|
|
|
|
|
const befLen = sock.rQlen;
|
|
|
|
|
const befRQi = sock.rQi;
|
|
|
|
|
const shifted = sock.rQshiftBytes(3);
|
|
|
|
|
expect(shifted).to.be.an.instanceof(Uint8Array);
|
|
|
|
|
expect(shifted).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, bef_rQi, 3));
|
|
|
|
|
expect(sock.rQlen).to.equal(bef_len - 3);
|
|
|
|
|
expect(shifted).to.array.equal(new Uint8Array(RQ_TEMPLATE.buffer, befRQi, 3));
|
|
|
|
|
expect(sock.rQlen).to.equal(befLen - 3);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should shift the entire rest of the queue off if no length is given', function () {
|
|
|
|
@ -132,9 +132,9 @@ describe('Websock', function () {
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should not modify the receive queue', function () {
|
|
|
|
|
const bef_len = sock.rQlen;
|
|
|
|
|
const befLen = sock.rQlen;
|
|
|
|
|
sock.rQslice(0, 2);
|
|
|
|
|
expect(sock.rQlen).to.equal(bef_len);
|
|
|
|
|
expect(sock.rQlen).to.equal(befLen);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should return an array containing the given slice of the receive queue', function () {
|
|
|
|
@ -198,7 +198,7 @@ describe('Websock', function () {
|
|
|
|
|
sock._websocket.readyState = WebSocket.OPEN;
|
|
|
|
|
sock._sQ = new Uint8Array([1, 2, 3]);
|
|
|
|
|
sock._sQlen = 3;
|
|
|
|
|
const encoded = sock._encode_message();
|
|
|
|
|
const encoded = sock._encodeMessage();
|
|
|
|
|
|
|
|
|
|
sock.flush();
|
|
|
|
|
expect(sock._websocket.send).to.have.been.calledOnce;
|
|
|
|
@ -232,22 +232,22 @@ describe('Websock', function () {
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('send_string', function () {
|
|
|
|
|
describe('sendString', function () {
|
|
|
|
|
beforeEach(function () {
|
|
|
|
|
sock.send = sinon.spy();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should call send after converting the string to an array', function () {
|
|
|
|
|
sock.send_string("\x01\x02\x03");
|
|
|
|
|
sock.sendString("\x01\x02\x03");
|
|
|
|
|
expect(sock.send).to.have.been.calledWith([1, 2, 3]);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('lifecycle methods', function () {
|
|
|
|
|
let old_WS;
|
|
|
|
|
let oldWS;
|
|
|
|
|
before(function () {
|
|
|
|
|
old_WS = WebSocket;
|
|
|
|
|
oldWS = WebSocket;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let sock;
|
|
|
|
@ -255,10 +255,10 @@ describe('Websock', function () {
|
|
|
|
|
sock = new Websock();
|
|
|
|
|
// eslint-disable-next-line no-global-assign
|
|
|
|
|
WebSocket = sinon.spy();
|
|
|
|
|
WebSocket.OPEN = old_WS.OPEN;
|
|
|
|
|
WebSocket.CONNECTING = old_WS.CONNECTING;
|
|
|
|
|
WebSocket.CLOSING = old_WS.CLOSING;
|
|
|
|
|
WebSocket.CLOSED = old_WS.CLOSED;
|
|
|
|
|
WebSocket.OPEN = oldWS.OPEN;
|
|
|
|
|
WebSocket.CONNECTING = oldWS.CONNECTING;
|
|
|
|
|
WebSocket.CLOSING = oldWS.CLOSING;
|
|
|
|
|
WebSocket.CLOSED = oldWS.CLOSED;
|
|
|
|
|
|
|
|
|
|
WebSocket.prototype.binaryType = 'arraybuffer';
|
|
|
|
|
});
|
|
|
|
@ -306,30 +306,30 @@ describe('Websock', function () {
|
|
|
|
|
expect(sock._websocket.close).not.to.have.been.called;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should reset onmessage to not call _recv_message', function () {
|
|
|
|
|
sinon.spy(sock, '_recv_message');
|
|
|
|
|
it('should reset onmessage to not call _recvMessage', function () {
|
|
|
|
|
sinon.spy(sock, '_recvMessage');
|
|
|
|
|
sock.close();
|
|
|
|
|
sock._websocket.onmessage(null);
|
|
|
|
|
try {
|
|
|
|
|
expect(sock._recv_message).not.to.have.been.called;
|
|
|
|
|
expect(sock._recvMessage).not.to.have.been.called;
|
|
|
|
|
} finally {
|
|
|
|
|
sock._recv_message.restore();
|
|
|
|
|
sock._recvMessage.restore();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('event handlers', function () {
|
|
|
|
|
beforeEach(function () {
|
|
|
|
|
sock._recv_message = sinon.spy();
|
|
|
|
|
sock._recvMessage = sinon.spy();
|
|
|
|
|
sock.on('open', sinon.spy());
|
|
|
|
|
sock.on('close', sinon.spy());
|
|
|
|
|
sock.on('error', sinon.spy());
|
|
|
|
|
sock.open('ws://');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should call _recv_message on a message', function () {
|
|
|
|
|
it('should call _recvMessage on a message', function () {
|
|
|
|
|
sock._websocket.onmessage(null);
|
|
|
|
|
expect(sock._recv_message).to.have.been.calledOnce;
|
|
|
|
|
expect(sock._recvMessage).to.have.been.calledOnce;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should call the open event handler on opening', function () {
|
|
|
|
@ -350,7 +350,7 @@ describe('Websock', function () {
|
|
|
|
|
|
|
|
|
|
after(function () {
|
|
|
|
|
// eslint-disable-next-line no-global-assign
|
|
|
|
|
WebSocket = old_WS;
|
|
|
|
|
WebSocket = oldWS;
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
@ -358,13 +358,13 @@ describe('Websock', function () {
|
|
|
|
|
let sock;
|
|
|
|
|
beforeEach(function () {
|
|
|
|
|
sock = new Websock();
|
|
|
|
|
sock._allocate_buffers();
|
|
|
|
|
sock._allocateBuffers();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should support adding binary Uint8Array data to the receive queue', function () {
|
|
|
|
|
const msg = { data: new Uint8Array([1, 2, 3]) };
|
|
|
|
|
sock._mode = 'binary';
|
|
|
|
|
sock._recv_message(msg);
|
|
|
|
|
sock._recvMessage(msg);
|
|
|
|
|
expect(sock.rQshiftStr(3)).to.equal('\x01\x02\x03');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
@ -372,7 +372,7 @@ describe('Websock', function () {
|
|
|
|
|
sock._eventHandlers.message = sinon.spy();
|
|
|
|
|
const msg = { data: new Uint8Array([1, 2, 3]).buffer };
|
|
|
|
|
sock._mode = 'binary';
|
|
|
|
|
sock._recv_message(msg);
|
|
|
|
|
sock._recvMessage(msg);
|
|
|
|
|
expect(sock._eventHandlers.message).to.have.been.calledOnce;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
@ -380,7 +380,7 @@ describe('Websock', function () {
|
|
|
|
|
sock._eventHandlers.message = sinon.spy();
|
|
|
|
|
const msg = { data: new Uint8Array([]).buffer };
|
|
|
|
|
sock._mode = 'binary';
|
|
|
|
|
sock._recv_message(msg);
|
|
|
|
|
sock._recvMessage(msg);
|
|
|
|
|
expect(sock._eventHandlers.message).not.to.have.been.called;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
@ -391,7 +391,7 @@ describe('Websock', function () {
|
|
|
|
|
sock.rQi = 6;
|
|
|
|
|
const msg = { data: new Uint8Array([1, 2, 3]).buffer };
|
|
|
|
|
sock._mode = 'binary';
|
|
|
|
|
sock._recv_message(msg);
|
|
|
|
|
sock._recvMessage(msg);
|
|
|
|
|
expect(sock._rQlen).to.equal(0);
|
|
|
|
|
expect(sock.rQi).to.equal(0);
|
|
|
|
|
});
|
|
|
|
@ -403,7 +403,7 @@ describe('Websock', function () {
|
|
|
|
|
sock.rQi = 10;
|
|
|
|
|
const msg = { data: new Uint8Array([1, 2]).buffer };
|
|
|
|
|
sock._mode = 'binary';
|
|
|
|
|
sock._recv_message(msg);
|
|
|
|
|
sock._recvMessage(msg);
|
|
|
|
|
expect(sock._rQlen).to.equal(12);
|
|
|
|
|
expect(sock.rQi).to.equal(0);
|
|
|
|
|
});
|
|
|
|
@ -415,7 +415,7 @@ describe('Websock', function () {
|
|
|
|
|
sock._rQbufferSize = 20;
|
|
|
|
|
const msg = { data: new Uint8Array(30).buffer };
|
|
|
|
|
sock._mode = 'binary';
|
|
|
|
|
sock._recv_message(msg);
|
|
|
|
|
sock._recvMessage(msg);
|
|
|
|
|
expect(sock._rQlen).to.equal(30);
|
|
|
|
|
expect(sock.rQi).to.equal(0);
|
|
|
|
|
expect(sock._rQ.length).to.equal(240); // keep the invariant that rQbufferSize / 8 >= rQlen
|
|
|
|
@ -428,7 +428,7 @@ describe('Websock', function () {
|
|
|
|
|
sock._rQbufferSize = 20;
|
|
|
|
|
const msg = { data: new Uint8Array(6).buffer };
|
|
|
|
|
sock._mode = 'binary';
|
|
|
|
|
sock._recv_message(msg);
|
|
|
|
|
sock._recvMessage(msg);
|
|
|
|
|
expect(sock._rQlen).to.equal(6);
|
|
|
|
|
expect(sock.rQi).to.equal(0);
|
|
|
|
|
expect(sock._rQ.length).to.equal(48);
|
|
|
|
@ -450,7 +450,7 @@ describe('Websock', function () {
|
|
|
|
|
it('should only send the send queue up to the send queue length', function () {
|
|
|
|
|
sock._sQ = new Uint8Array([1, 2, 3, 4, 5]);
|
|
|
|
|
sock._sQlen = 3;
|
|
|
|
|
const res = sock._encode_message();
|
|
|
|
|
const res = sock._encodeMessage();
|
|
|
|
|
expect(res).to.array.equal(new Uint8Array([1, 2, 3]));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|