Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 189 additions & 0 deletions TUnit.Assertions.Tests/JsonElementAssertionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
using System.Text.Json;
using TUnit.Assertions.Extensions;

namespace TUnit.Assertions.Tests;

public class JsonElementAssertionTests
{
[Test]
public async Task IsObject_WithObject_Passes()
{
using var doc = JsonDocument.Parse("{\"name\":\"test\"}");
await Assert.That(doc.RootElement).IsObject();
}

[Test]
public async Task IsObject_WithArray_Fails()
{
using var doc = JsonDocument.Parse("[1,2,3]");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(doc.RootElement).IsObject());
}

[Test]
public async Task IsArray_WithArray_Passes()
{
using var doc = JsonDocument.Parse("[1,2,3]");
await Assert.That(doc.RootElement).IsArray();
}

[Test]
public async Task IsArray_WithNonArray_Fails()
{
using var doc = JsonDocument.Parse("{\"key\":\"value\"}");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(doc.RootElement).IsArray());
}

[Test]
public async Task IsString_WithString_Passes()
{
using var doc = JsonDocument.Parse("\"hello\"");
await Assert.That(doc.RootElement).IsString();
}

[Test]
public async Task IsString_WithNonString_Fails()
{
using var doc = JsonDocument.Parse("42");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(doc.RootElement).IsString());
}

[Test]
public async Task IsNumber_WithNumber_Passes()
{
using var doc = JsonDocument.Parse("42");
await Assert.That(doc.RootElement).IsNumber();
}

[Test]
public async Task IsNumber_WithNonNumber_Fails()
{
using var doc = JsonDocument.Parse("\"text\"");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(doc.RootElement).IsNumber());
}

[Test]
public async Task IsBoolean_WithTrue_Passes()
{
using var doc = JsonDocument.Parse("true");
await Assert.That(doc.RootElement).IsBoolean();
}

[Test]
public async Task IsBoolean_WithNonBoolean_Fails()
{
using var doc = JsonDocument.Parse("null");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(doc.RootElement).IsBoolean());
}

[Test]
public async Task IsNull_WithNull_Passes()
{
using var doc = JsonDocument.Parse("null");
await Assert.That(doc.RootElement).IsNull();
}

[Test]
public async Task IsNull_WithNonNull_Fails()
{
using var doc = JsonDocument.Parse("{}");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(doc.RootElement).IsNull());
}

[Test]
public async Task IsNotNull_WithObject_Passes()
{
using var doc = JsonDocument.Parse("{}");
await Assert.That(doc.RootElement).IsNotNull();
}

[Test]
public async Task IsNotNull_WithNull_Fails()
{
using var doc = JsonDocument.Parse("null");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(doc.RootElement).IsNotNull());
}

[Test]
public async Task HasProperty_WhenPropertyExists_Passes()
{
using var doc = JsonDocument.Parse("{\"name\":\"Alice\",\"age\":30}");
await Assert.That(doc.RootElement).HasProperty("name");
}

[Test]
public async Task HasProperty_WhenPropertyMissing_Fails()
{
using var doc = JsonDocument.Parse("{\"name\":\"Alice\"}");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(doc.RootElement).HasProperty("missing"));
}

[Test]
public async Task DoesNotHaveProperty_WhenPropertyMissing_Passes()
{
using var doc = JsonDocument.Parse("{\"name\":\"Alice\"}");
await Assert.That(doc.RootElement).DoesNotHaveProperty("missing");
}

[Test]
public async Task DoesNotHaveProperty_WhenPropertyExists_Fails()
{
using var doc = JsonDocument.Parse("{\"name\":\"Alice\"}");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(doc.RootElement).DoesNotHaveProperty("name"));
}

#if NET9_0_OR_GREATER
[Test]
public async Task IsDeepEqualTo_WithIdenticalJson_Passes()
{
using var doc1 = JsonDocument.Parse("{\"name\":\"Alice\",\"age\":30}");
using var doc2 = JsonDocument.Parse("{\"name\":\"Alice\",\"age\":30}");
await Assert.That(doc1.RootElement).IsDeepEqualTo(doc2.RootElement);
}

[Test]
public async Task IsDeepEqualTo_WithDifferentWhitespace_Passes()
{
using var doc1 = JsonDocument.Parse("{ \"name\" : \"Alice\" }");
using var doc2 = JsonDocument.Parse("{\"name\":\"Alice\"}");
await Assert.That(doc1.RootElement).IsDeepEqualTo(doc2.RootElement);
}

[Test]
public async Task IsDeepEqualTo_WithDifferentValues_FailsWithPath()
{
using var doc1 = JsonDocument.Parse("{\"name\":\"Alice\",\"age\":30}");
using var doc2 = JsonDocument.Parse("{\"name\":\"Alice\",\"age\":31}");

var exception = await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(doc1.RootElement).IsDeepEqualTo(doc2.RootElement));

await Assert.That(exception.Message).Contains("$.age");
}

[Test]
public async Task IsNotDeepEqualTo_WithDifferentJson_Passes()
{
using var doc1 = JsonDocument.Parse("{\"name\":\"Alice\"}");
using var doc2 = JsonDocument.Parse("{\"name\":\"Bob\"}");
await Assert.That(doc1.RootElement).IsNotDeepEqualTo(doc2.RootElement);
}

[Test]
public async Task IsNotDeepEqualTo_WithIdenticalJson_Fails()
{
using var doc1 = JsonDocument.Parse("{\"name\":\"Alice\"}");
using var doc2 = JsonDocument.Parse("{\"name\":\"Alice\"}");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(doc1.RootElement).IsNotDeepEqualTo(doc2.RootElement));
}
#endif
}
184 changes: 184 additions & 0 deletions TUnit.Assertions.Tests/JsonNodeAssertionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
using System.Text.Json.Nodes;
using TUnit.Assertions.Extensions;

namespace TUnit.Assertions.Tests;

public class JsonNodeAssertionTests
{
[Test]
public async Task IsJsonObject_WithJsonObject_Passes()
{
JsonNode? node = JsonNode.Parse("{\"name\":\"test\"}");
await Assert.That(node).IsJsonObject();
}

[Test]
public async Task IsJsonObject_WithJsonArray_Fails()
{
JsonNode? node = JsonNode.Parse("[1,2,3]");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(node).IsJsonObject());
}

[Test]
public async Task IsJsonArray_WithJsonArray_Passes()
{
JsonNode? node = JsonNode.Parse("[1,2,3]");
await Assert.That(node).IsJsonArray();
}

[Test]
public async Task IsJsonArray_WithJsonObject_Fails()
{
JsonNode? node = JsonNode.Parse("{\"name\":\"test\"}");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(node).IsJsonArray());
}

[Test]
public async Task IsJsonValue_WithJsonValue_Passes()
{
JsonNode? node = JsonNode.Parse("42");
await Assert.That(node).IsJsonValue();
}

[Test]
public async Task IsJsonValue_WithJsonObject_Fails()
{
JsonNode? node = JsonNode.Parse("{\"name\":\"test\"}");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(node).IsJsonValue());
}

[Test]
public async Task HasJsonProperty_WhenPropertyExists_Passes()
{
JsonNode? node = JsonNode.Parse("{\"name\":\"Alice\"}");
await Assert.That(node).HasJsonProperty("name");
}

[Test]
public async Task HasJsonProperty_WhenPropertyMissing_Fails()
{
JsonNode? node = JsonNode.Parse("{\"name\":\"Alice\"}");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(node).HasJsonProperty("missing"));
}

[Test]
public async Task DoesNotHaveJsonProperty_WhenPropertyMissing_Passes()
{
JsonNode? node = JsonNode.Parse("{\"name\":\"Alice\"}");
await Assert.That(node).DoesNotHaveJsonProperty("missing");
}

[Test]
public async Task DoesNotHaveJsonProperty_WhenPropertyExists_Fails()
{
JsonNode? node = JsonNode.Parse("{\"name\":\"Alice\"}");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(node).DoesNotHaveJsonProperty("name"));
}

// JsonArray assertions - use JsonNode? to work with TUnit's assertion model
[Test]
public async Task IsJsonArrayEmpty_WithEmptyArray_Passes()
{
JsonNode? node = JsonNode.Parse("[]");
await Assert.That(node).IsJsonArrayEmpty();
}

[Test]
public async Task IsJsonArrayEmpty_WithNonEmptyArray_Fails()
{
JsonNode? node = JsonNode.Parse("[1, 2, 3]");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(node).IsJsonArrayEmpty());
}

[Test]
public async Task IsJsonArrayNotEmpty_WithNonEmptyArray_Passes()
{
JsonNode? node = JsonNode.Parse("[1, 2, 3]");
await Assert.That(node).IsJsonArrayNotEmpty();
}

[Test]
public async Task IsJsonArrayNotEmpty_WithEmptyArray_Fails()
{
JsonNode? node = JsonNode.Parse("[]");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(node).IsJsonArrayNotEmpty());
}

[Test]
public async Task HasJsonArrayCount_WithMatchingCount_Passes()
{
JsonNode? node = JsonNode.Parse("[1, 2, 3]");
await Assert.That(node).HasJsonArrayCount(3);
}

[Test]
public async Task HasJsonArrayCount_WithMismatchedCount_Fails()
{
JsonNode? node = JsonNode.Parse("[1, 2, 3]");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(node).HasJsonArrayCount(5));
}

#if NET8_0_OR_GREATER
[Test]
public async Task IsDeepEqualTo_WithIdenticalJson_Passes()
{
JsonNode? node1 = JsonNode.Parse("{\"name\":\"Alice\",\"age\":30}");
JsonNode? node2 = JsonNode.Parse("{\"name\":\"Alice\",\"age\":30}");
await Assert.That(node1).IsDeepEqualTo(node2);
}

[Test]
public async Task IsDeepEqualTo_WithDifferentWhitespace_Passes()
{
JsonNode? node1 = JsonNode.Parse("{ \"name\" : \"Alice\" }");
JsonNode? node2 = JsonNode.Parse("{\"name\":\"Alice\"}");
await Assert.That(node1).IsDeepEqualTo(node2);
}

[Test]
public async Task IsDeepEqualTo_WithDifferentJson_Fails()
{
JsonNode? node1 = JsonNode.Parse("{\"name\":\"Alice\"}");
JsonNode? node2 = JsonNode.Parse("{\"name\":\"Bob\"}");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(node1).IsDeepEqualTo(node2));
}

[Test]
public async Task IsDeepEqualTo_ErrorMessageContainsPath()
{
JsonNode? node1 = JsonNode.Parse("{\"person\":{\"name\":\"Alice\",\"age\":30}}");
JsonNode? node2 = JsonNode.Parse("{\"person\":{\"name\":\"Alice\",\"age\":31}}");

var exception = await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(node1).IsDeepEqualTo(node2));

await Assert.That(exception.Message).Contains("$.person.age");
}

[Test]
public async Task IsNotDeepEqualTo_WithDifferentJson_Passes()
{
JsonNode? node1 = JsonNode.Parse("{\"name\":\"Alice\"}");
JsonNode? node2 = JsonNode.Parse("{\"name\":\"Bob\"}");
await Assert.That(node1).IsNotDeepEqualTo(node2);
}

[Test]
public async Task IsNotDeepEqualTo_WithIdenticalJson_Fails()
{
JsonNode? node1 = JsonNode.Parse("{\"name\":\"Alice\"}");
JsonNode? node2 = JsonNode.Parse("{\"name\":\"Alice\"}");
await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
async () => await Assert.That(node1).IsNotDeepEqualTo(node2));
}
#endif
}
Loading
Loading