diff --git a/package.json b/package.json index 46784c1..7d39a42 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "modaq", - "version": "1.24.2", + "version": "1.25.0", "description": "Quiz Bowl Reader using TypeScript, React, and MobX", "repository": { "type": "git", diff --git a/src/components/GameBar.tsx b/src/components/GameBar.tsx index 272adb5..774dd82 100644 --- a/src/components/GameBar.tsx +++ b/src/components/GameBar.tsx @@ -427,21 +427,19 @@ function getPlayerManagementSubMenuItems( for (const teamName of teamNames) { const players: Player[] = game.getPlayers(teamName); const activePlayers: Set = game.getActivePlayers(teamName, uiState.cycleIndex); - - // Potential issue: if we have an "add player" sub, they shouldn't appear before they were added? const subs: Player[] = players.filter((player) => !activePlayers.has(player)); const activePlayerMenuItems: ICommandBarItemProps[] = []; - for (const activePlayer of activePlayers) { - const subMenuItems: ICommandBarItemProps[] = subs.map((player) => { + for (const player of players) { + const subMenuItems: ICommandBarItemProps[] = subs.map((p) => { const subItemData: ISubMenuItemData = { appState, - activePlayer, - player, + activePlayer: player, + player: p, }; return { - key: `sub_${teamName}_${player.name}`, - text: player.name, + key: `sub_${teamName}_${p.name}`, + text: p.name, data: subItemData, onClick: onSwapPlayerClick, }; @@ -457,30 +455,49 @@ function getPlayerManagementSubMenuItems( }, }; - const removeItemData: ISubMenuItemData = { + const changeActivityItemData: ISubMenuItemData = { appState, - activePlayer, - }; - const removeItem: ICommandBarItemProps = { - key: `remove_${teamName}_${activePlayer.name}`, - text: "Remove", - data: removeItemData, - onClick: onRemovePlayerClick, - // TODO: should this be styled in a different color? + activePlayer: player, }; + + // For active players, remove. For inactive players, join + const isActivePlayer: boolean = activePlayers.has(player); + let changeActivityItem: ICommandBarItemProps; + if (isActivePlayer) { + changeActivityItem = { + key: `remove_${teamName}_${player.name}`, + text: "Remove", + data: changeActivityItemData, + onClick: onRemovePlayerClick, + // TODO: should this be styled in a different color? + }; + } else { + changeActivityItem = { + key: `add_${teamName}_${player.name}`, + text: "Add", + data: changeActivityItemData, + onClick: onAddInactivePlayerClick, + // TODO: should this be styled in a different color? + }; + } + const renameItem: ICommandBarItemProps = { - key: `rename_${teamName}_${activePlayer.name}`, + key: `rename_${teamName}_${player.name}`, text: "Rename", - data: removeItemData, + data: changeActivityItemData, onClick: onRenamePlayerClick, // TODO: should this be styled in a different color? }; + const items: ICommandBarItemProps[] = isActivePlayer + ? [subMenuSectionItem, changeActivityItem, renameItem] + : [changeActivityItem, renameItem]; + activePlayerMenuItems.push({ - key: `active_${teamName}_${activePlayer.name}`, - text: activePlayer.name, + key: `active_${teamName}_${player.name}`, + text: player.name, subMenuProps: { - items: [subMenuSectionItem, removeItem, renameItem], + items, }, }); } @@ -508,10 +525,20 @@ function getPlayerManagementSubMenuItems( // We should disable this if there are no subs available }; + // Couple possible approaches + // - Submenu for Add Player, where it's Add New Player and then all the subs + // - Add all players to the sub/remove submenu, but the subs action item is just "join"/"rename" + // - You can get some weird behavior with joins/subs in the same event. May need to disable it if they have an + // existing action (sub vs join) + // - Should there be a color code for active players? + const addPlayerItem: ICommandBarItemProps = { key: "addNewPlayer", text: "Add player...", onClick: addPlayerHandler, + // subMenuProps: { + // items: addPlayerMenus, + // }, disabled: appState.game.cycles.length === 0, }; @@ -634,6 +661,20 @@ function getProtestSubMenuItems( }; } +function onAddInactivePlayerClick( + ev?: React.MouseEvent | React.KeyboardEvent, + item?: IContextualMenuItem +): void { + if (item == undefined) { + return; + } else if (!isSubMenuItemData(item.data)) { + return; + } + + const appState: AppState = item.data.appState; + appState.game.addInactivePlayer(item.data.activePlayer, appState.uiState.cycleIndex); +} + function onProtestTossupClick( ev?: React.MouseEvent | React.KeyboardEvent, item?: IContextualMenuItem diff --git a/src/components/dialogs/AddPlayerDialogController.ts b/src/components/dialogs/AddPlayerDialogController.ts index 363d32f..5ff8907 100644 --- a/src/components/dialogs/AddPlayerDialogController.ts +++ b/src/components/dialogs/AddPlayerDialogController.ts @@ -18,7 +18,7 @@ export function addPlayer(): void { throw new Error("Tried adding a player with no new player"); } - game.addPlayer(newPlayer); + game.addNewPlayer(newPlayer); // TODO: Only do this if the number of active players is less than the maximum number of active players game.cycles[uiState.cycleIndex].addPlayerJoins(newPlayer); diff --git a/src/components/dialogs/ImportGameDialog.tsx b/src/components/dialogs/ImportGameDialog.tsx index d71c00b..37390a2 100644 --- a/src/components/dialogs/ImportGameDialog.tsx +++ b/src/components/dialogs/ImportGameDialog.tsx @@ -287,8 +287,8 @@ function onSubmit(appState: AppState): void { // We need to set the game's packet, players, etc. to the values in the uiState game.clear(); - game.addPlayers(firstTeamPlayers.filter((player) => player.name !== "")); - game.addPlayers(secondTeamPlayers.filter((player) => player.name !== "")); + game.addNewPlayers(firstTeamPlayers.filter((player) => player.name !== "")); + game.addNewPlayers(secondTeamPlayers.filter((player) => player.name !== "")); game.loadPacket(pendingNewGame.packet); game.setCycles(pendingNewGame.manual.cycles ?? []); diff --git a/src/components/dialogs/NewGameDialog.tsx b/src/components/dialogs/NewGameDialog.tsx index 931c026..0b5fd6c 100644 --- a/src/components/dialogs/NewGameDialog.tsx +++ b/src/components/dialogs/NewGameDialog.tsx @@ -630,8 +630,8 @@ function onSubmit(appState: AppState): void { // We need to set the game's packet, players, etc. to the values in the uiState const game: GameState = appState.game; game.clear(); - game.addPlayers(firstTeamPlayers.filter((player) => player.name !== "")); - game.addPlayers(secondTeamPlayers.filter((player) => player.name !== "")); + game.addNewPlayers(firstTeamPlayers.filter((player) => player.name !== "")); + game.addNewPlayers(secondTeamPlayers.filter((player) => player.name !== "")); game.loadPacket(pendingNewGame.packet); game.setGameFormat(pendingNewGame.gameFormat); diff --git a/src/state/DialogState.ts b/src/state/DialogState.ts index 9991a6e..038003d 100644 --- a/src/state/DialogState.ts +++ b/src/state/DialogState.ts @@ -46,12 +46,16 @@ export class DialogState { public hideAddQuestionsDialog(): void { this.addQuestions = undefined; - this.hideModalDialog(); + if (this.visibleDialog === ModalVisibilityStatus.AddQuestions) { + this.hideModalDialog(); + } } public hideCustomizeGameFormatDialog(): void { this.customizeGameFormat = undefined; - this.hideModalDialog(); + if (this.visibleDialog === ModalVisibilityStatus.CustomizeGameFormat) { + this.hideModalDialog(); + } } public hideModalDialog(): void { @@ -60,22 +64,30 @@ export class DialogState { public hideFontDialog(): void { this.fontDialog = undefined; - this.hideModalDialog(); + if (this.visibleDialog === ModalVisibilityStatus.Font) { + this.hideModalDialog(); + } } public hideMessageDialog(): void { this.messageDialog = undefined; - this.hideModalDialog(); + if (this.visibleDialog === ModalVisibilityStatus.Message) { + this.hideModalDialog(); + } } public hideRenamePlayerDialog(): void { this.renamePlayerDialog = undefined; - this.hideModalDialog(); + if (this.visibleDialog === ModalVisibilityStatus.RenamePlayer) { + this.hideModalDialog(); + } } public hideReorderPlayersDialog(): void { this.reorderPlayersDialog = undefined; - this.hideModalDialog(); + if (this.visibleDialog === ModalVisibilityStatus.ReorderPlayers) { + this.hideModalDialog(); + } } public showAddQuestionsDialog(): void { @@ -155,7 +167,7 @@ export class DialogState { message, type: MessageDialogType.YesNocCancel, onOK: onYes, - onNo, + onNo: onNo, }; this.visibleDialog = ModalVisibilityStatus.Message; } diff --git a/src/state/GameState.ts b/src/state/GameState.ts index d29ac77..15aacc5 100644 --- a/src/state/GameState.ts +++ b/src/state/GameState.ts @@ -2,6 +2,7 @@ import { computed, observable, action, makeObservable, when } from "mobx"; import { format } from "mobx-sync"; import * as GameFormats from "./GameFormats"; +import * as PlayerUtils from "./PlayerUtils"; import { PacketState, Bonus, Tossup } from "./PacketState"; import { IPlayer, Player } from "./TeamState"; import { Cycle, ICycle } from "./Cycle"; @@ -53,8 +54,9 @@ export class GameState { finalScore: computed, playableCycles: computed, scores: computed, - addPlayer: action, - addPlayers: action, + addInactivePlayer: action, + addNewPlayer: action, + addNewPlayers: action, clear: action, loadPacket: action, setCycles: action, @@ -238,11 +240,105 @@ export class GameState { ]; } - public addPlayer(player: Player): void { + public addInactivePlayer(player: Player, cycleIndex: number): void { + for (let i = cycleIndex; i >= 0; i--) { + const cycle: Cycle = this.cycles[i]; + + if ( + cycle.playerJoins && + cycle.playerJoins.some((joinEvent) => PlayerUtils.playersEqual(player, joinEvent.inPlayer)) + ) { + // We have a current or earlier join event with no leave events. Adding a player now is a no-op. + return; + } + + if (cycle.subs) { + if (cycle.subs.some((subEvent) => PlayerUtils.playersEqual(player, subEvent.inPlayer))) { + // We have a current or earlier join event with no leave events. Adding a player now is a no-op. + return; + } else if (cycle.subs.some((subEvent) => PlayerUtils.playersEqual(player, subEvent.outPlayer))) { + // Need to test subbing someone out and also having them join. Very strange set of events. + break; + } + } + + if ( + cycle.playerLeaves && + cycle.playerLeaves.some((leaveEvent) => PlayerUtils.playersEqual(player, leaveEvent.outPlayer)) + ) { + // If it's the same cycle as the current one, remove the playerLeaves event, since this has priority + // as we're explicitly adding it afterwards + if (i == cycleIndex) { + const leaveEvent: IPlayerLeavesEvent | undefined = cycle.playerLeaves.find((leaveEvent) => + PlayerUtils.playersEqual(player, leaveEvent.outPlayer) + ); + + if (leaveEvent != undefined) { + cycle.removePlayerLeaves(leaveEvent); + } + } + + break; + } + } + + for (let i = cycleIndex + 1; i < this.cycles.length; i++) { + const cycle: Cycle = this.cycles[i]; + + if ( + cycle.playerLeaves && + cycle.playerLeaves.some((leaveEvent) => PlayerUtils.playersEqual(player, leaveEvent.outPlayer)) + ) { + break; + } else if ( + cycle.subs && + cycle.subs.some((subEvent) => PlayerUtils.playersEqual(player, subEvent.outPlayer)) + ) { + break; + } + + if (cycle.subs) { + if (cycle.subs.some((subEvent) => PlayerUtils.playersEqual(player, subEvent.inPlayer))) { + // We're adding the player earlier, and there's no leave event. Remove that event and then add the new + // one + const subEvent: IPlayerJoinsEvent | undefined = cycle.subs.find( + (joinEvent) => !PlayerUtils.playersEqual(player, joinEvent.inPlayer) + ); + if (subEvent) { + cycle.removePlayerJoins(subEvent); + } + + break; + } else if (cycle.subs.some((subEvent) => PlayerUtils.playersEqual(player, subEvent.outPlayer))) { + break; + } + } + + if ( + cycle.playerJoins && + cycle.playerJoins.some((joinEvent) => PlayerUtils.playersEqual(player, joinEvent.inPlayer)) + ) { + // We're adding the player earlier, and there's no leave event. Remove that event and then add the new + // one + const joinEvent: IPlayerJoinsEvent | undefined = cycle.playerJoins.find((joinEvent) => + PlayerUtils.playersEqual(player, joinEvent.inPlayer) + ); + if (joinEvent) { + cycle.removePlayerJoins(joinEvent); + } + + break; + } + } + + this.cycles[cycleIndex].addPlayerJoins(player); + } + + public addNewPlayer(player: Player): void { this.players.push(player); } - public addPlayers(players: Player[]): void { + public addNewPlayers(players: Player[]): void { this.players.push(...players); } diff --git a/tests/AddInactivePlayerTets.ts b/tests/AddInactivePlayerTets.ts new file mode 100644 index 0000000..9f122eb --- /dev/null +++ b/tests/AddInactivePlayerTets.ts @@ -0,0 +1,235 @@ +import { assert, expect } from "chai"; +import { AppState } from "src/state/AppState"; +import { Cycle } from "src/state/Cycle"; +import { GameState } from "src/state/GameState"; +import { PacketState, Tossup } from "src/state/PacketState"; +import { Player } from "src/state/TeamState"; + +const defaultPacket: PacketState = new PacketState(); +defaultPacket.setTossups([ + new Tossup("first q", "first a"), + new Tossup("second q", "second a"), + new Tossup("thrid q", "third a"), + new Tossup("fourth q", "fourth a"), + new Tossup("fifth q", "fifth a"), +]); + +const defaultTeamNames: string[] = ["Alpha", "Beta"]; + +const defaultExistingPlayers: Player[] = [ + new Player("Alice", defaultTeamNames[0], true), + new Player("Arthur", defaultTeamNames[0], false), + new Player("Bob", defaultTeamNames[1], true), + new Player("Betty", defaultTeamNames[1], false), +]; + +const defaultInactivePlayer: Player = new Player("Anna", defaultTeamNames[0], false); + +function initializeApp(): AppState { + const gameState: GameState = new GameState(); + gameState.loadPacket(defaultPacket); + + gameState.addNewPlayers(defaultExistingPlayers); + + AppState.resetInstance(); + const appState: AppState = AppState.instance; + appState.game = gameState; + appState.game.addNewPlayer(defaultInactivePlayer); + return appState; +} + +function assertPlayerJoin(cycle: Cycle, player: Player): void { + const joinEvents = cycle.playerJoins; + if (joinEvents == undefined) { + assert.fail("No join events found for this cycle"); + } + + expect(joinEvents[0].inPlayer).to.equal(player); +} + +describe("AddInactivePlayerTests", () => { + it("addInactivePlayer in first cycle", () => { + const appState: AppState = initializeApp(); + appState.game.addInactivePlayer(defaultInactivePlayer, 0); + const firstPlayers: Set = appState.game.getActivePlayers(defaultInactivePlayer.teamName, 0); + expect(firstPlayers.has(defaultInactivePlayer)).to.be.true; + + const lastPlayers: Set = appState.game.getActivePlayers( + defaultInactivePlayer.teamName, + appState.game.cycles.length - 1 + ); + expect(lastPlayers.has(defaultInactivePlayer)).to.be.true; + }); + it("addInactivePlayer in second cycle", () => { + const appState: AppState = initializeApp(); + appState.game.addInactivePlayer(defaultInactivePlayer, 1); + const beforePlayers: Set = appState.game.getActivePlayers(defaultInactivePlayer.teamName, 0); + expect(beforePlayers.has(defaultInactivePlayer)).to.be.false; + + const players: Set = appState.game.getActivePlayers(defaultInactivePlayer.teamName, 1); + expect(players.has(defaultInactivePlayer)).to.be.true; + }); + it("addInactivePlayer after they've joined before does nothing", () => { + const appState: AppState = initializeApp(); + appState.game.cycles[0].addPlayerJoins(defaultInactivePlayer); + appState.game.addInactivePlayer(defaultInactivePlayer, 1); + expect(appState.game.cycles[1].playerJoins).to.be.undefined; + assertPlayerJoin(appState.game.cycles[0], defaultInactivePlayer); + }); + it("addInactivePlayer before they've joined replaces joined event", () => { + const appState: AppState = initializeApp(); + appState.game.cycles[2].addPlayerJoins(defaultInactivePlayer); + appState.game.addInactivePlayer(defaultInactivePlayer, 1); + expect(appState.game.cycles[2].playerJoins).to.be.empty; + expect(appState.game.cycles[2].playerLeaves).to.be.undefined; + expect(appState.game.cycles[2].subs).to.be.undefined; + + assertPlayerJoin(appState.game.cycles[1], defaultInactivePlayer); + }); + it("addInactivePlayer after they've joined and left adds them back", () => { + const appState: AppState = initializeApp(); + appState.game.cycles[0].addPlayerJoins(defaultInactivePlayer); + appState.game.cycles[1].addPlayerLeaves(defaultInactivePlayer); + appState.game.addInactivePlayer(defaultInactivePlayer, 2); + + assertPlayerJoin(appState.game.cycles[0], defaultInactivePlayer); + assertPlayerJoin(appState.game.cycles[2], defaultInactivePlayer); + + const firstCyclePlayers: Set = appState.game.getActivePlayers(defaultInactivePlayer.teamName, 0); + expect(firstCyclePlayers.has(defaultInactivePlayer)).to.be.true; + const secondCyclePlayers: Set = appState.game.getActivePlayers(defaultInactivePlayer.teamName, 1); + expect(secondCyclePlayers.has(defaultInactivePlayer)).to.be.false; + const thirdCyclePlayers: Set = appState.game.getActivePlayers(defaultInactivePlayer.teamName, 2); + expect(thirdCyclePlayers.has(defaultInactivePlayer)).to.be.true; + }); + it("addInactivePlayer, leave after and then join after still adds the player", () => { + const appState: AppState = initializeApp(); + const playerToLeave: Player = defaultExistingPlayers[0]; + + appState.game.cycles[3].addPlayerJoins(playerToLeave); + appState.game.cycles[2].addPlayerLeaves(playerToLeave); + appState.game.addInactivePlayer(playerToLeave, 1); + + assertPlayerJoin(appState.game.cycles[1], playerToLeave); + assertPlayerJoin(appState.game.cycles[3], playerToLeave); + + const thirdCycleLeaveEvents = appState.game.cycles[2].playerLeaves; + if (thirdCycleLeaveEvents == undefined) { + assert.fail("No leave events found for the third cycle"); + } + + expect(thirdCycleLeaveEvents[0].outPlayer).to.equal(playerToLeave); + }); + it("addInactivePlayer after leave adds the player", () => { + const appState: AppState = initializeApp(); + const playerToLeave: Player = defaultExistingPlayers[0]; + appState.game.cycles[1].addPlayerLeaves(playerToLeave); + appState.game.addInactivePlayer(playerToLeave, 2); + + assertPlayerJoin(appState.game.cycles[2], playerToLeave); + + const secondCycleLeaveEvents = appState.game.cycles[1].playerLeaves; + if (secondCycleLeaveEvents == undefined) { + assert.fail("No leave events found for the second cycle"); + } + + expect(secondCycleLeaveEvents[0].outPlayer).to.equal(playerToLeave); + }); + it("addInactivePlayer but player was already subbed in", () => { + const appState: AppState = initializeApp(); + appState.game.cycles[1].addSwapSubstitution(defaultInactivePlayer, defaultExistingPlayers[0]); + appState.game.addInactivePlayer(defaultInactivePlayer, 3); + + expect(appState.game.cycles[3].playerJoins).to.be.undefined; + + const secondCycleSubEvents = appState.game.cycles[1].subs; + if (secondCycleSubEvents == undefined) { + assert.fail("No sub events found for the second cycle"); + } + + expect(secondCycleSubEvents[0].inPlayer).to.equal(defaultInactivePlayer); + }); + it("addInactivePlayer but player is subbed in later", () => { + const appState: AppState = initializeApp(); + appState.game.cycles[3].addSwapSubstitution(defaultInactivePlayer, defaultExistingPlayers[0]); + appState.game.addInactivePlayer(defaultInactivePlayer, 1); + + assertPlayerJoin(appState.game.cycles[1], defaultInactivePlayer); + + const fourthCycleSubEvents = appState.game.cycles[3].subs; + if (fourthCycleSubEvents == undefined) { + assert.fail("No sub events found for the fourth cycle"); + } + + expect(fourthCycleSubEvents.length).to.equal(1); + }); + it("addInactivePlayer, player subbed in but then left", () => { + const appState: AppState = initializeApp(); + const player: Player = defaultExistingPlayers[0]; + appState.game.cycles[1].addSwapSubstitution(defaultInactivePlayer, player); + appState.game.addInactivePlayer(player, 3); + + assertPlayerJoin(appState.game.cycles[3], player); + + const secondCycleSubEvents = appState.game.cycles[1].subs; + if (secondCycleSubEvents == undefined) { + assert.fail("No sub events found for the second cycle"); + } + + expect(secondCycleSubEvents[0].inPlayer).to.equal(defaultInactivePlayer); + expect(secondCycleSubEvents[0].outPlayer).to.equal(player); + }); + it("addInactivePlayer subbed in after they leave", () => { + const appState: AppState = initializeApp(); + appState.game.cycles[3].addSwapSubstitution(defaultInactivePlayer, defaultExistingPlayers[0]); + appState.game.cycles[2].addPlayerLeaves(defaultInactivePlayer); + appState.game.addInactivePlayer(defaultInactivePlayer, 1); + + assertPlayerJoin(appState.game.cycles[1], defaultInactivePlayer); + + const secondCycleSubEvents = appState.game.cycles[3].subs; + if (secondCycleSubEvents == undefined) { + assert.fail("No sub events found for the second cycle"); + } + + expect(secondCycleSubEvents[0].inPlayer).to.equal(defaultInactivePlayer); + }); + it("addInactivePlayer after they were subbed out", () => { + const appState: AppState = initializeApp(); + appState.game.cycles[3].addSwapSubstitution(defaultInactivePlayer, defaultExistingPlayers[0]); + appState.game.cycles[2].addPlayerLeaves(defaultInactivePlayer); + appState.game.addInactivePlayer(defaultInactivePlayer, 1); + + assertPlayerJoin(appState.game.cycles[1], defaultInactivePlayer); + + const secondCycleSubEvents = appState.game.cycles[3].subs; + if (secondCycleSubEvents == undefined) { + assert.fail("No sub events found for the second cycle"); + } + + expect(secondCycleSubEvents[0].inPlayer).to.equal(defaultInactivePlayer); + }); + + it("addInactivePlayer in second cycle with different team", () => { + const appState: AppState = initializeApp(); + + const newPlayer: Player = new Player("Bill", defaultTeamNames[1], false); + appState.game.addNewPlayer(newPlayer); + appState.game.addInactivePlayer(newPlayer, 1); + const beforePlayers: Set = appState.game.getActivePlayers(newPlayer.teamName, 0); + expect(beforePlayers.has(newPlayer)).to.be.false; + + const players: Set = appState.game.getActivePlayers(newPlayer.teamName, 1); + expect(players.has(newPlayer)).to.be.true; + }); + it("addInactivePlayer with same name from different team", () => { + const appState: AppState = initializeApp(); + + const newPlayer: Player = new Player(defaultInactivePlayer.name, defaultTeamNames[1], false); + appState.game.addNewPlayer(newPlayer); + appState.game.addInactivePlayer(newPlayer, 0); + const players: Set = appState.game.getActivePlayers(newPlayer.teamName, 0); + expect(players.has(defaultInactivePlayer)).to.be.false; + expect(players.has(newPlayer)).to.be.true; + }); +}); diff --git a/tests/AddPlayerDialogControllerTests.ts b/tests/AddPlayerDialogControllerTests.ts index 8160230..9c583b8 100644 --- a/tests/AddPlayerDialogControllerTests.ts +++ b/tests/AddPlayerDialogControllerTests.ts @@ -21,7 +21,7 @@ function initializeApp(): AppState { new Player("Faye", defaultTeamNames[0], true), new Player("Saul", defaultTeamNames[1], true), ]; - gameState.addPlayers(defaultExistingPlayers); + gameState.addNewPlayers(defaultExistingPlayers); AppState.resetInstance(); const appState: AppState = AppState.instance; diff --git a/tests/AddQuestionsDialogControllerTests.ts b/tests/AddQuestionsDialogControllerTests.ts index 9c25416..ca116cc 100644 --- a/tests/AddQuestionsDialogControllerTests.ts +++ b/tests/AddQuestionsDialogControllerTests.ts @@ -26,7 +26,7 @@ function initializeApp(): AppState { new Player("Faye", defaultTeamNames[0], true), new Player("Saul", defaultTeamNames[1], true), ]; - gameState.addPlayers(defaultExistingPlayers); + gameState.addNewPlayers(defaultExistingPlayers); AppState.resetInstance(); const appState: AppState = AppState.instance; diff --git a/tests/BonusProtestDialogControllerTests.ts b/tests/BonusProtestDialogControllerTests.ts index 6984f09..27d5616 100644 --- a/tests/BonusProtestDialogControllerTests.ts +++ b/tests/BonusProtestDialogControllerTests.ts @@ -23,7 +23,7 @@ function initializeApp(buzzerProtests = true): AppState { new Player("Faye", defaultTeamNames[0], true), new Player("Saul", defaultTeamNames[1], true), ]; - gameState.addPlayers(defaultExistingPlayers); + gameState.addNewPlayers(defaultExistingPlayers); AppState.resetInstance(); const appState: AppState = AppState.instance; diff --git a/tests/BonusQuestionControllerTests.ts b/tests/BonusQuestionControllerTests.ts index c64efe3..22b54fc 100644 --- a/tests/BonusQuestionControllerTests.ts +++ b/tests/BonusQuestionControllerTests.ts @@ -12,7 +12,7 @@ describe("BonusQuestionControllerTests", () => { it("Throw out Bonus", () => { AppState.resetInstance(); const appState: AppState = AppState.instance; - appState.game.addPlayers([new Player("Alice", "Alpha", true), new Player("Bob", "Beta", true)]); + appState.game.addNewPlayers([new Player("Alice", "Alpha", true), new Player("Bob", "Beta", true)]); const packet: PacketState = new PacketState(); packet.setTossups([ diff --git a/tests/GetActivePlayersTests.ts b/tests/GetActivePlayersTests.ts index cc058d8..dc1b28c 100644 --- a/tests/GetActivePlayersTests.ts +++ b/tests/GetActivePlayersTests.ts @@ -28,7 +28,7 @@ describe("GameStateTests", () => { it("All starters no subs", () => { const game: GameState = new GameState(); game.setCycles([new Cycle(), new Cycle()]); - game.addPlayers(allStarters); + game.addNewPlayers(allStarters); allPlayersInSet(game.getActivePlayers(firstTeamName, 0), firstTeamStarters); allPlayersInSet(game.getActivePlayers(secondTeamName, 0), secondTeamStarters); @@ -40,7 +40,7 @@ describe("GameStateTests", () => { it("Some non-starters no subs", () => { const game: GameState = new GameState(); game.setCycles([new Cycle(), new Cycle()]); - game.addPlayers(allPlayers); + game.addNewPlayers(allPlayers); expect(game.getPlayers(firstTeamName)).to.deep.equal( allPlayers.filter((player) => player.teamName === firstTeamName) @@ -59,7 +59,7 @@ describe("GameStateTests", () => { it("Some non-starters, all subbed", () => { const game: GameState = new GameState(); game.setCycles([new Cycle(), new Cycle(), new Cycle()]); - game.addPlayers(allPlayers); + game.addNewPlayers(allPlayers); const lastCycleIndex: number = game.cycles.length - 1; const subCycleIndex = 1; @@ -88,7 +88,7 @@ describe("GameStateTests", () => { it("New player joins", () => { const game: GameState = new GameState(); game.setCycles([new Cycle(), new Cycle(), new Cycle()]); - game.addPlayers(allPlayers); + game.addNewPlayers(allPlayers); const lastCycleIndex: number = game.cycles.length - 1; const joinCycleIndex = 1; @@ -96,7 +96,7 @@ describe("GameStateTests", () => { const newFirstTeamPlayer = new Player("Antonio", firstTeamName, /* isStarter */ false); const newSecondTeamPlayer = new Player("Belle", secondTeamName, /* isStarter */ false); - game.addPlayers([newFirstTeamPlayer, newSecondTeamPlayer]); + game.addNewPlayers([newFirstTeamPlayer, newSecondTeamPlayer]); game.cycles[joinCycleIndex].addPlayerJoins(newFirstTeamPlayer); game.cycles[joinCycleIndex].addPlayerJoins(newSecondTeamPlayer); @@ -121,7 +121,7 @@ describe("GameStateTests", () => { it("Player leaves", () => { const game: GameState = new GameState(); game.setCycles([new Cycle(), new Cycle(), new Cycle()]); - game.addPlayers(allPlayers); + game.addNewPlayers(allPlayers); const lastCycleIndex: number = game.cycles.length - 1; const joinCycleIndex = 1; @@ -154,7 +154,7 @@ describe("GameStateTests", () => { it("Subbed in then subbed out", () => { const game: GameState = new GameState(); game.setCycles([new Cycle(), new Cycle(), new Cycle()]); - game.addPlayers(allPlayers); + game.addNewPlayers(allPlayers); const lastCycleIndex: number = game.cycles.length - 1; const subCycleIndex: number = lastCycleIndex - 1; diff --git a/tests/GetBonusIndexTests.ts b/tests/GetBonusIndexTests.ts index bde5b56..d002db5 100644 --- a/tests/GetBonusIndexTests.ts +++ b/tests/GetBonusIndexTests.ts @@ -358,7 +358,7 @@ describe("GameStateTests", () => { function createDefaultGame(pairTossupsBonuses?: boolean): GameState { const game: GameState = new GameState(); - game.addPlayers(players); + game.addNewPlayers(players); game.loadPacket(defaultPacket); if (pairTossupsBonuses) { diff --git a/tests/GetTossupIndexTests.ts b/tests/GetTossupIndexTests.ts index beeacd5..04b6542 100644 --- a/tests/GetTossupIndexTests.ts +++ b/tests/GetTossupIndexTests.ts @@ -57,7 +57,7 @@ describe("GameStateTests", () => { function createDefaultGame(): GameState { const game: GameState = new GameState(); - game.addPlayers(players); + game.addNewPlayers(players); game.loadPacket(defaultPacket); return game; } diff --git a/tests/ProtestsMatterTests.ts b/tests/ProtestsMatterTests.ts index c08247f..3522289 100644 --- a/tests/ProtestsMatterTests.ts +++ b/tests/ProtestsMatterTests.ts @@ -225,7 +225,7 @@ describe("GameStateTests", () => { function createDefaultGame(): GameState { const game: GameState = new GameState(); - game.addPlayers(players); + game.addNewPlayers(players); game.loadPacket(defaultPacket); return game; } diff --git a/tests/QBJTests.ts b/tests/QBJTests.ts index 86b0004..9c41042 100644 --- a/tests/QBJTests.ts +++ b/tests/QBJTests.ts @@ -56,7 +56,7 @@ function verifyBuzz(buzz: QBJ.IMatchQuestionBuzz, player: Player, position: numb function verifyQBJ(updateGame: (game: GameState) => void, verifyMatch: (match: IMatch, game: GameState) => void): void { const game: GameState = new GameState(); game.loadPacket(defaultPacket); - game.addPlayers(players); + game.addNewPlayers(players); updateGame(game); const qbj: string = QBJ.toQBJString(game); @@ -848,7 +848,7 @@ describe("QBJTests", () => { verifyQBJ( (game) => { game.clear(); - game.addPlayers(players); + game.addNewPlayers(players); const packet: PacketState = new PacketState(); packet.setTossups([ @@ -937,7 +937,7 @@ describe("QBJTests", () => { it("Packet name in packets field", () => { const game: GameState = new GameState(); game.loadPacket(defaultPacket); - game.addPlayers(players); + game.addNewPlayers(players); const qbj: string = QBJ.toQBJString(game, "Packet_17.docx"); expect(qbj).to.not.be.undefined; @@ -947,7 +947,7 @@ describe("QBJTests", () => { it("Round number in _round field", () => { const game: GameState = new GameState(); game.loadPacket(defaultPacket); - game.addPlayers(players); + game.addNewPlayers(players); const qbj: string = QBJ.toQBJString(game, "Packet_The_U.docx", 5); expect(qbj).to.not.be.undefined; diff --git a/tests/RenamePlayerDialogControllerTests.ts b/tests/RenamePlayerDialogControllerTests.ts index 8c32c37..4026e5f 100644 --- a/tests/RenamePlayerDialogControllerTests.ts +++ b/tests/RenamePlayerDialogControllerTests.ts @@ -33,7 +33,7 @@ function initializeApp(player: Player | undefined = undefined): { appState: AppS gameState.loadPacket(defaultPacket); const players: Player[] = createDefaultExistingPlayers(); - gameState.addPlayers(players); + gameState.addNewPlayers(players); if (player == undefined) { player = players[0]; @@ -191,14 +191,14 @@ describe("RenamePlayerDialogControllerTests", () => { gameState.loadPacket(defaultPacket); const players: Player[] = createDefaultExistingPlayers(); - gameState.addPlayers(players); + gameState.addNewPlayers(players); AppState.resetInstance(); const appState: AppState = AppState.instance; appState.game = gameState; const originalPlayer: Player = new Player("Arty", defaultTeamNames[0], false); - gameState.addPlayer(originalPlayer); + gameState.addNewPlayer(originalPlayer); gameState.cycles[1].addPlayerJoins(originalPlayer); gameState.cycles[2].addSwapSubstitution(players[players.length - 1], originalPlayer); diff --git a/tests/ReorderPlayersDialogControllerTests.ts b/tests/ReorderPlayersDialogControllerTests.ts index 284f85b..c5e8cc8 100644 --- a/tests/ReorderPlayersDialogControllerTests.ts +++ b/tests/ReorderPlayersDialogControllerTests.ts @@ -40,7 +40,7 @@ function initializeApp(players?: Player[]): { appState: AppState; players: Playe gameState.loadPacket(defaultPacket); players = players ?? defaultExistingPlayers; - gameState.addPlayers(players); + gameState.addNewPlayers(players); AppState.resetInstance(); const appState: AppState = AppState.instance; diff --git a/tests/ScoreTests.ts b/tests/ScoreTests.ts index c55c230..798b625 100644 --- a/tests/ScoreTests.ts +++ b/tests/ScoreTests.ts @@ -28,7 +28,7 @@ describe("GameStateTests", () => { it("Game with more than two teams", () => { const game: GameState = new GameState(); const thirdPlayer: Player = new Player("Charlie", "C", /* isStarter */ true); - game.addPlayers(players.concat(thirdPlayer)); + game.addNewPlayers(players.concat(thirdPlayer)); game.loadPacket(defaultPacket); game.setGameFormat(GameFormats.StandardPowersMACFGameFormat); expect(game.scores[0]).to.deep.equal([0, 0, 0]); @@ -203,7 +203,7 @@ describe("GameStateTests", () => { function createDefaultGame(): GameState { const game: GameState = new GameState(); - game.addPlayers(players); + game.addNewPlayers(players); game.loadPacket(defaultPacket); game.setGameFormat(GameFormats.StandardPowersMACFGameFormat); return game; diff --git a/tests/SheetsTests.ts b/tests/SheetsTests.ts index 3204a0b..ebda6aa 100644 --- a/tests/SheetsTests.ts +++ b/tests/SheetsTests.ts @@ -38,7 +38,7 @@ function createMockApi(mocks: Partial): ISheetsApi { function createAppStateForExport(sheetType: SheetType = SheetType.Lifsheets): AppState { const appState: AppState = new AppState(); - appState.game.addPlayers([new Player("Alice", "Alpha", true), new Player("Bob", "Beta", true)]); + appState.game.addNewPlayers([new Player("Alice", "Alpha", true), new Player("Bob", "Beta", true)]); const packet: PacketState = new PacketState(); packet.setTossups([new Tossup("This tossup has five words.", "A")]); @@ -769,7 +769,7 @@ describe("SheetsTests", () => { const starter: Player = findPlayerOnTeam(appState, "Alpha"); const sub = new Player("Adam", "Alpha", /* isStarter */ false); - appState.game.addPlayer(sub); + appState.game.addNewPlayer(sub); const packet: PacketState = new PacketState(); const tossups: Tossup[] = []; @@ -824,7 +824,7 @@ describe("SheetsTests", () => { const starter: Player = findPlayerOnTeam(appState, "Beta"); const sub = new Player("Barbara", "Beta", /* isStarter */ false); - appState.game.addPlayer(sub); + appState.game.addNewPlayer(sub); const packet: PacketState = new PacketState(); const tossups: Tossup[] = []; @@ -951,7 +951,7 @@ describe("SheetsTests", () => { const moreThanTwoTeamsTest = async (sheetType: SheetType) => { const appState: AppState = createAppStateForExport(sheetType); - appState.game.addPlayer(new Player("Gail", "Gamma", true)); + appState.game.addNewPlayer(new Player("Gail", "Gamma", true)); await verifyExportToSheetsError( appState, @@ -976,7 +976,7 @@ describe("SheetsTests", () => { const alphaPlayersCount: number = appState.game.players.filter((player) => player.teamName === "Alpha") .length; for (let i = 0; i < 6 - alphaPlayersCount; i++) { - appState.game.addPlayer(new Player(`New${i}`, "Alpha", false)); + appState.game.addNewPlayer(new Player(`New${i}`, "Alpha", false)); } await Sheets.exportToSheet(appState, defaultMockSheetsApi); @@ -1003,7 +1003,7 @@ describe("SheetsTests", () => { const alphaPlayersCount: number = appState.game.players.filter((player) => player.teamName === "Alpha") .length; for (let i = 0; i < 7 - alphaPlayersCount; i++) { - appState.game.addPlayer(new Player(`New${i}`, "Alpha", false)); + appState.game.addNewPlayer(new Player(`New${i}`, "Alpha", false)); } await verifyExportToSheetsError( diff --git a/tests/TossupProtestDialogControllerTests.ts b/tests/TossupProtestDialogControllerTests.ts index 81b5b53..da20ef5 100644 --- a/tests/TossupProtestDialogControllerTests.ts +++ b/tests/TossupProtestDialogControllerTests.ts @@ -23,7 +23,7 @@ function initializeApp(buzzerProtests = true): AppState { const gameState: GameState = new GameState(); gameState.loadPacket(defaultPacket); - gameState.addPlayers(defaultExistingPlayers); + gameState.addNewPlayers(defaultExistingPlayers); AppState.resetInstance(); const appState: AppState = AppState.instance; diff --git a/tests/TossupQuestionControllerTests.ts b/tests/TossupQuestionControllerTests.ts index 7717c82..56c3a19 100644 --- a/tests/TossupQuestionControllerTests.ts +++ b/tests/TossupQuestionControllerTests.ts @@ -11,7 +11,7 @@ describe("TossupQuestionControllerTests", () => { it("Throw out Tossup", () => { AppState.resetInstance(); const appState: AppState = AppState.instance; - appState.game.addPlayers([new Player("Alice", "Alpha", true), new Player("Bob", "Beta", true)]); + appState.game.addNewPlayers([new Player("Alice", "Alpha", true), new Player("Bob", "Beta", true)]); const packet: PacketState = new PacketState(); packet.setTossups([