using MeterVault.Core.Domain; using MeterVault.Core.Normalization; using static MeterVault.Core.Tests.TestData; namespace MeterVault.Core.Tests; /// /// The water meter register swaps mid-series (…861 → 2 → 15). The swap month's consumption (12) /// cannot be derived from the two visible registers alone — an explicit swap event carries the /// boundary, and continuity is preserved across it (SDD §2.3, §7.1). /// public sealed class WaterSwapTests { private readonly INormalizationEngine _engine = NormalizationEngine.CreateDefault(); private static NormalizationContext WaterContext(MeterEvent swap) => new() { Meter = new MeterConfig { MeterId = 10, Mode = MeterMode.CumulativeCounter, Unit = "m3", InitialBaseline = 820, // Nov 2022 register, so Dez books 14. }, Readings = [ Reading(10, Month(2022, 12), 834), Reading(10, Month(2023, 1), 848), Reading(10, Month(2023, 2), 861), Reading(10, Month(2023, 3), 2), // new meter Reading(10, Month(2023, 4), 15), ], Events = [swap], }; [Fact] public void Swap_with_boundary_registers_reconciles_to_twelve() { // Old meter ran 861 → 873 before removal; new meter installed reading 2. var swap = Swap(10, Month(2023, 3), prevValue: 873, newValue: 2); var result = _engine.Normalize(WaterContext(swap)); Assert.Equal([14d, 14d, 13d, 12d, 13d], result.Select(c => c.Amount)); } [Fact] public void Swap_with_explicit_amount_override_reconciles_to_twelve() { // The importer can seed the sheet's own März consumption (12) as an override. var swap = Swap(10, Month(2023, 3), amount: 12); var result = _engine.Normalize(WaterContext(swap)); Assert.Equal([14d, 14d, 13d, 12d, 13d], result.Select(c => c.Amount)); } }