preparing to redefine some actions
This commit is contained in:
1425
package-lock.json
generated
1425
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -17,10 +17,12 @@
|
|||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@testing-library/react": "^13.3.0",
|
||||||
"@types/react": "^18.0.15",
|
"@types/react": "^18.0.15",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.6",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^8.3.4",
|
||||||
"@vitejs/plugin-react": "^2.0.0",
|
"@vitejs/plugin-react": "^2.0.0",
|
||||||
|
"jsdom": "^20.0.0",
|
||||||
"typescript": "^4.6.4",
|
"typescript": "^4.6.4",
|
||||||
"vite": "^3.0.0",
|
"vite": "^3.0.0",
|
||||||
"vitest": "^0.20.2"
|
"vitest": "^0.20.2"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export default function Card({ data, state, setState }: CardProps) {
|
|||||||
}
|
}
|
||||||
{ state.actions.buyCard.active &&
|
{ state.actions.buyCard.active &&
|
||||||
<button
|
<button
|
||||||
onClick={() => buyCard(data, state, setState)}
|
onClick={() => buyCard(state, setState, data)}
|
||||||
disabled={tooExpensive(data, state)}>
|
disabled={tooExpensive(data, state)}>
|
||||||
Buy This Card
|
Buy This Card
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
import { buyCard, getTotalBuyingPower, tooExpensive, updateResources } from './buyCardActions';
|
|
||||||
import { test, expect, describe } from 'vitest';
|
|
||||||
import { expensiveCard, midGameCardOne, midGameState, mockPlayerOne, mockPlayerTwo, mockState } from '../../../util/testUtils';
|
|
||||||
import { useCurrentPlayer } from '../../../util/useCurrentPlayer';
|
|
||||||
|
|
||||||
describe('buy cards', () => {
|
|
||||||
test('detects unaffordable cards', () => {
|
|
||||||
const result = tooExpensive(expensiveCard, mockState);
|
|
||||||
expect(result).toBeTruthy();
|
|
||||||
})
|
|
||||||
|
|
||||||
test('calculates total buying power', () => {
|
|
||||||
let modifiedState = {
|
|
||||||
...mockState,
|
|
||||||
players: [
|
|
||||||
{
|
|
||||||
...mockPlayerOne,
|
|
||||||
inventory: {
|
|
||||||
ruby: 3,
|
|
||||||
sapphire: 3,
|
|
||||||
emerald: 3,
|
|
||||||
onyx: 3,
|
|
||||||
diamond: 3,
|
|
||||||
gold: 3
|
|
||||||
},
|
|
||||||
cards: [expensiveCard]
|
|
||||||
},
|
|
||||||
mockPlayerTwo
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
const totalBuyingPower = getTotalBuyingPower(modifiedState);
|
|
||||||
|
|
||||||
const expectedValue = {
|
|
||||||
ruby: 3,
|
|
||||||
sapphire: 3,
|
|
||||||
emerald: 3,
|
|
||||||
onyx: 3,
|
|
||||||
diamond: 4,
|
|
||||||
gold: 3
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(totalBuyingPower).toStrictEqual(expectedValue);
|
|
||||||
})
|
|
||||||
|
|
||||||
test('updateResources', () => {
|
|
||||||
const currentPlayer = useCurrentPlayer(midGameState);
|
|
||||||
if (!currentPlayer) return;
|
|
||||||
|
|
||||||
const { newTradingResources, updatedPlayer } = updateResources(midGameState, midGameCardOne);
|
|
||||||
expect(newTradingResources).toBeDefined();
|
|
||||||
expect(updatedPlayer).toBeDefined();
|
|
||||||
})
|
|
||||||
|
|
||||||
test('renders the correct inventory', () => {
|
|
||||||
const output = 1;
|
|
||||||
expect(output).toBe(1);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('get chips', () => {})
|
|
||||||
describe('reserve card', () => {})
|
|
||||||
141
src/components/Player/ActionMethods/buyCard.test.ts
Normal file
141
src/components/Player/ActionMethods/buyCard.test.ts
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
import { expensiveCard, midGameCardOne, midGameCardTwo, midGameState, mockPlayerOne, mockPlayerTwo, mockState, playerTwoMidGame } from '../../../util/testUtils';
|
||||||
|
import { buyCard, tooExpensive } from './buyCardActions';
|
||||||
|
import getTotalBuyingPower from '../../../util/getTotalBuyingPower';
|
||||||
|
import { useCurrentPlayer } from '../../../util/useCurrentPlayer';
|
||||||
|
import { AppState, PlayerData } from '../../../util/types';
|
||||||
|
import { test, expect, describe } from 'vitest';
|
||||||
|
import { renderHook } from "@testing-library/react";
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { initialState } from '../../../util/stateSetters';
|
||||||
|
|
||||||
|
describe('buy cards', () => {
|
||||||
|
test('detects unaffordable cards', () => {
|
||||||
|
const result = tooExpensive(expensiveCard, mockState);
|
||||||
|
expect(result).toBeTruthy();
|
||||||
|
})
|
||||||
|
|
||||||
|
test('calculates total buying power', () => {
|
||||||
|
let modifiedState = {
|
||||||
|
...mockState,
|
||||||
|
players: [
|
||||||
|
{
|
||||||
|
...mockPlayerOne,
|
||||||
|
inventory: {
|
||||||
|
ruby: 3,
|
||||||
|
sapphire: 3,
|
||||||
|
emerald: 3,
|
||||||
|
onyx: 3,
|
||||||
|
diamond: 3,
|
||||||
|
gold: 3
|
||||||
|
},
|
||||||
|
cards: [expensiveCard]
|
||||||
|
},
|
||||||
|
mockPlayerTwo
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalBuyingPower = getTotalBuyingPower(modifiedState);
|
||||||
|
|
||||||
|
const expectedValue = {
|
||||||
|
ruby: 3,
|
||||||
|
sapphire: 3,
|
||||||
|
emerald: 3,
|
||||||
|
onyx: 3,
|
||||||
|
diamond: 4,
|
||||||
|
gold: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(totalBuyingPower).toStrictEqual(expectedValue);
|
||||||
|
})
|
||||||
|
|
||||||
|
test('buyCard and updateResources', () => {
|
||||||
|
const { result } = renderHook(() => {
|
||||||
|
const [state, setState] = useState(midGameState);
|
||||||
|
|
||||||
|
return { state, setState }
|
||||||
|
})
|
||||||
|
|
||||||
|
const { state, setState } = result.current;
|
||||||
|
|
||||||
|
const currentPlayer = useCurrentPlayer(state);
|
||||||
|
if (!currentPlayer) return;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* actions in test:
|
||||||
|
* midGameState :: playerOneMidGame, playerTwoMidGame
|
||||||
|
* playerOneMidGame => buy midGameCardTwo
|
||||||
|
* playerTwoMidGame => buy midGameCardOne
|
||||||
|
*/
|
||||||
|
|
||||||
|
let P1UPDATED = state.players.filter((p: PlayerData) => p.name === "Player One")[0];
|
||||||
|
let P2UPDATED = state.players.filter((p: PlayerData) => p.name === "Player Two")[0];
|
||||||
|
|
||||||
|
// playerOne receives midGameCardTwo and pays three diamonds back to resource pool
|
||||||
|
P1UPDATED = {
|
||||||
|
...P1UPDATED,
|
||||||
|
cards: [...P1UPDATED.cards, midGameCardTwo],
|
||||||
|
turnActive: false,
|
||||||
|
inventory: {
|
||||||
|
...P1UPDATED.inventory,
|
||||||
|
diamond: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
P2UPDATED = { ...P2UPDATED, turnActive: true }
|
||||||
|
|
||||||
|
const moveOneExpectedState: AppState = {
|
||||||
|
...state,
|
||||||
|
players: [P1UPDATED, P2UPDATED],
|
||||||
|
gameboard: {
|
||||||
|
...state.gameboard,
|
||||||
|
tradingResources: {
|
||||||
|
...state.gameboard.tradingResources,
|
||||||
|
diamond: 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// first player action
|
||||||
|
// @ts-ignore
|
||||||
|
const newState = buyCard(state, setState, midGameCardTwo);
|
||||||
|
expect(newState).toStrictEqual(moveOneExpectedState);
|
||||||
|
|
||||||
|
// playerTwo receives midGameCardOne and pays four rubies back to resource pool
|
||||||
|
P2UPDATED = {
|
||||||
|
...P2UPDATED,
|
||||||
|
cards: [...P2UPDATED.cards, midGameCardOne],
|
||||||
|
turnActive: false,
|
||||||
|
inventory: {
|
||||||
|
...P2UPDATED.inventory,
|
||||||
|
ruby: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
P1UPDATED = { ...P1UPDATED, turnActive: true }
|
||||||
|
|
||||||
|
const moveTwoExpectedState: AppState = {
|
||||||
|
...moveOneExpectedState,
|
||||||
|
players: [P1UPDATED, P2UPDATED],
|
||||||
|
gameboard: {
|
||||||
|
...moveOneExpectedState.gameboard,
|
||||||
|
tradingResources: {
|
||||||
|
...moveOneExpectedState.gameboard.tradingResources,
|
||||||
|
ruby: 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
if (!newState) throw Error();
|
||||||
|
}).not.toThrowError();
|
||||||
|
|
||||||
|
if (newState) {
|
||||||
|
// @ts-ignore
|
||||||
|
const finalState = buyCard(newState, setState, midGameCardOne);
|
||||||
|
expect(finalState).toStrictEqual(moveTwoExpectedState);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// describe('get chips', () => {})
|
||||||
|
// describe('reserve card', () => {})
|
||||||
@@ -2,31 +2,32 @@ import { initialActions } from "../../../util/stateSetters";
|
|||||||
import { turnOrderUtil } from "../../../util/turnOrderUtil";
|
import { turnOrderUtil } from "../../../util/turnOrderUtil";
|
||||||
import { AppState, CardData, ResourceCost, setStateType } from "../../../util/types";
|
import { AppState, CardData, ResourceCost, setStateType } from "../../../util/types";
|
||||||
import { useCurrentPlayer } from "../../../util/useCurrentPlayer";
|
import { useCurrentPlayer } from "../../../util/useCurrentPlayer";
|
||||||
|
import getTotalBuyingPower from "../../../util/getTotalBuyingPower";
|
||||||
|
|
||||||
export const getTotalBuyingPower = (state: AppState) => {
|
// export const _getTotalBuyingPower = (state: AppState) => {
|
||||||
const currentPlayer = useCurrentPlayer(state);
|
// const currentPlayer = useCurrentPlayer(state);
|
||||||
|
|
||||||
let totalBuyingPower = {
|
// let totalBuyingPower = {
|
||||||
ruby: 0,
|
// ruby: 0,
|
||||||
sapphire: 0,
|
// sapphire: 0,
|
||||||
emerald: 0,
|
// emerald: 0,
|
||||||
diamond: 0,
|
// diamond: 0,
|
||||||
onyx: 0,
|
// onyx: 0,
|
||||||
gold: 0,
|
// gold: 0,
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!currentPlayer) return totalBuyingPower;
|
// if (!currentPlayer) return totalBuyingPower;
|
||||||
|
|
||||||
for (let [key,quantity] of Object.entries(currentPlayer.inventory)) {
|
// for (let [key,quantity] of Object.entries(currentPlayer.inventory)) {
|
||||||
totalBuyingPower[key as keyof ResourceCost] += quantity;
|
// totalBuyingPower[key as keyof ResourceCost] += quantity;
|
||||||
}
|
// }
|
||||||
|
|
||||||
for (let each of currentPlayer.cards) {
|
// for (let each of currentPlayer.cards) {
|
||||||
totalBuyingPower[each.gemValue as keyof ResourceCost] += 1;
|
// totalBuyingPower[each.gemValue as keyof ResourceCost] += 1;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return totalBuyingPower;
|
// return totalBuyingPower;
|
||||||
}
|
// }
|
||||||
|
|
||||||
export const tooExpensive = (card: CardData, state: AppState): boolean => {
|
export const tooExpensive = (card: CardData, state: AppState): boolean => {
|
||||||
const currentPlayer = useCurrentPlayer(state);
|
const currentPlayer = useCurrentPlayer(state);
|
||||||
@@ -44,6 +45,7 @@ export const tooExpensive = (card: CardData, state: AppState): boolean => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const updateResources = (state: AppState, card: CardData) => {
|
export const updateResources = (state: AppState, card: CardData) => {
|
||||||
|
console.log('updateResources called');
|
||||||
let currentPlayer = useCurrentPlayer(state);
|
let currentPlayer = useCurrentPlayer(state);
|
||||||
let newTradingResources = state.gameboard.tradingResources;
|
let newTradingResources = state.gameboard.tradingResources;
|
||||||
let updatedPlayer = currentPlayer;
|
let updatedPlayer = currentPlayer;
|
||||||
@@ -64,6 +66,8 @@ export const buyCard = (state: AppState, setState: setStateType, card: CardData)
|
|||||||
let currentPlayer = useCurrentPlayer(state);
|
let currentPlayer = useCurrentPlayer(state);
|
||||||
if (!currentPlayer) return;
|
if (!currentPlayer) return;
|
||||||
const { newPlayers, roundIncrement } = turnOrderUtil(state, currentPlayer);
|
const { newPlayers, roundIncrement } = turnOrderUtil(state, currentPlayer);
|
||||||
|
|
||||||
|
console.log('cleared to setstate');
|
||||||
|
|
||||||
setState((prev: AppState) => {
|
setState((prev: AppState) => {
|
||||||
if (!currentPlayer) return prev;
|
if (!currentPlayer) return prev;
|
||||||
@@ -84,4 +88,7 @@ export const buyCard = (state: AppState, setState: setStateType, card: CardData)
|
|||||||
actions: initialActions
|
actions: initialActions
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// for testing?
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
82
src/components/Player/ActionMethods/getChips.test.ts
Normal file
82
src/components/Player/ActionMethods/getChips.test.ts
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import { describe, expect, it, test } from "vitest";
|
||||||
|
import { initialActions } from "../../../util/stateSetters";
|
||||||
|
import { mockPlayerOne, mockState } from "../../../util/testUtils";
|
||||||
|
import { AppState, PlayerData } from "../../../util/types";
|
||||||
|
import { hasMaxChips, validateChips } from "./getChipsActions";
|
||||||
|
|
||||||
|
const getChipsState: AppState = {
|
||||||
|
...mockState,
|
||||||
|
actions: {
|
||||||
|
...initialActions,
|
||||||
|
getChips: {
|
||||||
|
active: true,
|
||||||
|
selection: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('get chips', () => {
|
||||||
|
test('hasMaxChips', () => {
|
||||||
|
const illegalPlayer: PlayerData = {
|
||||||
|
...mockPlayerOne,
|
||||||
|
inventory: {
|
||||||
|
ruby: 2,
|
||||||
|
sapphire: 2,
|
||||||
|
emerald: 2,
|
||||||
|
diamond: 2,
|
||||||
|
onyx: 2,
|
||||||
|
gold: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(hasMaxChips(illegalPlayer)).toBeTruthy();
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('validateChips', () => {
|
||||||
|
test('is falsy when chips action is not active', () => {
|
||||||
|
expect(validateChips(mockState)).toBeFalsy();
|
||||||
|
})
|
||||||
|
|
||||||
|
test('is falsy when more than three chips selected', () => {
|
||||||
|
const illegalState = getChipsState;
|
||||||
|
illegalState.actions.getChips.selection = ['ruby', 'diamond', 'onyx', 'sapphire']
|
||||||
|
expect(validateChips(illegalState)).toBeFalsy();
|
||||||
|
})
|
||||||
|
|
||||||
|
test('proper handling of duplicates', () => {
|
||||||
|
const illegalState = getChipsState;
|
||||||
|
illegalState.actions.getChips.selection = ['ruby', 'ruby', 'ruby']
|
||||||
|
|
||||||
|
const legalState = getChipsState;
|
||||||
|
legalState.actions.getChips.selection = ['ruby', 'ruby']
|
||||||
|
|
||||||
|
expect(validateChips(illegalState)).toBeFalsy();
|
||||||
|
expect(validateChips(legalState)).toBeTruthy();
|
||||||
|
})
|
||||||
|
|
||||||
|
test('no pickup of unavailable resources', () => {
|
||||||
|
const illegalState = {
|
||||||
|
...mockState,
|
||||||
|
gameboard: {
|
||||||
|
...getChipsState.gameboard,
|
||||||
|
tradingResources: {
|
||||||
|
ruby: 4,
|
||||||
|
sapphire: 4,
|
||||||
|
emerald: 1,
|
||||||
|
diamond: 4,
|
||||||
|
onyx: 2,
|
||||||
|
gold: 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
...initialActions,
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('getChips', () => {
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
27
src/util/getTotalBuyingPower.ts
Normal file
27
src/util/getTotalBuyingPower.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { AppState, CardData, ResourceCost } from "./types";
|
||||||
|
import { useCurrentPlayer } from "./useCurrentPlayer";
|
||||||
|
|
||||||
|
export default function getTotalBuyingPower(state: AppState) {
|
||||||
|
const currentPlayer = useCurrentPlayer(state);
|
||||||
|
|
||||||
|
let totalBuyingPower = {
|
||||||
|
ruby: 0,
|
||||||
|
sapphire: 0,
|
||||||
|
emerald: 0,
|
||||||
|
diamond: 0,
|
||||||
|
onyx: 0,
|
||||||
|
gold: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!currentPlayer) return totalBuyingPower;
|
||||||
|
|
||||||
|
for (let [key,quantity] of Object.entries(currentPlayer.inventory)) {
|
||||||
|
totalBuyingPower[key as keyof ResourceCost] += quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let each of currentPlayer.cards) {
|
||||||
|
totalBuyingPower[each.gemValue as keyof ResourceCost] += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalBuyingPower;
|
||||||
|
}
|
||||||
@@ -44,6 +44,7 @@ export const mockState: AppState = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// mock data for midgame
|
// mock data for midgame
|
||||||
|
// playerOneMidGame buys high diamond cost card
|
||||||
export const playerOneMidGame = {
|
export const playerOneMidGame = {
|
||||||
...mockPlayerOne,
|
...mockPlayerOne,
|
||||||
cards: [
|
cards: [
|
||||||
@@ -83,6 +84,7 @@ export const playerOneMidGame = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// playerTwoMidGame buys high ruby cost card
|
||||||
export const playerTwoMidGame = {
|
export const playerTwoMidGame = {
|
||||||
...mockPlayerTwo,
|
...mockPlayerTwo,
|
||||||
cards: [
|
cards: [
|
||||||
@@ -126,7 +128,7 @@ export const midGameState: AppState = {
|
|||||||
gameboard: {
|
gameboard: {
|
||||||
...initialState.gameboard,
|
...initialState.gameboard,
|
||||||
tradingResources: {
|
tradingResources: {
|
||||||
ruby: 1,
|
ruby: 0,
|
||||||
sapphire: 1,
|
sapphire: 1,
|
||||||
emerald: 1,
|
emerald: 1,
|
||||||
onyx: 1,
|
onyx: 1,
|
||||||
|
|||||||
Reference in New Issue
Block a user