using System; using System.Linq; using System.Reflection; using NUnit.Framework; namespace Umbraco.Tests.Testing { public abstract class TestOptionAttributeBase : Attribute { public static TOptions GetTestOptions(MethodInfo method) where TOptions : TestOptionAttributeBase, new() { var attr = ((TOptions[]) method.GetCustomAttributes(typeof (TOptions), true)).FirstOrDefault(); var type = method.DeclaringType; return Get(type, attr); } public static TOptions GetFixtureOptions(Type type) where TOptions : TestOptionAttributeBase, new() { return Get(type, null); } public static TOptions GetTestOptions() where TOptions : TestOptionAttributeBase, new() { var test = TestContext.CurrentContext.Test; var typeName = test.ClassName; var methodName = test.MethodName; var type = Type.GetType(typeName, true); if (type == null) throw new Exception("panic"); // makes no sense var methodInfo = type.GetMethod(methodName); // what about overloads? var options = GetTestOptions(methodInfo); return options; } private static TOptions Get(Type type, TOptions attr) where TOptions : TestOptionAttributeBase, new() { while (type != null && type != typeof(object)) { var attr2 = ((TOptions[]) type.GetCustomAttributes(typeof (TOptions), true)).FirstOrDefault(); if (attr2 != null) attr = attr == null ? attr2 : attr2.Merge(attr); type = type.BaseType; } return attr ?? new TOptions(); } private TOptions Merge(TOptions other) where TOptions : TestOptionAttributeBase { if (other == null) throw new ArgumentNullException(nameof(other)); if (!(Merge((TestOptionAttributeBase) other) is TOptions merged)) throw new Exception("panic"); return merged; } protected virtual TestOptionAttributeBase Merge(TestOptionAttributeBase other) { return this; } } }