mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-23 07:03:54 -07:00
upgrade packages + improve typing
This commit is contained in:
parent
fd55f4fb7f
commit
19f5eefdd2
138 changed files with 4504 additions and 11015 deletions
|
|
@ -1,8 +1,14 @@
|
|||
import { ArrowInfo, CardInfo, CounterInfo, PlayerProperties } from 'types';
|
||||
import { ArrowInfo, CardInfo, CounterInfo, PlayerProperties, ProtoInit } from 'types';
|
||||
import { create } from '@bufbuild/protobuf';
|
||||
import { ServerInfo_CardSchema } from 'generated/proto/serverinfo_card_pb';
|
||||
import { ServerInfo_CounterSchema } from 'generated/proto/serverinfo_counter_pb';
|
||||
import { colorSchema } from 'generated/proto/color_pb';
|
||||
import { ServerInfo_ArrowSchema } from 'generated/proto/serverinfo_arrow_pb';
|
||||
import { ServerInfo_PlayerPropertiesSchema } from 'generated/proto/serverinfo_playerproperties_pb';
|
||||
import { GameEntry, GamesState, PlayerEntry, ZoneEntry } from '../game.interfaces';
|
||||
|
||||
export function makeCard(overrides: Partial<CardInfo> = {}): CardInfo {
|
||||
return {
|
||||
export function makeCard(overrides: ProtoInit<CardInfo> = {}): CardInfo {
|
||||
return create(ServerInfo_CardSchema, {
|
||||
id: 1,
|
||||
name: 'Test Card',
|
||||
x: 0,
|
||||
|
|
@ -21,22 +27,22 @@ export function makeCard(overrides: Partial<CardInfo> = {}): CardInfo {
|
|||
attachCardId: -1,
|
||||
providerId: '',
|
||||
...overrides,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function makeCounter(overrides: Partial<CounterInfo> = {}): CounterInfo {
|
||||
return {
|
||||
export function makeCounter(overrides: ProtoInit<CounterInfo> = {}): CounterInfo {
|
||||
return create(ServerInfo_CounterSchema, {
|
||||
id: 1,
|
||||
name: 'Life',
|
||||
counterColor: { r: 0, g: 0, b: 0, a: 255 },
|
||||
counterColor: create(colorSchema, { r: 0, g: 0, b: 0, a: 255 }),
|
||||
radius: 1,
|
||||
count: 20,
|
||||
...overrides,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function makeArrow(overrides: Partial<ArrowInfo> = {}): ArrowInfo {
|
||||
return {
|
||||
export function makeArrow(overrides: ProtoInit<ArrowInfo> = {}): ArrowInfo {
|
||||
return create(ServerInfo_ArrowSchema, {
|
||||
id: 1,
|
||||
startPlayerId: 1,
|
||||
startZone: 'table',
|
||||
|
|
@ -44,9 +50,9 @@ export function makeArrow(overrides: Partial<ArrowInfo> = {}): ArrowInfo {
|
|||
targetPlayerId: 1,
|
||||
targetZone: 'table',
|
||||
targetCardId: 2,
|
||||
arrowColor: { r: 255, g: 0, b: 0, a: 255 },
|
||||
arrowColor: create(colorSchema, { r: 255, g: 0, b: 0, a: 255 }),
|
||||
...overrides,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function makeZoneEntry(overrides: Partial<ZoneEntry> = {}): ZoneEntry {
|
||||
|
|
@ -62,10 +68,9 @@ export function makeZoneEntry(overrides: Partial<ZoneEntry> = {}): ZoneEntry {
|
|||
};
|
||||
}
|
||||
|
||||
export function makePlayerProperties(overrides: Partial<PlayerProperties> = {}): PlayerProperties {
|
||||
return {
|
||||
export function makePlayerProperties(overrides: ProtoInit<PlayerProperties> = {}): PlayerProperties {
|
||||
return create(ServerInfo_PlayerPropertiesSchema, {
|
||||
playerId: 1,
|
||||
userInfo: null,
|
||||
spectator: false,
|
||||
conceded: false,
|
||||
readyStart: false,
|
||||
|
|
@ -74,7 +79,7 @@ export function makePlayerProperties(overrides: Partial<PlayerProperties> = {}):
|
|||
sideboardLocked: false,
|
||||
judge: false,
|
||||
...overrides,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function makePlayerEntry(overrides: Partial<PlayerEntry> = {}): PlayerEntry {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { create } from '@bufbuild/protobuf';
|
||||
import { Actions } from './game.actions';
|
||||
import { Types } from './game.types';
|
||||
import {
|
||||
|
|
@ -6,8 +7,26 @@ import {
|
|||
makeCounter,
|
||||
makeGameEntry,
|
||||
makePlayerProperties,
|
||||
makeZoneEntry,
|
||||
} from './__mocks__/fixtures';
|
||||
import { Event_GameStateChangedSchema } from 'generated/proto/event_game_state_changed_pb';
|
||||
import { Event_MoveCardSchema } from 'generated/proto/event_move_card_pb';
|
||||
import { Event_FlipCardSchema } from 'generated/proto/event_flip_card_pb';
|
||||
import { Event_DestroyCardSchema } from 'generated/proto/event_destroy_card_pb';
|
||||
import { Event_AttachCardSchema } from 'generated/proto/event_attach_card_pb';
|
||||
import { Event_CreateTokenSchema } from 'generated/proto/event_create_token_pb';
|
||||
import { Event_SetCardAttrSchema } from 'generated/proto/event_set_card_attr_pb';
|
||||
import { Event_SetCardCounterSchema } from 'generated/proto/event_set_card_counter_pb';
|
||||
import { Event_CreateArrowSchema } from 'generated/proto/event_create_arrow_pb';
|
||||
import { Event_DeleteArrowSchema } from 'generated/proto/event_delete_arrow_pb';
|
||||
import { Event_CreateCounterSchema } from 'generated/proto/event_create_counter_pb';
|
||||
import { Event_SetCounterSchema } from 'generated/proto/event_set_counter_pb';
|
||||
import { Event_DelCounterSchema } from 'generated/proto/event_del_counter_pb';
|
||||
import { Event_DrawCardsSchema } from 'generated/proto/event_draw_cards_pb';
|
||||
import { Event_RevealCardsSchema } from 'generated/proto/event_reveal_cards_pb';
|
||||
import { Event_ShuffleSchema } from 'generated/proto/event_shuffle_pb';
|
||||
import { Event_RollDieSchema } from 'generated/proto/event_roll_die_pb';
|
||||
import { Event_DumpZoneSchema } from 'generated/proto/event_dump_zone_pb';
|
||||
import { Event_ChangeZonePropertiesSchema } from 'generated/proto/event_change_zone_properties_pb';
|
||||
|
||||
describe('Actions', () => {
|
||||
it('clearStore', () => {
|
||||
|
|
@ -32,7 +51,9 @@ describe('Actions', () => {
|
|||
});
|
||||
|
||||
it('gameStateChanged', () => {
|
||||
const data = { playerList: [], gameStarted: true, activePlayerId: 1, activePhase: 0, secondsElapsed: 0 };
|
||||
const data = create(Event_GameStateChangedSchema, {
|
||||
playerList: [], gameStarted: true, activePlayerId: 1, activePhase: 0, secondsElapsed: 0
|
||||
});
|
||||
expect(Actions.gameStateChanged(1, data)).toEqual({ type: Types.GAME_STATE_CHANGED, gameId: 1, data });
|
||||
});
|
||||
|
||||
|
|
@ -60,85 +81,85 @@ describe('Actions', () => {
|
|||
});
|
||||
|
||||
it('cardMoved', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_MoveCardSchema, { cardId: 1 });
|
||||
expect(Actions.cardMoved(1, 2, data)).toEqual({ type: Types.CARD_MOVED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('cardFlipped', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_FlipCardSchema, { cardId: 1 });
|
||||
expect(Actions.cardFlipped(1, 2, data)).toEqual({ type: Types.CARD_FLIPPED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('cardDestroyed', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_DestroyCardSchema, { cardId: 1 });
|
||||
expect(Actions.cardDestroyed(1, 2, data)).toEqual({ type: Types.CARD_DESTROYED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('cardAttached', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_AttachCardSchema, { cardId: 1 });
|
||||
expect(Actions.cardAttached(1, 2, data)).toEqual({ type: Types.CARD_ATTACHED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('tokenCreated', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_CreateTokenSchema, { cardId: 1 });
|
||||
expect(Actions.tokenCreated(1, 2, data)).toEqual({ type: Types.TOKEN_CREATED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('cardAttrChanged', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_SetCardAttrSchema, { cardId: 1 });
|
||||
expect(Actions.cardAttrChanged(1, 2, data)).toEqual({ type: Types.CARD_ATTR_CHANGED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('cardCounterChanged', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_SetCardCounterSchema, { cardId: 1 });
|
||||
expect(Actions.cardCounterChanged(1, 2, data)).toEqual({ type: Types.CARD_COUNTER_CHANGED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('arrowCreated', () => {
|
||||
const arrow = makeArrow();
|
||||
const data = { arrowInfo: arrow };
|
||||
const data = create(Event_CreateArrowSchema, { arrowInfo: arrow });
|
||||
expect(Actions.arrowCreated(1, 2, data)).toEqual({ type: Types.ARROW_CREATED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('arrowDeleted', () => {
|
||||
const data = { arrowId: 3 };
|
||||
const data = create(Event_DeleteArrowSchema, { arrowId: 3 });
|
||||
expect(Actions.arrowDeleted(1, 2, data)).toEqual({ type: Types.ARROW_DELETED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('counterCreated', () => {
|
||||
const counter = makeCounter();
|
||||
const data = { counterInfo: counter };
|
||||
const data = create(Event_CreateCounterSchema, { counterInfo: counter });
|
||||
expect(Actions.counterCreated(1, 2, data)).toEqual({ type: Types.COUNTER_CREATED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('counterSet', () => {
|
||||
const data = { counterId: 1, value: 10 };
|
||||
const data = create(Event_SetCounterSchema, { counterId: 1, value: 10 });
|
||||
expect(Actions.counterSet(1, 2, data)).toEqual({ type: Types.COUNTER_SET, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('counterDeleted', () => {
|
||||
const data = { counterId: 1 };
|
||||
const data = create(Event_DelCounterSchema, { counterId: 1 });
|
||||
expect(Actions.counterDeleted(1, 2, data)).toEqual({ type: Types.COUNTER_DELETED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('cardsDrawn', () => {
|
||||
const card = makeCard();
|
||||
const data = { number: 2, cards: [card] };
|
||||
const data = create(Event_DrawCardsSchema, { number: 2, cards: [card] });
|
||||
expect(Actions.cardsDrawn(1, 2, data)).toEqual({ type: Types.CARDS_DRAWN, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('cardsRevealed', () => {
|
||||
const data = { zoneName: 'hand', cards: [] } as any;
|
||||
const data = create(Event_RevealCardsSchema, { zoneName: 'hand', cards: [] });
|
||||
expect(Actions.cardsRevealed(1, 2, data)).toEqual({ type: Types.CARDS_REVEALED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('zoneShuffled', () => {
|
||||
const data = { zoneName: 'deck', start: 0, end: 39 };
|
||||
const data = create(Event_ShuffleSchema, { zoneName: 'deck', start: 0, end: 39 });
|
||||
expect(Actions.zoneShuffled(1, 2, data)).toEqual({ type: Types.ZONE_SHUFFLED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('dieRolled', () => {
|
||||
const data = { sides: 6, value: 4, values: [4] };
|
||||
const data = create(Event_RollDieSchema, { sides: 6, value: 4, values: [4] });
|
||||
expect(Actions.dieRolled(1, 2, data)).toEqual({ type: Types.DIE_ROLLED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
|
|
@ -155,12 +176,12 @@ describe('Actions', () => {
|
|||
});
|
||||
|
||||
it('zoneDumped', () => {
|
||||
const data = { zoneOwnerId: 1, zoneName: 'hand', numberCards: 3, isReversed: false };
|
||||
const data = create(Event_DumpZoneSchema, { zoneOwnerId: 1, zoneName: 'hand', numberCards: 3, isReversed: false });
|
||||
expect(Actions.zoneDumped(1, 2, data)).toEqual({ type: Types.ZONE_DUMPED, gameId: 1, playerId: 2, data });
|
||||
});
|
||||
|
||||
it('zonePropertiesChanged', () => {
|
||||
const data = { zoneName: 'deck', alwaysRevealTopCard: true, alwaysLookAtTopCard: false };
|
||||
const data = create(Event_ChangeZonePropertiesSchema, { zoneName: 'deck', alwaysRevealTopCard: true, alwaysLookAtTopCard: false });
|
||||
expect(Actions.zonePropertiesChanged(1, 2, data)).toEqual({
|
||||
type: Types.ZONE_PROPERTIES_CHANGED,
|
||||
gameId: 1,
|
||||
|
|
|
|||
|
|
@ -232,3 +232,5 @@ export const Actions = {
|
|||
message,
|
||||
}),
|
||||
};
|
||||
|
||||
export type GameAction = ReturnType<typeof Actions[keyof typeof Actions]>;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
vi.mock('store/store', () => ({ store: { dispatch: vi.fn() } }));
|
||||
|
||||
import { create } from '@bufbuild/protobuf';
|
||||
import { store } from 'store/store';
|
||||
import { Actions } from './game.actions';
|
||||
import { Dispatch } from './game.dispatch';
|
||||
|
|
@ -10,6 +11,25 @@ import {
|
|||
makeGameEntry,
|
||||
makePlayerProperties,
|
||||
} from './__mocks__/fixtures';
|
||||
import { Event_GameStateChangedSchema } from 'generated/proto/event_game_state_changed_pb';
|
||||
import { Event_MoveCardSchema } from 'generated/proto/event_move_card_pb';
|
||||
import { Event_FlipCardSchema } from 'generated/proto/event_flip_card_pb';
|
||||
import { Event_DestroyCardSchema } from 'generated/proto/event_destroy_card_pb';
|
||||
import { Event_AttachCardSchema } from 'generated/proto/event_attach_card_pb';
|
||||
import { Event_CreateTokenSchema } from 'generated/proto/event_create_token_pb';
|
||||
import { Event_SetCardAttrSchema } from 'generated/proto/event_set_card_attr_pb';
|
||||
import { Event_SetCardCounterSchema } from 'generated/proto/event_set_card_counter_pb';
|
||||
import { Event_CreateArrowSchema } from 'generated/proto/event_create_arrow_pb';
|
||||
import { Event_DeleteArrowSchema } from 'generated/proto/event_delete_arrow_pb';
|
||||
import { Event_CreateCounterSchema } from 'generated/proto/event_create_counter_pb';
|
||||
import { Event_SetCounterSchema } from 'generated/proto/event_set_counter_pb';
|
||||
import { Event_DelCounterSchema } from 'generated/proto/event_del_counter_pb';
|
||||
import { Event_DrawCardsSchema } from 'generated/proto/event_draw_cards_pb';
|
||||
import { Event_RevealCardsSchema } from 'generated/proto/event_reveal_cards_pb';
|
||||
import { Event_ShuffleSchema } from 'generated/proto/event_shuffle_pb';
|
||||
import { Event_RollDieSchema } from 'generated/proto/event_roll_die_pb';
|
||||
import { Event_DumpZoneSchema } from 'generated/proto/event_dump_zone_pb';
|
||||
import { Event_ChangeZonePropertiesSchema } from 'generated/proto/event_change_zone_properties_pb';
|
||||
|
||||
beforeEach(() => vi.clearAllMocks());
|
||||
|
||||
|
|
@ -41,7 +61,9 @@ describe('Dispatch', () => {
|
|||
});
|
||||
|
||||
it('gameStateChanged dispatches Actions.gameStateChanged()', () => {
|
||||
const data = { playerList: [], gameStarted: false, activePlayerId: 0, activePhase: 0, secondsElapsed: 0 };
|
||||
const data = create(Event_GameStateChangedSchema, {
|
||||
playerList: [], gameStarted: false, activePlayerId: 0, activePhase: 0, secondsElapsed: 0
|
||||
});
|
||||
Dispatch.gameStateChanged(1, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.gameStateChanged(1, data));
|
||||
});
|
||||
|
|
@ -69,97 +91,97 @@ describe('Dispatch', () => {
|
|||
});
|
||||
|
||||
it('cardMoved dispatches Actions.cardMoved()', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_MoveCardSchema, { cardId: 1 });
|
||||
Dispatch.cardMoved(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.cardMoved(1, 2, data));
|
||||
});
|
||||
|
||||
it('cardFlipped dispatches Actions.cardFlipped()', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_FlipCardSchema, { cardId: 1 });
|
||||
Dispatch.cardFlipped(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.cardFlipped(1, 2, data));
|
||||
});
|
||||
|
||||
it('cardDestroyed dispatches Actions.cardDestroyed()', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_DestroyCardSchema, { cardId: 1 });
|
||||
Dispatch.cardDestroyed(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.cardDestroyed(1, 2, data));
|
||||
});
|
||||
|
||||
it('cardAttached dispatches Actions.cardAttached()', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_AttachCardSchema, { cardId: 1 });
|
||||
Dispatch.cardAttached(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.cardAttached(1, 2, data));
|
||||
});
|
||||
|
||||
it('tokenCreated dispatches Actions.tokenCreated()', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_CreateTokenSchema, { cardId: 1 });
|
||||
Dispatch.tokenCreated(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.tokenCreated(1, 2, data));
|
||||
});
|
||||
|
||||
it('cardAttrChanged dispatches Actions.cardAttrChanged()', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_SetCardAttrSchema, { cardId: 1 });
|
||||
Dispatch.cardAttrChanged(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.cardAttrChanged(1, 2, data));
|
||||
});
|
||||
|
||||
it('cardCounterChanged dispatches Actions.cardCounterChanged()', () => {
|
||||
const data = { cardId: 1 } as any;
|
||||
const data = create(Event_SetCardCounterSchema, { cardId: 1 });
|
||||
Dispatch.cardCounterChanged(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.cardCounterChanged(1, 2, data));
|
||||
});
|
||||
|
||||
it('arrowCreated dispatches Actions.arrowCreated()', () => {
|
||||
const data = { arrowInfo: makeArrow() };
|
||||
const data = create(Event_CreateArrowSchema, { arrowInfo: makeArrow() });
|
||||
Dispatch.arrowCreated(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.arrowCreated(1, 2, data));
|
||||
});
|
||||
|
||||
it('arrowDeleted dispatches Actions.arrowDeleted()', () => {
|
||||
const data = { arrowId: 3 };
|
||||
const data = create(Event_DeleteArrowSchema, { arrowId: 3 });
|
||||
Dispatch.arrowDeleted(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.arrowDeleted(1, 2, data));
|
||||
});
|
||||
|
||||
it('counterCreated dispatches Actions.counterCreated()', () => {
|
||||
const data = { counterInfo: makeCounter() };
|
||||
const data = create(Event_CreateCounterSchema, { counterInfo: makeCounter() });
|
||||
Dispatch.counterCreated(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.counterCreated(1, 2, data));
|
||||
});
|
||||
|
||||
it('counterSet dispatches Actions.counterSet()', () => {
|
||||
const data = { counterId: 1, value: 10 };
|
||||
const data = create(Event_SetCounterSchema, { counterId: 1, value: 10 });
|
||||
Dispatch.counterSet(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.counterSet(1, 2, data));
|
||||
});
|
||||
|
||||
it('counterDeleted dispatches Actions.counterDeleted()', () => {
|
||||
const data = { counterId: 1 };
|
||||
const data = create(Event_DelCounterSchema, { counterId: 1 });
|
||||
Dispatch.counterDeleted(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.counterDeleted(1, 2, data));
|
||||
});
|
||||
|
||||
it('cardsDrawn dispatches Actions.cardsDrawn()', () => {
|
||||
const data = { number: 2, cards: [makeCard()] };
|
||||
const data = create(Event_DrawCardsSchema, { number: 2, cards: [makeCard()] });
|
||||
Dispatch.cardsDrawn(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.cardsDrawn(1, 2, data));
|
||||
});
|
||||
|
||||
it('cardsRevealed dispatches Actions.cardsRevealed()', () => {
|
||||
const data = { zoneName: 'hand', cards: [] } as any;
|
||||
const data = create(Event_RevealCardsSchema, { zoneName: 'hand', cards: [] });
|
||||
Dispatch.cardsRevealed(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.cardsRevealed(1, 2, data));
|
||||
});
|
||||
|
||||
it('zoneShuffled dispatches Actions.zoneShuffled()', () => {
|
||||
const data = { zoneName: 'deck', start: 0, end: 39 };
|
||||
const data = create(Event_ShuffleSchema, { zoneName: 'deck', start: 0, end: 39 });
|
||||
Dispatch.zoneShuffled(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.zoneShuffled(1, 2, data));
|
||||
});
|
||||
|
||||
it('dieRolled dispatches Actions.dieRolled()', () => {
|
||||
const data = { sides: 6, value: 4, values: [4] };
|
||||
const data = create(Event_RollDieSchema, { sides: 6, value: 4, values: [4] });
|
||||
Dispatch.dieRolled(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.dieRolled(1, 2, data));
|
||||
});
|
||||
|
|
@ -180,13 +202,13 @@ describe('Dispatch', () => {
|
|||
});
|
||||
|
||||
it('zoneDumped dispatches Actions.zoneDumped()', () => {
|
||||
const data = { zoneOwnerId: 1, zoneName: 'hand', numberCards: 3, isReversed: false };
|
||||
const data = create(Event_DumpZoneSchema, { zoneOwnerId: 1, zoneName: 'hand', numberCards: 3, isReversed: false });
|
||||
Dispatch.zoneDumped(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.zoneDumped(1, 2, data));
|
||||
});
|
||||
|
||||
it('zonePropertiesChanged dispatches Actions.zonePropertiesChanged()', () => {
|
||||
const data = { zoneName: 'deck', alwaysRevealTopCard: true, alwaysLookAtTopCard: false };
|
||||
const data = create(Event_ChangeZonePropertiesSchema, { zoneName: 'deck', alwaysRevealTopCard: true, alwaysLookAtTopCard: false });
|
||||
Dispatch.zonePropertiesChanged(1, 2, data);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(Actions.zonePropertiesChanged(1, 2, data));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { create } from '@bufbuild/protobuf';
|
||||
import { CardAttribute, PlayerInfo } from 'types';
|
||||
import { gamesReducer } from './game.reducer';
|
||||
import { Types } from './game.types';
|
||||
|
|
@ -11,6 +12,7 @@ import {
|
|||
makeState,
|
||||
makeZoneEntry,
|
||||
} from './__mocks__/fixtures';
|
||||
import { ServerInfo_PlayerSchema } from 'generated/proto/serverinfo_player_pb';
|
||||
|
||||
// ── 2A: Initialisation & lifecycle ───────────────────────────────────────────
|
||||
|
||||
|
|
@ -67,7 +69,7 @@ describe('2B: Game state & player management', () => {
|
|||
const counter = makeCounter({ id: 2 });
|
||||
const arrow = makeArrow({ id: 3 });
|
||||
const playerList: PlayerInfo[] = [
|
||||
{
|
||||
create(ServerInfo_PlayerSchema, {
|
||||
properties: makePlayerProperties({ playerId: 7 }),
|
||||
deckList: 'some deck',
|
||||
zoneList: [
|
||||
|
|
@ -83,7 +85,7 @@ describe('2B: Game state & player management', () => {
|
|||
],
|
||||
counterList: [counter],
|
||||
arrowList: [arrow],
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
const result = gamesReducer(state, {
|
||||
|
|
@ -620,7 +622,7 @@ describe('2F: CARD_COUNTER_CHANGED', () => {
|
|||
playerId: 1,
|
||||
data: { zoneName: 'table', cardId: 4, counterId: 1, counterValue: 3 },
|
||||
});
|
||||
expect(result.games[1].players[1].zones['table'].cards[0].counterList).toEqual([{ id: 1, value: 3 }]);
|
||||
expect(result.games[1].players[1].zones['table'].cards[0].counterList).toEqual([expect.objectContaining({ id: 1, value: 3 })]);
|
||||
});
|
||||
|
||||
it('updates existing counter value when counterId matches', () => {
|
||||
|
|
@ -631,7 +633,7 @@ describe('2F: CARD_COUNTER_CHANGED', () => {
|
|||
playerId: 1,
|
||||
data: { zoneName: 'table', cardId: 4, counterId: 1, counterValue: 7 },
|
||||
});
|
||||
expect(result.games[1].players[1].zones['table'].cards[0].counterList).toEqual([{ id: 1, value: 7 }]);
|
||||
expect(result.games[1].players[1].zones['table'].cards[0].counterList).toEqual([expect.objectContaining({ id: 1, value: 7 })]);
|
||||
});
|
||||
|
||||
it('removes counter from counterList when counterValue ≤ 0', () => {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,10 @@ import {
|
|||
PlayerInfo,
|
||||
PlayerProperties,
|
||||
} from 'types';
|
||||
import { create } from '@bufbuild/protobuf';
|
||||
import { ServerInfo_CardSchema } from 'generated/proto/serverinfo_card_pb';
|
||||
import { ServerInfo_CardCounterSchema } from 'generated/proto/serverinfo_cardcounter_pb';
|
||||
import { GameAction } from './game.actions';
|
||||
import { GameEntry, GameMessage, GamesState, PlayerEntry, ZoneEntry } from './game.interfaces';
|
||||
import { Types } from './game.types';
|
||||
|
||||
|
|
@ -120,7 +124,7 @@ function buildEmptyCard(
|
|||
faceDown: boolean,
|
||||
providerId: string
|
||||
): CardInfo {
|
||||
return {
|
||||
return create(ServerInfo_CardSchema, {
|
||||
id,
|
||||
name,
|
||||
x,
|
||||
|
|
@ -138,7 +142,7 @@ function buildEmptyCard(
|
|||
attachZone: '',
|
||||
attachCardId: -1,
|
||||
providerId,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// ── Initial state ─────────────────────────────────────────────────────────────
|
||||
|
|
@ -149,7 +153,7 @@ const initialState: GamesState = {
|
|||
|
||||
// ── Reducer ───────────────────────────────────────────────────────────────────
|
||||
|
||||
export const gamesReducer = (state: GamesState = initialState, action: any): GamesState => {
|
||||
export const gamesReducer = (state: GamesState = initialState, action: GameAction): GamesState => {
|
||||
switch (action.type) {
|
||||
case Types.CLEAR_STORE: {
|
||||
return initialState;
|
||||
|
|
@ -422,7 +426,7 @@ export const gamesReducer = (state: GamesState = initialState, action: any): Gam
|
|||
return state;
|
||||
}
|
||||
|
||||
const newCard: CardInfo = {
|
||||
const newCard: CardInfo = create(ServerInfo_CardSchema, {
|
||||
id: cardId,
|
||||
name: cardName,
|
||||
x,
|
||||
|
|
@ -440,7 +444,7 @@ export const gamesReducer = (state: GamesState = initialState, action: any): Gam
|
|||
attachZone: '',
|
||||
attachCardId: -1,
|
||||
providerId: cardProviderId,
|
||||
};
|
||||
});
|
||||
return updateZone(state, gameId, playerId, zoneName, {
|
||||
cards: [...zone.cards, newCard],
|
||||
cardCount: zone.cardCount + 1,
|
||||
|
|
@ -514,7 +518,7 @@ export const gamesReducer = (state: GamesState = initialState, action: any): Gam
|
|||
newCounterList =
|
||||
existing >= 0
|
||||
? card.counterList.map(c => (c.id === counterId ? { ...c, value: counterValue } : c))
|
||||
: [...card.counterList, { id: counterId, value: counterValue }];
|
||||
: [...card.counterList, create(ServerInfo_CardCounterSchema, { id: counterId, value: counterValue })];
|
||||
}
|
||||
|
||||
const updatedCards = [...zone.cards];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { Selectors } from './game.selectors';
|
||||
import {
|
||||
makeGameEntry, makePlayerEntry, makePlayerProperties, makeState,
|
||||
import { makeGameEntry, makePlayerEntry, makeState,
|
||||
makeZoneEntry, makeCard, makeCounter, makeArrow,
|
||||
} from './__mocks__/fixtures';
|
||||
import { GamesState } from './game.interfaces';
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { CardInfo } from 'types';
|
||||
import { GamesState, GameEntry, PlayerEntry, ZoneEntry } from './game.interfaces';
|
||||
|
||||
interface State {
|
||||
games: GamesState;
|
||||
}
|
||||
|
||||
const EMPTY_ARRAY: CardInfo[] = [];
|
||||
const EMPTY_OBJECT = {} as Record<string, never>;
|
||||
|
||||
export const Selectors = {
|
||||
getGames: ({ games }: State): { [gameId: number]: GameEntry } => games.games,
|
||||
|
||||
|
|
@ -41,13 +46,13 @@ export const Selectors = {
|
|||
): ZoneEntry | undefined => games.games[gameId]?.players[playerId]?.zones[zoneName],
|
||||
|
||||
getCards: ({ games }: State, gameId: number, playerId: number, zoneName: string) =>
|
||||
games.games[gameId]?.players[playerId]?.zones[zoneName]?.cards ?? [],
|
||||
games.games[gameId]?.players[playerId]?.zones[zoneName]?.cards ?? EMPTY_ARRAY,
|
||||
|
||||
getCounters: ({ games }: State, gameId: number, playerId: number) =>
|
||||
games.games[gameId]?.players[playerId]?.counters ?? {},
|
||||
games.games[gameId]?.players[playerId]?.counters ?? EMPTY_OBJECT,
|
||||
|
||||
getArrows: ({ games }: State, gameId: number, playerId: number) =>
|
||||
games.games[gameId]?.players[playerId]?.arrows ?? {},
|
||||
games.games[gameId]?.players[playerId]?.arrows ?? EMPTY_OBJECT,
|
||||
|
||||
getActivePlayerId: ({ games }: State, gameId: number): number | undefined =>
|
||||
games.games[gameId]?.activePlayerId,
|
||||
|
|
@ -65,8 +70,10 @@ export const Selectors = {
|
|||
games.games[gameId]?.reversed ?? false,
|
||||
|
||||
getMessages: ({ games }: State, gameId: number) =>
|
||||
games.games[gameId]?.messages ?? [],
|
||||
games.games[gameId]?.messages ?? EMPTY_ARRAY,
|
||||
|
||||
getActiveGameIds: ({ games }: State): number[] =>
|
||||
Object.keys(games.games).map(Number),
|
||||
getActiveGameIds: createSelector(
|
||||
[({ games }: State) => games.games],
|
||||
(games) => Object.keys(games).map(Number)
|
||||
),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -31,4 +31,4 @@ export const Types = {
|
|||
ZONE_DUMPED: '[Games] Zone Dumped',
|
||||
ZONE_PROPERTIES_CHANGED: '[Games] Zone Properties Changed',
|
||||
GAME_SAY: '[Games] Game Say',
|
||||
};
|
||||
} as const;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue