aboutsummaryrefslogtreecommitdiff
path: root/internal/behavior/roomrefs_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/behavior/roomrefs_test.go')
-rw-r--r--internal/behavior/roomrefs_test.go130
1 files changed, 130 insertions, 0 deletions
diff --git a/internal/behavior/roomrefs_test.go b/internal/behavior/roomrefs_test.go
new file mode 100644
index 0000000..9651b17
--- /dev/null
+++ b/internal/behavior/roomrefs_test.go
@@ -0,0 +1,130 @@
+package behavior
+
+// Structural room-reference remapping for non-room content files. The walker
+// must rewrite only known room-ID keys and must not touch author values that
+// merely happen to equal a room ID.
+
+import (
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+
+ "gopkg.in/yaml.v3"
+)
+
+func decode(t *testing.T, src string) any {
+ t.Helper()
+ var v any
+ if err := yaml.Unmarshal([]byte(src), &v); err != nil {
+ t.Fatalf("unmarshal: %v", err)
+ }
+ return v
+}
+
+func TestRemapRoomRefsRewritesStructuralKeys(t *testing.T) {
+ src := `
+destination: 10
+on_fail: 11
+room_id: 12
+start_room: 13
+wander_rooms: [14, 15]
+despawn_rooms: [16]
+teleport: 17
+nested:
+ room: 18
+ condition:
+ room: 19
+`
+ v := decode(t, src)
+ idMap := map[int]int{
+ 10: 110, 11: 111, 12: 112, 13: 113, 14: 114, 15: 115,
+ 16: 116, 17: 117, 18: 118, 19: 119,
+ }
+ if !RemapRoomRefs(v, idMap) {
+ t.Fatal("expected changed=true")
+ }
+ out, err := MarshalYAMLMap(v.(map[string]any))
+ if err != nil {
+ t.Fatal(err)
+ }
+ s := string(out)
+ for _, want := range []string{
+ "destination: 110", "on_fail: 111", "room_id: 112", "start_room: 113",
+ "teleport: 117",
+ } {
+ if !strings.Contains(s, want) {
+ t.Errorf("missing rewritten %q in:\n%s", want, s)
+ }
+ }
+ // Lists are rewritten in place.
+ for _, want := range []string{"- 114", "- 115", "- 116"} {
+ if !strings.Contains(s, want) {
+ t.Errorf("missing rewritten list entry %q in:\n%s", want, s)
+ }
+ }
+ for _, want := range []string{"room: 118", "room: 119"} {
+ if !strings.Contains(s, want) {
+ t.Errorf("missing nested rewritten %q in:\n%s", want, s)
+ }
+ }
+}
+
+func TestRemapRoomRefsLeavesAuthorValues(t *testing.T) {
+ // A delay, quantity, color index, and author flag value that equal room
+ // IDs must never be rewritten: only structural keys are room references.
+ src := `
+value: 10
+delay: 11
+quantity: 12
+color: "13"
+set_global_flags:
+ last_room: 14
+steps:
+ - wait: 15
+ credits: 16
+`
+ v := decode(t, src)
+ idMap := map[int]int{10: 110, 11: 111, 12: 112, 13: 113, 14: 114, 15: 115, 16: 116}
+ if RemapRoomRefs(v, idMap) {
+ t.Fatal("author values were remapped; only structural room keys may change")
+ }
+}
+
+func TestRewriteRoomRefsInDir(t *testing.T) {
+ dir := t.TempDir()
+ write := func(name, body string) {
+ t.Helper()
+ if err := os.WriteFile(filepath.Join(dir, name), []byte(body), 0o644); err != nil {
+ t.Fatal(err)
+ }
+ }
+ write("course.yaml", "start_room: 5\nobstacles:\n - room_id: 6\n")
+ write("unrelated.yaml", "value: 5\nname: keeps its value\n")
+
+ changes, err := RewriteRoomRefsInDir(dir, map[int]int{5: 50, 6: 60})
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(changes) != 1 {
+ t.Fatalf("changed %d files, want 1: %+v", len(changes), changes)
+ }
+ if !strings.Contains(string(changes[0].Content), "start_room: 50") ||
+ !strings.Contains(string(changes[0].Content), "room_id: 60") {
+ t.Fatalf("course not rewritten: %s", changes[0].Content)
+ }
+ if changes[0].Old == nil {
+ t.Fatal("before-image not captured for undo")
+ }
+}
+
+// Missing content directories are not an error (a family may be absent).
+func TestRewriteRoomRefsInDirMissingDir(t *testing.T) {
+ changes, err := RewriteRoomRefsInDir(t.TempDir()+"/nope", map[int]int{1: 2})
+ if err != nil {
+ t.Fatalf("missing dir must not error: %v", err)
+ }
+ if len(changes) != 0 {
+ t.Fatalf("expected no changes, got %+v", changes)
+ }
+}