A game about forced loneliness, made by TACStudios
at master 5.5 kB view raw
1using System; 2using System.Collections.Generic; 3using System.IO; 4using System.Linq; 5using System.Reflection; 6using UnityEditor; 7using UnityEditor.Scripting.ScriptCompilation; 8using UnityEngine.TestTools; 9using UnityEngine.TestTools.Utils; 10 11namespace UnityEditor.TestTools.TestRunner 12{ 13 internal class EditorLoadedTestAssemblyProvider : IEditorLoadedTestAssemblyProvider 14 { 15 private const string k_NunitAssemblyName = "nunit.framework"; 16 private const string k_TestRunnerAssemblyName = "UnityEngine.TestRunner"; 17 internal const string k_PerformanceTestingAssemblyName = "Unity.PerformanceTesting"; 18 19 private readonly IEditorAssembliesProxy m_EditorAssembliesProxy; 20 private readonly ScriptAssembly[] m_AllEditorScriptAssemblies; 21 private readonly PrecompiledAssembly[] m_AllPrecompiledAssemblies; 22 23 public EditorLoadedTestAssemblyProvider(IEditorCompilationInterfaceProxy compilationInterfaceProxy, IEditorAssembliesProxy editorAssembliesProxy) 24 { 25 m_EditorAssembliesProxy = editorAssembliesProxy; 26 m_AllEditorScriptAssemblies = compilationInterfaceProxy.GetAllEditorScriptAssemblies(); 27 m_AllPrecompiledAssemblies = compilationInterfaceProxy.GetAllPrecompiledAssemblies(); 28 } 29 30 public List<IAssemblyWrapper> GetAssembliesGroupedByType(TestPlatform mode) 31 { 32 var assemblies = GetAssembliesGroupedByTypeAsync(mode); 33 while (assemblies.MoveNext()) 34 { 35 } 36 37 return assemblies.Current.Where(pair => mode.IsFlagIncluded(pair.Key)).SelectMany(pair => pair.Value).ToList(); 38 } 39 40 public IEnumerator<IDictionary<TestPlatform, List<IAssemblyWrapper>>> GetAssembliesGroupedByTypeAsync(TestPlatform mode) 41 { 42 IAssemblyWrapper[] loadedAssemblies = m_EditorAssembliesProxy.loadedAssemblies; 43 44 IDictionary<TestPlatform, List<IAssemblyWrapper>> result = new Dictionary<TestPlatform, List<IAssemblyWrapper>> 45 { 46 {TestPlatform.EditMode, new List<IAssemblyWrapper>() }, 47 {TestPlatform.PlayMode, new List<IAssemblyWrapper>() } 48 }; 49 var filteredAssemblies = FilterAssembliesWithTestReference(loadedAssemblies); 50 51 foreach (var loadedAssembly in filteredAssemblies) 52 { 53 var assemblyName = new FileInfo(loadedAssembly.Location).Name; 54 var scriptAssemblies = m_AllEditorScriptAssemblies.Where(x => x.Filename == assemblyName).ToList(); 55 var precompiledAssemblies = m_AllPrecompiledAssemblies.Where(x => new FileInfo(x.Path).Name == assemblyName).ToList(); 56 if (scriptAssemblies.Count < 1 && precompiledAssemblies.Count < 1) 57 { 58 continue; 59 } 60 61 var assemblyFlags = scriptAssemblies.Any() ? scriptAssemblies.Single().Flags : precompiledAssemblies.Single().Flags; 62 var assemblyType = (assemblyFlags & AssemblyFlags.EditorOnly) == AssemblyFlags.EditorOnly ? TestPlatform.EditMode : TestPlatform.PlayMode; 63 result[assemblyType].Add(loadedAssembly); 64 yield return null; 65 } 66 67 yield return result; 68 } 69 70 private IAssemblyWrapper[] FilterAssembliesWithTestReference(IAssemblyWrapper[] loadedAssemblies) 71 { 72 var filteredResults = new Dictionary<IAssemblyWrapper, bool>(); 73 foreach (var assembly in loadedAssemblies) 74 { 75 FilterAssemblyForTestReference(assembly, loadedAssemblies, filteredResults, new Dictionary<IAssemblyWrapper, bool>()); 76 } 77 78 return filteredResults.Where(pair => pair.Value).Select(pair => pair.Key).ToArray(); 79 } 80 81 private void FilterAssemblyForTestReference(IAssemblyWrapper assemblyToFilter, IAssemblyWrapper[] loadedAssemblies, 82 IDictionary<IAssemblyWrapper, bool> filterResults, IDictionary<IAssemblyWrapper, bool> resultsAlreadyAnalyzed) 83 { 84 if(resultsAlreadyAnalyzed.ContainsKey(assemblyToFilter)) 85 { 86 return; 87 } 88 89 resultsAlreadyAnalyzed[assemblyToFilter] = true; 90 91 var references = assemblyToFilter.GetReferencedAssemblies(); 92 if (references.Any(IsTestReference)) 93 { 94 filterResults[assemblyToFilter] = true; 95 return; 96 } 97 98 foreach (var reference in references) 99 { 100 var referencedAssembly = loadedAssemblies.FirstOrDefault(a => a.Name.Name == reference.Name); 101 if (referencedAssembly == null) 102 { 103 continue; 104 } 105 106 FilterAssemblyForTestReference(referencedAssembly, loadedAssemblies, filterResults, resultsAlreadyAnalyzed); 107 108 if (filterResults.ContainsKey(referencedAssembly) && filterResults[referencedAssembly]) 109 { 110 filterResults[assemblyToFilter] = true; 111 return; 112 } 113 } 114 115 filterResults[assemblyToFilter] = false; 116 } 117 118 private static bool IsTestReference(AssemblyName assemblyName) 119 { 120 return assemblyName.Name == k_NunitAssemblyName || 121 assemblyName.Name == k_TestRunnerAssemblyName || 122 assemblyName.Name == k_PerformanceTestingAssemblyName; 123 } 124 } 125}