JsonNode
A JsonNode and its subtypes
JsonObject, JsonArray and JsonValue, nullable or not, have the same expectations as a JsonElement:
Matches, MatchesExactly, HasProperty, DoesNotHaveProperty, HasValueAt,
DoesNotHaveValueAt, HasElementAt, IsObject (with WhoseProperties), IsArray (with WhoseElements), IsString, IsNumber and IsBoolean, with the
same options and failure messages:
JsonNode? track = JsonNode.Parse("""{"title": "Let It Be", "artist": "The Beatles"}""");
await That(track).Matches(new { title = "Let It Be" });
await That(track).HasProperty("artist", a => a.IsString("The Beatles"));
JsonArray titles = new("Let It Be", "Yesterday");
await That(titles).IsArray().WhoseElements.HasCount(2);
MatchesExactly(new { title = "Let It Be" }) on the track would fail with:
Expected that track
matches new { title = "Let It Be" } exactly,
but it differed as $.artist had unexpected "The Beatles"
The expectations keep the type of the subject for chaining with .And. A call that names the number type, like
IsNumber<int>() or IsNumber<double>(243), continues on a JsonNode, as C# cannot infer the node type then, except
on a JsonValue, which has IsNumber<TNumber> overloads of its own.
The node is verified in the state it has when the expectation is awaited, so changes made after That(…) are
included.
A null node is the JSON value null, as JsonNode.Parse("null") returns it. Use the general IsNull() expectation
of aweXpect to verify that a node is the JSON value null, e.g. HasProperty("label", l => l.IsNull()), so there is
no JSON-specific IsNull() for a JsonNode.
Nested nodes and null nodes
The expectations on a property, a value at a path or an element receive the node itself, e.g. for IsSameAs(…).
Likewise, WhoseElements provides the nodes of an array as JsonNode? items and WhoseProperties the properties of an
object as KeyValuePair<string, JsonNode?> items with the name and the node of the value, instead of JsonElement and
JsonProperty items:
JsonArray playlist = new(new JsonObject { ["title"] = "Let It Be" });
JsonNode first = playlist[0]!;
await That(playlist).HasElementAt(0, e => e.IsSameAs(first));
await That(playlist).IsArray().WhoseElements.Contains(first);
await That(first).IsObject().WhoseProperties.All().Satisfy(p => p.Value is JsonValue);
Matches(null) succeeds for a null node, while IsObject() would fail with:
Expected that node
is an object,
but it was null