From d1e361f74e0d424b4d6a99adea1463982d9f1475 Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Thu, 15 Jan 2026 23:03:12 +0100 Subject: First integration test --- README.md | 6 +++++ integration_test.go | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 4 ++++ 3 files changed, 74 insertions(+) create mode 100644 integration_test.go diff --git a/README.md b/README.md index e3ba5a5..e4cca5c 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,11 @@ - Restart after kernel update until `glxinfo | grep "OpenGL version"` works +## Testing + +- **Integration tests** Use `Update()` to run N ticks. +- **Performance benchmarks** + ## TODO - see the current action (debug?) @@ -19,6 +24,7 @@ - perf: measure frame budget - rename Selection to Selectable - extract todos in todo list +- abstraction between ebiten and update to handle inputs in a simulation? ## Bugs diff --git a/integration_test.go b/integration_test.go new file mode 100644 index 0000000..8305719 --- /dev/null +++ b/integration_test.go @@ -0,0 +1,64 @@ +package main + +import ( + "testing" + "time" + + "age_of_empires/physics" +) + +func TestGatherLoop(t *testing.T) { + // Initialize Game + game := &Game{} + + // Town Center (Storage) at -100,0 (different grid cell from unit at 0,0) + tcBuilder := NewEntityBuilder(). + WithPosition(physics.Point{X: -100, Y: 0}). + WithResourceStorage() + _ = game.Append(tcBuilder.Build()) + + // Mine (Source) at 0, 200 + mineBuilder := NewEntityBuilder(). + WithPosition(physics.Point{X: 0, Y: 200}). + WithResourceSource(100) + mineID := game.Append(mineBuilder.Build()) + + // Unit (Gatherer) at 0, 0 + unitBuilder := NewEntityBuilder(). + WithPosition(physics.Point{X: 0, Y: 0}). + WithMove(). + WithOrder(). + WithResourceGatherer(10) + unitID := game.Append(unitBuilder.Build()) + + // Set up simulated time + simTime := time.Now() + game.NowFunc = func() time.Time { return simTime } + + // Simulate user selection: select the unit + game.GlobalSelection.Selected = append(game.GlobalSelection.Selected, unitID) + + // Simulate right-click on mine position to trigger Gather via MainAction + minePosition := game.Position[mineID] + MainAction(game, unitID, minePosition, game.getMoveMap()) + + initialResources := game.ResourceAmount + dt := 16 * time.Millisecond + maxTicks := 100_000 + + deposited := false + + for i := 0; i < maxTicks; i++ { + simTime = simTime.Add(dt) + game.Update() + + if game.ResourceAmount > initialResources { + deposited = true + break + } + } + + if !deposited { + t.Errorf("Unit failed to gather resources within %d ticks. ResourceAmount: %d", maxTicks, game.ResourceAmount) + } +} diff --git a/main.go b/main.go index e67e50b..80ee064 100644 --- a/main.go +++ b/main.go @@ -36,6 +36,7 @@ type Game struct { ResourceAmount int FaceSource *text.GoTextFaceSource UnitBuilder EntityBuilder + NowFunc func() time.Time // Components Mask []ecs.Mask // Entities []*Entity @@ -53,6 +54,9 @@ type Game struct { } func (g Game) Now() time.Time { + if g.NowFunc != nil { + return g.NowFunc() + } return time.Now() } -- cgit v1.3