"""Migration + WFM (no-AI) scenario — hand-check acceptance numbers.""" from __future__ import annotations import pytest from tokencalc import appendix4 as a4 from tokencalc import migration_wfm as mw from tokencalc.defaults import CTM_DEFAULT_SITES SITES = list(CTM_DEFAULT_SITES) def _default_benefit_rollout(): _, _, benefit_rollout = a4.build_rollouts(SITES) return benefit_rollout def test_wfm_scope_and_verbatim_total(): ben = mw.wfm_benefits_by_year(_default_benefit_rollout()) assert set(ben["capability"]) == {"WFM"} assert set(ben["region"]) == set(mw.DEFAULT_WFM_REGIONS) assert "EMEA" not in set(ben["region"]), "EMEA WFM is out of scope" # NA $0 (migration) + ANZ $1.4M + ASIA $914K — verbatim, exact. assert ben["benefit"].sum() == pytest.approx(2_314_000) def test_wfm_phasing_on_deck_schedule(): ben = mw.wfm_benefits_by_year(_default_benefit_rollout()) by_year = ben.groupby("year")["benefit"].sum() assert by_year[2026] == 0.0 # ANZ realizes Dec 2027 (1 of 13 live months lands in 2027). assert by_year[2027] == pytest.approx(1_400_000 / 13) assert by_year[2028] == pytest.approx(2_314_000 - 1_400_000 / 13) def test_runrate_saving_annual(): # (7.3M − 4.3M) licence + 1.3M ANZ + 1.6M ASIA + 0 NA = 5.9M. assert mw.wfm_annual_runrate() == pytest.approx(2_900_000) assert mw.runrate_saving_annual() == pytest.approx(5_900_000) assert mw.runrate_saving_annual(regions=["NA"]) == pytest.approx(3_000_000) assert mw.runrate_saving_annual(licence_annual=4_800_000, regions=[]) == pytest.approx(2_500_000) def test_breakeven_extrapolates_past_window(): cs = a4.current_state_inputs(SITES) cur = a4.current_costs_by_year(cs) lic = a4.licence_costs_by_year() ps = a4.ps_costs_by_year() total = {y: cur[y] + lic[y] + ps[y] for y in a4.YEARS} ben = mw.wfm_benefits_by_year(_default_benefit_rollout()) ben_y = {y: float(ben.loc[ben.year == y, "benefit"].sum()) for y in a4.YEARS} inc, net = a4.case_flows(total, ben_y) assert sum(net.values()) == pytest.approx(-1_553_000, abs=1_000) label = mw.runrate_breakeven_label(net, mw.runrate_saving_annual()) assert label == "40 months (~Apr 2029, extrapolated)" def test_breakeven_defers_in_window_and_guards_zero_runrate(): positive = {2026: 1_000_000.0, 2027: 0.0, 2028: 0.0} assert mw.runrate_breakeven_label(positive, 5_900_000) == \ a4.payback_label(positive) negative = {2026: -1_000_000.0, 2027: 0.0, 2028: 0.0} assert mw.runrate_breakeven_label(negative, 0.0) == \ "never at current run-rate"