Files
CONSOLGAMES/tests/sim/customers.test.ts
T

75 lines
2.9 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { chooseShelfItem, customersPerHour, spawnCustomer } from '../../src/sim/customers';
import { createNewGame, setPrice } from '../../src/sim/state';
import { issueCard } from '../../src/sim/loyalty';
import { makeCustomer, stock, testCatalog } from './helpers';
const catalog = testCatalog();
const tetrisNew = { gameId: 'tetris', condition: 'new' as const };
const smlNew = { gameId: 'sml', condition: 'new' as const };
describe('customers', () => {
it('comes more often with a better reputation', () => {
expect(customersPerHour(0)).toBeCloseTo(0.5);
expect(customersPerHour(100)).toBeCloseTo(4.5);
});
it('spawns a mix of intents with valid data', () => {
const s = createNewGame(99);
const counts = { buy: 0, request: 0, buy_back: 0, trade: 0 };
for (let i = 0; i < 2000; i++) {
const c = spawnCustomer(s, catalog);
counts[c.intent]++;
if (c.intent === 'request') expect(['tetris', 'sml']).toContain(c.wantedGameId);
if (c.intent === 'buy_back' || c.intent === 'trade') {
expect(c.offered).not.toBeNull();
expect(c.offered!.condition).not.toBe('new');
expect(c.offered!.gameId).not.toBe('future');
}
}
expect(counts.buy / 2000).toBeGreaterThan(0.45);
expect(counts.buy / 2000).toBeLessThan(0.65);
expect(counts.request).toBeGreaterThan(0);
expect(counts.buy_back).toBeGreaterThan(0);
expect(counts.trade).toBeGreaterThan(0);
expect(s.nextCustomerId).toBe(2001);
});
it('brings back card holders', () => {
const s = createNewGame(5);
for (let i = 0; i < 30; i++) issueCard(s.loyalty);
let returning = 0;
for (let i = 0; i < 1000; i++) if (spawnCustomer(s, catalog).cardId !== null) returning++;
expect(returning).toBeGreaterThan(300);
expect(returning).toBeLessThan(700);
});
it('picks nothing from empty shelves', () => {
const s = createNewGame(1);
expect(chooseShelfItem(s, catalog, makeCustomer())).toBeNull();
});
it('never picks an item priced at 150% or more of its reference', () => {
const s = createNewGame(2);
stock(s, 'slot-0', tetrisNew, 5);
setPrice(s, tetrisNew, 3034 * 2);
for (let i = 0; i < 200; i++) expect(chooseShelfItem(s, catalog, makeCustomer())).toBeNull();
});
it('usually buys well-priced popular games', () => {
const s = createNewGame(3);
stock(s, 'slot-0', smlNew, 5);
stock(s, 'slot-1', tetrisNew, 5);
let picks = 0;
for (let i = 0; i < 200; i++) if (chooseShelfItem(s, catalog, makeCustomer()) !== null) picks++;
expect(picks).toBeGreaterThan(150);
});
it('finds the requested game, or nothing', () => {
const s = createNewGame(4);
stock(s, 'slot-3', smlNew, 1);
expect(chooseShelfItem(s, catalog, makeCustomer({ intent: 'request', wantedGameId: 'sml' }))).toBe('slot-3');
expect(chooseShelfItem(s, catalog, makeCustomer({ intent: 'request', wantedGameId: 'tetris' }))).toBeNull();
});
});