/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* TestCaseExtension Library, Copyright 2015 Bryan Chadwick *
* *
* FILE: .\TestExtensionUtil.cs *
* *
* This file is part of TestCaseExtension. *
* *
* TestCaseExtension is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation, either version *
* 3 of the License, or (at your option) any later version. *
* *
* TestCaseExtension is distributed in the hope that it will be useful,*
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with TestCaseExtension. *
* If not, see . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace TestCaseExtension.Internal
{
/// Useful utility/extension methods for Reflection and Enumerables
public static class TestExtensionUtil
{
/// Get the type with the given typeName (full path)
public static Type GetType(string typeName)
{
Type t = Type.GetType(typeName);
if (t != null) return t;
var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetType(typeName) != null);
if (assembly != null)
{
return assembly.GetType(typeName);
}
return null;
}
/// Retrieve the static Members of this Type with the given memberName
public static MemberInfo[] GetStaticMembers(this Type type, string memberName)
{
return type.GetMember(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
}
/// Retrieve the value of the staic member (Field, Property, or no-argument Method)
public static T ValueOf(this Type type, MemberInfo info)
{
switch (info.MemberType)
{
case MemberTypes.Property: return (T)(info as PropertyInfo).GetValue(type);
case MemberTypes.Field: return (T)(info as FieldInfo).GetValue(type);
case MemberTypes.Method: return (T)(info as MethodInfo).Invoke(type, null);
default: throw new TestCaseSourceException("Cannot get Value of member {0} of type {1}",
info.Name, info.MemberType);
}
}
/// Get the Type of the MemberInfo (Field, Property, Method, or Event)
public static Type GetMemberType(this MemberInfo info)
{
switch (info.MemberType)
{
case MemberTypes.Property: return (info as PropertyInfo).PropertyType;
case MemberTypes.Field: return (info as FieldInfo).FieldType;
case MemberTypes.Method: return (info as MethodInfo).ReturnType;
case MemberTypes.Event: return (info as EventInfo).EventHandlerType;
default: throw new TestCaseSourceException("Cannot get Type of member {0} (MemberType = {1}",
info.Name, info.MemberType);
}
}
/// Is this Method marked with an Ignore or Explicit attribute?
public static bool IsExplicitOrIgnored(this MethodInfo method)
{
return GetAttributes(method).Any() || GetAttributes(method).Any();
}
/// Get the Attributes of the given type on thie Method
public static IList GetAttributes(this MethodInfo method) where T : Attribute
{
return method.GetCustomAttributes().ToList();
}
/// Get the inner-most Exception within this one
public static Exception DeepestException(this Exception e)
{
if (e == null || e.InnerException == null)
return e;
return DeepestException(e.InnerException);
}
/// Concatenate string versions of the elements in this IEnumerable separated by
/// the given string separator
public static string StringJoin(this IEnumerable elements, string separator)
{
return elements.StringJoin(t => t.ToString(), separator);
}
/// Concatenate the elements in this IEnumerable converted by the given conversion
/// function, separated by the given string separator
public static string StringJoin(this IEnumerable elements, Func conversion, string separator)
{
return string.Join(separator, elements.Select(t => t == null ? "null" : conversion(t)));
}
/// Convert this Type into a string that includes generic type-parameters.
/// E.g., "KeyValuePair<Double, String>" rather than "System.Collections.Generic.KeyValuePair`2"
public static string GenericTypeString(this Type t)
{
string simple = t.SimpleName();
if (!t.IsGenericType)
return simple;
return simple + "<" + t.GenericTypeArguments.StringJoin(u => u.GenericTypeString(), ", ") + ">";
}
/// Returns the Name of the type without the Namspace prefix
public static string SimpleName(this Type t)
{
string name = t.Name;
int trimStart = name.LastIndexOf('.') + 1;
int end = name.LastIndexOf('`');
if (end < trimStart)
end = name.Length;
return name.Substring(trimStart, end - trimStart);
}
}
}