import { bookingTrainLengthMeters, deriveTrainCapacityFromLocomotive, minLocomotiveLimits, } from './train-capacity.util'; describe('train-capacity.util', () => { const nw5 = { lengthMeters: 14, capacityTons: 70 }; it('derives wagon slots from locomotive length and weight, not a fixed 53', () => { const shortLoco = deriveTrainCapacityFromLocomotive( { maxPullWeightTons: 2000, maxTrainLengthMeters: 280 }, [nw5], ); expect(shortLoco.maxWagonSlots).toBe(20); // 280 / 14 expect(shortLoco.maxWagonSlots).not.toBe(53); const heavyLoco = deriveTrainCapacityFromLocomotive( { maxPullWeightTons: 2100, maxTrainLengthMeters: 760 }, [nw5], ); expect(heavyLoco.maxWagonSlots).toBe(30); // min(54, 30) from weight 2100/70 }); it('uses shortest wagon type when mixed types are present', () => { const longBulk = { lengthMeters: 18, capacityTons: 80 }; const mixed = deriveTrainCapacityFromLocomotive( { maxPullWeightTons: 3500, maxTrainLengthMeters: 760 }, [nw5, longBulk], ); expect(mixed.maxWagonSlots).toBe( Math.min(Math.floor(760 / 14), Math.floor(3500 / 70)), ); }); it('computes booking length by freight type', () => { expect( bookingTrainLengthMeters('CONTAINER', 2, { container: 14, bulk: 14 }), ).toBe(28); expect(bookingTrainLengthMeters('BULK', 3, { container: 14, bulk: 18 })).toBe(54); }); it('extends weight/length caps by the locomotive overage tolerance (fertilizer +90T example)', () => { const pw2 = { lengthMeters: 17.066, capacityTons: 70 }; const derived = deriveTrainCapacityFromLocomotive( { maxPullWeightTons: 3500, maxTrainLengthMeters: 760, overageToleranceTons: 90 }, [pw2], ); expect(derived.maxWeightTons).toBe(3590); }); it('ignores overage tolerance when unset (strict cap, no behavior change)', () => { const derived = deriveTrainCapacityFromLocomotive( { maxPullWeightTons: 3500, maxTrainLengthMeters: 760 }, [{ lengthMeters: 14, capacityTons: 70 }], ); expect(derived.maxWeightTons).toBe(3500); expect(derived.maxLengthMeters).toBe(760); }); it('takes the weakest locomotive tolerance across a multi-locomotive set', () => { const limits = minLocomotiveLimits([ { maxPullWeightTons: 3500, maxTrainLengthMeters: 760, overageToleranceTons: 90 }, { maxPullWeightTons: 4000, maxTrainLengthMeters: 760, overageToleranceTons: 20 }, ]); expect(limits?.maxPullWeightTons).toBe(3500); expect(limits?.overageToleranceTons).toBe(20); }); });