Skip to content

Commit dfb2974

Browse files
committed
Format method parameter type list more accurately
This ensures that `in`, `ref`, `out`, and `params` modifiers are in- cluded in the formatting of parameter type lists.
1 parent 76bc013 commit dfb2974

File tree

4 files changed

+101
-4
lines changed

4 files changed

+101
-4
lines changed

src/Moq/Extensions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Reflection;
1111
using System.Runtime.CompilerServices;
1212
using System.Runtime.ExceptionServices;
13+
using System.Text;
1314

1415
using Moq.Properties;
1516

@@ -188,6 +189,11 @@ public static bool CompareTo<TTypes, TOtherTypes>(this TTypes types, TOtherTypes
188189
return true;
189190
}
190191

192+
public static string GetParameterTypeList(this MethodInfo method)
193+
{
194+
return new StringBuilder().AppendParameterTypeList(method.GetParameters()).ToString();
195+
}
196+
191197
public static ParameterTypes GetParameterTypes(this MethodInfo method)
192198
{
193199
return new ParameterTypes(method.GetParameters());

src/Moq/MethodCall.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,12 @@ public void SetCallbackResponse(Delegate callback)
187187
var expectedParamTypes = this.Method.GetParameterTypes();
188188
if (!callback.CompareParameterTypesTo(expectedParamTypes))
189189
{
190-
// TODO: the following won't properly distinguish between `in`, `ref`, and `out` parameters!
191-
var actualParams = callback.GetMethodInfo().GetParameters();
192190
throw new ArgumentException(
193191
string.Format(
194192
CultureInfo.CurrentCulture,
195193
Resources.InvalidCallbackParameterMismatch,
196-
string.Join(", ", expectedParamTypes.Select(p => p.GetFormattedName()).ToArray()),
197-
string.Join(", ", actualParams.Select(p => p.ParameterType.GetFormattedName()).ToArray())));
194+
this.Method.GetParameterTypeList(),
195+
callback.GetMethodInfo().GetParameterTypeList()));
198196
}
199197

200198
if (callback.GetMethodInfo().ReturnType != typeof(void))

src/Moq/StringBuilderExtensions.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,54 @@ public static StringBuilder AppendNameOf(this StringBuilder stringBuilder, Type
7474
return stringBuilder.AppendFormattedName(type);
7575
}
7676

77+
public static StringBuilder AppendParameterType(this StringBuilder stringBuilder, ParameterInfo parameter)
78+
{
79+
var parameterType = parameter.ParameterType;
80+
81+
if (parameterType.IsByRef)
82+
{
83+
switch (parameter.Attributes & (ParameterAttributes.In | ParameterAttributes.Out))
84+
{
85+
case ParameterAttributes.In:
86+
stringBuilder.Append("in ");
87+
break;
88+
89+
case ParameterAttributes.Out:
90+
stringBuilder.Append("out ");
91+
break;
92+
93+
case ParameterAttributes.In | ParameterAttributes.Out:
94+
default:
95+
stringBuilder.Append("ref ");
96+
break;
97+
}
98+
99+
parameterType = parameterType.GetElementType();
100+
}
101+
102+
if (parameterType.IsArray && parameter.IsDefined(typeof(ParamArrayAttribute), true))
103+
{
104+
stringBuilder.Append("params ");
105+
}
106+
107+
return stringBuilder.AppendFormattedName(parameterType);
108+
}
109+
110+
public static StringBuilder AppendParameterTypeList(this StringBuilder stringBuilder, ParameterInfo[] parameters)
111+
{
112+
for (int i = 0; i < parameters.Length; ++i)
113+
{
114+
if (i > 0)
115+
{
116+
stringBuilder.Append(", ");
117+
}
118+
119+
stringBuilder.AppendParameterType(parameters[i]);
120+
}
121+
122+
return stringBuilder;
123+
}
124+
77125
public static StringBuilder AppendValueOf(this StringBuilder stringBuilder, object obj)
78126
{
79127
if (obj == null)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD.
2+
// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.
3+
4+
using System.Text;
5+
6+
using Xunit;
7+
8+
namespace Moq.Tests
9+
{
10+
public class StringBuilderExtensionsFixture
11+
{
12+
[Theory]
13+
[InlineData(nameof(IMethods.Empty), "")]
14+
[InlineData(nameof(IMethods.Int), "int")]
15+
[InlineData(nameof(IMethods.IntAndString), "int, string")]
16+
[InlineData(nameof(IMethods.InInt), "in int")]
17+
[InlineData(nameof(IMethods.RefInt), "ref int")]
18+
[InlineData(nameof(IMethods.OutInt), "out int")]
19+
[InlineData(nameof(IMethods.BoolAndParamsString), "bool, params string[]")]
20+
public void AppendParameterList_formats_parameter_lists_correctly(string methodName, string expected)
21+
{
22+
var actual = GetFormattedParameterListOf(methodName);
23+
Assert.Equal(expected, actual);
24+
}
25+
26+
private string GetFormattedParameterListOf(string methodName)
27+
{
28+
var stringBuilder = new StringBuilder();
29+
var method = typeof(IMethods).GetMethod(methodName);
30+
stringBuilder.AppendParameterTypeList(method.GetParameters());
31+
return stringBuilder.ToString();
32+
}
33+
34+
public interface IMethods
35+
{
36+
void Empty();
37+
void Int(int arg1);
38+
void IntAndString(int arg1, string arg2);
39+
void InInt(in int arg1);
40+
void RefInt(ref int arg1);
41+
void OutInt(out int arg1);
42+
void BoolAndParamsString(bool arg1, params string[] arg2);
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)