A game about forced loneliness, made by TACStudios
1using System;
2using System.Linq;
3using UnityEditor.Scripting.ScriptCompilation;
4
5namespace UnityEditor.TestTools.TestRunner.GUI.TestAssets
6{
7 /// <inheritdoc />
8 internal class FolderPathTestCompilationContextProvider : IFolderPathTestCompilationContextProvider
9 {
10 internal const string nUnitLibraryFilename = "nunit.framework.dll";
11
12 private static ICustomScriptAssemblyMappingFinder s_CustomScriptAssemblyMappingFinder;
13
14 internal static ICustomScriptAssemblyMappingFinder CustomScriptAssemblyMappingFinder
15 {
16 private get => s_CustomScriptAssemblyMappingFinder ?? (s_CustomScriptAssemblyMappingFinder = new CustomScriptAssemblyMappingFinder());
17 set => s_CustomScriptAssemblyMappingFinder = value;
18 }
19
20 /// <summary>
21 /// Checks if the provided folder path belongs to a Custom Test Assembly.
22 /// A Custom Test Assembly is defined by a valid reference to the precompiled NUnit library.
23 /// </summary>
24 /// <param name="folderPath">The folder path to check.</param>
25 /// <returns>True if a custom test assembly associated with the provided folder can be found; false otherwise.</returns>
26 /// <exception cref="ArgumentNullException">The <paramref name="folderPath" /> string argument is null.</exception>
27 public bool FolderPathBelongsToCustomTestAssembly(string folderPath)
28 {
29 if (folderPath == null)
30 {
31 throw new ArgumentNullException(nameof(folderPath));
32 }
33
34 var customScriptAssembly = CustomScriptAssemblyMappingFinder.FindCustomScriptAssemblyFromFolderPath(folderPath);
35 var assemblyIsCustomTestAssembly = customScriptAssembly != null
36 && customScriptAssembly.HasPrecompiledReference(nUnitLibraryFilename);
37 return assemblyIsCustomTestAssembly;
38 }
39
40 /// <summary>
41 /// Checks if the provided folder path belongs to an assembly capable of compiling Test Scripts.
42 /// Unless the <see cref="PlayerSettings.playModeTestRunnerEnabled" /> setting is enabled,
43 /// a Test Script can only be compiled in a Custom Test Assembly
44 /// or an (implicit or explicit) <see cref="AssemblyFlags.EditorOnly" /> assembly.
45 /// </summary>
46 /// <param name="folderPath">The folder path to check.</param>
47 /// <returns>True if Test Scripts can be successfully compiled when added to this folder path; false otherwise.</returns>
48 /// <exception cref="ArgumentNullException">The <paramref name="folderPath" /> string argument is null.</exception>
49 public bool TestScriptWillCompileInFolderPath(string folderPath)
50 {
51 if (folderPath == null)
52 {
53 throw new ArgumentNullException(nameof(folderPath));
54 }
55
56 if (PlayerSettings.playModeTestRunnerEnabled)
57 {
58 return true;
59 }
60
61 var customScriptAssembly = CustomScriptAssemblyMappingFinder.FindCustomScriptAssemblyFromFolderPath(folderPath);
62 if (customScriptAssembly != null)
63 {
64 var assemblyCanCompileTestScripts = customScriptAssembly.HasPrecompiledReference(nUnitLibraryFilename)
65 || customScriptAssembly.HasAssemblyFlag(AssemblyFlags.EditorOnly);
66 return assemblyCanCompileTestScripts;
67 }
68
69 var isImplicitEditorAssembly = FolderPathBelongsToImplicitEditorAssembly(folderPath);
70 return isImplicitEditorAssembly;
71 }
72
73 /// <summary>
74 /// Checks if the provided folder path is a special editor path that belongs to an implicit editor assembly.
75 /// </summary>
76 /// <param name="folderPath">The folder path to check.</param>
77 /// <returns>True if the folder path belongs to an implicit editor assembly; false otherwise.</returns>
78 /// <exception cref="ArgumentNullException">The <paramref name="folderPath" /> string argument is null.</exception>
79 internal static bool FolderPathBelongsToImplicitEditorAssembly(string folderPath)
80 {
81 if (folderPath == null)
82 {
83 throw new ArgumentNullException(nameof(folderPath));
84 }
85
86 const char unityPathSeparator = '/';
87 var unityFormatPath = folderPath.Replace('\\', unityPathSeparator);
88 var folderComponents = unityFormatPath.Split(unityPathSeparator);
89 var folderComponentsIncludeEditorFolder = folderComponents.Any(n => n.ToLower().Equals("editor"));
90 return folderComponentsIncludeEditorFolder;
91 }
92 }
93}