1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
package admin
// Room-rename runtime-state regressions: renaming a room must move its live
// contents (ground items, seeded spawn markers, object state) to the new ID
// — never clear them — and undo must bring them back.
import (
"testing"
)
// TestRoomRenameMovesRuntimeState: renaming a room with ground items moves
// them to the new room ID. The old implementation cleared the state before
// the migration callback could rekey it, destroying the room's contents.
func TestRoomRenameMovesRuntimeState(t *testing.T) {
s := newTestAdminServer(t, map[int]string{
1: "id: 1\nname: Room\nexits:\n east:\n room: 2\n",
2: "id: 2\nname: Neighbor\nexits:\n west:\n room: 1\n",
})
s.world.AddGroundItem(1, "chips", 50)
s.world.AddGroundItem(1, "chips", 10) // second entry: rekey must move the whole list
s.rewriteRoomIDs = func(idMap map[int]int) { s.world.RekeyRooms(idMap) }
s.undoStack.SetMigrateRoomIDs(s.rewriteRoomIDs)
if rec := renameRoom(t, s, 1, 3); rec.Code != 200 {
t.Fatalf("rename failed: %d %s", rec.Code, rec.Body.String())
}
if got := s.world.GroundItems(3)["chips"]; got != 60 {
t.Fatalf("ground items after rename = %d, want 60 in room 3", got)
}
if got := s.world.GroundItems(1)["chips"]; got != 0 {
t.Fatalf("ground items left behind in the old room: %d", got)
}
// Undo restores the files AND the runtime state through the inverse map.
if s.undoStack.Undo() == nil {
t.Fatal("undo failed")
}
if got := s.world.GroundItems(1)["chips"]; got != 60 {
t.Fatalf("ground items after undo = %d, want 60 back in room 1", got)
}
}
// TestRoomRenameUndoDoesNotClearSurvivingRoomState: undoing a rename must
// not clear runtime state of rooms whose files still exist afterwards
// (only undo-of-create / redo-of-delete drops state).
func TestRoomRenameUndoDoesNotClearSurvivingRoomState(t *testing.T) {
s := newTestAdminServer(t, map[int]string{
1: "id: 1\nname: Room\n",
2: "id: 2\nname: Unrelated\n",
})
s.world.AddGroundItem(2, "chips", 5)
s.rewriteRoomIDs = func(idMap map[int]int) { s.world.RekeyRooms(idMap) }
s.undoStack.SetMigrateRoomIDs(s.rewriteRoomIDs)
if rec := renameRoom(t, s, 1, 3); rec.Code != 200 {
t.Fatalf("rename failed: %d %s", rec.Code, rec.Body.String())
}
// The unrelated room's state must survive the rename and its undo.
if got := s.world.GroundItems(2)["chips"]; got != 5 {
t.Fatalf("unrelated room state lost during rename: %d", got)
}
if s.undoStack.Undo() == nil {
t.Fatal("undo failed")
}
if got := s.world.GroundItems(2)["chips"]; got != 5 {
t.Fatalf("unrelated room state lost during undo: %d", got)
}
}
|