Files
probability/tests/economy.test.js
T

59 lines
2.1 KiB
JavaScript

import { describe, it, expect } from 'vitest';
import { priceOf, advancePlanet, marketView, applyTrade } from '../src/sim/economy.js';
import { BASE_PRICE, GOODS, TYPICAL_STOCK } from '../src/sim/constants.js';
function makePlanet() {
return {
id: 0, systemId: 0, name: 'Test Prime',
produces: { food: 10 }, consumes: { fuel: 5 },
stock: { ore: 100, food: 100, fuel: 100, tech: 100, meds: 100, luxury: 100 },
stockTime: 0,
};
}
describe('economy', () => {
it('price falls as stock rises, clamped to [0.25x, 4x] base', () => {
expect(priceOf('ore', TYPICAL_STOCK)).toBeCloseTo(BASE_PRICE.ore, 1);
expect(priceOf('ore', 10)).toBeGreaterThan(priceOf('ore', 500));
expect(priceOf('ore', 0)).toBe(BASE_PRICE.ore * 4);
expect(priceOf('ore', 1e9)).toBe(BASE_PRICE.ore * 0.25);
});
it('advancePlanet applies production/consumption over elapsed time', () => {
const p = makePlanet();
advancePlanet(p, 10);
expect(p.stock.food).toBeCloseTo(200, 5); // +10/day
expect(p.stock.fuel).toBeCloseTo(50, 5); // -5/day
expect(p.stock.ore).toBeCloseTo(100, 5); // untouched
expect(p.stockTime).toBe(10);
});
it('advancePlanet never goes negative and is idempotent', () => {
const p = makePlanet();
advancePlanet(p, 100);
expect(p.stock.fuel).toBe(0);
const snapshot = { ...p.stock };
advancePlanet(p, 100); // same time again: no change
expect(p.stock).toEqual(snapshot);
});
it('applyTrade returns pre-trade price and mutates stock', () => {
const p = makePlanet();
const price = applyTrade(p, 0, 'ore', -20); // a buyer removes 20
expect(price).toBeCloseTo(priceOf('ore', 100), 5);
expect(p.stock.ore).toBe(80);
applyTrade(p, 0, 'ore', 50); // a seller delivers 50
expect(p.stock.ore).toBe(130);
});
it('marketView lists all goods with integer stock and price', () => {
const p = makePlanet();
const view = marketView(p, 5);
expect(view.map((r) => r.good)).toEqual(GOODS);
for (const row of view) {
expect(Number.isInteger(row.stock)).toBe(true);
expect(row.price).toBeGreaterThan(0);
}
});
});