Select Git revision
controller.test.js
Forked from
SOFT Core / SOFT 260 / Boost Board Game
Source project has a limited visibility.
-
Brady James Garvin authoredBrady James Garvin authored
controller.test.js 13.88 KiB
/* eslint-disable no-magic-numbers */
import { jest, describe, test, expect } from '@jest/globals';
import { callsTo, anyUnexpectedCalls } from '../testing/awaitCalls.js';
import Controller from './controller.js';
function controllerWithMocks(engineURL, engineThreadURL, gameIdentifier) {
globalThis.Worker = jest.fn().mockName('Worker').mockReturnValue({
addEventListener: jest.fn().mockName('addEventListener'),
postMessage: jest.fn().mockName('postMessage'),
});
const result = new Controller(
engineURL,
engineThreadURL,
gameIdentifier,
jest.fn().mockName('propertyHandler'),
jest.fn().mockName('moveHandler'),
);
return result;
}
describe('the controller\'s automatic behaviors', () => {
test('connect as needed when setting strength', async() => {
const controller = controllerWithMocks('abc', 'def', 'ghi');
controller.setStrength(999);
controller.setStrength(9999);
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
]);
controller.receiveMessage('protocol 1.0.0');
controller.receiveMessage('beiok');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
['setoption strength 999'],
['isready'],
]);
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
['setoption strength 999'],
['isready'],
['setoption strength 9999'],
['isready'],
]);
});
test('connect and start a game as needed when setting a line', async() => {
const controller = controllerWithMocks('abc', 'def', 'ghi');
controller.setLine({ serialization: 'jkl' }, [{ serialization: 'mno' }, { serialization: 'pqr' }]);
controller.setLine({ serialization: 'stu' }, []);
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
]);
controller.receiveMessage('protocol 1.0.0');
controller.receiveMessage('beiok');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
['newgame ghi'],
['isready'],
]);
controller.receiveMessage('known');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
['newgame ghi'],
['isready'],
['setline jkl mno pqr'],
['isready'],
]);
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
['newgame ghi'],
['isready'],
['setline jkl mno pqr'],
['isready'],
['setline stu'],
['isready'],
]);
});
test('connect and start a game as needed when starting a search', async() => {
const controller = controllerWithMocks('abc', 'def', 'ghi');
controller.go();
controller.stop();
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
]);
controller.receiveMessage('protocol 1.0.0');
controller.receiveMessage('beiok');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
['newgame ghi'],
['isready'],
]);
controller.receiveMessage('known');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
['newgame ghi'],
['isready'],
['go'],
['isready'],
]);
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
['newgame ghi'],
['isready'],
['go'],
['isready'],
['stop'],
['isready'],
]);
});
});
describe('the controller\'s communication checks', () => {
test('block communication when the engine protocol is too new', async() => {
const controller = controllerWithMocks('abc', 'def', 'ghi');
controller.setLine({ serialization: 'jkl' }, []);
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
]);
controller.receiveMessage('protocol 9999.9.9');
controller.receiveMessage('beiok');
controller.receiveMessage('readyok');
await anyUnexpectedCalls();
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
]);
});
test('block a game line if the engine does not know the game', async() => {
const controller = controllerWithMocks('abc', 'def', 'ghi');
controller.setLine({ serialization: 'jkl' }, []);
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
]);
controller.receiveMessage('protocol 1.0.0');
controller.receiveMessage('beiok');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
['newgame ghi'],
['isready'],
]);
controller.receiveMessage('unknown');
controller.receiveMessage('readyok');
await anyUnexpectedCalls();
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
['newgame ghi'],
['isready'],
]);
});
test('block starting an already started search', async() => {
const controller = controllerWithMocks('abc', 'def', 'ghi');
controller.go();
controller.go();
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
]);
controller.receiveMessage('protocol 1.0.0');
controller.receiveMessage('beiok');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
['newgame ghi'],
['isready'],
]);
controller.receiveMessage('known');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
['newgame ghi'],
['isready'],
['go'],
['isready'],
]);
controller.receiveMessage('readyok');
await anyUnexpectedCalls();
expect(controller.worker.postMessage.mock.calls).toEqual([
['bei def'],
['isready'],
['newgame ghi'],
['isready'],
['go'],
['isready'],
]);
});
test('block stopping an already stopped search', async() => {
const controller = controllerWithMocks('abc', 'def', 'ghi');
controller.stop();
await anyUnexpectedCalls();
expect(controller.worker.postMessage.mock.calls).toEqual([]);
});
});
describe('the controller\'s callbacks', () => {
test('report engine properties', async() => {
const controller = controllerWithMocks('abc', 'def', 'ghi');
controller.setStrength(999);
await callsTo(controller.worker.postMessage);
controller.receiveMessage('protocol 1.0.0');
controller.receiveMessage('id name jkl');
controller.receiveMessage('id author mno');
controller.receiveMessage('id version pqr');
controller.receiveMessage('beiok');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
expect(controller.propertyHandler.mock.calls).toEqual([
['name', 'jkl'],
['author', 'mno'],
['version', 'pqr'],
]);
});
test('report single moves', async() => {
const controller = controllerWithMocks('abc', 'def', 'ghi');
controller.go();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('protocol 1.0.0');
controller.receiveMessage('beiok');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
controller.receiveMessage('known');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.receiveMessage('move jkl');
expect(controller.moveHandler.mock.calls).toEqual([
['jkl'],
]);
});
test('report consecutive moves', async() => {
const controller = controllerWithMocks('abc', 'def', 'ghi');
controller.go();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('protocol 1.0.0');
controller.receiveMessage('beiok');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
controller.receiveMessage('known');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.receiveMessage('move jkl');
expect(controller.moveHandler.mock.calls).toEqual([
['jkl'],
]);
controller.go();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.receiveMessage('move mno');
expect(controller.moveHandler.mock.calls).toEqual([
['jkl'],
['mno'],
]);
});
test('do not report unwanted moves from stopped searches', async() => {
const controller = controllerWithMocks('abc', 'def', 'ghi');
controller.go();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('protocol 1.0.0');
controller.receiveMessage('beiok');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
controller.receiveMessage('known');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.stop();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.go();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.receiveMessage('move jkl');
expect(controller.moveHandler.mock.calls).toEqual([]);
controller.stop();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.go();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.receiveMessage('move mno');
expect(controller.moveHandler.mock.calls).toEqual([]);
controller.receiveMessage('move pqr');
expect(controller.moveHandler.mock.calls).toEqual([
['pqr'],
]);
});
test('do report wanted moves from stopped searches', async() => {
const controller = controllerWithMocks('abc', 'def', 'ghi');
controller.go();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('protocol 1.0.0');
controller.receiveMessage('beiok');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
controller.receiveMessage('known');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.stop(true);
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.go();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.receiveMessage('move jkl');
expect(controller.moveHandler.mock.calls).toEqual([
['jkl'],
]);
controller.stop(true);
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.go();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.receiveMessage('move mno');
expect(controller.moveHandler.mock.calls).toEqual([
['jkl'],
['mno'],
]);
controller.receiveMessage('move pqr');
expect(controller.moveHandler.mock.calls).toEqual([
['jkl'],
['mno'],
['pqr'],
]);
});
test('do report late-arriving wanted moves from stopped searches', async() => {
const controller = controllerWithMocks('abc', 'def', 'ghi');
controller.go();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('protocol 1.0.0');
controller.receiveMessage('beiok');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
controller.receiveMessage('known');
controller.receiveMessage('readyok');
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.stop(true);
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.go();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.stop(false);
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.go();
await callsTo(controller.worker.postMessage);
controller.receiveMessage('readyok');
controller.receiveMessage('move jkl');
expect(controller.moveHandler.mock.calls).toEqual([
['jkl'],
]);
controller.receiveMessage('move mno');
expect(controller.moveHandler.mock.calls).toEqual([
['jkl'],
]);
controller.receiveMessage('move pqr');
expect(controller.moveHandler.mock.calls).toEqual([
['jkl'],
['pqr'],
]);
});
});