[
{"name": "ARPA 100.00, 80% margin, 2.5% churn, CAC 1,200.00: payback exactly 15 months", "args": [{"minor": 10000, "currency": "GBP"}, 8000, 250, {"minor": 120000, "currency": "GBP"}], "expect": {"ltv": {"minor": 320000, "currency": "GBP"}, "ltvToCacBasisPoints": 26667, "paybackMonths": 15}},
{"name": "the same customer with CAC 1,000.00: 12.5 months of payback is 13, not 12", "args": [{"minor": 10000, "currency": "GBP"}, 8000, 250, {"minor": 100000, "currency": "GBP"}], "expect": {"ltv": {"minor": 320000, "currency": "GBP"}, "ltvToCacBasisPoints": 32000, "paybackMonths": 13}},
{"name": "awkward figures: every result is rounded once from the inputs", "args": [{"minor": 999, "currency": "GBP"}, 7500, 700, {"minor": 50000, "currency": "GBP"}], "expect": {"ltv": {"minor": 10704, "currency": "GBP"}, "ltvToCacBasisPoints": 2141, "paybackMonths": 67}},
{"name": "no churn: the simple formula has no finite lifetime, so LTV and the ratio are null", "args": [{"minor": 10000, "currency": "GBP"}, 8000, 0, {"minor": 120000, "currency": "GBP"}], "expect": {"ltv": null, "ltvToCacBasisPoints": null, "paybackMonths": 15}},
{"name": "no acquisition cost: no ratio, and payback is immediate", "args": [{"minor": 10000, "currency": "GBP"}, 8000, 250, {"minor": 0, "currency": "GBP"}], "expect": {"ltv": {"minor": 320000, "currency": "GBP"}, "ltvToCacBasisPoints": null, "paybackMonths": 0}},
{"name": "no gross margin: nothing is ever paid back", "args": [{"minor": 10000, "currency": "GBP"}, 0, 250, {"minor": 1000, "currency": "GBP"}], "expect": {"ltv": {"minor": 0, "currency": "GBP"}, "ltvToCacBasisPoints": 0, "paybackMonths": null}},
{"name": "no revenue: LTV zero and payback never", "args": [{"minor": 0, "currency": "GBP"}, 8000, 250, {"minor": 1000, "currency": "GBP"}], "expect": {"ltv": {"minor": 0, "currency": "GBP"}, "ltvToCacBasisPoints": 0, "paybackMonths": null}},
{"name": "100% margin and 100% churn: LTV is one month's ARPA", "args": [{"minor": 5000, "currency": "GBP"}, 10000, 10000, {"minor": 5000, "currency": "GBP"}], "expect": {"ltv": {"minor": 5000, "currency": "GBP"}, "ltvToCacBasisPoints": 10000, "paybackMonths": 1}},
{"name": "in US dollars", "args": [{"minor": 25000, "currency": "USD"}, 7000, 300, {"minor": 300000, "currency": "USD"}], "expect": {"ltv": {"minor": 583333, "currency": "USD"}, "ltvToCacBasisPoints": 19444, "paybackMonths": 18}},
{"name": "a margin above 100% is an error", "args": [{"minor": 10000, "currency": "GBP"}, 10001, 250, {"minor": 1000, "currency": "GBP"}], "expectError": "gross margin basis points must be between 0 and 10000"},
{"name": "a negative churn rate is an error", "args": [{"minor": 10000, "currency": "GBP"}, 8000, -1, {"minor": 1000, "currency": "GBP"}], "expectError": "monthly churn basis points must be between 0 and 10000"},
{"name": "a negative CAC is an error", "args": [{"minor": 10000, "currency": "GBP"}, 8000, 250, {"minor": -1, "currency": "GBP"}], "expectError": "ARPA and CAC must not be negative"},
{"name": "ARPA and CAC in different currencies are an error", "args": [{"minor": 10000, "currency": "GBP"}, 8000, 250, {"minor": 1000, "currency": "USD"}], "expectError": "currency mismatch"},
{"name": "amounts beyond the exact range are an error rather than a wrong answer", "args": [{"minor": 100000000000, "currency": "GBP"}, 10000, 250, {"minor": 1000, "currency": "GBP"}], "expectError": "amounts too large for exact arithmetic"}
]