diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-21 21:47:59 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-21 21:47:59 +0800 |
| commit | 722ec6c19c0c64ea5348c6bc3aefc0061bd96307 (patch) | |
| tree | 65fc127dcb808e05ab332d15332b5cb69ccf6620 /tests/FundLab.Domain.Tests | |
| parent | 98c41c37896a41c5f2f15ed187e55ab617735342 (diff) | |
| download | fund-lab-722ec6c19c0c64ea5348c6bc3aefc0061bd96307.tar.gz | |
Add dividend slice (3d-8)
Book cash dividends to available cash exactly once and reinvest dividends through the shared subscription pipeline, with deterministic scheme idempotency and cross-position isolation.
Diffstat (limited to 'tests/FundLab.Domain.Tests')
| -rw-r--r-- | tests/FundLab.Domain.Tests/DomainTests.fs | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/tests/FundLab.Domain.Tests/DomainTests.fs b/tests/FundLab.Domain.Tests/DomainTests.fs index b2a2f0b..ff5245e 100644 --- a/tests/FundLab.Domain.Tests/DomainTests.fs +++ b/tests/FundLab.Domain.Tests/DomainTests.fs @@ -757,3 +757,78 @@ module RebalancePolicyTests = Assert.Equal("rebalance-redeem:7c9e6679-7425-40de-944b-e07fc1f90ae7:2026-09-21:000001", RebalancePolicy.redemptionKey planId runDate "000001") Assert.Equal(RebalancePolicy.orderKey planId runDate "000001", RebalancePolicy.orderKey planId runDate "000001") + +module DividendPolicyTests = + + open Xunit + open FundLab.Domain + + let private unwrap result = + match result with + | Ok value -> value + | Error error -> failwithf "%A" error + + [<Fact>] + let ``dividend per unit validation rejects non positive or imprecise values`` () = + Assert.Equal(Error "dividend per unit must be positive", DividendPolicy.validateDps 0m) + Assert.Equal(Error "dividend per unit must be positive", DividendPolicy.validateDps -0.05m) + Assert.Equal(Error "dividend per unit exceeds supported precision", DividendPolicy.validateDps 0.015000001m) + Assert.Equal(Ok(), DividendPolicy.validateDps 0.01500000m) + + [<Fact>] + let ``future dividend dates are rejected without look-ahead`` () = + let today = System.DateOnly(2026, 9, 21) + + Assert.Equal( + Error "dividend nav date is in the future", + DividendPolicy.validateNavDate (System.DateOnly(2026, 9, 22)) today + ) + Assert.Equal(Ok(), DividendPolicy.validateNavDate today today) + + [<Fact>] + let ``cash dividend payout truncates to two decimals and keeps units untouched`` () = + let payout: DividendPolicy.CashDividendOutcome = + DividendPolicy.computeCashPayout 500.00000000m 0.1m + |> unwrap + + Assert.Equal(50.00m, payout.GrossCash) + + let uneven: DividendPolicy.CashDividendOutcome = + DividendPolicy.computeCashPayout 123.45678900m 0.12345678m + |> unwrap + + Assert.Equal(15.24m, uneven.GrossCash) + Assert.Equal(Error "held units must be positive for a cash dividend", DividendPolicy.computeCashPayout 0m 0.1m) + Assert.Equal(Error "dividend per unit must be positive", DividendPolicy.computeCashPayout 500m -0.1m) + + [<Fact>] + let ``reinvestment follows the subscription math`` () = + let reinvest: DividendPolicy.ReinvestDividendOutcome = + DividendPolicy.computeReinvest 500.00000000m 0.1m 2.5m + |> unwrap + + // gross 50.00 -> units 20.00000000 at nav 2.5 + Assert.Equal(50.00m, 50.00m) + Assert.Equal(20.00000000m, reinvest.RequestedUnits) + Assert.Equal(2.5m, reinvest.NAV) + + let proceedsZero = + DividendPolicy.computeReinvest 1.00000000m 0.00000001m 2.5m + + Assert.Equal(Error "dividend proceeds round to zero", proceedsZero) + + let badNav = + DividendPolicy.computeReinvest 500.00000000m 0.1m 0m + + Assert.Equal(Error "unit nav must be positive", badNav) + + [<Fact>] + let ``mode parsing roundtrips and record keys are deterministic`` () = + Assert.Equal(Some DividendPolicy.Cash, DividendPolicy.parseMode "cash") + Assert.Equal(Some DividendPolicy.Reinvest, DividendPolicy.parseMode "reinvest") + Assert.Equal(None, DividendPolicy.parseMode "stock") + + let recordId = System.Guid "7c9e6679-7425-40de-944b-e07fc1f90ae7" + + Assert.Equal("dividend:7c9e6679-7425-40de-944b-e07fc1f90ae7", DividendPolicy.recordKey recordId) + Assert.Equal("dividend-confirm:7c9e6679-7425-40de-944b-e07fc1f90ae7", DividendPolicy.confirmKey recordId) |
