package controller_test import ( "slices" "testing" e "github.com/iliadenisov/galaxy/internal/error" "github.com/iliadenisov/galaxy/internal/model/game" "github.com/stretchr/testify/assert" ) func TestSetRoute(t *testing.T) { c, g := newCache() assert.NotContains(t, c.MustPlanet(0).Route, game.RouteMaterial) assert.NotContains(t, c.MustPlanet(0).Route, game.RouteCapital) assert.NotContains(t, c.MustPlanet(0).Route, game.RouteColonist) assert.NotContains(t, c.MustPlanet(0).Route, game.RouteEmpty) assert.NoError(t, g.SetRoute(Race_0.Name, "COL", 0, 2)) assert.NotContains(t, c.MustPlanet(0).Route, game.RouteMaterial) assert.NotContains(t, c.MustPlanet(0).Route, game.RouteCapital) assert.Contains(t, c.MustPlanet(0).Route, game.RouteColonist) assert.NotContains(t, c.MustPlanet(0).Route, game.RouteEmpty) assert.NoError(t, g.SetRoute(Race_0.Name, "MAT", 0, 2)) assert.Contains(t, c.MustPlanet(0).Route, game.RouteMaterial) assert.NotContains(t, c.MustPlanet(0).Route, game.RouteCapital) assert.Contains(t, c.MustPlanet(0).Route, game.RouteColonist) assert.NotContains(t, c.MustPlanet(0).Route, game.RouteEmpty) assert.NoError(t, g.SetRoute(Race_0.Name, "CAP", 0, 2)) assert.Contains(t, c.MustPlanet(0).Route, game.RouteMaterial) assert.Contains(t, c.MustPlanet(0).Route, game.RouteCapital) assert.Contains(t, c.MustPlanet(0).Route, game.RouteColonist) assert.NotContains(t, c.MustPlanet(0).Route, game.RouteEmpty) assert.NoError(t, g.SetRoute(Race_0.Name, "EMP", 0, 2)) assert.Contains(t, c.MustPlanet(0).Route, game.RouteMaterial) assert.Contains(t, c.MustPlanet(0).Route, game.RouteCapital) assert.Contains(t, c.MustPlanet(0).Route, game.RouteColonist) assert.Contains(t, c.MustPlanet(0).Route, game.RouteEmpty) assert.ErrorContains(t, g.SetRoute("UnknownRace", "COL", 0, 2), e.GenericErrorText(e.ErrInputUnknownRace)) assert.ErrorContains(t, g.SetRoute(Race_0.Name, "IND", 0, 2), e.GenericErrorText(e.ErrInputCargoTypeInvalid)) assert.ErrorContains(t, g.SetRoute(Race_0.Name, "COL", 500, 2), e.GenericErrorText(e.ErrInputEntityNotExists)) assert.ErrorContains(t, g.SetRoute(Race_0.Name, "COL", 1, 2), e.GenericErrorText(e.ErrInputEntityNotOwned)) assert.ErrorContains(t, g.SetRoute(Race_0.Name, "COL", 0, 3), e.GenericErrorText(e.ErrSendUnreachableDestination)) } func TestRemoveRoute(t *testing.T) { c, g := newCache() assert.NoError(t, g.SetRoute(Race_0.Name, "COL", 0, 2)) assert.NoError(t, g.SetRoute(Race_0.Name, "CAP", 0, 2)) assert.NoError(t, g.SetRoute(Race_0.Name, "EMP", 2, 0)) assert.Contains(t, c.MustPlanet(0).Route, game.RouteColonist) assert.Contains(t, c.MustPlanet(0).Route, game.RouteCapital) assert.Contains(t, c.MustPlanet(2).Route, game.RouteEmpty) assert.NoError(t, g.RemoveRoute(Race_0.Name, "COL", 0)) assert.NotContains(t, c.MustPlanet(0).Route, game.RouteColonist) assert.Contains(t, c.MustPlanet(0).Route, game.RouteCapital) assert.NoError(t, g.RemoveRoute(Race_0.Name, "EMP", 2)) assert.NotContains(t, c.MustPlanet(2).Route, game.RouteEmpty) assert.ErrorContains(t, g.RemoveRoute("UnknownRace", "COL", 0), e.GenericErrorText(e.ErrInputUnknownRace)) assert.ErrorContains(t, g.RemoveRoute(Race_0.Name, "IND", 0), e.GenericErrorText(e.ErrInputCargoTypeInvalid)) assert.ErrorContains(t, g.RemoveRoute(Race_0.Name, "COL", 500), e.GenericErrorText(e.ErrInputEntityNotExists)) assert.ErrorContains(t, g.RemoveRoute(Race_0.Name, "COL", 1), e.GenericErrorText(e.ErrInputEntityNotOwned)) } func TestListRouteEligibleGroupIds(t *testing.T) { c, g := newCache() // 1: idx = 0 / Ready to load assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 10)) // 2: idx = 1 / Has no cargo bay assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Gunship, R0_Planet_0_num, 1)) // 3: idx = 2 / In_Space assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 7)) c.ShipGroup(2).StateInSpace = &game.InSpace{ Origin: 2, Range: 31.337, } // 4: idx = 3 / loaded with COL assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 11)) c.ShipGroup(3).CargoType = game.CargoColonist.Ref() c.ShipGroup(3).Load = 1.234 // Foreign group -> idx 1 assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 10)) assert.NoError(t, g.GiveawayGroup(Race_0.Name, Race_1.Name, 5, 0)) // 5: idx = 4 / Part of the Fleet assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 10)) assert.NoError(t, g.JoinShipGroupToFleet(Race_0.Name, "Fleet", 5, 0)) planet_0_groups := slices.Collect(c.ListRouteEligibleGroupIds(0)) assert.Len(t, planet_0_groups, 1) for _, i := range planet_0_groups { sg := c.ShipGroup(i) st := c.ShipGroupShipClass(i) assert.Equal(t, Race_0_ID, sg.OwnerID) assert.Greater(t, sg.CargoCapacity(st), 0.) assert.Equal(t, game.StateInOrbit, sg.State()) assert.Equal(t, 0., sg.Load) assert.Nil(t, sg.FleetID) } } func TestEnrouteGroups_SplitGroup(t *testing.T) { c, g := newCache() assert.NoError(t, g.SetRoute(Race_0.Name, "COL", R0_Planet_0_num, R0_Planet_2_num)) // assert.NoError(t, g.SetRoute(Race_0.Name, "MAT", R0_Planet_0_num, R0_Planet_2_num)) // assert.NoError(t, g.SetRoute(Race_0.Name, "CAP", R0_Planet_0_num, R0_Planet_2_num)) // assert.NoError(t, g.SetRoute(Race_0.Name, "EMP", R0_Planet_2_num, R1_Planet_1_num)) c.MustPlanet(R0_Planet_0_num).Colonists = 65 assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 5)) // 21.0 per Ship assert.Equal(t, 105., c.ShipGroup(0).CargoCapacity(c.ShipGroupShipClass(0))) c.EnrouteGroups() assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 2) assert.Equal(t, game.StateInOrbit, c.ShipGroup(0).State()) assert.Equal(t, uint(1), c.ShipGroup(0).Number) assert.Equal(t, 0., c.ShipGroup(0).Load) assert.Equal(t, game.StateLaunched, c.ShipGroup(1).State()) assert.Equal(t, uint(4), c.ShipGroup(1).Number) assert.Equal(t, 65., c.ShipGroup(1).Load) assert.Equal(t, 0., c.MustPlanet(R0_Planet_0_num).Colonists) } func TestEnrouteGroups_GroupSorting(t *testing.T) { c, g := newCache() assert.NoError(t, g.SetRoute(Race_0.Name, "COL", R0_Planet_0_num, R0_Planet_2_num)) // assert.NoError(t, g.SetRoute(Race_0.Name, "MAT", R0_Planet_0_num, R0_Planet_2_num)) // assert.NoError(t, g.SetRoute(Race_0.Name, "CAP", R0_Planet_0_num, R0_Planet_2_num)) // assert.NoError(t, g.SetRoute(Race_0.Name, "EMP", R0_Planet_2_num, R1_Planet_1_num)) c.MustPlanet(R0_Planet_0_num).Colonists = 100 // 0: idx = 1 assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 4)) // 21.0 per Ship assert.Equal(t, 84., c.ShipGroup(0).CargoCapacity(c.ShipGroupShipClass(0))) // 1: idx = 2 assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 5)) // 21.0 per Ship assert.Equal(t, 105., c.ShipGroup(1).CargoCapacity(c.ShipGroupShipClass(1))) c.EnrouteGroups() assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 2) assert.Equal(t, game.StateInOrbit, c.ShipGroup(0).State()) assert.Equal(t, game.StateLaunched, c.ShipGroup(1).State()) assert.Equal(t, 100., c.ShipGroup(1).Load) assert.Equal(t, 0., c.MustPlanet(R0_Planet_0_num).Colonists) } func TestEnrouteGroups_LaunchOrder(t *testing.T) { c, g := newCache() assert.NoError(t, g.SetRoute(Race_0.Name, "COL", R0_Planet_0_num, R0_Planet_2_num)) assert.NoError(t, g.SetRoute(Race_0.Name, "CAP", R0_Planet_0_num, R0_Planet_2_num)) assert.NoError(t, g.SetRoute(Race_0.Name, "MAT", R0_Planet_0_num, R0_Planet_2_num)) assert.NoError(t, g.SetRoute(Race_0.Name, "EMP", R0_Planet_0_num, R1_Planet_1_num)) c.MustPlanet(R0_Planet_0_num).Colonists = 150 c.MustPlanet(R0_Planet_0_num).Capital = 100 c.MustPlanet(R0_Planet_0_num).Material = 20 // 0: idx = 1 (105 COL) -> // 3: idx = 4 ( 45 COL) assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 5)) assert.Equal(t, 105., c.ShipGroup(0).CargoCapacity(c.ShipGroupShipClass(0))) // 1: idx = 2 (In_Orbit) -> // 4: idx = 5 (20 MAT) assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 5)) assert.Equal(t, 105., c.ShipGroup(1).CargoCapacity(c.ShipGroupShipClass(1))) // 2: idx = 3 (100 CAP) assert.NoError(t, c.CreateShips(Race_0_idx, Race_0_Freighter, R0_Planet_0_num, 5)) assert.Equal(t, 105., c.ShipGroup(2).CargoCapacity(c.ShipGroupShipClass(2))) c.EnrouteGroups() assert.Len(t, slices.Collect(c.RaceShipGroups(Race_0_idx)), 5) // full load of COL sgi := 0 assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State()) assert.Equal(t, R0_Planet_2_num, c.ShipGroup(sgi).Destination) assert.Equal(t, 105., c.ShipGroup(sgi).Load) assert.NotNil(t, c.ShipGroup(sgi).CargoType) assert.Equal(t, game.CargoColonist, *c.ShipGroup(sgi).CargoType) assert.Equal(t, uint(5), c.ShipGroup(sgi).Number) // rest of COL sgi = 3 assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State()) assert.Equal(t, R0_Planet_2_num, c.ShipGroup(sgi).Destination) assert.Equal(t, 45., c.ShipGroup(sgi).Load) assert.NotNil(t, c.ShipGroup(sgi).CargoType) assert.Equal(t, game.CargoColonist, *c.ShipGroup(sgi).CargoType) assert.Equal(t, uint(3), c.ShipGroup(sgi).Number) // full load of CAP sgi = 2 assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State()) assert.Equal(t, R0_Planet_2_num, c.ShipGroup(sgi).Destination) assert.Equal(t, 100., c.ShipGroup(sgi).Load) assert.NotNil(t, c.ShipGroup(sgi).CargoType) assert.Equal(t, game.CargoCapital, *c.ShipGroup(sgi).CargoType) assert.Equal(t, uint(5), c.ShipGroup(sgi).Number) // partial load of MAT sgi = 4 assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State()) assert.Equal(t, R0_Planet_2_num, c.ShipGroup(sgi).Destination) assert.Equal(t, 20., c.ShipGroup(sgi).Load) assert.NotNil(t, c.ShipGroup(sgi).CargoType) assert.Equal(t, game.CargoMaterial, *c.ShipGroup(sgi).CargoType) assert.Equal(t, uint(1), c.ShipGroup(sgi).Number) // empty / on_planet sgi = 1 assert.Equal(t, game.StateLaunched, c.ShipGroup(sgi).State()) assert.Equal(t, R1_Planet_1_num, c.ShipGroup(sgi).Destination) assert.Equal(t, 0., c.ShipGroup(sgi).Load) assert.Nil(t, c.ShipGroup(sgi).CargoType) assert.Equal(t, uint(1), c.ShipGroup(sgi).Number) }