Skip to content

Commit

Permalink
Add BeDefined and NotBeDefined to EnumAssertions (#1888)
Browse files Browse the repository at this point in the history
Add methods `BeDefined` and `NotBeDefined` to `EnumAssertions`
  • Loading branch information
IT-VBFK committed Apr 15, 2022
1 parent db4562b commit 192f48c
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 0 deletions.
52 changes: 52 additions & 0 deletions Src/FluentAssertions/Primitives/EnumAssertions.cs
Expand Up @@ -129,6 +129,58 @@ public AndConstraint<TAssertions> Be(TEnum? expected, string because = "", param
return new AndConstraint<TAssertions>((TAssertions)this);
}

/// <summary>
/// Asserts that the current value of <typeparamref name="TEnum"/> is defined inside the enum.
/// </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 <paramref name="because" />.
/// </param>
public AndConstraint<TAssertions> BeDefined(string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.WithExpectation("Expected {context:the enum} to be defined in {0}{reason}, ", typeof(TEnum))
.ForCondition(Subject is not null)
.FailWith("but found <null>.")
.Then
.ForCondition(Enum.IsDefined(typeof(TEnum), Subject))
.FailWith("but it is not.")
.Then
.ClearExpectation();

return new AndConstraint<TAssertions>((TAssertions)this);
}

/// <summary>
/// Asserts that the current value of <typeparamref name="TEnum"/> is not defined inside the enum.
/// </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 <paramref name="because" />.
/// </param>
public AndConstraint<TAssertions> NotBeDefined(string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.WithExpectation("Did not expect {context:the enum} to be defined in {0}{reason}, ", typeof(TEnum))
.ForCondition(Subject is not null)
.FailWith("but found <null>.")
.Then
.ForCondition(!Enum.IsDefined(typeof(TEnum), Subject))
.FailWith("but it is.")
.Then
.ClearExpectation();

return new AndConstraint<TAssertions>((TAssertions)this);
}

/// <summary>
/// Asserts that the current <typeparamref name="TEnum"/> is exactly equal to the <paramref name="expected"/> value.
/// </summary>
Expand Down
Expand Up @@ -1887,6 +1887,7 @@ namespace FluentAssertions.Primitives
public TEnum? Subject { get; }
public FluentAssertions.AndConstraint<TAssertions> Be(TEnum expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> Be(TEnum? expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeDefined(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeOneOf(params TEnum[] validValues) { }
public FluentAssertions.AndConstraint<TAssertions> BeOneOf(System.Collections.Generic.IEnumerable<TEnum> validValues, string because = "", params object[] becauseArgs) { }
public override bool Equals(object obj) { }
Expand All @@ -1899,6 +1900,7 @@ namespace FluentAssertions.Primitives
public FluentAssertions.AndConstraint<TAssertions> Match(System.Linq.Expressions.Expression<System.Func<TEnum?, bool>> predicate, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBe(TEnum unexpected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBe(TEnum? unexpected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBeDefined(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotHaveFlag(TEnum unexpectedFlag, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotHaveSameNameAs<T>(T unexpected, string because = "", params object[] becauseArgs)
where T : struct, System.Enum { }
Expand Down
Expand Up @@ -1944,6 +1944,7 @@ namespace FluentAssertions.Primitives
public TEnum? Subject { get; }
public FluentAssertions.AndConstraint<TAssertions> Be(TEnum expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> Be(TEnum? expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeDefined(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeOneOf(params TEnum[] validValues) { }
public FluentAssertions.AndConstraint<TAssertions> BeOneOf(System.Collections.Generic.IEnumerable<TEnum> validValues, string because = "", params object[] becauseArgs) { }
public override bool Equals(object obj) { }
Expand All @@ -1956,6 +1957,7 @@ namespace FluentAssertions.Primitives
public FluentAssertions.AndConstraint<TAssertions> Match(System.Linq.Expressions.Expression<System.Func<TEnum?, bool>> predicate, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBe(TEnum unexpected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBe(TEnum? unexpected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBeDefined(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotHaveFlag(TEnum unexpectedFlag, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotHaveSameNameAs<T>(T unexpected, string because = "", params object[] becauseArgs)
where T : struct, System.Enum { }
Expand Down
Expand Up @@ -1887,6 +1887,7 @@ namespace FluentAssertions.Primitives
public TEnum? Subject { get; }
public FluentAssertions.AndConstraint<TAssertions> Be(TEnum expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> Be(TEnum? expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeDefined(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeOneOf(params TEnum[] validValues) { }
public FluentAssertions.AndConstraint<TAssertions> BeOneOf(System.Collections.Generic.IEnumerable<TEnum> validValues, string because = "", params object[] becauseArgs) { }
public override bool Equals(object obj) { }
Expand All @@ -1899,6 +1900,7 @@ namespace FluentAssertions.Primitives
public FluentAssertions.AndConstraint<TAssertions> Match(System.Linq.Expressions.Expression<System.Func<TEnum?, bool>> predicate, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBe(TEnum unexpected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBe(TEnum? unexpected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBeDefined(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotHaveFlag(TEnum unexpectedFlag, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotHaveSameNameAs<T>(T unexpected, string because = "", params object[] becauseArgs)
where T : struct, System.Enum { }
Expand Down
Expand Up @@ -1887,6 +1887,7 @@ namespace FluentAssertions.Primitives
public TEnum? Subject { get; }
public FluentAssertions.AndConstraint<TAssertions> Be(TEnum expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> Be(TEnum? expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeDefined(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeOneOf(params TEnum[] validValues) { }
public FluentAssertions.AndConstraint<TAssertions> BeOneOf(System.Collections.Generic.IEnumerable<TEnum> validValues, string because = "", params object[] becauseArgs) { }
public override bool Equals(object obj) { }
Expand All @@ -1899,6 +1900,7 @@ namespace FluentAssertions.Primitives
public FluentAssertions.AndConstraint<TAssertions> Match(System.Linq.Expressions.Expression<System.Func<TEnum?, bool>> predicate, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBe(TEnum unexpected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBe(TEnum? unexpected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBeDefined(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotHaveFlag(TEnum unexpectedFlag, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotHaveSameNameAs<T>(T unexpected, string because = "", params object[] becauseArgs)
where T : struct, System.Enum { }
Expand Down
Expand Up @@ -1839,6 +1839,7 @@ namespace FluentAssertions.Primitives
public TEnum? Subject { get; }
public FluentAssertions.AndConstraint<TAssertions> Be(TEnum expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> Be(TEnum? expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeDefined(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeOneOf(params TEnum[] validValues) { }
public FluentAssertions.AndConstraint<TAssertions> BeOneOf(System.Collections.Generic.IEnumerable<TEnum> validValues, string because = "", params object[] becauseArgs) { }
public override bool Equals(object obj) { }
Expand All @@ -1851,6 +1852,7 @@ namespace FluentAssertions.Primitives
public FluentAssertions.AndConstraint<TAssertions> Match(System.Linq.Expressions.Expression<System.Func<TEnum?, bool>> predicate, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBe(TEnum unexpected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBe(TEnum? unexpected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBeDefined(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotHaveFlag(TEnum unexpectedFlag, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotHaveSameNameAs<T>(T unexpected, string because = "", params object[] becauseArgs)
where T : struct, System.Enum { }
Expand Down
Expand Up @@ -1887,6 +1887,7 @@ namespace FluentAssertions.Primitives
public TEnum? Subject { get; }
public FluentAssertions.AndConstraint<TAssertions> Be(TEnum expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> Be(TEnum? expected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeDefined(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> BeOneOf(params TEnum[] validValues) { }
public FluentAssertions.AndConstraint<TAssertions> BeOneOf(System.Collections.Generic.IEnumerable<TEnum> validValues, string because = "", params object[] becauseArgs) { }
public override bool Equals(object obj) { }
Expand All @@ -1899,6 +1900,7 @@ namespace FluentAssertions.Primitives
public FluentAssertions.AndConstraint<TAssertions> Match(System.Linq.Expressions.Expression<System.Func<TEnum?, bool>> predicate, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBe(TEnum unexpected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBe(TEnum? unexpected, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotBeDefined(string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotHaveFlag(TEnum unexpectedFlag, string because = "", params object[] becauseArgs) { }
public FluentAssertions.AndConstraint<TAssertions> NotHaveSameNameAs<T>(T unexpected, string because = "", params object[] becauseArgs)
where T : struct, System.Enum { }
Expand Down
79 changes: 79 additions & 0 deletions Tests/FluentAssertions.Specs/Primitives/EnumAssertionSpecs.cs
Expand Up @@ -791,5 +791,84 @@ public void An_enum_cannot_be_part_of_a_null_list()
}

#endregion

#region Be defined / Not be defined

[Fact]
public void A_valid_entry_of_an_enum_is_defined()
{
// Arrange
var dayOfWeek = (DayOfWeek)1;

// Act / Assert
dayOfWeek.Should().BeDefined();
}

[Fact]
public void If_a_value_casted_to_an_enum_type_and_it_does_not_exist_in_the_enum_it_throws()
{
// Arrange
var dayOfWeek = (DayOfWeek)999;

// Act
Action act = () => dayOfWeek.Should().BeDefined("we want to test the failure {0}", "message");

// Assert
act.Should().Throw<XunitException>()
.WithMessage("Expected *to be defined in*failure message*, but it is not*");
}

[Fact]
public void A_null_entry_of_an_enum_throws()
{
// Arrange
MyEnum? subject = null;

// Act
Action act = () => subject.Should().BeDefined();

// Assert
act.Should().Throw<XunitException>()
.WithMessage("Expected *to be defined in*, but found <null>.");
}

[Fact]
public void An_invalid_entry_of_an_enum_is_not_defined_passes()
{
// Arrange
var dayOfWeek = (DayOfWeek)999;

// Act / Assert
dayOfWeek.Should().NotBeDefined();
}

[Fact]
public void A_valid_entry_of_an_enum_is_not_defined_fails()
{
// Arrange
var dayOfWeek = (DayOfWeek)1;

// Act
Action act = () => dayOfWeek.Should().NotBeDefined();

// Assert
act.Should().Throw<XunitException>()
.WithMessage("Did not expect*to be defined in*, but it is.");
}

[Fact]
public void A_null_value_of_an_enum_is_not_defined_and_throws()
{
// Arrange
MyEnum? subject = null;

// Act
Action act = () => subject.Should().NotBeDefined();

// Assert
act.Should().Throw<XunitException>()
.WithMessage("Did not expect *to be defined in*, but found <null>.");
}
#endregion
}
}
8 changes: 8 additions & 0 deletions docs/_pages/enums.md
Expand Up @@ -42,3 +42,11 @@ Lastly, if you want to verify than an enum has a specific integral value, you ca
MyEnum.One.Should().HaveValue(1);
MyEnum.One.Should().NotHaveValue(2);
```

```csharp
var myEnum = (MyEnum)1;
myEnum.Should().BeDefined();

myEnum = (MyEnum)99;
myEnum.Should().NotBeDefined();
```
5 changes: 5 additions & 0 deletions docs/_pages/releases.md
Expand Up @@ -9,6 +9,11 @@ sidebar:

## Unreleased

### What's new
* Add `BeDefined` and `NotBeDefined` to assert on existence of an enum value - [#1888](https://github.com/fluentassertions/fluentassertions/pull/1888)

## 6.6.0

### What's New
* Annotated `[Not]MatchRegex(string)` with `[StringSyntax("Regex")]` which IDEs can use to colorize the regular expression argument - [#1816](https://github.com/fluentassertions/fluentassertions/pull/1816)
* Added support for .NET6 `DateOnly` struct - [#1844](https://github.com/fluentassertions/fluentassertions/pull/1844)
Expand Down

0 comments on commit 192f48c

Please sign in to comment.