aboutsummaryrefslogtreecommitdiff
path: root/internal/validate
diff options
context:
space:
mode:
Diffstat (limited to 'internal/validate')
-rw-r--r--internal/validate/checks.go47
-rw-r--r--internal/validate/local_test.go46
-rw-r--r--internal/validate/validate.go1
3 files changed, 94 insertions, 0 deletions
diff --git a/internal/validate/checks.go b/internal/validate/checks.go
index 7da2e4a..87c078e 100644
--- a/internal/validate/checks.go
+++ b/internal/validate/checks.go
@@ -1087,9 +1087,56 @@ func validateTalkConfig(prefix string, cfg *behavior.TalkConfig, itemIDs map[str
}
}
}
+
return issues
}
+func validateExitReciprocity(s Source) []Issue {
+ var issues []Issue
+ roomIndex := s.World.RoomIndex()
+
+ for srcID := range roomIndex {
+ src, err := s.World.LoadRoom(srcID)
+ if err != nil {
+ continue
+ }
+ for dir, exit := range src.Exits {
+ if exit.Room <= 0 || !roomIndex[exit.Room] {
+ continue
+ }
+ if srcID >= exit.Room {
+ continue
+ }
+ dst, err := s.World.LoadRoom(exit.Room)
+ if err != nil {
+ continue
+ }
+ expected := world.OppositeExit[dir]
+ hasCorrect := false
+ var returnDirs []string
+ for retDir, retExit := range dst.Exits {
+ if retExit.Room == srcID {
+ if retDir == expected {
+ hasCorrect = true
+ break
+ }
+ returnDirs = append(returnDirs, string(retDir))
+ }
+ }
+ if !hasCorrect && len(returnDirs) > 0 {
+ issues = append(issues, Issue{
+ Level: "WARN",
+ Type: "integrity",
+ Message: fmt.Sprintf(
+ "Room %d: exit %q to room %d, but return exit(s) %s are not the expected opposite direction %q",
+ srcID, dir, exit.Room, returnDirs, expected),
+ })
+ }
+ }
+ }
+
+ return issues
+}
func validateUseConfig(prefix string, cfg *behavior.UseConfig, itemIDs map[string]bool) []Issue {
var issues []Issue
if cfg == nil {
diff --git a/internal/validate/local_test.go b/internal/validate/local_test.go
index 23bf8ca..d37838e 100644
--- a/internal/validate/local_test.go
+++ b/internal/validate/local_test.go
@@ -116,6 +116,52 @@ objects:
}
}
+func TestValidateExitReciprocityOK(t *testing.T) {
+ dir := t.TempDir()
+ writeFile(t, filepath.Join(dir, "rooms", "1.yaml"), `name: Room One
+exits:
+ north: 2
+`)
+ writeFile(t, filepath.Join(dir, "rooms", "2.yaml"), `name: Room Two
+exits:
+ south: 1
+`)
+ issues := validateExitReciprocity(newSource(dir))
+ if len(issues) != 0 {
+ t.Errorf("expected no issues for correct reciprocal exits, got: %+v", issues)
+ }
+}
+
+func TestValidateExitReciprocityMismatch(t *testing.T) {
+ dir := t.TempDir()
+ writeFile(t, filepath.Join(dir, "rooms", "1.yaml"), `name: Room One
+exits:
+ down: 2
+`)
+ writeFile(t, filepath.Join(dir, "rooms", "2.yaml"), `name: Room Two
+exits:
+ south: 1
+`)
+ issues := validateExitReciprocity(newSource(dir))
+ if !containsMsg(issues, "not the expected opposite direction") {
+ t.Errorf("expected mismatch warning, got: %+v", issues)
+ }
+}
+
+func TestValidateExitReciprocityOneWay(t *testing.T) {
+ dir := t.TempDir()
+ writeFile(t, filepath.Join(dir, "rooms", "1.yaml"), `name: Room One
+exits:
+ east: 2
+`)
+ writeFile(t, filepath.Join(dir, "rooms", "2.yaml"), `name: Room Two
+`)
+ issues := validateExitReciprocity(newSource(dir))
+ if len(issues) != 0 {
+ t.Errorf("expected no issues for one-way exit, got: %+v", issues)
+ }
+}
+
func TestValidateRoomsPartialNameSiblingsOK(t *testing.T) {
dir := t.TempDir()
writeFile(t, filepath.Join(dir, "rooms", "1.yaml"), `name: Test Room
diff --git a/internal/validate/validate.go b/internal/validate/validate.go
index 56de6f1..6558216 100644
--- a/internal/validate/validate.go
+++ b/internal/validate/validate.go
@@ -81,6 +81,7 @@ func Run(s Source) []Issue {
issues = append(issues, validateTechs(s)...)
issues = append(issues, validateRoomWiring(s)...)
issues = append(issues, validateRoomGrid(s)...)
+ issues = append(issues, validateExitReciprocity(s)...)
return issues
}