aboutsummaryrefslogtreecommitdiff
path: root/internal/validate/inline_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/validate/inline_test.go')
-rw-r--r--internal/validate/inline_test.go134
1 files changed, 134 insertions, 0 deletions
diff --git a/internal/validate/inline_test.go b/internal/validate/inline_test.go
new file mode 100644
index 0000000..5816c26
--- /dev/null
+++ b/internal/validate/inline_test.go
@@ -0,0 +1,134 @@
+package validate
+
+import (
+ "os"
+ "path/filepath"
+ "testing"
+
+ "thehouseoficarus/internal/behavior"
+ "thehouseoficarus/internal/item"
+ "thehouseoficarus/internal/object"
+ "thehouseoficarus/internal/world"
+)
+
+func TestValidateInlineObjectPassiveOK(t *testing.T) {
+ robj := world.RoomObject{ID: "window", Inline: &object.ObjectDef{
+ Name: "window",
+ Hidden: true,
+ Description: behavior.DescList{{Text: "A small window."}},
+ }}
+ issues := validateInlineObject(1001, robj, nil, nil)
+ if len(issues) != 0 {
+ t.Errorf("expected no issues for passive inline object, got: %+v", issues)
+ }
+}
+
+func TestValidateInlineObjectRejectsInteractable(t *testing.T) {
+ robj := world.RoomObject{ID: "rock", Inline: &object.ObjectDef{
+ Name: "rock",
+ Gather: &behavior.GatherConfig{},
+ }}
+ issues := validateInlineObject(1001, robj, nil, nil)
+ if !containsMsg(issues, "interactable behavior") {
+ t.Errorf("expected interactable-behavior error, got: %+v", issues)
+ }
+}
+
+func TestValidateInlineObjectRequiresName(t *testing.T) {
+ robj := world.RoomObject{ID: "x", Inline: &object.ObjectDef{
+ Description: behavior.DescList{{Text: "no name"}},
+ }}
+ issues := validateInlineObject(1001, robj, nil, nil)
+ if !containsMsg(issues, "has no name") {
+ t.Errorf("expected has-no-name error, got: %+v", issues)
+ }
+}
+
+func TestValidateInlineObjectStrayIDWarns(t *testing.T) {
+ robj := world.RoomObject{ID: "anvil", Inline: &object.ObjectDef{Name: "anvil", ID: "anvil"}}
+ issues := validateInlineObject(1001, robj, nil, nil)
+ if !containsMsg(issues, "ignored on inline objects") {
+ t.Errorf("expected stray-id warning, got: %+v", issues)
+ }
+}
+
+func newSource(dir string) Source {
+ return Source{
+ DataDir: dir,
+ Items: item.NewItemStore(dir),
+ Objects: object.NewObjectStore(dir),
+ Mobs: world.NewMobStore(dir),
+ World: world.New(dir),
+ }
+}
+
+func writeFile(t *testing.T, path, body string) {
+ t.Helper()
+ if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
+ t.Fatal(err)
+ }
+ if err := os.WriteFile(path, []byte(body), 0o644); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestValidateRoomsSameNameCollision(t *testing.T) {
+ dir := t.TempDir()
+ writeFile(t, filepath.Join(dir, "rooms", "1.yaml"), `name: Test Room
+objects:
+ - id: ghost_object
+ - name: sign
+ description: "one"
+ - name: sign
+ description: "two"
+`)
+ issues := validateRooms(newSource(dir))
+
+ if !containsMsg(issues, "nonexistent object \"ghost_object\"") {
+ t.Errorf("expected missing-reference error, got: %+v", issues)
+ }
+ if !containsMsg(issues, "objects share the name \"sign\"") {
+ t.Errorf("expected same-name collision error, got: %+v", issues)
+ }
+}
+
+func TestValidateRoomsDefIDCollisionAndDuplicateRefs(t *testing.T) {
+ dir := t.TempDir()
+ writeFile(t, filepath.Join(dir, "objects", "anvil.yaml"), "name: heavy anvil\n")
+ writeFile(t, filepath.Join(dir, "objects", "copper_rock.yaml"), "name: copper rock\n")
+ writeFile(t, filepath.Join(dir, "rooms", "1.yaml"), `name: Test Room
+objects:
+ - id: copper_rock
+ - id: copper_rock
+ - id: anvil
+ - name: anvil
+ description: "an inline thing that collides with the file id"
+`)
+ issues := validateRooms(newSource(dir))
+
+ // Inline name "anvil" normalizes to the referenced file id "anvil".
+ if !containsMsg(issues, "object id collision \"anvil\"") {
+ t.Errorf("expected defID collision error, got: %+v", issues)
+ }
+ // Two references to the same copper_rock file are allowed.
+ if containsMsg(issues, "name \"copper rock\"") || containsMsg(issues, "collision \"copper_rock\"") {
+ t.Errorf("repeated references to one file object should not collide, got: %+v", issues)
+ }
+}
+
+func TestValidateRoomsPartialNameSiblingsOK(t *testing.T) {
+ dir := t.TempDir()
+ writeFile(t, filepath.Join(dir, "rooms", "1.yaml"), `name: Test Room
+objects:
+ - name: rusty sign
+ description: "rusty"
+ - name: shiny sign
+ description: "shiny"
+`)
+ issues := validateRooms(newSource(dir))
+ for _, iss := range issues {
+ if iss.Type == "duplicate" {
+ t.Errorf("partial-name siblings should not collide, got: %+v", iss)
+ }
+ }
+}