package world import "testing" func TestRoomRewriteRoomIDs(t *testing.T) { r := &Room{ Exits: map[ExitDir]ExitDef{ North: {Room: 10, SetFlags: map[string]any{"last": 10}}, South: {Room: 99}, }, Triggers: []TriggerDef{ { Room: 30, Steps: []TriggerStep{ {Teleport: 40, SpawnMob: &SpawnMobConfig{DespawnRooms: []int{50, 60}}}, }, }, }, OnEnter: []EnterStep{ {Teleport: 70, SpawnMob: &SpawnMobConfig{DespawnRooms: []int{80}}}, }, Mobs: []RoomMob{ {ID: "guard", WanderRooms: []int{90, 100}}, }, } idMap := map[int]int{ 10: 11, 20: 21, 30: 31, 40: 41, 50: 51, 60: 61, 70: 71, 80: 81, 90: 91, 100: 101, } if !r.RewriteRoomIDs(idMap) { t.Fatal("expected changed=true") } checkExit := func(dir ExitDir, want int) { t.Helper() if got := r.Exits[dir].Room; got != want { t.Errorf("exit %s room = %d, want %d", dir, got, want) } } checkExit(North, 11) checkExit(South, 99) // unchanged (not in idMap) // Author set_flags values are NOT structural room references and must not // be remapped (the old swapid regex wrongly rewrote these). if v := r.Exits[North].SetFlags["last"]; v != 10 { t.Errorf("set_flags value remapped: got %v, want 10", v) } if r.Triggers[0].Room != 31 { t.Errorf("trigger room = %d, want 31", r.Triggers[0].Room) } if r.Triggers[0].Steps[0].Teleport != 41 { t.Errorf("trigger teleport = %d, want 41", r.Triggers[0].Steps[0].Teleport) } if got := r.Triggers[0].Steps[0].SpawnMob.DespawnRooms; len(got) != 2 || got[0] != 51 || got[1] != 61 { t.Errorf("trigger despawn_rooms = %v, want [51 61]", got) } if r.OnEnter[0].Teleport != 71 { t.Errorf("on_enter teleport = %d, want 71", r.OnEnter[0].Teleport) } if got := r.OnEnter[0].SpawnMob.DespawnRooms; len(got) != 1 || got[0] != 81 { t.Errorf("on_enter despawn_rooms = %v, want [81]", got) } if got := r.Mobs[0].WanderRooms; len(got) != 2 || got[0] != 91 || got[1] != 101 { t.Errorf("mob wander_rooms = %v, want [91 101]", got) } } func TestRoomRewriteRoomIDsNoChange(t *testing.T) { r := &Room{ Exits: map[ExitDir]ExitDef{North: {Room: 5}}, } // idMap does not mention 5 -> nothing changes. if r.RewriteRoomIDs(map[int]int{99: 100}) { t.Error("expected changed=false when no references match") } if r.Exits[North].Room != 5 { t.Errorf("exit room = %d, want 5 (untouched)", r.Exits[North].Room) } } func TestRoomRewriteRoomIDsSwapRoundTrips(t *testing.T) { r := &Room{Exits: map[ExitDir]ExitDef{ North: {Room: 10}, South: {Room: 20}, }} swap := map[int]int{10: 20, 20: 10} r.RewriteRoomIDs(swap) if r.Exits[North].Room != 20 || r.Exits[South].Room != 10 { t.Errorf("after swap: north=%d south=%d, want north=20 south=10", r.Exits[North].Room, r.Exits[South].Room) } // Applying the same swap again reverts (a swap is its own inverse). r.RewriteRoomIDs(swap) if r.Exits[North].Room != 10 || r.Exits[South].Room != 20 { t.Errorf("after double swap: north=%d south=%d, want north=10 south=20", r.Exits[North].Room, r.Exits[South].Room) } } func TestRoomRewriteRoomIDsIdempotentRename(t *testing.T) { r := &Room{Exits: map[ExitDir]ExitDef{North: {Room: 10}}} rename := map[int]int{10: 11} r.RewriteRoomIDs(rename) if r.Exits[North].Room != 11 { t.Fatalf("after rename: room=%d, want 11", r.Exits[North].Room) } // Second pass: 11 is not a key in idMap, so nothing changes. if r.RewriteRoomIDs(rename) { t.Error("expected changed=false on second pass of a rename idMap") } }