Files
MeterVault/tests/Core.Tests/ExpressionEvaluatorTests.cs
T
schmidt.florian d972f67bad M1: pure normalization engine + default seed
Infrastructure-free normalization engine in Core dispatching on MeterMode:
- Cumulative/Generation counters: register deltas, first-reading baseline (Haus 411,
  Auto 3755), meter swaps (water …861→2 reconciles to 12 via boundary registers OR an
  explicit amount override), counter resets, anomaly-guarded decreases.
- RuntimeCounter: Δhours × rate (fixed/empirical).
- ConsumableBalance: tank level-Δ + deliveries → consumption, cm→litre calibration;
  delivery-only rows before the first dipstick emit nothing.
- DirectDelta, and Virtual meters via a small safe arithmetic evaluator (Netz Einsparung
  = Haus − Netz, Eigenverbrauch = Erzeugung − Einsparung) — data-driven, not hardcoded.
- DatabaseSeeder: default energy types, cost categories, base settings (idempotent).

24 Core unit tests + 4 integration tests green.

Claude-Session: https://claude.ai/code/session_01WujdMtMJPbxDpDnMeK22rr
2026-07-13 11:12:03 +02:00

37 lines
1.0 KiB
C#

using MeterVault.Core.Normalization.Expressions;
namespace MeterVault.Core.Tests;
public sealed class ExpressionEvaluatorTests
{
private static readonly Dictionary<string, double> Vars = new()
{
["m1"] = 411,
["m2"] = 416,
};
[Theory]
[InlineData("1 + 2 * 3", 7)]
[InlineData("(1 + 2) * 3", 9)]
[InlineData("-5", -5)]
[InlineData("10 / 4", 2.5)]
[InlineData("2 - 3 - 4", -5)] // left-associative
[InlineData("m1 - m2", -5)]
[InlineData("m1 + m2", 827)]
[InlineData("unknown + 1", 1)] // unknown identifiers resolve to 0
public void Evaluates_arithmetic(string expression, double expected)
{
var result = ExpressionEvaluator.Compile(expression).Evaluate(Vars);
Assert.Equal(expected, result, 6);
}
[Theory]
[InlineData("1 +")]
[InlineData("(1 + 2")]
[InlineData("1 2")]
[InlineData("")]
public void Rejects_malformed_expressions(string expression) =>
Assert.ThrowsAny<Exception>(() => ExpressionEvaluator.Compile(expression));
}