v0.1.0
[0.1.0] - 2026-06-07: full assertion surface
The full surface: a queryable MeasurementSet, multi-instrument MeterCapture, meter-introspection
MeterInspector, baseline deltas, and the complete Assert.That assertion vocabulary across all three.
Added
MeasurementSet(core): an immutable, queryable set of captured measurements with counter-style
(Total) and histogram-style (Sum/Min/Max/Average) aggregates, rawValues/All, ordered and
order-insensitive sample comparisons, tag and instrument narrowing (Tagged/ForInstrument), range and
tag predicates, and a deterministicToSnapshotStringprojection.MeterCapture(core): a meter-wide bundle composed from per-instrument captures, built fluently
withFor+Add, queried per instrument or across all viaMeasurements, withRecordObservable
for observable gauges.MeterInspector(core): discovers which instruments a meter publishes
(PublishedInstrumentNames/IsPublished/PublishesAll) via a short-livedMeterListener.InstrumentCapture(core): expanded withOfName/OfObservableconstruction,Total/LastValue,
tag queries (Tagged/HasMeasurementTagged), baseline deltas (Snapshot/Since+MeasurementBaseline),
RecordObservable, andWaitForAsync.MetricsAssertions.TUnit(adapter): the fullAssert.That(...).Has*vocabulary (counter and
up-down-counter totals, measurement counts, emptiness, last value, histogram sum/average/range, exact and
order-insensitive sample sets, and tag-consistency) overInstrumentCapture,MeasurementSet, and
MeterCapture.- Failure diagnostics: every assertion dumps the captured measurements (instrument, value, tags,
timestamp) under the failure, so a mismatch shows what was actually recorded, not only the mismatched
scalar. - Hardening: tolerance arguments are validated (finite, non-negative), inverted range bounds are
rejected, baselines are bound to their originating capture, duplicateMeterCaptureinstrument names
dispose the prior capture, and unknown meter-capture instruments fail as assertions rather than throwing.
Changed
- Breaking:
InstrumentCapture.Measurementsnow returns aMeasurementSetinstead of
IReadOnlyList<CapturedMeasurement>. UseMeasurements.Allfor the underlying list, or the new query
surface directly.