Fixes TypeFinder issue but retains the improved performance. Adds TypeHelper tests.
This commit is contained in:
@@ -19,8 +19,6 @@ using Umbraco.Core.IO;
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
|
||||
//TODO: Get the App_Code stuff in here from the old one
|
||||
|
||||
/// <summary>
|
||||
/// A utility class to find all classes of a certain type by reflection in the current bin folder
|
||||
/// of the web application.
|
||||
@@ -244,42 +242,66 @@ namespace Umbraco.Core
|
||||
"Examine."
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the type T that contain the attribute TAttribute
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>()
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(GetAssembliesWithKnownExclusions(), true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the type T that contain the attribute TAttribute
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(assemblies, true);
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the type T that contain the attribute TAttribute
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<TAttribute>(typeof (T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds any classes derived from the assignTypeFrom Type that contain the attribute TAttribute
|
||||
/// </summary>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <param name="assignTypeFrom"></param>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<TAttribute>(
|
||||
Type assignTypeFrom,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
// a assembly cant contain types that are assignable to a type it doesn't reference
|
||||
assemblies = RemoveAssembliesThatDontReferenceAssemblyOfType(typeof (T), assemblies);
|
||||
// a assembly cant contain types with a attribute it doesn't reference
|
||||
assemblies = RemoveAssembliesThatDontReferenceAssemblyOfType(typeof (TAttribute), assemblies);
|
||||
|
||||
var l = new List<Type>();
|
||||
foreach(var a in assemblies)
|
||||
{
|
||||
var types = from t in GetTypesWithFormattedException(a)
|
||||
where !t.IsInterface
|
||||
&& typeof (T).IsAssignableFrom(t)
|
||||
&& t.GetCustomAttributes<TAttribute>(false).Any()
|
||||
&& (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t;
|
||||
l.AddRange(types);
|
||||
}
|
||||
|
||||
return l;
|
||||
|
||||
return GetClasses(assignTypeFrom, assemblies, onlyConcreteClasses,
|
||||
//the additional filter will ensure that any found types also have the attribute applied.
|
||||
t => t.GetCustomAttributes<TAttribute>(false).Any());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -303,7 +325,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
return GetAssignablesFromType<T>(assemblies, onlyConcreteClasses);
|
||||
return GetClasses(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -330,66 +352,50 @@ namespace Umbraco.Core
|
||||
return FindClassesWithAttribute(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <param name="type">The attribute type </param>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute(Type type, IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
if (!TypeHelper.IsTypeAssignableFrom<Attribute>(type))
|
||||
throw new ArgumentException("The type specified: " + type + " is not an Attribute type");
|
||||
// a assembly cant contain types with a attribute it doesn't reference
|
||||
assemblies = RemoveAssembliesThatDontReferenceAssemblyOfType(type, assemblies);
|
||||
/// <summary>
|
||||
/// Finds any classes with the attribute.
|
||||
/// </summary>
|
||||
/// <param name="attributeType">The attribute type </param>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute(
|
||||
Type attributeType,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
var l = new List<Type>();
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
var types = from t in GetTypesWithFormattedException(a)
|
||||
where
|
||||
!t.IsInterface && t.GetCustomAttributes(type, false).Any() &&
|
||||
(!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t;
|
||||
l.AddRange(types);
|
||||
}
|
||||
if (TypeHelper.IsTypeAssignableFrom<Attribute>(attributeType) == false)
|
||||
throw new ArgumentException("The type specified: " + attributeType + " is not an Attribute type");
|
||||
|
||||
return l;
|
||||
}
|
||||
/// <summary>
|
||||
/// Removes assemblies that doesn't reference the assembly of the type we are looking for.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Assembly> RemoveAssembliesThatDontReferenceAssemblyOfType(Type type, IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
// Avoid scanning assembly if it doesn't contain a reference to the assembly containing the type we are looking for
|
||||
// to the assembly containing the attribute we are looking for
|
||||
var assemblyNameOfType = type.Assembly.GetName().Name;
|
||||
var foundAssignableTypes = new List<Type>();
|
||||
|
||||
return assemblies
|
||||
.Where(assembly => assembly == type.Assembly
|
||||
|| HasReferenceToAssemblyWithName(assembly, assemblyNameOfType)).ToList();
|
||||
}
|
||||
/// <summary>
|
||||
/// checks if the assembly has a reference with the same name as the expected assembly name.
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <param name="expectedAssemblyName"></param>
|
||||
/// <returns></returns>
|
||||
private static bool HasReferenceToAssemblyWithName(Assembly assembly, string expectedAssemblyName)
|
||||
{
|
||||
return assembly
|
||||
.GetReferencedAssemblies()
|
||||
.Select(a => a.Name)
|
||||
.Contains(expectedAssemblyName, StringComparer.Ordinal);
|
||||
}
|
||||
var assemblyList = assemblies.ToArray();
|
||||
|
||||
/// <summary>
|
||||
//find all assembly references that are referencing the attribute type's assembly since we
|
||||
//should only be scanning those assemblies because any other assembly will definitely not
|
||||
//contain a class that has this attribute.
|
||||
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(attributeType, assemblyList);
|
||||
|
||||
foreach (var a in referencedAssemblies)
|
||||
{
|
||||
//get all types in the assembly that are sub types of the current type
|
||||
var allTypes = GetTypesWithFormattedException(a).ToArray();
|
||||
|
||||
var types = allTypes.Where(t => TypeHelper.IsNonStaticClass(t)
|
||||
&& (onlyConcreteClasses == false || t.IsAbstract == false)
|
||||
//the type must have this attribute
|
||||
&& t.GetCustomAttributes(attributeType, false).Any());
|
||||
|
||||
foundAssignableTypes.AddRange(types);
|
||||
}
|
||||
|
||||
return foundAssignableTypes;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
@@ -415,34 +421,96 @@ namespace Umbraco.Core
|
||||
|
||||
#region Private methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of assignables of type T from a collection of assemblies
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Type> GetAssignablesFromType<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
/// <summary>
|
||||
/// Finds types that are assignable from the assignTypeFrom parameter and will scan for these types in the assembly
|
||||
/// list passed in, however we will only scan assemblies that have a reference to the assignTypeFrom Type or any type
|
||||
/// deriving from the base type.
|
||||
/// </summary>
|
||||
/// <param name="assignTypeFrom"></param>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <param name="additionalFilter">An additional filter to apply for what types will actually be included in the return value</param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<Type> GetClasses(
|
||||
Type assignTypeFrom,
|
||||
IEnumerable<Assembly> assemblies,
|
||||
bool onlyConcreteClasses,
|
||||
Func<Type, bool> additionalFilter = null)
|
||||
{
|
||||
return GetTypes(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
//the default filter will always return true.
|
||||
if (additionalFilter == null)
|
||||
{
|
||||
additionalFilter = type => true;
|
||||
}
|
||||
|
||||
private static IEnumerable<Type> GetTypes(Type assignTypeFrom, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
{
|
||||
// a assembly cant contain types that are assignable to a type it doesn't reference
|
||||
assemblies = RemoveAssembliesThatDontReferenceAssemblyOfType(assignTypeFrom, assemblies);
|
||||
var foundAssignableTypes = new List<Type>();
|
||||
|
||||
var assemblyList = assemblies.ToArray();
|
||||
|
||||
//find all assembly references that are referencing the current type's assembly since we
|
||||
//should only be scanning those assemblies because any other assembly will definitely not
|
||||
//contain sub type's of the one we're currently looking for
|
||||
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(assignTypeFrom, assemblyList);
|
||||
|
||||
//get a list of non-referenced assemblies (we'll use this when we recurse below)
|
||||
var otherAssemblies = assemblyList.Where(x => referencedAssemblies.Contains(x) == false).ToArray();
|
||||
|
||||
//loop through the referenced assemblies
|
||||
foreach (var a in referencedAssemblies)
|
||||
{
|
||||
//get all types in the assembly that are sub types of the current type
|
||||
var allSubTypes = GetTypesWithFormattedException(a)
|
||||
.Where(assignTypeFrom.IsAssignableFrom)
|
||||
.ToArray();
|
||||
|
||||
//now filter the types based on the onlyConcreteClasses flag, not interfaces, not static classes
|
||||
var filteredTypes = allSubTypes
|
||||
.Where(t => (TypeHelper.IsNonStaticClass(t)
|
||||
&& (onlyConcreteClasses == false || t.IsAbstract == false)
|
||||
&& additionalFilter(t)))
|
||||
.ToArray();
|
||||
|
||||
//add the types to our list to return
|
||||
foundAssignableTypes.AddRange(filteredTypes);
|
||||
|
||||
//now we need to include types that may be inheriting from sub classes of the type being searched for
|
||||
//so we will search in assemblies that reference those types too.
|
||||
foreach (var subTypesInAssembly in allSubTypes.GroupBy(x => x.Assembly))
|
||||
{
|
||||
|
||||
//So that we are not scanning too much, we need to group the sub types:
|
||||
// * if there is more than 1 sub type in the same assembly then we should only search on the 'lowest base' type.
|
||||
// * We should also not search for sub types if the type is sealed since you cannot inherit from a sealed class
|
||||
// * We should not search for sub types if the type is static since you cannot inherit from them.
|
||||
var subTypeList = subTypesInAssembly
|
||||
.Where(t => t.IsSealed == false && TypeHelper.IsStaticClass(t) == false)
|
||||
.ToArray();
|
||||
|
||||
var baseClassAttempt = TypeHelper.GetLowestBaseType(subTypeList);
|
||||
|
||||
//if there's a base class amongst the types then we'll only search for that type.
|
||||
//otherwise we'll have to search for all of them.
|
||||
var subTypesToSearch = new List<Type>();
|
||||
if (baseClassAttempt.Success)
|
||||
{
|
||||
subTypesToSearch.Add(baseClassAttempt.Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
subTypesToSearch.AddRange(subTypeList);
|
||||
}
|
||||
|
||||
foreach (var typeToSearch in subTypesToSearch)
|
||||
{
|
||||
//recursively find the types inheriting from this sub type in the other non-scanned assemblies.
|
||||
var foundTypes = GetClasses(typeToSearch, otherAssemblies, onlyConcreteClasses);
|
||||
foundAssignableTypes.AddRange(foundTypes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var l = new List<Type>();
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
var types = from t in GetTypesWithFormattedException(a)
|
||||
where
|
||||
!t.IsInterface && assignTypeFrom.IsAssignableFrom(t) &&
|
||||
(!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t;
|
||||
l.AddRange(types);
|
||||
}
|
||||
return l;
|
||||
return foundAssignableTypes;
|
||||
}
|
||||
|
||||
private static IEnumerable<Type> GetTypesWithFormattedException(Assembly a)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
@@ -11,12 +12,114 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
internal static class TypeHelper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<Tuple<Type, Type>, bool> TypeCheckCache = new ConcurrentDictionary<Tuple<Type, Type>, bool>();
|
||||
private static readonly ConcurrentDictionary<Type, bool> ValueTypeCache = new ConcurrentDictionary<Type, bool>();
|
||||
private static readonly ConcurrentDictionary<Type, bool> ImplicitValueTypeCache = new ConcurrentDictionary<Type, bool>();
|
||||
|
||||
private static readonly ConcurrentDictionary<Type, FieldInfo[]> GetFieldsCache = new ConcurrentDictionary<Type, FieldInfo[]>();
|
||||
private static readonly ConcurrentDictionary<Tuple<Type, bool, bool, bool>, PropertyInfo[]> GetPropertiesCache = new ConcurrentDictionary<Tuple<Type, bool, bool, bool>, PropertyInfo[]>();
|
||||
|
||||
/// <summary>
|
||||
/// Find all assembly references that are referencing the assignTypeFrom Type's assembly found in the assemblyList
|
||||
/// </summary>
|
||||
/// <param name="assignTypeFrom"></param>
|
||||
/// <param name="assemblies"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// If the assembly of the assignTypeFrom Type is in the App_Code assembly, then we return nothing since things cannot
|
||||
/// reference that assembly, same with the global.asax assembly.
|
||||
/// </remarks>
|
||||
public static Assembly[] GetReferencedAssemblies(Type assignTypeFrom, IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
//check if it is the app_code assembly.
|
||||
//check if it is App_global.asax assembly
|
||||
var appCodeAssembly = Assembly.Load("App_Code");
|
||||
if (assignTypeFrom.Assembly == appCodeAssembly || assignTypeFrom.Assembly.FullName.StartsWith("App_global.asax"))
|
||||
{
|
||||
return Enumerable.Empty<Assembly>().ToArray();
|
||||
}
|
||||
|
||||
//find all assembly references that are referencing the current type's assembly since we
|
||||
//should only be scanning those assemblies because any other assembly will definitely not
|
||||
//contain sub type's of the one we're currently looking for
|
||||
return assemblies
|
||||
.Where(assembly =>
|
||||
assembly == assignTypeFrom.Assembly || HasReferenceToAssemblyWithName(assembly, assignTypeFrom.Assembly.GetName().Name))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// checks if the assembly has a reference with the same name as the expected assembly name.
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <param name="expectedAssemblyName"></param>
|
||||
/// <returns></returns>
|
||||
private static bool HasReferenceToAssemblyWithName(Assembly assembly, string expectedAssemblyName)
|
||||
{
|
||||
return assembly
|
||||
.GetReferencedAssemblies()
|
||||
.Select(a => a.Name)
|
||||
.Contains(expectedAssemblyName, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the type is a class and is not static
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsNonStaticClass(Type t)
|
||||
{
|
||||
return t.IsClass && IsStaticClass(t) == false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the type is a static class
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// In IL a static class is abstract and sealed
|
||||
/// see: http://stackoverflow.com/questions/1175888/determine-if-a-type-is-static
|
||||
/// </remarks>
|
||||
public static bool IsStaticClass(Type type)
|
||||
{
|
||||
return type.IsAbstract && type.IsSealed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a lowest base class amongst a collection of types
|
||||
/// </summary>
|
||||
/// <param name="types"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// The term 'lowest' refers to the most base class of the type collection.
|
||||
/// If a base type is not found amongst the type collection then an invalid attempt is returned.
|
||||
/// </remarks>
|
||||
public static Attempt<Type> GetLowestBaseType(params Type[] types)
|
||||
{
|
||||
if (types.Length == 0)
|
||||
{
|
||||
return Attempt<Type>.False;
|
||||
}
|
||||
if (types.Length == 1)
|
||||
{
|
||||
return new Attempt<Type>(true, types[0]);
|
||||
}
|
||||
|
||||
foreach (var curr in types)
|
||||
{
|
||||
var others = types.Except(new[] {curr});
|
||||
|
||||
//is the curr type a common denominator for all others ?
|
||||
var isBase = others.All(curr.IsAssignableFrom);
|
||||
|
||||
//if this type is the base for all others
|
||||
if (isBase)
|
||||
{
|
||||
return new Attempt<Type>(true, curr);
|
||||
}
|
||||
}
|
||||
|
||||
return Attempt<Type>.False;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the type <paramref name="implementation"/> is assignable from the specified implementation <typeparamref name="TContract"/>,
|
||||
/// and caches the result across the application using a <see cref="ConcurrentDictionary{TKey,TValue}"/>.
|
||||
@@ -28,8 +131,7 @@ namespace Umbraco.Core
|
||||
/// </returns>
|
||||
public static bool IsTypeAssignableFrom(Type contract, Type implementation)
|
||||
{
|
||||
// NOTE The use of a Tuple<,> here is because its Equals / GetHashCode implementation is literally 10.5x faster than KeyValuePair<,>
|
||||
return TypeCheckCache.GetOrAdd(new Tuple<Type, Type>(contract, implementation), x => x.Item1.IsAssignableFrom(x.Item2));
|
||||
return contract.IsAssignableFrom(implementation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -49,7 +151,7 @@ namespace Umbraco.Core
|
||||
/// <param name="implementation">The implementation.</param>
|
||||
public static bool IsValueType(Type implementation)
|
||||
{
|
||||
return ValueTypeCache.GetOrAdd(implementation, x => x.IsValueType || x.IsPrimitive);
|
||||
return implementation.IsValueType || implementation.IsPrimitive;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -58,7 +160,7 @@ namespace Umbraco.Core
|
||||
/// <param name="implementation">The implementation.</param>
|
||||
public static bool IsImplicitValueType(Type implementation)
|
||||
{
|
||||
return ImplicitValueTypeCache.GetOrAdd(implementation, x => IsValueType(implementation) || implementation.IsEnum || implementation == typeof(string));
|
||||
return IsValueType(implementation) || implementation.IsEnum || implementation == typeof (string);
|
||||
}
|
||||
|
||||
public static bool IsTypeAssignableFrom<TContract>(object implementation)
|
||||
|
||||
@@ -16,7 +16,6 @@ using SqlCE4Umbraco;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Tests;
|
||||
using Umbraco.Tests.PartialTrust;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web.BaseRest;
|
||||
using umbraco;
|
||||
@@ -30,8 +29,9 @@ using umbraco.uicontrols;
|
||||
|
||||
namespace Umbraco.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Full Trust benchmark tests for typefinder and the old typefinder
|
||||
|
||||
/// <summary>
|
||||
/// Tests for typefinder
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TypeFinderTests
|
||||
|
||||
84
src/Umbraco.Tests/TypeHelperTests.cs
Normal file
84
src/Umbraco.Tests/TypeHelperTests.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Data.Common;
|
||||
using System.Data.Odbc;
|
||||
using System.Data.OleDb;
|
||||
using System.Data.SqlClient;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Tests.PartialTrust;
|
||||
using Umbraco.Web;
|
||||
using UmbracoExamine;
|
||||
using umbraco;
|
||||
using umbraco.presentation;
|
||||
using umbraco.presentation.nodeFactory;
|
||||
using umbraco.presentation.umbraco.Search;
|
||||
|
||||
namespace Umbraco.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests for TypeHelper
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TypeHelperTests : AbstractPartialTrustFixture<TypeHelperTests>
|
||||
{
|
||||
|
||||
[Test]
|
||||
public void Is_Static_Class()
|
||||
{
|
||||
Assert.IsTrue(TypeHelper.IsStaticClass(typeof(TypeHelper)));
|
||||
Assert.IsFalse(TypeHelper.IsStaticClass(typeof(TypeHelperTests)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Find_Common_Base_Class()
|
||||
{
|
||||
var t1 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand),
|
||||
typeof (OdbcCommand),
|
||||
typeof (SqlCommand));
|
||||
Assert.IsFalse(t1.Success);
|
||||
|
||||
var t2 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand),
|
||||
typeof (OdbcCommand),
|
||||
typeof (SqlCommand),
|
||||
typeof (Component));
|
||||
Assert.IsTrue(t2.Success);
|
||||
Assert.AreEqual(typeof(Component), t2.Result);
|
||||
|
||||
var t3 = TypeHelper.GetLowestBaseType(typeof (OleDbCommand),
|
||||
typeof (OdbcCommand),
|
||||
typeof (SqlCommand),
|
||||
typeof (Component),
|
||||
typeof (Component).BaseType);
|
||||
Assert.IsTrue(t3.Success);
|
||||
Assert.AreEqual(typeof(MarshalByRefObject), t3.Result);
|
||||
|
||||
var t4 = TypeHelper.GetLowestBaseType(typeof(OleDbCommand),
|
||||
typeof(OdbcCommand),
|
||||
typeof(SqlCommand),
|
||||
typeof(Component),
|
||||
typeof(Component).BaseType,
|
||||
typeof(int));
|
||||
Assert.IsFalse(t4.Success);
|
||||
|
||||
var t5 = TypeHelper.GetLowestBaseType(typeof(UmbracoEventManager));
|
||||
Assert.IsTrue(t5.Success);
|
||||
Assert.AreEqual(typeof(UmbracoEventManager), t5.Result);
|
||||
|
||||
var t6 = TypeHelper.GetLowestBaseType(typeof (IApplicationEventHandler),
|
||||
typeof (LegacyScheduledTasks),
|
||||
typeof(CacheHelperExtensions.CacheHelperApplicationEventListener));
|
||||
Assert.IsTrue(t6.Success);
|
||||
Assert.AreEqual(typeof(IApplicationEventHandler), t6.Result);
|
||||
|
||||
}
|
||||
|
||||
public override void TestSetup()
|
||||
{
|
||||
}
|
||||
|
||||
public override void TestTearDown()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,6 +121,7 @@
|
||||
<DependentUpon>ExamineResources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="TestHelpers\ExamineHelpers\IndexInitializer.cs" />
|
||||
<Compile Include="TypeHelperTests.cs" />
|
||||
<Compile Include="UriUtilityTests.cs" />
|
||||
<Compile Include="Resolvers\MacroFieldEditorsResolverTests.cs" />
|
||||
<Compile Include="MacroEngineFactoryTests.cs" />
|
||||
|
||||
Reference in New Issue
Block a user