@jeremyckahn/farmhand
Version:
A farming game
357 lines (280 loc) • 9.44 kB
text/typescript
import * as reducers from '../game-logic/reducers/index.js'
import { testCrop } from '../test-utils/index.js'
import { toolLevel, toolType } from '../enums.js'
import { INFINITE_STORAGE_LIMIT } from '../constants.js'
import { achievementsMap, progressAchievement } from './achievements.js'
import { carrot } from './crops/index.js'
describe('progressAchievement', () => {
test('condition is false and getProgress reflects currentValue below goal', () => {
const { condition, getProgress } = progressAchievement(10, () => 9)
expect(condition({} as any)).toEqual(false)
expect(getProgress?.({} as any)).toEqual({ currentValue: 9, goal: 10 })
})
test('condition is true and getProgress reflects currentValue at goal', () => {
const { condition, getProgress } = progressAchievement(10, () => 10)
expect(condition({} as any)).toEqual(true)
expect(getProgress?.({} as any)).toEqual({ currentValue: 10, goal: 10 })
})
test('condition is true and getProgress reflects currentValue above goal', () => {
const { condition, getProgress } = progressAchievement(10, () => 11)
expect(condition({} as any)).toEqual(true)
expect(getProgress?.({} as any)).toEqual({ currentValue: 11, goal: 10 })
})
})
describe('harvest-crop', () => {
describe('condition', () => {
let inputState: any
beforeEach(() => {
inputState = {
cropsHarvested: {},
field: [[null, null, testCrop({ itemId: carrot.id, daysWatered: 5 })]],
inventory: [],
inventoryLimit: INFINITE_STORAGE_LIMIT,
toolLevels: {
[toolType.SCYTHE]: toolLevel.DEFAULT,
},
}
})
describe('is not met', () => {
test('returns false', () => {
expect(
achievementsMap['harvest-crop'].condition(inputState, inputState)
).toEqual(false)
})
})
describe('is met', () => {
test('returns true', () => {
expect(
achievementsMap['harvest-crop'].condition(
reducers.harvestPlot(inputState, 2, 0),
inputState
)
).toEqual(true)
})
})
})
})
const iAmRichVariants = [
['i-am-rich-1', 500000, 'Earn $500,000.', 'All sales receive a 5% bonus'],
['i-am-rich-2', 1000000, 'Earn $1,000,000.', 'All sales receive a 10% bonus'],
[
'i-am-rich-3',
1000000000,
'Earn $1,000,000,000.',
'All sales receive a 25% bonus',
],
]
describe.each(iAmRichVariants)(
'I am Rich variants',
(id, goal, description, rewardDescription) => {
describe(id, () => {
test('has the expected description', () => {
expect(achievementsMap[id].description).toEqual(description)
})
test('has the expected rewardDescription', () => {
expect(achievementsMap[id].rewardDescription).toEqual(rewardDescription)
})
test(`is achieved when revenue is greater than or equal to ${goal}`, () => {
const achievement = achievementsMap[id]
const state = {
revenue: goal,
} as any
expect(achievement.condition(state)).toEqual(true)
})
test(`is not achieved when revenue is less than ${goal}`, () => {
const achievement = achievementsMap[id]
const state = {
revenue: Number(goal) - 1,
} as any
expect(achievement.condition(state)).toEqual(false)
})
test('reports progress toward the revenue goal', () => {
const achievement = achievementsMap[id]
const state = {
revenue: Number(goal) - 1,
} as any
expect(achievement.getProgress?.(state)).toEqual({
currentValue: Number(goal) - 1,
goal: Number(goal),
})
})
})
}
)
describe('gold-digger', () => {
const achievement = achievementsMap['gold-digger']
let state: any
beforeEach(() => {
state = {
inventory: [{ id: 'gold-ore' }],
inventoryLimit: 99,
}
})
test('is achieved when the player acquires a piece of gold ore', () => {
expect(achievement.condition(state)).toEqual(true)
})
test('it rewards the player with a gold ingot', () => {
state = achievement.reward(state)
const ingot = state.inventory.find(
(item: { id: string }) => item.id === 'gold-ingot'
)
expect(ingot).toEqual({ id: 'gold-ingot', quantity: 1 })
})
})
describe('financial-freedom', () => {
const achievement = achievementsMap['financial-freedom']
let state: any
beforeEach(() => {
state = {
loanBalance: 100,
}
})
test('is not achievemed when loan balance is greater than 0', () => {
expect(achievement.condition(state)).toEqual(false)
})
test('is achievemented when the loan balance is at 0', () => {
state.loanBalance = 0
expect(achievement.condition(state)).toEqual(true)
})
})
describe('orchardist', () => {
const achievement = achievementsMap['orchardist']
let state: any
beforeEach(() => {
state = {
treeFruitsHarvested: { apple: 999 },
inventory: [],
inventoryLimit: INFINITE_STORAGE_LIMIT,
}
})
test('is not achieved when fewer than 1000 fruits have been picked', () => {
expect(achievement.condition(state)).toEqual(false)
})
test('is achieved when 1000 or more fruits have been picked', () => {
state.treeFruitsHarvested.apple = 1000
expect(achievement.condition(state)).toEqual(true)
})
test('sums fruits across multiple tree species', () => {
state.treeFruitsHarvested = { apple: 500, pear: 500 }
expect(achievement.condition(state)).toEqual(true)
})
test('rewards the player with apple saplings', () => {
state = achievement.reward(state)
const saplings = state.inventory.find(
(item: { id: string }) => item.id === 'apple-sapling'
)
expect(saplings).toEqual({ id: 'apple-sapling', quantity: 50 })
})
test('reports progress toward the fruits-picked goal', () => {
expect(achievement.getProgress?.(state)).toEqual({
currentValue: 999,
goal: 1000,
})
})
})
describe('piemaker', () => {
const achievement = achievementsMap['piemaker']
let state: any
beforeEach(() => {
state = {
recipesMade: { 'apple-pie': 99 },
money: 0,
}
})
test('is not achieved when fewer than 100 pies have been made', () => {
expect(achievement.condition(state)).toEqual(false)
})
test('is achieved when 100 or more pies have been made', () => {
state.recipesMade['apple-pie'] = 100
expect(achievement.condition(state)).toEqual(true)
})
test('sums pies across all pie recipes', () => {
state.recipesMade = {
'chickn-pot-pie': 25,
'pumpkin-pie': 25,
'apple-pie': 25,
'sweet-potato-pie': 25,
}
expect(achievement.condition(state)).toEqual(true)
})
test('does not count non-pie recipes', () => {
state.recipesMade = { mulch: 1000 }
expect(achievement.condition(state)).toEqual(false)
})
test('rewards the player with money', () => {
state = achievement.reward(state)
expect(state.money).toEqual(100_000)
})
test('reports progress toward the pies-made goal', () => {
expect(achievement.getProgress?.(state)).toEqual({
currentValue: 99,
goal: 100,
})
})
})
describe('deforestation', () => {
const achievement = achievementsMap['deforestation']
let state: any
beforeEach(() => {
state = {
treesChopped: 249,
inventory: [],
inventoryLimit: INFINITE_STORAGE_LIMIT,
}
})
test('is not achieved when fewer than 250 trees have been chopped', () => {
expect(achievement.condition(state)).toEqual(false)
})
test('is achieved when 250 or more trees have been chopped', () => {
state.treesChopped = 250
expect(achievement.condition(state)).toEqual(true)
})
test('rewards the player with wood', () => {
state = achievement.reward(state)
const wood = state.inventory.find(
(item: { id: string }) => item.id === 'wood'
)
expect(wood).toEqual({ id: 'wood', quantity: 500 })
})
test('reports progress toward the trees-chopped goal', () => {
expect(achievement.getProgress?.(state)).toEqual({
currentValue: 249,
goal: 250,
})
})
})
describe('landscaper', () => {
const achievement = achievementsMap['landscaper']
let state: any
beforeEach(() => {
state = {
mulchApplied: { mulch: 99 },
inventory: [],
inventoryLimit: INFINITE_STORAGE_LIMIT,
}
})
test('is not achieved when fewer than 100 bags of mulch have been applied', () => {
expect(achievement.condition(state)).toEqual(false)
})
test('is achieved when 100 or more bags of mulch have been applied', () => {
state.mulchApplied.mulch = 100
expect(achievement.condition(state)).toEqual(true)
})
test('sums mulch applications across mulch types', () => {
state.mulchApplied = { mulch: 50, 'rainbow-mulch': 50 }
expect(achievement.condition(state)).toEqual(true)
})
test('rewards the player with rainbow mulch', () => {
state = achievement.reward(state)
const rainbowMulch = state.inventory.find(
(item: { id: string }) => item.id === 'rainbow-mulch'
)
expect(rainbowMulch).toEqual({ id: 'rainbow-mulch', quantity: 25 })
})
test('reports progress toward the mulch-applied goal', () => {
expect(achievement.getProgress?.(state)).toEqual({
currentValue: 99,
goal: 100,
})
})
})