package controller_test import ( "slices" "testing" e "galaxy/error" "galaxy/game/internal/model/game" "github.com/stretchr/testify/assert" ) func TestRaceVote(t *testing.T) { c, g := newCache() assert.Equal(t, c.Voted(Race_0_idx), Race_0_idx) assert.Equal(t, c.Voted(Race_1_idx), Race_1_idx) assert.NoError(t, g.RaceVote(Race_0.Name, Race_1.Name)) assert.Equal(t, Race_1_idx, c.Voted(Race_0_idx)) assert.Equal(t, Race_1_idx, c.Voted(Race_1_idx)) assert.ErrorContains(t, g.RaceVote(UnknownRace, Race_1.Name), e.GenericErrorText(e.ErrInputUnknownRace)) assert.ErrorContains(t, g.RaceVote(Race_0.Name, UnknownRace), e.GenericErrorText(e.ErrInputUnknownRace)) assert.ErrorContains(t, g.RaceVote(Race_0.Name, Race_Extinct.Name), e.GenericErrorText(e.ErrRaceExtinct)) assert.ErrorContains(t, g.RaceVote(Race_Extinct.Name, Race_1.Name), e.GenericErrorText(e.ErrRaceExtinct)) } func TestRaceRelation(t *testing.T) { c, g := newCache() assert.NoError(t, g.RaceRelation(Race_0.Name, Race_1.Name, "war")) assert.NoError(t, g.RaceRelation(Race_1.Name, Race_0.Name, "PEACE")) assert.Equal(t, game.RelationWar, c.Relation(Race_0_idx, Race_1_idx)) assert.Equal(t, game.RelationPeace, c.Relation(Race_1_idx, Race_0_idx)) assert.ErrorContains(t, g.RaceRelation(Race_0.Name, Race_1.Name, "Wojna"), e.GenericErrorText(e.ErrInputUnknownRelation)) assert.ErrorContains(t, g.RaceRelation(Race_0.Name, UnknownRace, "War"), e.GenericErrorText(e.ErrInputUnknownRace)) assert.ErrorContains(t, g.RaceRelation(UnknownRace, Race_0.Name, "Peace"), e.GenericErrorText(e.ErrInputUnknownRace)) assert.ErrorContains(t, g.RaceRelation(Race_0.Name, Race_Extinct.Name, "War"), e.GenericErrorText(e.ErrRaceExtinct)) assert.ErrorContains(t, g.RaceRelation(Race_Extinct.Name, Race_0.Name, "War"), e.GenericErrorText(e.ErrRaceExtinct)) } func TestRaceQuit(t *testing.T) { c, g := newCache() assert.ErrorContains(t, g.RaceQuit(UnknownRace), e.GenericErrorText(e.ErrInputUnknownRace)) assert.ErrorContains(t, g.RaceQuit(Race_Extinct.Name), e.GenericErrorText(e.ErrRaceExtinct)) assert.NoError(t, g.RaceQuit(Race_0.Name)) assert.Equal(t, 3, int(c.Race(Race_0_idx).TTL)) } func TestRaceID(t *testing.T) { c, g := newCache() c.Race(Race_0_idx).TTL = 9 _, err := g.RaceID(UnknownRace) assert.ErrorContains(t, err, e.GenericErrorText(e.ErrInputUnknownRace)) _, err = g.RaceID(Race_Extinct.Name) assert.ErrorContains(t, err, e.GenericErrorText(e.ErrRaceExtinct)) id, err := g.RaceID(Race_0.Name) assert.NoError(t, err) assert.Equal(t, Race_0_ID, id) } // TestBanishReleasesAssets checks that an administratively banished race only // gets flagged extinct, and its planets and ships are released during turn // generation; a second pass is a no-op. func TestBanishReleasesAssets(t *testing.T) { c, g := newCache() c.CreateShipsUnsafe_T(Race_1_idx, c.MustShipClass(Race_1_idx, Race_1_Gunship).ID, R1_Planet_1_num, 3) assert.True(t, c.MustPlanet(R1_Planet_1_num).OwnedBy(Race_1_ID)) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_1_idx)), 1) assert.NoError(t, g.RaceBanish(Race_1.Name)) assert.True(t, c.Race(Race_1_idx).Extinct) assert.True(t, c.MustPlanet(R1_Planet_1_num).OwnedBy(Race_1_ID), "still owned until the turn runs") c.TurnWipeExtinctRaces() assert.False(t, c.MustPlanet(R1_Planet_1_num).Owned()) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_1_idx)), 0) // Idempotent: re-running over an already-wiped (asset-less) race is a no-op. c.TurnWipeExtinctRaces() assert.False(t, c.MustPlanet(R1_Planet_1_num).Owned()) } // TestIdleRaceWipedOnTimeout guards that a still-active race whose TTL ran out // (idle timeout or quit) is still wiped after the iterator change. func TestIdleRaceWipedOnTimeout(t *testing.T) { c, _ := newCache() c.CreateShipsUnsafe_T(Race_1_idx, c.MustShipClass(Race_1_idx, Race_1_Gunship).ID, R1_Planet_1_num, 1) c.Race(Race_1_idx).TTL = 0 assert.False(t, c.Race(Race_1_idx).Extinct) c.TurnWipeExtinctRaces() assert.True(t, c.Race(Race_1_idx).Extinct) assert.False(t, c.MustPlanet(R1_Planet_1_num).Owned()) assert.Len(t, slices.Collect(c.RaceShipGroups(Race_1_idx)), 0) }