Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should().HaveAccessModifier() fails for internal interfaces #1741

Closed
Code-Grump opened this issue Nov 10, 2021 · 3 comments · Fixed by #1793
Closed

Should().HaveAccessModifier() fails for internal interfaces #1741

Code-Grump opened this issue Nov 10, 2021 · 3 comments · Fixed by #1793

Comments

@Code-Grump
Copy link

Description

When trying to assert that an interface type has internal access, the following assertion message is thrown:

Expected expression to be Internal, but it is InvalidForCSharp.

Complete minimal example reproducing the issue

Assuming the following definition exists in the scope of the test:

internal interface ITest {}

The following demonstrates the problem:

typeof(ITest).Should().HaveAccessModifier(CSharpAccessModifier.Internal);

Expected behavior:

The assertion should succeed.

Actual behavior:

The following assertion message is thrown:

Expected typeof(ITest) ITest to be Internal, but it is InvalidForCSharp.

Versions

  • Fluent Assertions version: 6.2.0
  • Compiled against .NET 5.0
  • Run against .NET 6.0
@jnyrup
Copy link
Member

jnyrup commented Nov 11, 2021

4022157a#diff-cf5320057041f95e2a95dc073d4c611bc8279dacb4504cedfd708ffe5b253c90R50
Added

(type.IsClass && type.IsNotPublic)

Off the top of my head I don't know why IsNotPublic only applies to class types.
Removing it seems to make it work for interfaces as well.
Note, I haven't realized why IsNotPublic can be used to check if a type is internal at all.

To make a failing test I had to ensure that ITest was a non-nested type.

@jonathonchase
Copy link
Contributor

jonathonchase commented Nov 17, 2021

@jnyrup IsNotPublic works here because it'll return true if the type is not nested, and not public. Internal and Public are the only valid type accessibility modifiers that can be used on non-nested types.

In looking at this, I've observed that the same issue will apply to enums as well due to the IsClass check. Additionally, Private Protected is not currently supported for types either, which could be replicated with something like this class.

public class Nested { private protected class PP { } }

As well as this test.

typeof(Nested).GetNestedType("PP").Should().HaveAccessibilityModifier(CSharpAccessModifier.PrivateProtected);

That said, I'm not sure that nested private/private protected classes are in scope.

I think I have a fix for this, I'll get it tested and put in a PR.

@jonathonchase
Copy link
Contributor

I can't determine why exactly the IsClass check was placed there initially. All that it really seems to do is restrict internal interface and value types from being identified as such. If there was some kind of strange runtime created type that could cause weird behavior with this check it would have the same issue if it was marked as public in the IL as there isn't a check for that condition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment