Skip to content

Commit

Permalink
Add support for private protected access modifier (#932)
Browse files Browse the repository at this point in the history
  • Loading branch information
krajek authored and jnyrup committed Oct 1, 2018
1 parent 8620cbc commit f18bed6
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 8 deletions.
3 changes: 2 additions & 1 deletion Src/FluentAssertions/Common/CSharpAccessModifier.cs
Expand Up @@ -7,6 +7,7 @@ public enum CSharpAccessModifier
Protected,
Internal,
ProtectedInternal,
InvalidForCSharp
InvalidForCSharp,
PrivateProtected,
}
}
10 changes: 10 additions & 0 deletions Src/FluentAssertions/Common/CSharpAccessModifierExtensions.cs
Expand Up @@ -32,6 +32,11 @@ internal static CSharpAccessModifier GetCSharpAccessModifier(this MethodBase met
return CSharpAccessModifier.ProtectedInternal;
}

if (methodBase.IsFamilyAndAssembly)
{
return CSharpAccessModifier.PrivateProtected;
}

return CSharpAccessModifier.InvalidForCSharp;
}

Expand Down Expand Up @@ -62,6 +67,11 @@ internal static CSharpAccessModifier GetCSharpAccessModifier(this FieldInfo fiel
return CSharpAccessModifier.ProtectedInternal;
}

if(fieldInfo.IsFamilyAndAssembly)
{
return CSharpAccessModifier.PrivateProtected;
}

return CSharpAccessModifier.InvalidForCSharp;
}

Expand Down
1 change: 1 addition & 0 deletions Tests/Net45.Specs/Net45.Specs.csproj
Expand Up @@ -6,6 +6,7 @@
<DefineConstants>$(DefineConstants);NET45</DefineConstants>
<CodeAnalysisRuleSet>..\..\TestRules.ruleset</CodeAnalysisRuleSet>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="4.8.1" />
Expand Down
1 change: 1 addition & 0 deletions Tests/Net47.Specs/Net47.Specs.csproj
Expand Up @@ -6,6 +6,7 @@
<DefineConstants>$(DefineConstants);NET47</DefineConstants>
<CodeAnalysisRuleSet>..\..\TestRules.ruleset</CodeAnalysisRuleSet>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="4.8.1" />
Expand Down
1 change: 1 addition & 0 deletions Tests/NetCore.Specs/NetCore.Specs.csproj
Expand Up @@ -4,6 +4,7 @@
<AssemblyName>FluentAssertions.NetCore.Specs</AssemblyName>
<RootNamespace>FluentAssertions.NetCore.Specs</RootNamespace>
<CodeAnalysisRuleSet>..\..\TestRules.ruleset</CodeAnalysisRuleSet>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FakeItEasy" Version="4.8.0" />
Expand Down
1 change: 1 addition & 0 deletions Tests/NetCore20.Specs/NetCore20.Specs.csproj
Expand Up @@ -4,6 +4,7 @@
<AssemblyName>FluentAssertions.NetCore20.Specs</AssemblyName>
<RootNamespace>FluentAssertions.NetCore20.Specs</RootNamespace>
<CodeAnalysisRuleSet>..\..\TestRules.ruleset</CodeAnalysisRuleSet>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Chill" Version="3.2.0" />
Expand Down
1 change: 1 addition & 0 deletions Tests/NetStandard13.Specs/NetStandard13.Specs.csproj
Expand Up @@ -5,6 +5,7 @@
<RootNamespace>FluentAssertions.NetStandard13.Specs</RootNamespace>
<DefineConstants>NETSTANDARD1_3</DefineConstants>
<CodeAnalysisRuleSet>..\..\TestRules.ruleset</CodeAnalysisRuleSet>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FakeItEasy" Version="4.8.0" />
Expand Down
25 changes: 18 additions & 7 deletions Tests/Shared.Specs/BasicEquivalencySpecs.cs
Expand Up @@ -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
Expand All @@ -1475,22 +1478,25 @@ 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
//-----------------------------------------------------------------------------------------------------------
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
Expand Down Expand Up @@ -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; }
Expand All @@ -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;
Expand All @@ -4209,6 +4219,7 @@ public class ClassWithAllAccessModifiersForMembers
InternalProperty = internalValue;
ProtectedInternalProperty = protectedInternalValue;
PrivateProperty = privateValue;
PrivateProtectedProperty = privateProtectedValue;
}
}

Expand Down
65 changes: 65 additions & 0 deletions Tests/Shared.Specs/MethodBaseAssertionSpecs.cs
Expand Up @@ -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()
{
Expand Down Expand Up @@ -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()
{
Expand Down Expand Up @@ -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()
{
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit f18bed6

Please sign in to comment.