using System;
using System.Linq;
using UnityEditor.Scripting.ScriptCompilation;
namespace UnityEditor.TestTools.TestRunner.GUI.TestAssets
{
///
internal class FolderPathTestCompilationContextProvider : IFolderPathTestCompilationContextProvider
{
internal const string nUnitLibraryFilename = "nunit.framework.dll";
private static ICustomScriptAssemblyMappingFinder s_CustomScriptAssemblyMappingFinder;
internal static ICustomScriptAssemblyMappingFinder CustomScriptAssemblyMappingFinder
{
private get => s_CustomScriptAssemblyMappingFinder ?? (s_CustomScriptAssemblyMappingFinder = new CustomScriptAssemblyMappingFinder());
set => s_CustomScriptAssemblyMappingFinder = value;
}
///
/// Checks if the provided folder path belongs to a Custom Test Assembly.
/// A Custom Test Assembly is defined by a valid reference to the precompiled NUnit library.
///
/// The folder path to check.
/// True if a custom test assembly associated with the provided folder can be found; false otherwise.
/// The string argument is null.
public bool FolderPathBelongsToCustomTestAssembly(string folderPath)
{
if (folderPath == null)
{
throw new ArgumentNullException(nameof(folderPath));
}
var customScriptAssembly = CustomScriptAssemblyMappingFinder.FindCustomScriptAssemblyFromFolderPath(folderPath);
var assemblyIsCustomTestAssembly = customScriptAssembly != null
&& customScriptAssembly.HasPrecompiledReference(nUnitLibraryFilename);
return assemblyIsCustomTestAssembly;
}
///
/// Checks if the provided folder path belongs to an assembly capable of compiling Test Scripts.
/// Unless the setting is enabled,
/// a Test Script can only be compiled in a Custom Test Assembly
/// or an (implicit or explicit) assembly.
///
/// The folder path to check.
/// True if Test Scripts can be successfully compiled when added to this folder path; false otherwise.
/// The string argument is null.
public bool TestScriptWillCompileInFolderPath(string folderPath)
{
if (folderPath == null)
{
throw new ArgumentNullException(nameof(folderPath));
}
if (PlayerSettings.playModeTestRunnerEnabled)
{
return true;
}
var customScriptAssembly = CustomScriptAssemblyMappingFinder.FindCustomScriptAssemblyFromFolderPath(folderPath);
if (customScriptAssembly != null)
{
var assemblyCanCompileTestScripts = customScriptAssembly.HasPrecompiledReference(nUnitLibraryFilename)
|| customScriptAssembly.HasAssemblyFlag(AssemblyFlags.EditorOnly);
return assemblyCanCompileTestScripts;
}
var isImplicitEditorAssembly = FolderPathBelongsToImplicitEditorAssembly(folderPath);
return isImplicitEditorAssembly;
}
///
/// Checks if the provided folder path is a special editor path that belongs to an implicit editor assembly.
///
/// The folder path to check.
/// True if the folder path belongs to an implicit editor assembly; false otherwise.
/// The string argument is null.
internal static bool FolderPathBelongsToImplicitEditorAssembly(string folderPath)
{
if (folderPath == null)
{
throw new ArgumentNullException(nameof(folderPath));
}
const char unityPathSeparator = '/';
var unityFormatPath = folderPath.Replace('\\', unityPathSeparator);
var folderComponents = unityFormatPath.Split(unityPathSeparator);
var folderComponentsIncludeEditorFolder = folderComponents.Any(n => n.ToLower().Equals("editor"));
return folderComponentsIncludeEditorFolder;
}
}
}