/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 <http://www.gnu.org/licenses/>. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace TestCaseExtension.Internal { /// <summary>Useful utility/extension methods for Reflection and Enumerables</summary> public static class TestExtensionUtil { /// <summary>Get the type with the given typeName (full path)</summary> 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; } /// <summary>Retrieve the static Members of this Type with the given memberName</summary> public static MemberInfo[] GetStaticMembers(this Type type, string memberName) { return type.GetMember(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); } /// <summary>Retrieve the value of the staic member (Field, Property, or no-argument Method)</summary> public static T ValueOf<T>(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); } } /// <summary>Get the Type of the MemberInfo (Field, Property, Method, or Event)</summary> 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); } } /// <summary>Is this Method marked with an Ignore or Explicit attribute?</summary> public static bool IsExplicitOrIgnored(this MethodInfo method) { return GetAttributes<ExplicitAttribute>(method).Any() || GetAttributes<IgnoreAttribute>(method).Any(); } /// <summary>Get the Attributes of the given type on thie Method</summary> public static IList<T> GetAttributes<T>(this MethodInfo method) where T : Attribute { return method.GetCustomAttributes<T>().ToList(); } /// <summary>Get the inner-most Exception within this one</summary> public static Exception DeepestException(this Exception e) { if (e == null || e.InnerException == null) return e; return DeepestException(e.InnerException); } /// <summary>Concatenate string versions of the elements in this IEnumerable separated by /// the given string separator</summary> public static string StringJoin<T>(this IEnumerable<T> elements, string separator) { return elements.StringJoin(t => t.ToString(), separator); } /// <summary>Concatenate the elements in this IEnumerable converted by the given conversion /// function, separated by the given string separator</summary> public static string StringJoin<T>(this IEnumerable<T> elements, Func<T, string> conversion, string separator) { return string.Join(separator, elements.Select(t => t == null ? "null" : conversion(t))); } /// <summary>Convert this Type into a string that includes generic type-parameters. /// E.g., "KeyValuePair<Double, String>" rather than "System.Collections.Generic.KeyValuePair`2"</summary> public static string GenericTypeString(this Type t) { string simple = t.SimpleName(); if (!t.IsGenericType) return simple; return simple + "<" + t.GenericTypeArguments.StringJoin(u => u.GenericTypeString(), ", ") + ">"; } /// <summary>Returns the Name of the type without the Namspace prefix</summary> 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); } } }