docs: introduce Mercury Notebook Deliverable Pattern
This commit is contained in:
62
template/MercuryNotebook/tests/test_model.py
Normal file
62
template/MercuryNotebook/tests/test_model.py
Normal file
@@ -0,0 +1,62 @@
|
||||
"""Toy-model acceptance pins — hand-checked, like every study must have.
|
||||
|
||||
Every number here was computed by hand before it was pinned. When you
|
||||
replace the toy domain, replace these with hand-checks of YOUR math;
|
||||
the in-notebook verification gate is the second layer, not a substitute.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from studylib import model as m
|
||||
|
||||
|
||||
def test_contracted_overlays_verbatim():
|
||||
assert m.anchor("platform_annual") == 500_000 # signed contract
|
||||
assert m.ANCHOR_VERBATIM["platform_annual"] == 600_000 # pitch record intact
|
||||
assert m.anchor("baseline_annual") == m.ANCHOR_VERBATIM["baseline_annual"]
|
||||
|
||||
|
||||
def test_ramp_mechanics():
|
||||
assert m.platform_costs_by_year() == {2026: 300_000, 2027: 600_000,
|
||||
2028: 600_000}
|
||||
assert m.platform_costs_by_year(12)[2026] == 0.0
|
||||
assert m.platform_costs_by_year(0)[2026] == 600_000.0
|
||||
assert m.platform_costs_by_year(annual=m.anchor("platform_annual")) == \
|
||||
{2026: 250_000, 2027: 500_000, 2028: 500_000}
|
||||
|
||||
|
||||
def test_benefits_phase_on_the_schedule():
|
||||
ben = m.benefits_by_year()
|
||||
assert ben[2026] == 0.0 # nothing lands in year 1
|
||||
assert ben[2027] == pytest.approx(900_000 * 6 / 18) # months 19-24
|
||||
assert ben[2028] == pytest.approx(900_000 * 12 / 18)
|
||||
assert sum(ben.values()) == pytest.approx(m.anchor("benefit_3yr"))
|
||||
|
||||
|
||||
def _frame(annual):
|
||||
plat = m.platform_costs_by_year(annual=annual)
|
||||
total = {y: m.current_costs_by_year()[y] + plat[y] + m.services_by_year()[y]
|
||||
for y in m.YEARS}
|
||||
return m.case_flows(total, m.benefits_by_year())
|
||||
|
||||
|
||||
def test_contracted_frame_kpis():
|
||||
inc, net = _frame(m.anchor("platform_annual"))
|
||||
assert sum(net.values()) == pytest.approx(400_000)
|
||||
kpi = m.case_kpis(inc, net)
|
||||
assert kpi["roi"] == pytest.approx(0.8)
|
||||
assert kpi["npv"] == pytest.approx(206_612, abs=1) # @10%, hand-checked
|
||||
assert kpi["payback"] == "32 months (~Aug 2028)"
|
||||
|
||||
|
||||
def test_vendor_frame_kpis():
|
||||
inc, net = _frame(None) # verbatim pitch rate
|
||||
assert sum(net.values()) == pytest.approx(150_000)
|
||||
assert m.case_kpis(inc, net)["payback"] == "35 months (~Nov 2028)"
|
||||
|
||||
|
||||
def test_payback_edges():
|
||||
assert m.payback_label({2026: 1.0, 2027: 0.0, 2028: 0.0}) == "immediate"
|
||||
assert m.payback_label({2026: -1.0, 2027: -1.0, 2028: -1.0}) == "beyond 2028"
|
||||
Reference in New Issue
Block a user