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

Add support for private protected access modifier #932

Merged
merged 1 commit into from Oct 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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