Files
galaxy-game/ui/core/calc/planet_test.go
T
Ilia Denisov 9ae7b88b89
Tests · UI / test (push) Successful in 2m14s
Tests · Go / test (push) Successful in 2m25s
feat(ui): Phase 30 ship-class calculator with goal-seek and reach circles
Fuse the standalone ship-class designer (Phases 17/18) into a sidebar calculator: live mass/speed/attack/defence/bombing results, a planet build-rate readout, single-target goal-seek, a modernization-cost mode, and auto reach circles on the map for the selected planet.

pkg/calc becomes the single source for the new math (no mirroring): extract BombingPower from the engine model and the per-turn ship-production loop from controller.ProduceShip into pkg/calc (engine now delegates), and add inverse goal-seek solvers in pkg/calc/solve.go. Thin-bridge the combat, planet-build, and solver functions through ui/core/calc + ui/wasm and rebuild core.wasm.

Remove the standalone designer view/route; the ship-classes table and the view/bottom menus open the calculator via a shared request store.

Docs: rewrite ui/PLAN.md Phase 30, adjust Phase 34 (realistic forecast + CAP/COL ownership), add ui/docs/calculator-ux.md, extend calc-bridge.md, fix navigation.md; remove ui/CALCULATOR.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 20:04:07 +02:00

58 lines
1.5 KiB
Go

package calc_test
import (
"testing"
source "galaxy/calc"
bridge "galaxy/core/calc"
"github.com/stretchr/testify/assert"
)
func TestShipBuildCostParity(t *testing.T) {
t.Parallel()
cases := []struct {
name string
shipMass, material, resources float64
}{
{"material_covers_mass", 5, 10, 0.5},
{"material_short", 10, 3, 0.5},
{"no_material", 4, 0, 0.5},
{"zero_resources_guard", 10, 3, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
t.Parallel()
want := source.ShipBuildCost(c.shipMass, c.material, c.resources)
got := bridge.ShipBuildCost(c.shipMass, c.material, c.resources)
assert.Equal(t, want, got)
})
}
}
func TestProduceShipsInTurnParity(t *testing.T) {
t.Parallel()
cases := []struct {
name string
productionAvailable, material, resources, shipMass float64
}{
{"ample_material", 100, 100, 10, 1},
{"farmed_partial", 114, 0, 0.5, 10},
{"no_production", 0, 50, 10, 5},
{"zero_ship_mass", 100, 50, 10, 0},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
t.Parallel()
wantShips, wantMat, wantUsed, wantProg := source.ProduceShipsInTurn(
c.productionAvailable, c.material, c.resources, c.shipMass)
gotShips, gotMat, gotUsed, gotProg := bridge.ProduceShipsInTurn(
c.productionAvailable, c.material, c.resources, c.shipMass)
assert.Equal(t, wantShips, gotShips)
assert.Equal(t, wantMat, gotMat)
assert.Equal(t, wantUsed, gotUsed)
assert.Equal(t, wantProg, gotProg)
})
}
}