Skip to content
This repository has been archived by the owner on Jun 12, 2021. It is now read-only.

Commit

Permalink
refactor:
Browse files Browse the repository at this point in the history
 - make ArgumentFormatter.cs an *exact* copy of xunit's
 - MethodInfoExtensions changes
 - reinstate argument formatting encapsulation in Argument.ToString()
 - whitespace
  • Loading branch information
adamralph committed Nov 21, 2015
1 parent 7c77502 commit 0c464bb
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 87 deletions.
124 changes: 64 additions & 60 deletions src/Xbehave.2.Execution.desktop/ArgumentFormatter.cs
@@ -1,18 +1,17 @@
// <copyright file="ArgumentFormatter.cs" company="xBehave.net contributors">
// Copyright (c) xBehave.net contributors. All rights reserved.
// </copyright>
namespace Xbehave.Execution
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace Xunit.Sdk
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

// the ArgumentFormatter is duplicated from xUnit.Sdk
internal static class ArgumentFormatter
/// <summary>
/// Formats arguments for display in theories.
/// </summary>
static class ArgumentFormatter
{
const int MAX_DEPTH = 3;
const int MAX_ENUMERABLE_LENGTH = 5;
Expand All @@ -24,23 +23,23 @@ internal static class ArgumentFormatter

// List of system types => C# type names
static readonly Dictionary<TypeInfo, string> TypeMappings = new Dictionary<TypeInfo, string>
{
{ typeof(bool).GetTypeInfo(), "bool" },
{ typeof(byte).GetTypeInfo(), "byte" },
{ typeof(sbyte).GetTypeInfo(), "sbyte" },
{ typeof(char).GetTypeInfo(), "char" },
{ typeof(decimal).GetTypeInfo(), "decimal" },
{ typeof(double).GetTypeInfo(), "double" },
{ typeof(float).GetTypeInfo(), "float" },
{ typeof(int).GetTypeInfo(), "int" },
{ typeof(uint).GetTypeInfo(), "uint" },
{ typeof(long).GetTypeInfo(), "long" },
{ typeof(ulong).GetTypeInfo(), "ulong" },
{ typeof(object).GetTypeInfo(), "object" },
{ typeof(short).GetTypeInfo(), "short" },
{ typeof(ushort).GetTypeInfo(), "ushort" },
{ typeof(string).GetTypeInfo(), "string" },
};
{
{ typeof(bool).GetTypeInfo(), "bool" },
{ typeof(byte).GetTypeInfo(), "byte" },
{ typeof(sbyte).GetTypeInfo(), "sbyte" },
{ typeof(char).GetTypeInfo(), "char" },
{ typeof(decimal).GetTypeInfo(), "decimal" },
{ typeof(double).GetTypeInfo(), "double" },
{ typeof(float).GetTypeInfo(), "float" },
{ typeof(int).GetTypeInfo(), "int" },
{ typeof(uint).GetTypeInfo(), "uint" },
{ typeof(long).GetTypeInfo(), "long" },
{ typeof(ulong).GetTypeInfo(), "ulong" },
{ typeof(object).GetTypeInfo(), "object" },
{ typeof(short).GetTypeInfo(), "short" },
{ typeof(ushort).GetTypeInfo(), "ushort" },
{ typeof(string).GetTypeInfo(), "string" },
};

/// <summary>
/// Format the value for presentation.
Expand All @@ -59,27 +58,27 @@ static string Format(object value, int depth)

var valueAsType = value as Type;
if (valueAsType != null)
return String.Format("typeof({0})", new object[] { FormatTypeName(valueAsType) });
return string.Format("typeof({0})", new object[] { FormatTypeName(valueAsType) });

if (value is char)
{
var charValue = (char)value;
if (Char.IsLetterOrDigit(charValue) || Char.IsPunctuation(charValue) || Char.IsSymbol(charValue) || charValue == ' ')
return String.Format("'{0}'", new object[] { value });
if (char.IsLetterOrDigit(charValue) || char.IsPunctuation(charValue) || char.IsSymbol(charValue) || charValue == ' ')
return string.Format("'{0}'", new object[] { value });

return String.Format("0x{0:x4}", new object[] { (int)charValue });
return string.Format("0x{0:x4}", new object[] { (int)charValue });
}

if (value is DateTime || value is DateTimeOffset)
return String.Format("{0:o}", new object[] { value });
return string.Format("{0:o}", new object[] { value });

var stringParameter = value as string;
if (stringParameter != null)
{
if (stringParameter.Length > MAX_STRING_LENGTH)
return String.Format("\"{0}\"...", new object[] { stringParameter.Substring(0, MAX_STRING_LENGTH) });
return string.Format("\"{0}\"...", new object[] { stringParameter.Substring(0, MAX_STRING_LENGTH) });

return String.Format("\"{0}\"", new object[] { stringParameter });
return string.Format("\"{0}\"", new object[] { stringParameter });
}

var enumerable = value as IEnumerable;
Expand All @@ -95,8 +94,8 @@ static string Format(object value, int depth)
if (task != null)
{
var typeParameters = typeInfo.GenericTypeArguments;
var typeName = typeParameters.Length == 0 ? "Task" : String.Format("Task<{0}>", String.Join(",", typeParameters.Select(FormatTypeName)));
return String.Format("{0} {{ Status = {1} }}", typeName, task.Status);
var typeName = typeParameters.Length == 0 ? "Task" : string.Format("Task<{0}>", string.Join(",", typeParameters.Select(FormatTypeName)));
return string.Format("{0} {{ Status = {1} }}", typeName, task.Status);
}

#if PLATFORM_DOTNET
Expand All @@ -105,7 +104,7 @@ static string Format(object value, int depth)
var toString = type.GetMethod("ToString", EmptyTypes);
#endif

if (toString != null && toString.DeclaringType != typeof(Object))
if (toString != null && toString.DeclaringType != typeof(object))
return (string)toString.Invoke(value, EmptyObjects);

return FormatComplexValue(value, depth, type);
Expand All @@ -114,29 +113,29 @@ static string Format(object value, int depth)
static string FormatComplexValue(object value, int depth, Type type)
{
if (depth == MAX_DEPTH)
return String.Format("{0} {{ ... }}", new object[] { type.Name });
return string.Format("{0} {{ ... }}", new object[] { type.Name });

var fields = type.GetRuntimeFields()
.Where(f => f.IsPublic && !f.IsStatic)
.Select(f => new { name = f.Name, value = WrapAndGetFormattedValue(() => f.GetValue(value), depth) });
.Where(f => f.IsPublic && !f.IsStatic)
.Select(f => new { name = f.Name, value = WrapAndGetFormattedValue(() => f.GetValue(value), depth) });
var properties = type.GetRuntimeProperties()
.Where(p => p.GetMethod != null && p.GetMethod.IsPublic && !p.GetMethod.IsStatic)
.Select(p => new { name = p.Name, value = WrapAndGetFormattedValue(() => p.GetValue(value), depth) });
.Where(p => p.GetMethod != null && p.GetMethod.IsPublic && !p.GetMethod.IsStatic)
.Select(p => new { name = p.Name, value = WrapAndGetFormattedValue(() => p.GetValue(value), depth) });
var parameters = fields.Concat(properties)
.OrderBy(p => p.name)
.Take(MAX_OBJECT_PARAMETER_COUNT + 1)
.ToList();
.OrderBy(p => p.name)
.Take(MAX_OBJECT_PARAMETER_COUNT + 1)
.ToList();

if (parameters.Count == 0)
return String.Format("{0} {{ }}", new object[] { type.Name });
return string.Format("{0} {{ }}", new object[] { type.Name });

var formattedParameters = String.Join(", ", parameters.Take(MAX_OBJECT_PARAMETER_COUNT)
.Select(p => String.Format("{0} = {1}", new object[] { p.name, p.value })));
var formattedParameters = string.Join(", ", parameters.Take(MAX_OBJECT_PARAMETER_COUNT)
.Select(p => string.Format("{0} = {1}", new object[] { p.name, p.value })));

if (parameters.Count > MAX_OBJECT_PARAMETER_COUNT)
formattedParameters += ", ...";

return String.Format("{0} {{ {1} }}", new object[] { type.Name, formattedParameters });
return string.Format("{0} {{ {1} }}", new object[] { type.Name, formattedParameters });
}

static string FormatEnumerable(IEnumerable<object> enumerableValues, int depth)
Expand All @@ -145,12 +144,12 @@ static string FormatEnumerable(IEnumerable<object> enumerableValues, int depth)
return "[...]";

var values = enumerableValues.Take(MAX_ENUMERABLE_LENGTH + 1).ToList();
var printedValues = String.Join(", ", values.Take(MAX_ENUMERABLE_LENGTH).Select(x => Format(x, depth + 1)));
var printedValues = string.Join(", ", values.Take(MAX_ENUMERABLE_LENGTH).Select(x => Format(x, depth + 1)));

if (values.Count > MAX_ENUMERABLE_LENGTH)
printedValues += ", ...";

return String.Format("[{0}]", new object[] { printedValues });
return string.Format("[{0}]", new object[] { printedValues });
}

static string FormatTypeName(Type type)
Expand All @@ -162,7 +161,7 @@ static string FormatTypeName(Type type)
while (typeInfo.IsArray)
{
var rank = typeInfo.GetArrayRank();
arraySuffix += String.Format("[{0}]", new object[] { new string(',', rank - 1) });
arraySuffix += string.Format("[{0}]", new object[] { new string(',', rank - 1) });
typeInfo = typeInfo.GetElementType().GetTypeInfo();
}

Expand All @@ -173,18 +172,23 @@ static string FormatTypeName(Type type)

// Strip off generic suffix
var name = typeInfo.FullName;

// catch special case of generic parameters not being bound to a specific type:
if (name == null)
return typeInfo.Name;

var tickIdx = name.IndexOf('`');
if (tickIdx > 0)
name = name.Substring(0, tickIdx);

if (typeInfo.IsGenericTypeDefinition)
name = String.Format("{0}<{1}>", new object[] { name, new string(',', typeInfo.GenericTypeParameters.Length - 1) });
name = string.Format("{0}<{1}>", new object[] { name, new string(',', typeInfo.GenericTypeParameters.Length - 1) });
else if (typeInfo.IsGenericType)
{
if (typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>))
name = FormatTypeName(typeInfo.GenericTypeArguments[0]) + "?";
else
name = String.Format("{0}<{1}>", new object[] { name, String.Join(", ", typeInfo.GenericTypeArguments.Select(FormatTypeName)) });
name = string.Format("{0}<{1}>", new object[] { name, string.Join(", ", typeInfo.GenericTypeArguments.Select(FormatTypeName)) });
}

return name + arraySuffix;
Expand All @@ -198,7 +202,7 @@ static string WrapAndGetFormattedValue(Func<object> getter, int depth)
}
catch (Exception ex)
{
return String.Format("(throws {0})", new object[] { UnwrapException(ex).GetType().Name });
return string.Format("(throws {0})", new object[] { UnwrapException(ex).GetType().Name });
}
}

Expand All @@ -214,4 +218,4 @@ static Exception UnwrapException(Exception ex)
}
}
}
}
}
Expand Up @@ -4,8 +4,8 @@

namespace Xbehave.Execution.Extensions
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Xunit.Sdk;
Expand All @@ -17,11 +17,7 @@ public static async Task InvokeAsync(this MethodInfo method, object obj, object[
{
Guard.AgainstNullArgument("method", method);

var parameters = method.GetParameters();
var parameterTypes = new Type[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
parameterTypes[i] = parameters[i].ParameterType;

var parameterTypes = method.GetParameters().Select(parameter => parameter.ParameterType).ToArray();
Reflector.ConvertArguments(arguments, parameterTypes);

var result = method.Invoke(obj, arguments);
Expand Down
22 changes: 2 additions & 20 deletions src/Xbehave.2.Execution.desktop/ScenarioRunnerFactory.cs
Expand Up @@ -202,7 +202,7 @@ public ScenarioRunner Create(object[] scenarioMethodArguments)
parameterAndArgumentTokens.Add(string.Concat(
parameterIndex >= parameters.Count ? "???" : parameters[parameterIndex].Name,
": ",
ArgumentFormatter.Format(arguments[parameterIndex].Value)));
arguments[parameterIndex].ToString()));
}

for (; parameterIndex < parameters.Count; parameterIndex++)
Expand Down Expand Up @@ -250,25 +250,7 @@ public bool IsGeneratedDefault

public override string ToString()
{
if (this.Value == null)
{
return "null";
}

if (this.Value is char)
{
return "'" + this.Value + "'";
}

var stringArgument = this.Value as string;
if (stringArgument != null)
{
return stringArgument.Length > 50
? string.Concat("\"", stringArgument.Substring(0, 50), "\"...")
: string.Concat("\"", stringArgument, "\"");
}

return Convert.ToString(this.Value, CultureInfo.InvariantCulture);
return ArgumentFormatter.Format(this.value);
}

private static MethodInfo CreateGenericFactoryMethod()
Expand Down
Expand Up @@ -33,4 +33,4 @@ public void Arrays(string[] words, int[] numbers, IStepContext stepContext)
.Should().Match("*(words: [\"one\", \"two\"], numbers: [1, 2])*"));
}
}
}
}

0 comments on commit 0c464bb

Please sign in to comment.