Skip to content

Releases: JohnVerheij/JsonAssertions.TUnit

v0.6.1

Choose a tag to compare

@github-actions github-actions released this 12 Jul 06:20
v0.6.1
96bfcc4

[0.6.1] - 2026-07-12: document the 0.6.0 traps

Patch release. Documentation only; no API or behavioral change. Everything here comes from migrating a real suite onto 0.6.0, where the two new features landed cleanly but three shapes in the surface misled a reader who was pattern-matching from the rest of the package.

Changed

  • ContainsJson documentation now carries an explicit warning against folding a volatile value into the expected subset. ContainsJson asserts equality for every field placed in it: "subset" constrains which fields are checked, not how strictly they are compared. Pinning a duration reading, a server-generated identifier, or a legitimately-varying status therefore asserts more than the contract does, and the test fails on the first run that differs. This is the failure mode a migration onto 0.6.0 walks into, because collapsing a block of per-property checks feels mechanical enough to sweep a volatile field in with the stable ones, turning a presence check into an equality check.
  • GetJsonValue<T> / GetJsonString / GetJsonElement are now documented as extending the receiver rather than the assertion chain, and as living in the JsonAssertions namespace, so they need using JsonAssertions;. Every other feature auto-imports through TUnit.Assertions.Extensions, which trains a reader to reach for Assert.That(response).GetJsonValueAsync<T>(...) first: that does not compile, and the resulting CS1061 never names the missing namespace. The namespace table, the entry-point list, and the cookbook pattern now all show the receiver form.
  • HasJsonArrayLength and the other shape and value assertions now document that only the HttpResponseMessage forms take a CancellationToken (it flows to the body read; a string or JsonElement source has nothing to cancel). Passing one on a JsonElement reports CS1929 naming HttpResponseMessage as the required receiver, which points at the receiver when the fix is to drop the token.
  • HasJsonTypeInfoFor<T> is now documented as the one assertion in the package that guards a failure class the rest of a suite can miss: a type absent from the JsonSerializerContext is not a compile error, and with a reflection fallback in the resolver chain a JIT test run serializes it happily while the published Native-AOT binary throws at runtime.
  • MatchesProblemDetails now documents that it asserts the media type as well as the fields, so a separate content-type test becomes redundant on migration (which a strict analyzer set will flag as duplicate method bodies).

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 11 Jul 15:57
v0.6.0
fb0de04

[0.6.0] - 2026-07-11: JSON subset matching and typed extraction

Minor release. Adds subset (contains) assertions and typed value extraction. Purely additive.

Added

  • Assert.That(actual).ContainsJson(expectedSubset) asserts that a JSON document contains an expected subset: every property in the expected document must be present in the actual document with an equivalent value (recursively), while the actual document may carry additional properties. This is the subset counterpart of IsEquivalentJsonTo (full equality), for the common case where a response carries fields a test does not want to pin. A JSON string, a JsonElement, and an HttpResponseMessage (body read with a flowed CancellationToken) are accepted as the actual value; the expected subset is a JSON string. Matching is independent of object-property order and number form. An expected array asserts a positional prefix (the actual array may be longer); IgnoreArrayOrder() matches expected elements against the actual array as a multiset subset, and IgnorePath(...) excludes a path, both through the configure overload. On failure the message lists every missing or mismatched path in one report, each with its category and a rendered view of both sides, so a single run enumerates every field that is wrong.
  • JsonEquivalence.ContainsAll(expected, actual, options) (framework-agnostic core) exposes the subset comparison directly over JSON strings or JsonElements, returning every JsonDifference found (empty when the actual document contains the subset). JsonFailureMessage.ContainsMismatch(differences) renders the multi-difference failure text.
  • GetJsonValue<T>(path), GetJsonString(path), and GetJsonElement(path) read a typed value out of a JSON document at a path and return it, for a test that needs the value (pulling an id to drive the next request, reading a count to cross-check an array length) rather than an assertion. GetJsonValue<T> parses the value as any IParsable<T> (int / long / bool / Guid / DateTimeOffset, ...) from a JSON string or a JSON number literal, using CultureInfo.InvariantCulture; GetJsonElement returns a detached copy that stays valid after the source document is disposed. Each is available over a JSON string, a JsonElement, and (as GetJsonValueAsync / GetJsonStringAsync / GetJsonElementAsync) an HttpResponseMessage. A failure to resolve the path, convert the value, or parse the source throws JsonExtractionException with the same path-context message the assertions render, replacing a hand-rolled JsonDocument.Parse(...).GetProperty(...).GetInt32() chain and its bare BCL exceptions.

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 14 Jun 12:35
v0.5.0
28ce945

[0.5.0] - 2026-06-14: structural JSON equivalence

Minor release. Adds whole-document structural equivalence assertions. Purely additive.

Added

  • Assert.That(actual).IsEquivalentJsonTo(expected) asserts that two JSON documents carry the same values at the same paths. Equivalence ignores object-property order and the lexical form of numbers, so 1, 1.0, and 1e0 are equal. Both a JSON string and a JsonElement are accepted as the actual value; the expected document is a JSON string. A configure overload sets options: IgnorePath("items[*].timestamp") excludes a path from the comparison (the same path grammar as the other assertions, including the [*] wildcard), and IgnoreArrayOrder() compares arrays as multisets rather than position by position. On failure the message names the first diverging path, the category of difference, and a rendered view of each side, with container values shown as truncated raw JSON.
  • JsonEquivalence (framework-agnostic core) exposes the comparison directly: Compare(expected, actual, options) over JSON strings or JsonElements returns the first JsonDifference, or null when the documents are equivalent. JsonEquivalenceOptions, JsonDifference, and JsonDifferenceKind are public so the engine is usable outside the assertion path.

v0.4.2

Choose a tag to compare

@github-actions github-actions released this 05 Jun 19:27
v0.4.2
f9da36f

[0.4.2] - 2026-06-05: documentation refresh

Documentation and release-tooling release. No API or behavior change.

Changed

  • Refreshed the README (plain-ASCII punctuation) and rewrote the shared CONVENTIONS.md: removed the version-history preamble so it reads as a conventions document, not a changelog.
  • Documented the JSON path syntax (dot-separated with [n] indices plus the [*] wildcard) and why it is a navigable subset rather than JSONPath/JMESPath.
  • The release workflow now publishes the matching CHANGELOG.md section as the GitHub release body (body_path), so release notes carry the full hand-written detail instead of GitHub's auto-generated commit summary.

v0.4.1

Choose a tag to compare

@github-actions github-actions released this 04 Jun 15:23
v0.4.1
203184f

What's Changed

  • deps(nuget): update tunit to v1.49.0 by @renovate[bot] in #43
  • docs: note [*] wildcard empty-array footgun and index-scoped caveat by @JohnVerheij in #42

Full Changelog: v0.4.0...v0.4.1

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 03 Jun 04:10
v0.4.0
f632ce2

What's Changed

  • feat: int/uint/long/ulong JSON value overloads match a number or numeric string by @JohnVerheij in #41

Full Changelog: v0.2.0...v0.4.0

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 17 May 10:47

What's Changed

  • chore: split CoC and security reporting channels by @JohnVerheij in #6
  • feat(v0.3.0): AOT-context regression + HTTP-response JSON by @JohnVerheij in #7

Full Changelog: v0.2.0...v0.3.0

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 15 May 08:12

What's Changed

  • docs: CONVENTIONS.md v0.4 - add JsonAssertions.TUnit to the family roster by @JohnVerheij in #2
  • chore: auto-populate PackageReleaseNotes from CHANGELOG at pack time by @JohnVerheij in #3
  • feat: v0.2.0 - array-indexed paths, root-self, boolean/non-empty-string/matching/one-of/parsable-as assertions by @JohnVerheij in #4
  • docs: bring README / SECURITY / bug-report to the v0.2.0 surface by @JohnVerheij in #5

Full Changelog: v0.1.0...v0.2.0

v0.1.0

Choose a tag to compare

@github-actions github-actions released this 14 May 17:40

What's Changed

  • feat: v0.1.0 - value-at-path, shape, and HTTP assertions by @JohnVerheij in #1

New Contributors

Full Changelog: v0.0.1...v0.1.0

v0.0.1

Choose a tag to compare

@github-actions github-actions released this 14 May 13:59