test(historian): pin Uncertain-input degradation (T1 review)

Two Sql.Common tests close review finding I-1: an Uncertain NEXT neighbour makes an AtTime
interpolation Uncertain, and an Uncertain (non-Bad) sample in a bucket makes the aggregate
Uncertain. Each falsified with the reviewer's surviving mutation.

Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
Joseph Doherty
2026-10-11 01:42:22 -04:00
parent f0700571e8
commit 082e808d0d
2 changed files with 19 additions and 0 deletions
@@ -119,4 +119,14 @@ public sealed class AggregateEvaluatorTests
AggregateEvaluator.Evaluate(HistoryAggregateType.TimeAverage, RowsA()[0], At(0), Now));
ex.Aggregate.ShouldBe(HistoryAggregateType.TimeAverage);
}
[Fact]
public void An_uncertain_sample_in_a_bucket_degrades_the_aggregate_to_uncertain()
{
// Two usable samples, one Good and one Uncertain, no Bad: the value is computed, the status is Uncertain.
var row = new BucketRow { Total = 2, Usable = 2, Good = 1, Bad = 0, Avg = 15, Min = 10, Max = 20, Sum = 30 };
var avg = AggregateEvaluator.Evaluate(HistoryAggregateType.Average, row, At(0), Now);
avg.Value.ShouldBe(15d);
avg.StatusCode.ShouldBe(UncertainCalc);
}
}
@@ -106,4 +106,13 @@ public sealed class AtTimeEvaluatorTests
r.Value.ShouldBe("a");
r.StatusCode.ShouldBe(Uncertain | 0x402u);
}
[Fact]
public void An_uncertain_next_neighbour_makes_the_interpolation_uncertain()
{
var r = AtTimeEvaluator.Evaluate(At(5), S(0, HistorianValue.FromDouble(10), Good),
S(10, HistorianValue.FromDouble(20), Uncertain), Now, Now);
r.Value.ShouldBe(15d);
r.StatusCode.ShouldBe(UncertainInterpolated);
}
}