mulocal-socket
Version:
Local socket emulation for mudb
282 lines (243 loc) • 8.69 kB
text/typescript
import test = require('tape');
import { createLocalSocket, createLocalSocketServer } from '../';
import { MuSocketState, MuSocketServerState } from 'mudb/socket';
function noop () {}
function id () {
return Math.random().toString(36).substr(2);
}
test('socket initial state', (t) => {
const socket = createLocalSocket({
sessionId: id(),
server: createLocalSocketServer(),
});
t.equals(socket.state, MuSocketState.INIT, 'should be INIT');
t.end();
});
test('socket.open() - when INIT', (t) => {
t.plan(5);
let unreliableMessageFromClient = 0;
let reliableMessagesFromClient = 0;
const server = createLocalSocketServer();
server.start({
ready: noop,
connection: (serverSocket) => serverSocket.open({
ready: () => {
// attempt to send messages from client socket when it is not OPEN
clientSocket.send('unreliable message from client', true);
clientSocket.send('another unreliable message from client', true);
clientSocket.send('reliable message from client', false);
clientSocket.send('another reliable message from client', false);
clientSocket.open({
ready: () => {
t.equals(clientSocket.state, MuSocketState.OPEN, 'should change socket state to OPEN');
t.equals(unreliableMessageFromClient, 2, 'should send pending unreliable messages');
t.equals(reliableMessagesFromClient, 2, 'should send pending reliable messages');
clientSocket._duplex.send('unreliable message from server');
},
message: () => {
t.pass('should set message handler');
clientSocket.close();
},
close: (error) => t.equals(error, undefined, 'should set close handler'),
});
},
message: (_, unreliable) => {
if (unreliable) {
++unreliableMessageFromClient;
} else {
++reliableMessagesFromClient;
}
},
close: noop,
}),
close: noop,
});
const clientSocket = createLocalSocket({
sessionId: id(),
server,
});
});
test('socket.open() - when OPEN', (t) => {
t.plan(1);
const socket = createLocalSocket({
sessionId: id(),
server: createLocalSocketServer(),
});
socket.open({
// attempt to open socket when it is already OPEN
ready: () => socket.open({
ready: noop,
message: noop,
close: noop,
}),
message: noop,
close: (error) => t.equals(typeof error, 'string', 'should invoke close handler with error message'),
});
});
test('socket.open() - when CLOSED', (t) => {
t.plan(1);
const socket = createLocalSocket({
sessionId: id(),
server: createLocalSocketServer(),
});
socket.open({
ready: () => {
socket.close();
// attempt to open socket when it is already CLOSED
socket.open({
ready: noop,
message: noop,
close: noop,
});
},
message: noop,
close: (error) => {
if (error) {
t.equals(typeof error, 'string', 'should invoke close handler with error message');
}
},
});
});
test('socket.send() - when OPEN', (t) => {
t.plan(1);
const server = createLocalSocketServer();
server.start({
ready: noop,
connection: (serverSocket) => serverSocket.open({
// open client socket after server socket is OPEN
ready: () => clientSocket.open({
// send message from client socket when it is OPEN
ready: () => clientSocket.send('unreliable message from client'),
message: noop,
close: noop,
}),
message: () => t.pass('should send messages to server'),
close: noop,
}),
close: noop,
});
const clientSocket = createLocalSocket({
sessionId: id(),
server,
});
});
test('socket.send() - when INIT', (t) => {
t.plan(2);
let unreliableMessagesReceived = 0;
let reliableMessagesReceived = 0;
const server = createLocalSocketServer();
server.start({
ready: noop,
connection: (serverSocket) => serverSocket.open({
// when server socket is OPEN
ready: () => {
// attempt to send messages when client socket is INIT
// messages are pending until socket is OPEN
clientSocket.send('unreliable message', true);
clientSocket.send('another unreliable message', true);
clientSocket.send('reliable message', false);
clientSocket.send('another reliable message', false);
clientSocket.open({
ready: () => {
// pending messages are sent when client socket is OPEN
t.equals(unreliableMessagesReceived, 2, 'should save unreliable messages until socket is OPEN');
t.equals(reliableMessagesReceived, 2, 'should save reliable messages until socket is OPEN');
},
message: noop,
close: noop,
});
},
message: (_, unreliable) => {
if (unreliable) {
++unreliableMessagesReceived;
} else {
++reliableMessagesReceived;
}
},
close: noop,
}),
close: noop,
});
const clientSocket = createLocalSocket({
sessionId: id(),
server,
});
});
test('socket.send() - when CLOSED', (t) => {
t.plan(1);
const server = createLocalSocketServer();
server.start({
ready: noop,
connection: (serverSocket) => serverSocket.open({
ready: () => {
clientSocket.close();
// attempt to send message when client socket is CLOSED
clientSocket.send('message never got sent');
t.pass('should return silently');
},
message: () => t.fail('should not invoke message handler'),
close: noop,
}),
close: noop,
});
const clientSocket = createLocalSocket({
sessionId: id(),
server,
});
});
test('socket.close() - when OPEN', (t) => {
t.plan(4);
const server = createLocalSocketServer();
server.start({
ready: noop,
connection: (serverSocket) => serverSocket.open({
// open client socket when server socket is OPEN
ready: () => clientSocket.open({
// close client socket when it is OPEN
ready: () => clientSocket.close(),
message: noop,
close: (error) => {
t.equals(error, undefined, 'should invoke close handler without error message');
t.equals(clientSocket.state, MuSocketState.CLOSED, 'should change socket state to CLOSED');
},
}),
message: noop,
close: (error) => {
t.equals(server.clients.length, 0, 'should remove connection from server');
t.equals(serverSocket.state, MuSocketState.CLOSED, 'should also close server socket');
},
}),
close: noop,
});
const clientSocket = createLocalSocket({
sessionId: id(),
server,
});
});
test('socket.close() - when INIT', (t) => {
const socket = createLocalSocket({
sessionId: id(),
server: createLocalSocketServer(),
});
socket.close();
t.equals(socket.state, MuSocketState.CLOSED, 'should change socket state to CLOSED');
t.end();
});
test('socket.close() - when CLOSED', (t) => {
t.plan(1);
let callsToOnClose = 0;
const socket = createLocalSocket({
sessionId: id(),
server: createLocalSocketServer(),
});
socket.open({
ready: () => {
socket.close();
// attempt to close socket when it is already CLOSED
socket.close();
t.equals(callsToOnClose, 1, 'should not invoke close handler')
},
message: noop,
close: () => ++callsToOnClose,
});
});