test(D.2b): conformance polish — table-driven slice asserts + BOM-safe loader

Fix 1: replace 3 copy-paste meter blocks in VitalsTree_MetersHaveExpectedSliceIds
with a single table-driven loop — a 4th meter is now a one-liner and failures
name the failing meter id directly.

Fix 2: FixtureLoader now reads the fixture as bytes and strips the UTF-8 BOM
(EF BB BF) before passing the span to JsonSerializer, so a BOM-bearing fixture
file never causes a spurious JsonReaderException.

Fix 3: add [Trait("Category", "Conformance")] at the class level so conformance
tests are selectable by category filter.

Fix 4: add missing <param name="layoutId"> doc tag to LayoutImporter.ImportInfos.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-15 14:38:55 +02:00
parent 3567135a04
commit 2b653b8fc0
3 changed files with 23 additions and 35 deletions

View file

@ -29,9 +29,14 @@ public static class FixtureLoader
if (!File.Exists(fixturePath))
throw new FileNotFoundException($"Vitals fixture not found at: {fixturePath}");
var json = File.ReadAllText(fixturePath, System.Text.Encoding.UTF8);
var root = JsonSerializer.Deserialize<ElementInfo>(json, _opts)
?? throw new InvalidOperationException("Failed to deserialize vitals fixture.");
var bytes = File.ReadAllBytes(fixturePath);
// Strip UTF-8 BOM (EF BB BF) if present so JsonSerializer.Deserialize<T>(ReadOnlySpan<byte>)
// does not reject the first byte.
ReadOnlySpan<byte> span = bytes;
if (span.Length >= 3 && span[0] == 0xEF && span[1] == 0xBB && span[2] == 0xBF)
span = span[3..];
var root = JsonSerializer.Deserialize<AcDream.App.UI.Layout.ElementInfo>(span, _opts)
?? throw new InvalidOperationException($"fixture deserialized to null: {fixturePath}");
return LayoutImporter.Build(root, _ => (0u, 0, 0), null);
}