diff options
| author | historia <[not public]> | 2026-06-28 02:40:30 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-28 02:40:30 -0400 |
| commit | a1b6613c6c6a2f8d6e1ecd47e766bd40f92ac295 (patch) | |
| tree | 4ff8fefb029c93f2aa3db7361658b0b4e9805b66 /internal/validate/local_test.go | |
| parent | 87dacfbb3dd16e7f55a82361eace98f9a39d75c8 (diff) | |
| download | thehouseoficarus-a1b6613c6c6a2f8d6e1ecd47e766bd40f92ac295.tar.gz | |
feat: admin accounts, god mode, OLC commands like dig/room, 'inline' objects changed to 'local' objects
Diffstat (limited to 'internal/validate/local_test.go')
| -rw-r--r-- | internal/validate/local_test.go | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/internal/validate/local_test.go b/internal/validate/local_test.go new file mode 100644 index 0000000..23bf8ca --- /dev/null +++ b/internal/validate/local_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 TestValidateLocalObjectPassiveOK(t *testing.T) { + robj := world.RoomObject{ID: "window", Local: &object.ObjectDef{ + Name: "window", + Hidden: true, + Description: behavior.DescList{{Text: "A small window."}}, + }} + issues := validateLocalObject(1001, robj, nil, nil) + if len(issues) != 0 { + t.Errorf("expected no issues for passive local object, got: %+v", issues) + } +} + +func TestValidateLocalObjectRejectsInteractable(t *testing.T) { + robj := world.RoomObject{ID: "rock", Local: &object.ObjectDef{ + Name: "rock", + Gather: &behavior.GatherConfig{}, + }} + issues := validateLocalObject(1001, robj, nil, nil) + if !containsMsg(issues, "interactable behavior") { + t.Errorf("expected interactable-behavior error, got: %+v", issues) + } +} + +func TestValidateLocalObjectRequiresName(t *testing.T) { + robj := world.RoomObject{ID: "x", Local: &object.ObjectDef{ + Description: behavior.DescList{{Text: "no name"}}, + }} + issues := validateLocalObject(1001, robj, nil, nil) + if !containsMsg(issues, "has no name") { + t.Errorf("expected has-no-name error, got: %+v", issues) + } +} + +func TestValidateLocalObjectStrayIDWarns(t *testing.T) { + robj := world.RoomObject{ID: "anvil", Local: &object.ObjectDef{Name: "anvil", ID: "anvil"}} + issues := validateLocalObject(1001, robj, nil, nil) + if !containsMsg(issues, "ignored on local 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: "a local thing that collides with the file id" +`) + issues := validateRooms(newSource(dir)) + + // Local 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) + } + } +} |
