EditorLoadedTestAssemblyProvider.cs 5.1 KB

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