diff options
Diffstat (limited to 'internal/validate/hardening_mob_stats_validation_test.go')
| -rw-r--r-- | internal/validate/hardening_mob_stats_validation_test.go | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/internal/validate/hardening_mob_stats_validation_test.go b/internal/validate/hardening_mob_stats_validation_test.go new file mode 100644 index 0000000..1ea30f9 --- /dev/null +++ b/internal/validate/hardening_mob_stats_validation_test.go @@ -0,0 +1,107 @@ +package validate + +import ( + "path/filepath" + "testing" +) + +// Regression: validateMobs must reject a fighting mob authored without an +// attack speed (engine.ToTicks clips 0 to 1, so the mob would attack every +// tick) or without a max hit for a declared attack type (a silent no-op). +// Task worksites are explicitly exempt: data/mobs/examples/solar_panel_frame.yaml +// ships max_melee_hit: 0 and must remain valid. + +func writeMob(t *testing.T, dir, name, body string) { + t.Helper() + writeFile(t, filepath.Join(dir, "mobs", name+".yaml"), body) +} + +func TestMobMissingSpeedIsError(t *testing.T) { + dir := t.TempDir() + writeMob(t, dir, "test_mob", `id: test_mob +name: test mob +combat: + kind: combat + attack_types: [crush] + stats: + hp: 10 + speed: 0 + max_melee_hit: 5 +`) + issues := validateMobs(newSource(dir)) + if !containsMsg(issues, "stats.speed") { + t.Fatalf("expected missing-speed error, got: %+v", issues) + } +} + +func TestMobMissingMaxMeleeHitIsError(t *testing.T) { + dir := t.TempDir() + writeMob(t, dir, "test_mob", `id: test_mob +name: test mob +combat: + kind: combat + attack_types: [crush] + stats: + hp: 10 + speed: 5 + max_melee_hit: 0 +`) + issues := validateMobs(newSource(dir)) + if !containsMsg(issues, "max_melee_hit") { + t.Fatalf("expected missing-melee-hit error, got: %+v", issues) + } +} + +func TestMobMissingMaxRangedHitIsError(t *testing.T) { + dir := t.TempDir() + writeMob(t, dir, "test_mob", `id: test_mob +name: test mob +combat: + kind: combat + attack_types: [crush, ranged] + stats: + hp: 10 + speed: 5 + max_melee_hit: 3 +`) + issues := validateMobs(newSource(dir)) + if !containsMsg(issues, "max_ranged_hit") { + t.Fatalf("expected missing-ranged-hit error, got: %+v", issues) + } +} + +func TestTaskWorksiteMobExemptFromCombatStatChecks(t *testing.T) { + dir := t.TempDir() + writeMob(t, dir, "test_worksite", `id: test_worksite +name: test worksite +combat: + kind: task + attack_types: [crush] + stats: + hp: 10 + speed: 0 + max_melee_hit: 0 +`) + if issues := validateMobs(newSource(dir)); len(issues) != 0 { + t.Fatalf("task worksite must be exempt from combat-stat checks, got: %+v", issues) + } +} + +func TestValidCombatMobProducesNoIssue(t *testing.T) { + dir := t.TempDir() + writeMob(t, dir, "test_mob", `id: test_mob +name: test mob +combat: + kind: combat + attack_types: [slash, ranged, science] + stats: + hp: 10 + speed: 4 + max_melee_hit: 3 + max_ranged_hit: 4 + max_science_hit: 5 +`) + if issues := validateMobs(newSource(dir)); len(issues) != 0 { + t.Fatalf("valid combat mob must validate cleanly, got: %+v", issues) + } +} |
