Skip to content

Conversation

@jnyrup
Copy link
Member

@jnyrup jnyrup commented Aug 12, 2020

Motivations:

  • To get rid of HaveFlag from ObjectAssertions as most objects are not enums
  • Additional compile time safety

I've moved [Not]HaveFlag to the new EnumAssertions which derives from the generic ObjectAssertions introduced in #1371.

Optimally we would want to create

Should<TEnum>(this TEnum @enum)
    where TEnum : struct, Enum
    => new EnumAssertions(@enum);

but we have a tradition of not introducing overloads of Should directly generic in T.

Current state of develop branch

// Uses ObjectAssertions
TestEnum.One.Should().HaveFlag(TestEnum.One);
TestEnum.One.Should().HaveFlag(OtherEnum.First); // compiles but fails at runtime
TestEnum.One.Should().HaveFlag(null); // compiles but fails at runtime
((TestEnum?)TestEnum.One).Should().HaveFlag(TestEnum.One);
((TestEnum?)TestEnum.One).Should().HaveFlag(OtherEnum.First); // compiles but fails at runtime
((TestEnum?)TestEnum.One).Should().HaveFlag(null); // compiles but fails at runtime

With this PR

// Uses EnumAssertions
TestEnum.One.Should().HaveFlag(TestEnum.One);
TestEnum.One.Should().HaveFlag(OtherEnum.First); // compiles but fails at runtime
//TestEnum.One.Should().HaveFlag((Enum)null); // CS0453: The type 'Enum' must be a non-nullable value type in order to use it as parameter 'T'
((TestEnum?)TestEnum.One).Should().HaveFlag(TestEnum.One);
((TestEnum?)TestEnum.One).Should().HaveFlag(OtherEnum.First); // compiles but fails at runtime
//((TestEnum?)TestEnum.One).Should().HaveFlag((Enum)null); // CS0453: The type 'Enum' must be a non-nullable value type in order to use it as parameter 'T'

For additional compile-time safety, you can also create a dedicated EnumAssertions for your favorite enum.

public class TestEnumAssertions : EnumAssertions<TestEnum, TestEnumAssertions>
{
    public TestEnumAssertions(TestEnum subject)
        : base(subject)
    {
    }
}

public static class Ext
{
    public static TestEnumAssertions Should(this TestEnum testEnum) => 
        new TestEnumAssertions(testEnum);
}
// Uses TestEnumAssertions
TestEnum.One.Should().HaveFlag(TestEnum.One);
//TestEnum.One.Should().HaveFlag(OtherEnum.First); // CS0315: There is no boxing conversion from 'OtherEnum' to 'TestEnum'
//TestEnum.One.Should().HaveFlag((Enum)null); // CS0453: The type 'Enum' must be a non-nullable value type in order to use it as parameter 'T'

// Still uses EnumAssertions
((TestEnum?)TestEnum.One).Should().HaveFlag(TestEnum.One);
((TestEnum?)TestEnum.One).Should().HaveFlag(OtherEnum.First); // compiles but fails at runtime
//((TestEnum?)TestEnum.One).Should().HaveFlag((Enum)null); // CS0453: The type 'Enum' must be a non-nullable value type in order to use it as parameter 'T'

This supersedes #1315

@jnyrup
Copy link
Member Author

jnyrup commented Aug 13, 2020

Just noticed that I forgot updating release notes

Copy link
Member

@dennisdoomen dennisdoomen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one.

@jnyrup jnyrup merged commit 04579d6 into fluentassertions:develop Aug 18, 2020
@jnyrup jnyrup deleted the EnumAssertions branch August 18, 2020 14:54
@jnyrup jnyrup mentioned this pull request Jan 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants