using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework.Interfaces; using UnityEngine; using UnityEngine.TestTools; namespace UnityEditor.TestTools.TestRunner { internal abstract class AttributeFinderBase : IAttributeFinder { public abstract IEnumerable Search(ITest tests, ITestFilter filter, RuntimePlatform testTargetPlatform); } internal interface IAttributeFinder { IEnumerable Search(ITest tests, ITestFilter filter, RuntimePlatform testTargetPlatform); } internal abstract class AttributeFinderBase : AttributeFinderBase where T2 : Attribute { private readonly Func m_TypeSelector; protected AttributeFinderBase(Func typeSelector) { m_TypeSelector = typeSelector; } public override IEnumerable Search(ITest tests, ITestFilter filter, RuntimePlatform testTargetPlatform) { var selectedTests = new List(); GetMatchingTests(tests, filter, ref selectedTests, testTargetPlatform); var result = new List(); result.AddRange(GetTypesFromPrebuildAttributes(selectedTests)); result.AddRange(GetTypesFromInterface(selectedTests, testTargetPlatform)); return result.Distinct(); } private static void GetMatchingTests(ITest tests, ITestFilter filter, ref List resultList, RuntimePlatform testTargetPlatform) { foreach (var test in tests.Tests) { if (IsTestEnabledOnPlatform(test, testTargetPlatform)) { if (test.IsSuite) { GetMatchingTests(test, filter, ref resultList, testTargetPlatform); } else { if (filter.Pass(test)) resultList.Add(test); } } } } private static bool IsTestEnabledOnPlatform(ITest test, RuntimePlatform testTargetPlatform) { if (test.Method == null) { return true; } var attributesFromMethods = test.Method.GetCustomAttributes(true); var attributesFromTypes = test.Method.TypeInfo.GetCustomAttributes(true); if (attributesFromMethods.Length == 0 && attributesFromTypes.Length == 0) { return true; } if (!attributesFromMethods.All(a => a.IsPlatformSupported(testTargetPlatform))) { return false; } if (!attributesFromTypes.All(a => a.IsPlatformSupported(testTargetPlatform))) { return false; } return true; } private IEnumerable GetTypesFromPrebuildAttributes(IEnumerable tests) { var allAssemblies = AppDomain.CurrentDomain.GetAssemblies(); allAssemblies = allAssemblies.Where(x => x.GetReferencedAssemblies().Any(z => z.Name == "UnityEditor.TestRunner")).ToArray(); var attributesFromAssemblies = allAssemblies.SelectMany(assembly => assembly.GetCustomAttributes(typeof(T2), true).OfType()); var attributesFromMethods = tests.SelectMany(t => t.Method.GetCustomAttributes(true).Select(attribute => attribute)); var attributesFromTypes = tests.SelectMany(t => t.Method.TypeInfo.GetCustomAttributes(true).Select(attribute => attribute)); var result = new List(); result.AddRange(attributesFromAssemblies); result.AddRange(attributesFromMethods); result.AddRange(attributesFromTypes); return result.Select(m_TypeSelector).Where(type => type != null); } private static IEnumerable GetTypesFromInterface(IEnumerable selectedTests, RuntimePlatform testTargetPlatform) { var typesWithInterfaces = selectedTests.Where(t => typeof(T1).IsAssignableFrom(t.Method.TypeInfo.Type) && IsTestEnabledOnPlatform(t, testTargetPlatform)); return typesWithInterfaces.Select(t => t.Method.TypeInfo.Type); } } }