Skip to content

Commit

Permalink
bugfix: Stand-alone events should be undoable.
Browse files Browse the repository at this point in the history
  • Loading branch information
shaoster committed May 22, 2021
1 parent dc6cd45 commit 65b8b0d
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 10 deletions.
25 changes: 24 additions & 1 deletion src/core/reducer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,17 @@ describe('undo / redo', () => {
G.roll = ctx.random.D6();
},
},
turn: {
stages: {
special: {},
},
},
};

beforeEach(() => {
jest.clearAllMocks();
});

const reducer = CreateGameReducer({ game });

const initialState = InitializeGame({ game });
Expand All @@ -341,7 +350,7 @@ describe('undo / redo', () => {
expect(state._undo[1].ctx.random).toBeUndefined();
});

test('undo restores previous state', () => {
test('undo restores previous state after move', () => {
let state = reducer(initialState, makeMove('move', 'A', '0'));
const { G, ctx, plugins } = state;
state = reducer(state, makeMove('roll', null, '0'));
Expand All @@ -351,6 +360,20 @@ describe('undo / redo', () => {
expect(state.plugins).toEqual(plugins);
});

test('undo restores previous state after event', () => {
let state = reducer(initialState, gameEvent('setStage', 'special', '0'));
const { G, ctx, plugins } = state;
state = reducer(state, gameEvent('endStage', undefined, '0'));
expect(error).not.toBeCalled();
// Make sure we actually modified the stage.
expect(state.ctx.activePlayers).not.toEqual(ctx.activePlayers);
state = reducer(state, undo());
expect(error).not.toBeCalled();
expect(state.G).toEqual(G);
expect(state.ctx).toEqual(ctx);
expect(state.plugins).toEqual(plugins);
});

test('redo restores undone state', () => {
let state = initialState;
// Make two moves.
Expand Down
19 changes: 10 additions & 9 deletions src/core/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,18 +314,19 @@ export function CreateGameReducer({
return state;
}

// Only allow undoable moves to be undone.
const lastMove: Move = game.flow.getMove(
restore.ctx,
last.moveType,
last.playerID
);
if (!CanUndoMove(state.G, state.ctx, lastMove)) {
return state;
// Only allow events and undoable moves to be undone.
if (last.moveType) {
const lastMove: Move = game.flow.getMove(
restore.ctx,
last.moveType,
last.playerID
);
if (!CanUndoMove(state.G, state.ctx, lastMove)) {
return state;
}
}

state = initializeDeltalog(state, action);

return {
...state,
G: restore.G,
Expand Down

0 comments on commit 65b8b0d

Please sign in to comment.