diff --git a/Src/FluentAssertions/Common/CSharpAccessModifier.cs b/Src/FluentAssertions/Common/CSharpAccessModifier.cs index 3ea2010b21..02952313f6 100644 --- a/Src/FluentAssertions/Common/CSharpAccessModifier.cs +++ b/Src/FluentAssertions/Common/CSharpAccessModifier.cs @@ -7,6 +7,7 @@ public enum CSharpAccessModifier Protected, Internal, ProtectedInternal, - InvalidForCSharp + InvalidForCSharp, + PrivateProtected, } } diff --git a/Src/FluentAssertions/Common/CSharpAccessModifierExtensions.cs b/Src/FluentAssertions/Common/CSharpAccessModifierExtensions.cs index 2d703d6a6a..1d0b817a0d 100644 --- a/Src/FluentAssertions/Common/CSharpAccessModifierExtensions.cs +++ b/Src/FluentAssertions/Common/CSharpAccessModifierExtensions.cs @@ -32,6 +32,11 @@ internal static CSharpAccessModifier GetCSharpAccessModifier(this MethodBase met return CSharpAccessModifier.ProtectedInternal; } + if (methodBase.IsFamilyAndAssembly) + { + return CSharpAccessModifier.PrivateProtected; + } + return CSharpAccessModifier.InvalidForCSharp; } @@ -62,6 +67,11 @@ internal static CSharpAccessModifier GetCSharpAccessModifier(this FieldInfo fiel return CSharpAccessModifier.ProtectedInternal; } + if(fieldInfo.IsFamilyAndAssembly) + { + return CSharpAccessModifier.PrivateProtected; + } + return CSharpAccessModifier.InvalidForCSharp; } diff --git a/Tests/Net45.Specs/Net45.Specs.csproj b/Tests/Net45.Specs/Net45.Specs.csproj index 815e73e145..4f7130643b 100644 --- a/Tests/Net45.Specs/Net45.Specs.csproj +++ b/Tests/Net45.Specs/Net45.Specs.csproj @@ -6,6 +6,7 @@ $(DefineConstants);NET45 ..\..\TestRules.ruleset true + 7.2 diff --git a/Tests/Net47.Specs/Net47.Specs.csproj b/Tests/Net47.Specs/Net47.Specs.csproj index 6b9d8f1c2e..ade7729566 100644 --- a/Tests/Net47.Specs/Net47.Specs.csproj +++ b/Tests/Net47.Specs/Net47.Specs.csproj @@ -6,6 +6,7 @@ $(DefineConstants);NET47 ..\..\TestRules.ruleset true + 7.2 diff --git a/Tests/NetCore.Specs/NetCore.Specs.csproj b/Tests/NetCore.Specs/NetCore.Specs.csproj index 8433e8a2c6..281d279a29 100644 --- a/Tests/NetCore.Specs/NetCore.Specs.csproj +++ b/Tests/NetCore.Specs/NetCore.Specs.csproj @@ -4,6 +4,7 @@ FluentAssertions.NetCore.Specs FluentAssertions.NetCore.Specs ..\..\TestRules.ruleset + 7.2 diff --git a/Tests/NetCore20.Specs/NetCore20.Specs.csproj b/Tests/NetCore20.Specs/NetCore20.Specs.csproj index fe8f431c05..4bf166e29e 100644 --- a/Tests/NetCore20.Specs/NetCore20.Specs.csproj +++ b/Tests/NetCore20.Specs/NetCore20.Specs.csproj @@ -4,6 +4,7 @@ FluentAssertions.NetCore20.Specs FluentAssertions.NetCore20.Specs ..\..\TestRules.ruleset + 7.2 diff --git a/Tests/NetStandard13.Specs/NetStandard13.Specs.csproj b/Tests/NetStandard13.Specs/NetStandard13.Specs.csproj index de546090d0..8bcf1a0634 100644 --- a/Tests/NetStandard13.Specs/NetStandard13.Specs.csproj +++ b/Tests/NetStandard13.Specs/NetStandard13.Specs.csproj @@ -5,6 +5,7 @@ FluentAssertions.NetStandard13.Specs NETSTANDARD1_3 ..\..\TestRules.ruleset + 7.2 diff --git a/Tests/Shared.Specs/BasicEquivalencySpecs.cs b/Tests/Shared.Specs/BasicEquivalencySpecs.cs index 808133b8bf..2f08c3f43f 100644 --- a/Tests/Shared.Specs/BasicEquivalencySpecs.cs +++ b/Tests/Shared.Specs/BasicEquivalencySpecs.cs @@ -1442,21 +1442,24 @@ public void When_members_are_excluded_by_the_access_modifier_of_the_getter_using "protected", "internal", "protected-internal", - "private"); + "private", + "private-protected"); var expected = new ClassWithAllAccessModifiersForMembers( "public", "protected", "ignored-internal", "ignored-protected-internal", - "private"); + "private", + "ignore-private-protected"); //----------------------------------------------------------------------------------------------------------- // Act //----------------------------------------------------------------------------------------------------------- Action act = () => subject.Should().BeEquivalentTo(expected, config => config.Excluding(ctx => ctx.WhichGetterHas(CSharpAccessModifier.Internal) || - ctx.WhichGetterHas(CSharpAccessModifier.ProtectedInternal))); + ctx.WhichGetterHas(CSharpAccessModifier.ProtectedInternal) || + ctx.WhichGetterHas(CSharpAccessModifier.PrivateProtected))); //----------------------------------------------------------------------------------------------------------- // Assert @@ -1475,14 +1478,16 @@ public void When_members_are_excluded_by_the_access_modifier_of_the_setter_using "protected", "internal", "protected-internal", - "private"); + "private", + "private-protected"); var expected = new ClassWithAllAccessModifiersForMembers( "public", "protected", "ignored-internal", "ignored-protected-internal", - "ignored-private"); + "ignored-private", + "ignore-private-protected"); //----------------------------------------------------------------------------------------------------------- // Act @@ -1490,7 +1495,8 @@ public void When_members_are_excluded_by_the_access_modifier_of_the_setter_using Action act = () => subject.Should().BeEquivalentTo(expected, config => config.Excluding(ctx => ctx.WhichSetterHas(CSharpAccessModifier.Internal) || ctx.WhichSetterHas(CSharpAccessModifier.ProtectedInternal) || - ctx.WhichSetterHas(CSharpAccessModifier.Private))); + ctx.WhichSetterHas(CSharpAccessModifier.Private) || + ctx.WhichSetterHas(CSharpAccessModifier.PrivateProtected))); //----------------------------------------------------------------------------------------------------------- // Assert @@ -4184,6 +4190,7 @@ public class ClassWithAllAccessModifiersForMembers internal string InternalField; protected internal string ProtectedInternalField; private string PrivateField; + private protected string PrivateProtectedField; public string PublicProperty { get; set; } public string ReadOnlyProperty { get; private set; } @@ -4193,14 +4200,17 @@ public class ClassWithAllAccessModifiersForMembers protected internal string ProtectedInternalProperty { get; set; } private string PrivateProperty { get; set; } + private protected string PrivateProtectedProperty { get; set; } + public ClassWithAllAccessModifiersForMembers(string publicValue, string protectedValue, string internalValue, - string protectedInternalValue, string privateValue) + string protectedInternalValue, string privateValue, string privateProtectedValue) { PublicField = publicValue; ProtectedField = protectedValue; InternalField = internalValue; ProtectedInternalField = protectedInternalValue; PrivateField = privateValue; + PrivateProtectedField = privateProtectedValue; PublicProperty = publicValue; ReadOnlyProperty = privateValue; @@ -4209,6 +4219,7 @@ public class ClassWithAllAccessModifiersForMembers InternalProperty = internalValue; ProtectedInternalProperty = protectedInternalValue; PrivateProperty = privateValue; + PrivateProtectedProperty = privateProtectedValue; } } diff --git a/Tests/Shared.Specs/MethodBaseAssertionSpecs.cs b/Tests/Shared.Specs/MethodBaseAssertionSpecs.cs index 134d4dbccb..74a5fa4639 100644 --- a/Tests/Shared.Specs/MethodBaseAssertionSpecs.cs +++ b/Tests/Shared.Specs/MethodBaseAssertionSpecs.cs @@ -328,6 +328,26 @@ public void When_asserting_a_private_member_is_private_it_succeeds() act.Should().NotThrow(); } + [Fact] + public void When_asserting_a_private_protected_member_is_private_protected_it_succeeds() + { + //------------------------------------------------------------------------------------------------------------------- + // Arrange + //------------------------------------------------------------------------------------------------------------------- + MethodInfo methodInfo = typeof(TestClass).GetParameterlessMethod("PrivateProtectedMethod"); + + //------------------------------------------------------------------------------------------------------------------- + // Act + //------------------------------------------------------------------------------------------------------------------- + Action act = () => + methodInfo.Should().HaveAccessModifier(CSharpAccessModifier.PrivateProtected); + + //------------------------------------------------------------------------------------------------------------------- + // Assert + //------------------------------------------------------------------------------------------------------------------- + act.Should().NotThrow(); + } + [Fact] public void When_asserting_a_private_member_is_protected_it_throws_with_a_useful_message() { @@ -555,6 +575,26 @@ public void When_asserting_a_private_member_is_not_protected_it_succeeds() act.Should().NotThrow(); } + [Fact] + public void When_asserting_a_private_member_is_not_private_protected_it_succeeds() + { + //------------------------------------------------------------------------------------------------------------------- + // Arrange + //------------------------------------------------------------------------------------------------------------------- + MethodInfo methodInfo = typeof(TestClass).GetParameterlessMethod("PrivateMethod"); + + //------------------------------------------------------------------------------------------------------------------- + // Act + //------------------------------------------------------------------------------------------------------------------- + Action act = () => + methodInfo.Should().NotHaveAccessModifier(CSharpAccessModifier.PrivateProtected); + + //------------------------------------------------------------------------------------------------------------------- + // Assert + //------------------------------------------------------------------------------------------------------------------- + act.Should().NotThrow(); + } + [Fact] public void When_asserting_a_private_member_is_not_private_it_throws_with_a_useful_message() { @@ -642,6 +682,27 @@ public void When_asserting_a_public_member_is_not_private_it_succeeds() act.Should().NotThrow(); } + [Fact] + public void When_asserting_a_private_protected_member_is_not_private_it_succeeds() + { + //------------------------------------------------------------------------------------------------------------------- + // Arrange + //------------------------------------------------------------------------------------------------------------------- + PropertyInfo propertyInfo = typeof(TestClass).GetPropertyByName("PublicGetPrivateProtectedSet"); + MethodInfo setMethod = propertyInfo.SetMethod; + + //------------------------------------------------------------------------------------------------------------------- + // Act + //------------------------------------------------------------------------------------------------------------------- + Action act = () => + setMethod.Should().NotHaveAccessModifier(CSharpAccessModifier.Private); + + //------------------------------------------------------------------------------------------------------------------- + // Assert + //------------------------------------------------------------------------------------------------------------------- + act.Should().NotThrow(); + } + [Fact] public void When_asserting_a_public_member_is_not_public_it_throws_with_a_useful_message() { @@ -766,9 +827,13 @@ internal class TestClass protected string ProtectedSetProperty { private get; set; } + public string PublicGetPrivateProtectedSet { get; private protected set; } + internal string InternalMethod() { return null; } protected internal void ProtectedInternalMethod() { } + + private protected void PrivateProtectedMethod() { } } #endregion