assembly-economics/simulations/gadm02/test_gadm02.py
tegwick 0e372398bf Implement ASSEMBLY-WP-0004: GADM-0.2 model, simulation, scenarios, sensitivity
- models/GADM-CLD.md: causal-loop diagram, loops, 49 signed links
- models/GADM-0.2.md: organism extensions (K split, attention headroom,
  selection channel O, membrane/lineage levers, participation claims),
  equations, findings
- simulations/gadm02: stdlib simulation, scenario runner, OAT sensitivity,
  unit tests; results committed
- scenarios/: six GADM-0.1 regimes + baseline + two organism-axis variants
- metrics/MetricsCatalog.md, models/GADM-0.3-Candidates.md,
  references/LiteratureComparison.md
- ASSEMBLY-WP-0005 (proposed, residual): GADM-0.3

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1494246@bnt-lap001
Assistant-Session: caf6de6f-f9e4-47ce-a584-49baa271fa4b
2026-10-12 00:43:53 +02:00

50 lines
1.7 KiB
Python

"""Sanity tests for the GADM-0.2 toy simulation.
Usage: python3 -m unittest discover -s simulations/gadm02
"""
import unittest
import gadm02 as g
from scenarios import load_all
class TestGADM02(unittest.TestCase):
def test_stocks_stay_bounded_in_all_scenarios(self):
for name, sc in load_all().items():
for row in g.simulate(sc["params"], sc["init"]):
for k in g.STOCKS:
self.assertGreaterEqual(row[k], 0.0, (name, k))
self.assertLessEqual(row[k], 1.0, (name, k))
def test_deterministic(self):
self.assertEqual(g.simulate(), g.simulate())
def test_unknown_parameter_rejected(self):
with self.assertRaises(KeyError):
g.simulate({"not_a_param": 1.0})
def test_vfac_is_geometric_mean(self):
s = {k: 0.5 for k in g.STOCKS}
self.assertAlmostEqual(g.vfac(s), 0.5)
s["E"] = 0.0
self.assertEqual(g.vfac(s), 0.0) # full collapse in one factor collapses VFAC
s["E"] = 0.01
# equal exponents damp near-collapse: (0.01/0.5)^(1/9) ≈ 0.65 of the level,
# which is why constitutional floors are checked separately from VFAC
self.assertAlmostEqual(g.vfac(s), 0.5 * (0.02 ** (1 / 9)), places=6)
def test_scenarios_only_use_known_parameters(self):
for name, sc in load_all().items():
self.assertFalse(set(sc["params"]) - set(g.PARAMS), name)
def test_floor_violations(self):
rows = [{"G": 0.1, "E": 0.5, "P": 0.8, "A": 0.5}, {"G": 0.5, "E": 0.5, "P": 0.5, "A": 0.5}]
v = g.floor_violations(rows)
self.assertEqual(v["G"], 0.5)
self.assertEqual(v["P"], 0.5)
self.assertEqual(v["E"], 0.0)
if __name__ == "__main__":
unittest.main()