Skip to content

Commit

Permalink
Merge pull request #1393 from FakeItEasy/release/4.7.1
Browse files Browse the repository at this point in the history
Release 4.7.1
  • Loading branch information
thomaslevesque committed Jul 6, 2018
2 parents 9125484 + 854d69e commit ce8ea2a
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/FakeItEasy/Configuration/BuildableCallRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ private static ICollection<int> GetIndexesOfOutAndRefParameters(IInterceptedFake
var arguments = fakeObjectCall.Method.GetParameters();
for (var i = 0; i < arguments.Length; i++)
{
if (arguments[i].ParameterType.IsByRef)
if (arguments[i].IsOutOrRef())
{
indexes.Add(i);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ public virtual IArgumentConstraint GetArgumentConstraint(ParsedArgumentExpressio
return this.CreateParamArrayConstraint((NewArrayExpression)argument.Expression, parameterType);
}

var isByRefArgument = IsByRefArgument(argument);
var isOutOrRefArgument = argument.ArgumentInformation.IsOutOrRef();

var constraint = this.GetArgumentConstraintFromExpression(argument.Expression, parameterType, out var argumentValue);
if (isByRefArgument)
if (isOutOrRefArgument)
{
if (IsOutArgument(argument))
{
Expand Down Expand Up @@ -66,11 +66,6 @@ private static bool IsOutArgument(ParsedArgumentExpression argument)
return argument.ArgumentInformation.IsOut;
}

private static bool IsByRefArgument(ParsedArgumentExpression argument)
{
return argument.ArgumentInformation.ParameterType.IsByRef;
}

private static IArgumentConstraint CreateEqualityConstraint(object expressionValue)
{
return new EqualityArgumentConstraint(expressionValue);
Expand Down
23 changes: 14 additions & 9 deletions src/FakeItEasy/FakeItEasy.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
<PackageTags>TDD;unittesting;mocks;mocking;fakes;faking;stubs;stubbing;spy;spies;doubles;isolation;substitutes;substitution</PackageTags>
</PropertyGroup>

<PropertyGroup Label="Common referenced package versions">
<CastleCoreVersion>4.3.1</CastleCoreVersion>
<ILMergeVersion>2.14.1208</ILMergeVersion>
</PropertyGroup>

<ItemGroup>
<Compile Include="../*.cs" />
</ItemGroup>
Expand All @@ -35,11 +40,11 @@
<!-- .NET Standard 1.6 -->

<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.6'">
<DefineConstants>$(DefineConstants);FEATURE_NETCORE_REFLECTION;FEATURE_EXCEPTION_DISPATCH_INFO;FEATURE_ARRAY_EMPTY</DefineConstants>
<DefineConstants>$(DefineConstants);FEATURE_NETCORE_REFLECTION;FEATURE_EXCEPTION_DISPATCH_INFO;FEATURE_ARRAY_EMPTY;FEATURE_PARAMETERINFO_CUSTOMATTRIBUTES_PROPERTY</DefineConstants>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.6'">
<PackageReference Include="Castle.Core" Version="4.3.1" />
<PackageReference Include="Castle.Core" Version="$(CastleCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="1.0.0" />
<PackageReference Include="System.Collections.Concurrent" Version="4.3.0" />
<PackageReference Include="System.Runtime.Loader" Version="4.0.0" />
Expand All @@ -48,16 +53,16 @@
<!-- .NET 4.5 -->

<PropertyGroup Condition="'$(TargetFramework)' == 'net45'">
<DefineConstants>$(DefineConstants);FEATURE_BINARY_SERIALIZATION;FEATURE_REFLECTION_GETASSEMBLIES</DefineConstants>
<DefineConstants>$(DefineConstants);FEATURE_BINARY_SERIALIZATION;FEATURE_REFLECTION_GETASSEMBLIES;FEATURE_PARAMETERINFO_CUSTOMATTRIBUTES_PROPERTY</DefineConstants>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
<PackageReference Include="ILMerge" Version="2.14.1208" PrivateAssets="all" />
<PackageReference Include="Castle.Core" Version="4.2.1" PrivateAssets="all" />
<PackageReference Include="ILMerge" Version="$(ILMergeVersion)" PrivateAssets="all" />
<PackageReference Include="Castle.Core" Version="$(CastleCoreVersion)" PrivateAssets="all" />
</ItemGroup>

<Target Name="ILMerge45" AfterTargets="Build" Condition="'$(TargetFramework)' == 'net45'">
<Exec Command="&quot;$(NuGetPackageRoot)\ilmerge\2.14.1208\tools\ILmerge.exe&quot; /keyfile:..\FakeItEasy.snk /lib:$(OutputPath) /targetplatform:&quot;v4,$(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5&quot; /internalize:&quot;..\ILMerge.Internalize.Exclude.txt&quot; /out:@(MainAssembly) /log:$(OutputPath)ILMerge.log &quot;@(IntermediateAssembly)&quot; &quot;$(OutputPath)Castle.Core.dll&quot;" />
<Exec Command="&quot;$(NuGetPackageRoot)\ilmerge\$(ILMergeVersion)\tools\ILmerge.exe&quot; /keyfile:..\FakeItEasy.snk /lib:$(OutputPath) /targetplatform:&quot;v4,$(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5&quot; /internalize:&quot;..\ILMerge.Internalize.Exclude.txt&quot; /out:@(MainAssembly) /log:$(OutputPath)ILMerge.log &quot;@(IntermediateAssembly)&quot; &quot;$(OutputPath)Castle.Core.dll&quot;" />
</Target>

<!-- .NET 4.0 -->
Expand All @@ -67,12 +72,12 @@
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net40'">
<PackageReference Include="ILMerge" Version="2.14.1208" PrivateAssets="all" />
<PackageReference Include="Castle.Core" Version="4.2.1" PrivateAssets="all" />
<PackageReference Include="ILMerge" Version="$(ILMergeVersion)" PrivateAssets="all" />
<PackageReference Include="Castle.Core" Version="$(CastleCoreVersion)" PrivateAssets="all" />
</ItemGroup>

<Target Name="ILMerge40" AfterTargets="Build" Condition="'$(TargetFramework)' == 'net40'">
<Exec Command="&quot;$(NuGetPackageRoot)\ilmerge\2.14.1208\tools\ILmerge.exe&quot; /keyfile:..\FakeItEasy.snk /lib:$(OutputPath) /targetplatform:&quot;v4,$(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0&quot; /internalize:&quot;..\ILMerge.Internalize.Exclude.txt&quot; /out:@(MainAssembly) /log:$(OutputPath)ILMerge.log &quot;@(IntermediateAssembly)&quot; &quot;$(OutputPath)Castle.Core.dll&quot;" />
<Exec Command="&quot;$(NuGetPackageRoot)\ilmerge\$(ILMergeVersion)\tools\ILmerge.exe&quot; /keyfile:..\FakeItEasy.snk /lib:$(OutputPath) /targetplatform:&quot;v4,$(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0&quot; /internalize:&quot;..\ILMerge.Internalize.Exclude.txt&quot; /out:@(MainAssembly) /log:$(OutputPath)ILMerge.log &quot;@(IntermediateAssembly)&quot; &quot;$(OutputPath)Castle.Core.dll&quot;" />
</Target>


Expand Down
31 changes: 31 additions & 0 deletions src/FakeItEasy/ParameterInfoExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace FakeItEasy
{
using System.Linq;
using System.Reflection;

/// <summary>
/// Provides extension methods for <see cref="ParameterInfo"/>.
/// </summary>
internal static class ParameterInfoExtensions
{
private const string IsReadOnlyAttributeFullName = "System.Runtime.CompilerServices.IsReadOnlyAttribute";

public static bool IsOutOrRef(this ParameterInfo parameterInfo)
{
if (!parameterInfo.ParameterType.IsByRef)
{
return false;
}

#if FEATURE_PARAMETERINFO_CUSTOMATTRIBUTES_PROPERTY
var parameterAttributes = parameterInfo.CustomAttributes;
return parameterAttributes == null ||
parameterAttributes.All(customAttributeData => customAttributeData.AttributeType.FullName != IsReadOnlyAttributeFullName);
#else
var parameterAttributes = parameterInfo.GetCustomAttributesData();
return parameterAttributes == null ||
parameterAttributes.All(customAttributeData => customAttributeData.Constructor.DeclaringType?.FullName != IsReadOnlyAttributeFullName);
#endif
}
}
}
42 changes: 42 additions & 0 deletions tests/FakeItEasy.Specs/InParametersSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public interface IGenericInParam<T>
int Foo(in int x);
}

public delegate void DelegateWithInParam(in int i);

[Scenario]
public void FakingInParam(IInParam fake, int argument, int result)
{
Expand All @@ -35,6 +37,46 @@ public void FakingInParam(IInParam fake, int argument, int result)
.x(() => result.Should().Be(42));
}

[Scenario]
public void SettingInParamInterface(IInParam fake, Exception exception)
{
"Given a faked interface with a method that takes an 'in' parameter"
.x(() => fake = A.Fake<IInParam>());

"And a call to this method is configured to set a new value for the parameter"
.x(() => A.CallTo(() => fake.Foo(A<int>._)).AssignsOutAndRefParameters(19));

"When the method is called"
.x(() => exception = Record.Exception(() => fake.Foo(A.Dummy<int>())));

"Then it throws an exception"
.x(() => exception.Should().BeAnExceptionOfType<InvalidOperationException>());

"And the exception message indicates that the out and ref parameter counts don't agree"
.x(() => exception.Message.Should()
.Be("The number of values for out and ref parameters specified does not match the number of out and ref parameters in the call."));
}

[Scenario]
public void SettingInParamDelegate(DelegateWithInParam fake, Exception exception)
{
"Given a faked delegate with a method that takes an 'in' parameter"
.x(() => fake = A.Fake<DelegateWithInParam>());

"And a call to this method is configured to set a new value for the parameter"
.x(() => A.CallTo(() => fake.Invoke(A<int>._)).AssignsOutAndRefParameters(19));

"When the method is called"
.x(() => exception = Record.Exception(() => fake.Invoke(A.Dummy<int>())));

"Then it throws an exception"
.x(() => exception.Should().BeAnExceptionOfType<InvalidOperationException>());

"And the exception message indicates that the out and ref parameter counts don't agree"
.x(() => exception.Message.Should()
.Be("The number of values for out and ref parameters specified does not match the number of out and ref parameters in the call."));
}

// A characterization test, representing the current capabilities of the code, not the desired state.
// If it start failing, update it and fix the "What can be faked" documentation page.
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ namespace Castle.DynamicProxy.Internal
public static bool IsFinalizer(this System.Reflection.MethodInfo methodInfo) { }
public static bool IsGetType(this System.Reflection.MethodInfo methodInfo) { }
public static bool IsMemberwiseClone(this System.Reflection.MethodInfo methodInfo) { }
public static bool IsNullableType(this System.Type type) { }
public static void SetStaticField(this System.Type type, string fieldName, System.Reflection.BindingFlags additionalFlags, object value) { }
public static System.Reflection.MemberInfo[] Sort(System.Reflection.MemberInfo[] members) { }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ namespace Castle.DynamicProxy.Internal
public static bool IsFinalizer(this System.Reflection.MethodInfo methodInfo) { }
public static bool IsGetType(this System.Reflection.MethodInfo methodInfo) { }
public static bool IsMemberwiseClone(this System.Reflection.MethodInfo methodInfo) { }
public static bool IsNullableType(this System.Type type) { }
public static void SetStaticField(this System.Type type, string fieldName, System.Reflection.BindingFlags additionalFlags, object value) { }
public static System.Reflection.MemberInfo[] Sort(System.Reflection.MemberInfo[] members) { }
}
Expand Down

0 comments on commit ce8ea2a

Please sign in to comment.