Skip to content

Commit

Permalink
Add assertions on JSON nodes null, string, number, true, and false.
Browse files Browse the repository at this point in the history
  • Loading branch information
Corniel committed Aug 17, 2023
1 parent 2d736bd commit 3bcbc37
Show file tree
Hide file tree
Showing 2 changed files with 249 additions and 2 deletions.
102 changes: 102 additions & 0 deletions Src/FluentAssertions/Json/JsonElementAssertions.cs
Expand Up @@ -42,6 +42,108 @@ public AndConstraint<JsonElementAssertions> HaveValueKind(JsonValueKind valueKin
return new(this);

Check notice on line 42 in Src/FluentAssertions/Json/JsonElementAssertions.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Use preferred style of 'new' expression when created type is not evident

Missing type specification
}

/// <summary>
/// Asserts that the current <see cref="JsonElement"/> is the JSON null node.

Check failure on line 46 in Src/FluentAssertions/Json/JsonElementAssertions.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Cannot resolve reference in XML comment

Cannot resolve symbol 'JsonElement'
/// </summary>
/// <param name="because">
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
/// </param>
/// <param name="becauseArgs">
/// Zero or more objects to format using the placeholders in <see paramref="because" />.
/// </param>
public AndConstraint<JsonElementAssertions> BeNull(string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.ForCondition(Subject.ValueKind == JsonValueKind.Null)
.FailWith("Expected {context:JSON} to be a JSON null{reason}, but found {0}.", Subject);

return new(this);

Check notice on line 62 in Src/FluentAssertions/Json/JsonElementAssertions.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Use preferred style of 'new' expression when created type is not evident

Missing type specification
}

/// <summary>
/// Asserts that the current <see cref="JsonElement"/> is the JSON string node.

Check failure on line 66 in Src/FluentAssertions/Json/JsonElementAssertions.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Cannot resolve reference in XML comment

Cannot resolve symbol 'JsonElement'
/// </summary>
/// <param name="value">The value of the JSON string node.</param>
/// <param name="because">
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
/// </param>
/// <param name="becauseArgs">
/// Zero or more objects to format using the placeholders in <see paramref="because" />.
/// </param>
public AndConstraint<JsonElementAssertions> BeString(string value, string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.ForCondition(Subject.ValueKind == JsonValueKind.String && Subject.GetString() == value)
.FailWith("Expected {context:JSON} to be a JSON string {0}{reason}, but found {1}.", value, Subject);

return new(this);

Check notice on line 83 in Src/FluentAssertions/Json/JsonElementAssertions.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Use preferred style of 'new' expression when created type is not evident

Missing type specification
}

/// <summary>
/// Asserts that the current <see cref="JsonElement"/> is the JSON number node.

Check failure on line 87 in Src/FluentAssertions/Json/JsonElementAssertions.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Cannot resolve reference in XML comment

Cannot resolve symbol 'JsonElement'
/// </summary>
/// <param name="value">The value of the JSON string node.</param>
/// <param name="because">
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
/// </param>
/// <param name="becauseArgs">
/// Zero or more objects to format using the placeholders in <see paramref="because" />.
/// </param>
public AndConstraint<JsonElementAssertions> BeNumber(decimal value, string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.ForCondition(Subject.ValueKind == JsonValueKind.Number && Subject.GetDecimal() == value)
.FailWith("Expected {context:JSON} to be a JSON string {0}{reason}, but found {1}.", value, Subject);

return new(this);

Check notice on line 104 in Src/FluentAssertions/Json/JsonElementAssertions.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Use preferred style of 'new' expression when created type is not evident

Missing type specification
}

/// <summary>
/// Asserts that the current <see cref="JsonElement"/> is the JSON true node.

Check failure on line 108 in Src/FluentAssertions/Json/JsonElementAssertions.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Cannot resolve reference in XML comment

Cannot resolve symbol 'JsonElement'
/// </summary>
/// <param name="because">
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
/// </param>
/// <param name="becauseArgs">
/// Zero or more objects to format using the placeholders in <see paramref="because" />.
/// </param>
public AndConstraint<JsonElementAssertions> BeTrue(string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.ForCondition(Subject.ValueKind == JsonValueKind.True)
.FailWith("Expected {context:JSON} to be a JSON true{reason}, but found {0}.", Subject);

return new(this);

Check notice on line 124 in Src/FluentAssertions/Json/JsonElementAssertions.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Use preferred style of 'new' expression when created type is not evident

Missing type specification
}

/// <summary>
/// Asserts that the current <see cref="JsonElement"/> is the JSON false node.

Check failure on line 128 in Src/FluentAssertions/Json/JsonElementAssertions.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Cannot resolve reference in XML comment

Cannot resolve symbol 'JsonElement'
/// </summary>
/// <param name="because">
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
/// </param>
/// <param name="becauseArgs">
/// Zero or more objects to format using the placeholders in <see paramref="because" />.
/// </param>
public AndConstraint<JsonElementAssertions> BeFalse(string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.ForCondition(Subject.ValueKind == JsonValueKind.False)
.FailWith("Expected {context:JSON} to be JSON false{reason}, but found {0}.", Subject);

return new(this);

Check notice on line 144 in Src/FluentAssertions/Json/JsonElementAssertions.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Use preferred style of 'new' expression when created type is not evident

Missing type specification
}

public void Be(long jsonNumber)
{
Execute.Assertion
Expand Down
149 changes: 147 additions & 2 deletions Tests/FluentAssertions.Specs/Json/JsonElementAssertionsSpecs.cs
Expand Up @@ -17,11 +17,11 @@ public void Throws_for_unexcepected_value_kind()

// Act
Action act = () => options.Should().Serialize(42)
.And.Value.Should().HaveValueKind(JsonValueKind.String, because: "Why not?");
.And.Value.Should().HaveValueKind(JsonValueKind.String, because: "why not?");

// Assert
act.Should().Throw<XunitException>()
.WithMessage("Expected options to have value kind JsonValueKind.String {value: 3} because Why not?, but found JsonValueKind.Number {value: 4}");
.WithMessage("Expected options to have value kind JsonValueKind.String {value: 3} because why not?, but found JsonValueKind.Number {value: 4}.");
}

[Fact]
Expand All @@ -34,4 +34,149 @@ public void Guards_excepected_value_kinds()
options.Should().Serialize(42).And.Value.Should().HaveValueKind(JsonValueKind.Number);
}
}

public class BeNull
{
[Fact]
public void Throws_for_other_elements()
{
// Arrange
JsonSerializerOptions options = new();

// Act
Action act = () => options.Should().Serialize("null").And.Value.Should().BeNull(because: "why not?");

// Assert
act.Should().Throw<XunitException>()
.WithMessage("TODO");
}

[Fact]
public void Guards_null_node()
{
// Arrange
JsonSerializerOptions options = new();

// Act + assert
options.Should().Serialize<object>(null).And.Value.Should().BeNull();
}
}

public class BeString
{
[Fact]
public void Throws_for_other_elements()
{
// Arrange
JsonSerializerOptions options = new();

// Act
Action act = () => options.Should().Serialize<object>(null).And.Value.Should().BeString("null", because: "why not?");

// Assert
act.Should().Throw<XunitException>()
.WithMessage("TODO");
}

[Fact]
public void Guards_string_node()
{
// Arrange
JsonSerializerOptions options = new();

// Act + assert
options.Should().Serialize(Guid.Parse("61088fce-43c5-4327-b591-0d7e862075d8")).And.Value.Should().BeString("61088fce-43c5-4327-b591-0d7e862075d8");
}
}

public class BeNumber
{
[Fact]
public void Throws_for_other_elements()
{
// Arrange
JsonSerializerOptions options = new();

// Act
Action act = () => options.Should().Serialize("42").And.Value.Should().BeNumber(42, because: "why not?");

// Assert
act.Should().Throw<XunitException>()
.WithMessage("TODO");
}

[Fact]
public void Guards_integer_number_node()
{
// Arrange
JsonSerializerOptions options = new();

// Act + assert
options.Should().Serialize(42).And.Value.Should().BeNumber(42);
}

[Fact]
public void Guards_floating_point_number_node()
{
// Arrange
JsonSerializerOptions options = new();

// Act + assert
options.Should().Serialize(42.17).And.Value.Should().BeNumber(42.17m);
}
}

public class BeTrue
{
[Fact]
public void Throws_for_other_elements()
{
// Arrange
JsonSerializerOptions options = new();

// Act
Action act = () => options.Should().Serialize("true").And.Value.Should().BeTrue(because: "why not?");

// Assert
act.Should().Throw<XunitException>()
.WithMessage("TODO");
}

[Fact]
public void Guards_true_node()
{
// Arrange
JsonSerializerOptions options = new();

// Act + assert
options.Should().Serialize(true).And.Value.Should().BeTrue();
}
}

public class BeFalse
{
[Fact]
public void Throws_for_other_elements()
{
// Arrange
JsonSerializerOptions options = new();

// Act
Action act = () => options.Should().Serialize("false").And.Value.Should().BeFalse(because: "why not?");

// Assert
act.Should().Throw<XunitException>()
.WithMessage("TODO");
}

[Fact]
public void Guards_false_node()
{
// Arrange
JsonSerializerOptions options = new();

// Act + assert
options.Should().Serialize(false).And.Value.Should().BeFalse();
}
}
}

0 comments on commit 3bcbc37

Please sign in to comment.