using MeterVault.Core.Analysis.Virtual; using MeterVault.Core.Domain; using MeterVault.Infrastructure.Analysis; namespace MeterVault.Integration.Tests.Analysis; /// /// The analysis catalog built from loaded rows, without a database: one meter's broken configuration stays that meter's /// finding and never fails the catalog every analysis, cost, flow and solar read is built on. /// public sealed class AnalysisCatalogTests { [Fact] public void A_legacy_sum_of_hundreds_of_links_needs_configuration_and_the_other_meters_still_read() { // Review virtual F3: an expression-less virtual meter fed by 300 links implies a formula longer than 2,000 // characters. Deriving it used to throw out of Build, which every read calls. var meters = Enumerable.Range(1000, 300) .Select(id => new Meter { Id = id, Name = $"PV {id}", EnergyTypeId = 1, Mode = MeterMode.GenerationCounter, Unit = "kWh", Meta = "{}" }) .Append(new Meter { Id = 5000, Name = "Sum", EnergyTypeId = 1, Mode = MeterMode.Virtual, Unit = "kWh", Meta = "{}" }) .Append(new Meter { Id = 6000, Name = "Unrelated", EnergyTypeId = 2, Mode = MeterMode.CumulativeCounter, Unit = "kWh", Meta = "{}" }) .ToList(); var links = Enumerable.Range(1000, 300).Select(id => new MeterLink { FromMeterId = id, ToMeterId = 5000 }).ToList(); var catalog = AnalysisCatalog.Build(meters, [], links, [], TimeZoneInfo.Utc); Assert.Equal(VirtualMeterStatus.NeedsConfiguration, catalog.Find(5000)!.VirtualStatus); Assert.Equal(LegacyDerivationOutcome.Invalid, catalog.Find(5000)!.Legacy!.Outcome); Assert.NotNull(catalog.Find(6000)); Assert.NotNull(catalog.Find(1000)); } }