Skip to content

Commit

Permalink
refactor(client): Convert clients to Typescript (#744)
Browse files Browse the repository at this point in the history
* refactor(client): Move isConnected field to base Transport class

* refactor(client): Protect fields in base Transport class

* refactor(client): Add game and gameKey to base Transport options

The client passes these to the transport when instantiating it, so they 
should be included.

* refactor(client): Convert plain JS client to TS

Adds a layer of indirection between the client and the debug panel 
import to allow import of Svelte module.

* refactor(client): Convert React client to TS

* refactor(client): Enforce correct type of client.getState return

* refactor(client): Make `impl` optional in client’s debug options

* test(client): Convert client test suite to TS

* test(client): Convert React SSR test to TS

* refactor(client): Expose BoardProps type to users

Co-authored-by: Nicolo John Davis <nicolodavis@gmail.com>
  • Loading branch information
delucis and nicolodavis committed Jun 20, 2020
1 parent a6698e6 commit 31cb443
Show file tree
Hide file tree
Showing 13 changed files with 273 additions and 77 deletions.
50 changes: 50 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"proxydirs": "node scripts/proxy-dirs.js",
"prepack": "run-s build proxydirs",
"postpack": "npm run clean",
"prettier": "prettier --write \"{examples,src,benchmark}/**/*.{ts,js,css,md}\"",
"prettier": "prettier --write \"{examples,src,benchmark}/**/*.{ts,tsx,js,jsx,css,md}\"",
"changelog": "node ./scripts/changelog.js",
"clean": "node ./scripts/clean.js"
},
Expand Down Expand Up @@ -82,10 +82,13 @@
"@babel/preset-typescript": "^7.3.3",
"@testing-library/jest-dom": "^4.1.2",
"@testing-library/svelte": "^1.9.0",
"@types/enzyme": "^3.10.5",
"@types/jest": "^24.0.0",
"@types/koa": "^2.11.3",
"@types/koa-router": "^7.4.0",
"@types/koa__cors": "^3.0.1",
"@types/react": "^16.9.36",
"@types/react-dom": "^16.9.8",
"@types/shortid": "0.0.29",
"@types/socket.io": "^2.1.4",
"ajv": "^6.6.2",
Expand Down
37 changes: 22 additions & 15 deletions src/client/client.test.js → src/client/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import { CreateGameReducer } from '../core/reducer';
import { InitializeGame } from '../core/initialize';
import { Client, createMoveDispatchers } from './client';
import { ProcessGameConfig } from '../core/game';
import { Transport } from './transport/transport';
import { LocalTransport, Local } from './transport/local';
import { SocketIOTransport, SocketIO } from './transport/socketio';
import { update, sync, makeMove, gameEvent } from '../core/action-creators';
import Debug from './debug/Debug.svelte';
import Debug from './debug';
import { error } from '../core/logger';
import { LogEntry, State, SyncInfo } from '../types';

jest.mock('../core/logger', () => ({
info: jest.fn(),
Expand Down Expand Up @@ -157,7 +159,7 @@ describe('multiplayer', () => {
jest.spyOn(client.transport, 'onAction');
const state = { G: {}, ctx: { phase: '' }, plugins: {} };
const filteredMetadata = [];
client.store.dispatch(sync({ state, filteredMetadata }));
client.store.dispatch(sync({ state, filteredMetadata } as SyncInfo));
client.moves.A();
expect(client.transport.onAction).toHaveBeenCalled();
});
Expand Down Expand Up @@ -225,6 +227,8 @@ describe('multiplayer', () => {

describe('custom transport', () => {
class CustomTransport {
callback;

constructor() {
this.callback = null;
}
Expand All @@ -233,7 +237,8 @@ describe('multiplayer', () => {
this.callback = fn;
}
}
const customTransport = () => new CustomTransport();
const customTransport = () =>
(new CustomTransport() as unknown) as Transport;

let client;

Expand Down Expand Up @@ -262,7 +267,7 @@ test('accepts enhancer for store', () => {
const vanillaStore = vanillaCreateStore(...args);
return {
...vanillaStore,
dispatch: (spyDispatcher = jest.fn(vanillaStore.dispatch)),
dispatch: spyDispatcher = jest.fn(vanillaStore.dispatch),
};
};
const client = Client({
Expand Down Expand Up @@ -443,7 +448,7 @@ describe('log handling', () => {
});

test('update', () => {
const state = { restore: true, _stateID: 0 };
const state = ({ restore: true, _stateID: 0 } as unknown) as State;
const deltalog = [
{
action: {},
Expand All @@ -453,7 +458,7 @@ describe('log handling', () => {
action: {},
_stateID: 1,
},
];
] as LogEntry[];
const action = update(state, deltalog);

client.store.dispatch(action);
Expand All @@ -465,7 +470,7 @@ describe('log handling', () => {
test('sync', () => {
const state = { restore: true };
const log = ['0', '1'];
const action = sync({ state, log });
const action = sync(({ state, log } as unknown) as SyncInfo);

client.store.dispatch(action);
client.store.dispatch(action);
Expand All @@ -474,13 +479,13 @@ describe('log handling', () => {
});

test('update - log missing', () => {
const action = update();
const action = update(undefined, undefined);
client.store.dispatch(action);
expect(client.log).toEqual([]);
});

test('sync - log missing', () => {
const action = sync({});
const action = sync({} as SyncInfo);
client.store.dispatch(action);
expect(client.log).toEqual([]);
});
Expand Down Expand Up @@ -600,15 +605,17 @@ describe('subscribe', () => {
});

test('transport notifies subscribers', () => {
const client = Client({
game: {},
multiplayer: SocketIO(),
});
let transport: ReturnType<ReturnType<typeof SocketIO>>;
const multiplayer = (opts: any) => {
transport = SocketIO()(opts);
return transport;
};
const client = Client({ game: {}, multiplayer });
const fn = jest.fn();
client.subscribe(fn);
client.start();
fn.mockClear();
client.transport.callback();
transport.callback();
expect(fn).toHaveBeenCalled();
});

Expand Down Expand Up @@ -664,7 +671,7 @@ describe('start / stop', () => {
});

test('no error when mounting on null element', () => {
const client = Client({ game: {}, debug: { target: null } });
const client = Client({ game: {}, debug: { target: null } }) as any;
client.start();
client.stop();
expect(client._debugPanel).toBe(null);
Expand Down
Loading

0 comments on commit 31cb443

Please sign in to comment.