forked from phenom/healer-man
106 lines
4.7 KiB
Python
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()
|