airship-phaser/tests/dock-economy.test.mjs

88 lines
3.2 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { generateWorld } from '../src/world/world-generator.js';
import { createStarterProgression, deriveShipStats } from '../src/progression/ship-loadout.js';
import {
acceptMission,
buyTradeGood,
completeMission,
marketAtPort,
missionOffersAtPort,
missionStatus,
sellTradeGood,
tradeCargoUnits,
} from '../src/progression/dock-economy.js';
test('port markets are deterministic and expose buy/sell prices', () => {
const world = generateWorld({ seed: 'DOCK-MARKET' });
const port = world.ports[0];
const a = marketAtPort(world, port);
const b = marketAtPort(world, port);
assert.deepEqual(a, b);
assert.ok(a.length >= 4);
assert.ok(a.every((item) => item.buyPrice > item.sellPrice));
});
test('trade cargo respects capacity and selling returns coin', () => {
const world = generateWorld({ seed: 'DOCK-TRADE' });
const market = marketAtPort(world, world.ports[0]);
const item = market[0];
const starter = { ...createStarterProgression(), credits: 2000 };
const stats = deriveShipStats(starter.loadout);
const bought = buyTradeGood(starter, item, stats);
assert.equal(bought.traded, true);
assert.equal(tradeCargoUnits(bought), 1);
assert.ok(bought.credits < starter.credits);
const sold = sellTradeGood(bought, item);
assert.equal(sold.traded, true);
assert.equal(tradeCargoUnits(sold), 0);
assert.ok(sold.credits > bought.credits);
});
test('delivery missions follow generated trade routes and complete at destination', () => {
const world = generateWorld({ seed: 'DOCK-MISSIONS' });
const origin = world.ports[0];
const offers = missionOffersAtPort(world, origin, 0);
const delivery = offers.find(({ type }) => type === 'delivery');
assert.ok(delivery);
assert.ok(world.tradeRoutes.some((route) =>
(route.fromPortId === origin.id && route.toPortId === delivery.targetPortId)
|| (route.toPortId === origin.id && route.fromPortId === delivery.targetPortId)
));
const starter = createStarterProgression();
const stats = deriveShipStats(starter.loadout);
const accepted = acceptMission(starter, delivery, stats, 0);
assert.equal(accepted.missionAccepted, true);
assert.equal(missionStatus(accepted, { portId: origin.id, defeated: 0 }).ready, false);
const completed = completeMission(accepted, {
portId: delivery.targetPortId,
defeated: 0,
});
assert.equal(completed.missionCompleted, true);
assert.equal(completed.activeMission, null);
assert.equal(completed.credits, starter.credits + delivery.reward);
});
test('bounty missions advance from actual pirate kill count', () => {
const world = generateWorld({ seed: 'DOCK-BOUNTY' });
const offers = missionOffersAtPort(world, world.ports[0], 5);
const bounty = offers.find(({ type }) => type === 'bounty');
const starter = createStarterProgression();
const stats = deriveShipStats(starter.loadout);
const accepted = acceptMission(starter, bounty, stats, 5);
const pending = missionStatus(accepted, {
portId: world.ports[0].id,
defeated: 5 + bounty.targetKills - 1,
});
assert.equal(pending.ready, false);
const ready = missionStatus(accepted, {
portId: world.ports[0].id,
defeated: 5 + bounty.targetKills,
});
assert.equal(ready.ready, true);
});