Skip to content

Commit

Permalink
Reset Game (#155)
Browse files Browse the repository at this point in the history
* make the changelog look nice again, fix small typo and have a consitent look

* add tests for resetGame

* implementing resetGame functionality

* extendet the resetGame test to cover more edge cases

* update tests to resemble the reset api as discussed in #155

* update reset game implementation as discussed in #155

* removed special treatment from reducer and added reducer test for reset

* minor tweaks
  • Loading branch information
sladwig authored and nicolodavis committed Mar 20, 2018
1 parent 9cd3fdf commit 2ee244e
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ class _ClientImpl {
multiplayer,
});

this.reset = () => {
this.store.dispatch(ActionCreators.reset());
};

this.store = null;

if (multiplayer) {
Expand Down
4 changes: 3 additions & 1 deletion src/client/react.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { Client as RawClient } from './client';
* Returns:
* A React component that wraps board and provides an
* API through props for it to interact with the framework
* and dispatch actions such as MAKE_MOVE and END_TURN.
* and dispatch actions such as MAKE_MOVE, GAME_EVENT and RESET.
*/
export function Client({
game,
Expand Down Expand Up @@ -108,6 +108,7 @@ export function Client({
events: this.client.events,
gameID: this.props.gameID,
playerID: this.props.playerID,
reset: this.client.reset,
});
}

Expand All @@ -120,6 +121,7 @@ export function Client({
events: this.client.events,
gameID: this.props.gameID,
playerID: this.props.playerID,
reset: this.client.reset,
});
}

Expand Down
23 changes: 23 additions & 0 deletions src/client/react.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,26 @@ test('local playerView', () => {
expect(board.props.G).toEqual({ stripped: '1' });
}
});

test('reset Game', () => {
const Board = Client({
game: Game({
moves: {
A: (G, ctx, arg) => ({ arg }),
},
}),
board: TestBoard,
});

const game = Enzyme.mount(<Board />);
const board = game.find('TestBoard').instance();

const initial = { G: { ...board.props.G }, ctx: { ...board.props.ctx } };

expect(board.props.G).toEqual({});
board.props.moves.A(42);
expect(board.props.G).toEqual({ arg: 42 });
board.props.reset();
expect(board.props.G).toEqual(initial.G);
expect(board.props.ctx).toEqual(initial.ctx);
});
7 changes: 7 additions & 0 deletions src/core/action-creators.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,10 @@ export const restore = state => ({
type: Actions.RESTORE,
state,
});

/**
* Used to reset the game state.
*/
export const reset = () => ({
type: Actions.RESET,
});
1 change: 1 addition & 0 deletions src/core/action-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
export const MAKE_MOVE = 'MAKE_MOVE';
export const GAME_EVENT = 'GAME_EVENT';
export const RESTORE = 'RESTORE';
export const RESET = 'RESET';
40 changes: 39 additions & 1 deletion src/core/flow.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Game from './game';
import { createGameReducer } from './reducer';
import { makeMove, gameEvent } from './action-creators';
import { makeMove, gameEvent, reset } from './action-creators';
import { Flow, FlowWithPhases } from './flow';

test('Flow', () => {
Expand Down Expand Up @@ -618,6 +618,44 @@ test('endGame', () => {
}
});

test('resetGame', () => {
let game = Game({
moves: {
move: (G, ctx, arg) => ({ ...G, [arg]: true }),
},
});

const reducer = createGameReducer({ game, numPlayers: 2 });

let state = reducer(undefined, { type: 'init' });

const originalState = state;

state = reducer(state, makeMove('move', 'A'));
expect(state.G).toEqual({ A: true });

state = reducer(state, makeMove('move', 'B'));
expect(state.G).toEqual({ A: true, B: true });

state = reducer(state, gameEvent('endTurn'));
expect(state.ctx.turn).toEqual(1);

state = reducer(state, reset());
expect(state).toEqual(originalState);

state = reducer(state, makeMove('move', 'C'));
expect(state.G).toEqual({ C: true });

state = reducer(state, gameEvent('undo'));
expect(state.G).toEqual({});

state = reducer(state, gameEvent('redo'));
expect(state.G).toEqual({ C: true });

state = reducer(state, reset());
expect(state).toEqual(originalState);
});

test('change action players', () => {
const flow = FlowWithPhases({});
const state = { ctx: {} };
Expand Down
4 changes: 4 additions & 0 deletions src/core/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ export function createGameReducer({ game, numPlayers, multiplayer }) {
return action.state;
}

case Actions.RESET: {
return initial;
}

default: {
return state;
}
Expand Down
12 changes: 11 additions & 1 deletion src/core/reducer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Game from './game';
import { createGameReducer } from './reducer';
import { makeMove, gameEvent, restore } from './action-creators';
import { makeMove, gameEvent, restore, reset } from './action-creators';

const game = Game({
moves: {
Expand Down Expand Up @@ -68,6 +68,16 @@ test('restore', () => {
expect(state).toEqual({ G: 'restored' });
});

test('reset', () => {
const reducer = createGameReducer({ game });
let state = reducer(undefined, makeMove('A'));
const initialState = { ...state._initial, _initial: { ...state._initial } };

expect(state).not.toEqual(initialState);
state = reducer(state, reset());
expect(state).toEqual(initialState);
});

test('victory', () => {
const reducer = createGameReducer({ game });

Expand Down

0 comments on commit 2ee244e

Please sign in to comment.