Files
healer-man/scripts/test_balance_lab_brackets.py
2026-09-20 21:50:50 -04:00

106 lines
4.7 KiB
Python

import argparse
import json
import sys
import tempfile
import unittest
from pathlib import Path
from scripts.balance_lab_brackets import (
add_growth_metrics,
bracket_levels,
build_balance_lab_command,
evaluate_rows,
summarize_report,
)
class BalanceLabBracketTests(unittest.TestCase):
def test_bracket_levels_match_the_gm_schedules(self) -> None:
self.assertEqual(bracket_levels(10), [1, 10, 20, 30, 40, 50, 60, 70, 80])
self.assertEqual(bracket_levels(5)[:4], [1, 5, 10, 15])
self.assertEqual(bracket_levels(1), list(range(1, 81)))
def test_command_uses_the_existing_live_balance_lab_controller(self) -> None:
args = argparse.Namespace(
source="wow", spec_selection="all", party_seed=7, party_configurations=10,
simulations_per_party=3, duration=80, boss_category="wow", seeds="1,2,3",
active_slot=None, spec=[], boss=["stormwind-stockade/entry-1717"],
seat_sweep=True, cooldown_policy=None,
companion_readiness_policy=Path("policy.json"), include_beta_specs=True,
ready_only=True,
)
command = build_balance_lab_command(args, 40, Path("output/level-40"))
self.assertEqual(command[0], sys.executable)
self.assertTrue(command[1].endswith("scripts\\balance_lab.py") or command[1].endswith("scripts/balance_lab.py"))
self.assertIn("automatic", command)
self.assertEqual(command[command.index("--level") + 1], "40")
self.assertEqual(command[command.index("--seeds") + 1], "1,2,3")
self.assertIn("--seat-sweep", command)
self.assertIn("--include-beta-specs", command)
self.assertIn("--ready-only", command)
self.assertEqual(
command[command.index("--companion-readiness-policy") + 1],
str(Path("policy.json").resolve()),
)
def test_summary_measures_healer_requirement_from_raw_runs(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
report_path = root / "suite-report.json"
report = {
"level": 20,
"summary": {"partyConfigurations": 1, "bosses": 1},
"bosses": [{
"runs": 1, "bossMaxHealth": 1000, "defeatRate": 1,
"averageTimeToDefeat": 10,
}],
"classSpecs": [{
"role": "healer", "totalHealing": 150, "totalAbsorbs": 25,
}],
}
report_path.write_text(json.dumps(report), encoding="utf-8")
raw_path = root / "parties" / "wow-party-001" / "raw-runs.json"
raw_path.parent.mkdir(parents=True)
raw_path.write_text(json.dumps({"runs": [{
"elapsedSeconds": 10, "partyDamage": 1200, "bossDamage": 1000,
"incomingDamage": 200, "rawIncomingDamage": 250, "outcome": "defeated",
"pressureWindows": 2, "healerThroughputWindows": 2, "healerResponseWindows": 2,
"members": [
{"role": "healer", "healing": 150, "absorbs": 25, "minimumHealthPercent": 0.6},
{"role": "tank", "healing": 0, "absorbs": 0, "minimumHealthPercent": 0.4},
],
}]}), encoding="utf-8")
summary = summarize_report(report_path)
self.assertEqual(summary["healthToDpsSeconds"], 10)
self.assertEqual(summary["incomingDtps"], 20)
self.assertEqual(summary["healerHps"], 15)
self.assertEqual(summary["healingCoverageRate"], 0.875)
self.assertEqual(summary["incomingRunRate"], 1)
self.assertEqual(summary["healingRequiredRunRate"], 1)
self.assertEqual(summary["healerResponseRate"], 1)
self.assertEqual(summary["averageMinimumHealthPercent"], 0.4)
def test_growth_check_flags_health_that_outpaces_damage(self) -> None:
rows = [
{"level": 10, "bossHealth": 1000, "bossDps": 100},
{"level": 20, "bossHealth": 2500, "bossDps": 150},
]
for row in rows:
row.update({
"healthToDpsSeconds": row["bossHealth"] / row["bossDps"],
"incomingDtps": 10, "healerHps": 8, "incomingRunRate": 1,
"healingRequiredRunRate": 1,
})
add_growth_metrics(rows)
args = argparse.Namespace(
min_health_to_dps_seconds=5, max_health_to_dps_seconds=70, max_durability_growth=1.4,
min_incoming_run_rate=0.95, min_healing_required_run_rate=0.8,
min_healer_response_rate=0.6,
)
self.assertFalse(evaluate_rows(rows, args))
self.assertIn("boss health outgrew party DPS", rows[1]["flags"])
if __name__ == "__main__":
unittest.main()