Newer
Older
Simple-Multiplayer-Unity3D / Multiplayer Project / Library / PackageCache / com.unity.testtools.codecoverage@1.2.5 / Editor / Utils / CoverageUtils.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using UnityEditor.Networking.PlayerConnection;
  7. using UnityEngine;
  8. using UnityEngine.TestTools;
  9. namespace UnityEditor.TestTools.CodeCoverage.Utils
  10. {
  11. internal static class CoverageUtils
  12. {
  13. public static bool IsConnectedToPlayer
  14. {
  15. get
  16. {
  17. return EditorConnection.instance.ConnectedPlayers.Count > 0;
  18. }
  19. }
  20. public static string NormaliseFolderSeparators(string folderPath, bool stripTrailingSlash = false)
  21. {
  22. if (folderPath != null)
  23. {
  24. folderPath = folderPath.Replace('\\', '/');
  25. if (stripTrailingSlash)
  26. {
  27. folderPath = folderPath.TrimEnd('/');
  28. }
  29. }
  30. return folderPath;
  31. }
  32. public static bool EnsureFolderExists(string folderPath)
  33. {
  34. if (string.IsNullOrEmpty(folderPath))
  35. return false;
  36. if (!Directory.Exists(folderPath))
  37. {
  38. try
  39. {
  40. Directory.CreateDirectory(folderPath);
  41. }
  42. catch (Exception)
  43. {
  44. return false;
  45. }
  46. }
  47. return true;
  48. }
  49. public static string GetProjectFolderName()
  50. {
  51. string[] projectPathArray = GetProjectPath().Split('/');
  52. Debug.Assert(projectPathArray.Length > 0);
  53. string folderName = projectPathArray[projectPathArray.Length - 1];
  54. char[] invalidChars = Path.GetInvalidPathChars();
  55. StringBuilder folderNameStringBuilder = new StringBuilder();
  56. foreach (char c in folderName)
  57. {
  58. if (invalidChars.Contains(c))
  59. {
  60. folderNameStringBuilder.Append('_');
  61. }
  62. else
  63. {
  64. folderNameStringBuilder.Append(c);
  65. }
  66. }
  67. return folderNameStringBuilder.ToString();
  68. }
  69. public static string StripAssetsFolderIfExists(string folderPath)
  70. {
  71. if (folderPath != null)
  72. {
  73. string toTrim = "Assets";
  74. folderPath = folderPath.TrimEnd(toTrim.ToCharArray());
  75. }
  76. return folderPath;
  77. }
  78. public static string GetProjectPath()
  79. {
  80. return NormaliseFolderSeparators(StripAssetsFolderIfExists(Application.dataPath), true);
  81. }
  82. public static string GetRootFolderPath(CoverageSettings coverageSettings)
  83. {
  84. string rootFolderPath = string.Empty;
  85. string coverageFolderPath = string.Empty;
  86. if (CommandLineManager.instance.batchmode && !CommandLineManager.instance.useProjectSettings)
  87. {
  88. if (coverageSettings.resultsPathFromCommandLine.Length > 0)
  89. {
  90. coverageFolderPath = coverageSettings.resultsPathFromCommandLine;
  91. EnsureFolderExists(coverageFolderPath);
  92. }
  93. }
  94. else
  95. {
  96. if (CommandLineManager.instance.runFromCommandLine && coverageSettings.resultsPathFromCommandLine.Length > 0)
  97. {
  98. coverageFolderPath = coverageSettings.resultsPathFromCommandLine;
  99. EnsureFolderExists(coverageFolderPath);
  100. }
  101. else
  102. {
  103. coverageFolderPath = CoveragePreferences.instance.GetStringForPaths("Path", string.Empty);
  104. }
  105. }
  106. string projectPath = GetProjectPath();
  107. if (EnsureFolderExists(coverageFolderPath))
  108. {
  109. coverageFolderPath = NormaliseFolderSeparators(coverageFolderPath, true);
  110. // Add 'CodeCoverage' directory if coverageFolderPath is projectPath
  111. if (string.Equals(coverageFolderPath, projectPath, StringComparison.InvariantCultureIgnoreCase))
  112. rootFolderPath = JoinPaths(coverageFolderPath, coverageSettings.rootFolderName);
  113. // else user coverageFolderPath as the root folder
  114. else
  115. rootFolderPath = coverageFolderPath;
  116. }
  117. else
  118. {
  119. // Add 'CodeCoverage' directory to projectPath if coverageFolderPath is not valid
  120. rootFolderPath = JoinPaths(projectPath, coverageSettings.rootFolderName);
  121. }
  122. return rootFolderPath;
  123. }
  124. public static string GetHistoryFolderPath(CoverageSettings coverageSettings)
  125. {
  126. string historyFolderPath = string.Empty;
  127. string rootFolderPath = coverageSettings.rootFolderPath;
  128. if (CommandLineManager.instance.batchmode && !CommandLineManager.instance.useProjectSettings)
  129. {
  130. if (coverageSettings.historyPathFromCommandLine.Length > 0)
  131. {
  132. historyFolderPath = coverageSettings.historyPathFromCommandLine;
  133. EnsureFolderExists(historyFolderPath);
  134. }
  135. }
  136. else
  137. {
  138. if (CommandLineManager.instance.runFromCommandLine && coverageSettings.historyPathFromCommandLine.Length > 0)
  139. {
  140. historyFolderPath = coverageSettings.historyPathFromCommandLine;
  141. EnsureFolderExists(historyFolderPath);
  142. }
  143. else
  144. {
  145. historyFolderPath = CoveragePreferences.instance.GetStringForPaths("HistoryPath", string.Empty);
  146. }
  147. }
  148. bool addHistorySubDir = false;
  149. string projectPath = GetProjectPath();
  150. if (EnsureFolderExists(historyFolderPath))
  151. {
  152. historyFolderPath = NormaliseFolderSeparators(historyFolderPath, true);
  153. // If historyFolderPath == rootFolderPath, add 'Report-history' sub directory in rootFolderPath
  154. if (string.Equals(historyFolderPath, rootFolderPath, StringComparison.InvariantCultureIgnoreCase))
  155. {
  156. addHistorySubDir = true;
  157. }
  158. // If historyFolderPath == projectPath, add 'CodeCoverage' directory to projectPath
  159. // and add 'Report-history' sub directory in rootFolderPath
  160. else if (string.Equals(historyFolderPath, projectPath, StringComparison.InvariantCultureIgnoreCase))
  161. {
  162. rootFolderPath = JoinPaths(projectPath, coverageSettings.rootFolderName);
  163. addHistorySubDir = true;
  164. }
  165. // otherwise keep the original historyFolderPath
  166. }
  167. else
  168. {
  169. // If historyFolderPath is not valid, add 'CodeCoverage' directory to projectPath
  170. // and add 'Report-history' sub directory in rootFolderPath
  171. rootFolderPath = JoinPaths(projectPath, coverageSettings.rootFolderName);
  172. addHistorySubDir = true;
  173. }
  174. if (addHistorySubDir)
  175. {
  176. historyFolderPath = JoinPaths(rootFolderPath, CoverageSettings.ReportHistoryFolderName);
  177. }
  178. return historyFolderPath;
  179. }
  180. public static string JoinPaths(string pathLeft, string pathRight)
  181. {
  182. string[] pathsToJoin = new string[] { pathLeft, pathRight };
  183. return string.Join("/", pathsToJoin);
  184. }
  185. public static int GetNumberOfFilesInFolder(string folderPath, string filePattern, SearchOption searchOption)
  186. {
  187. if (folderPath != null && Directory.Exists(folderPath))
  188. {
  189. string[] files = Directory.GetFiles(folderPath, filePattern, searchOption);
  190. return files.Length;
  191. }
  192. return 0;
  193. }
  194. public static void ClearFolderIfExists(string folderPath, string filePattern)
  195. {
  196. if (folderPath != null && Directory.Exists(folderPath))
  197. {
  198. DirectoryInfo dirInfo = new DirectoryInfo(folderPath);
  199. foreach (FileInfo file in dirInfo.GetFiles(filePattern))
  200. {
  201. try
  202. {
  203. file.Delete();
  204. }
  205. catch (Exception)
  206. {
  207. ResultsLogger.Log(ResultID.Warning_FailedToDeleteFile, file.FullName);
  208. }
  209. }
  210. foreach (DirectoryInfo dir in dirInfo.GetDirectories())
  211. {
  212. try
  213. {
  214. dir.Delete(true);
  215. }
  216. catch (Exception)
  217. {
  218. ResultsLogger.Log(ResultID.Warning_FailedToDeleteDir, dir.FullName);
  219. }
  220. }
  221. }
  222. }
  223. public static bool IsValidFolder(string folderPath)
  224. {
  225. return !string.IsNullOrEmpty(folderPath) && Directory.Exists(folderPath);
  226. }
  227. public static bool IsValidFile(string filePath)
  228. {
  229. return !string.IsNullOrEmpty(filePath) && File.Exists(filePath);
  230. }
  231. private static HashSet<char> regexSpecialChars = new HashSet<char>(new[] { '[', '\\', '^', '$', '.', '|', '?', '*', '+', '(', ')' });
  232. public static string GlobToRegex(string glob, bool startEndConstrains = true)
  233. {
  234. var regex = new StringBuilder();
  235. var characterClass = false;
  236. char prevChar = Char.MinValue;
  237. if (startEndConstrains)
  238. regex.Append("^");
  239. foreach (var c in glob)
  240. {
  241. if (characterClass)
  242. {
  243. if (c == ']')
  244. {
  245. characterClass = false;
  246. }
  247. regex.Append(c);
  248. continue;
  249. }
  250. switch (c)
  251. {
  252. case '*':
  253. if (prevChar == '*')
  254. regex.Append(".*"); //if it's double * pattern then don't stop at folder separator
  255. else
  256. regex.Append("[^\\n\\r/]*"); //else match everything except folder separator (and new line)
  257. break;
  258. case '?':
  259. regex.Append("[^\\n\\r/]");
  260. break;
  261. case '[':
  262. characterClass = true;
  263. regex.Append(c);
  264. break;
  265. default:
  266. if (regexSpecialChars.Contains(c))
  267. {
  268. regex.Append('\\');
  269. }
  270. regex.Append(c);
  271. break;
  272. }
  273. prevChar = c;
  274. }
  275. if (startEndConstrains)
  276. regex.Append("$");
  277. return regex.ToString();
  278. }
  279. public static string[] GetFilteringLogParams(AssemblyFiltering assemblyFiltering, PathFiltering pathFiltering, string[] otherParams = null)
  280. {
  281. string[] logParams = { assemblyFiltering != null && assemblyFiltering.includedAssemblies.Length > 0 ? assemblyFiltering.includedAssemblies : "<Not specified>",
  282. assemblyFiltering != null && assemblyFiltering.excludedAssemblies.Length > 0 ? assemblyFiltering.excludedAssemblies : "<Not specified>",
  283. pathFiltering != null && pathFiltering.includedPaths.Length > 0 ? pathFiltering.includedPaths : "<Not specified>",
  284. pathFiltering != null && pathFiltering.excludedPaths.Length > 0 ? pathFiltering.excludedPaths : "<Not specified>" };
  285. if (otherParams != null && otherParams.Length > 0)
  286. logParams = otherParams.Concat(logParams).ToArray();
  287. return logParams;
  288. }
  289. [ExcludeFromCoverage]
  290. public static string BrowseForDir(string directory, string title)
  291. {
  292. if (string.IsNullOrEmpty(directory))
  293. {
  294. string variable = "ProgramFiles";
  295. #if UNITY_EDITOR_OSX
  296. variable = "HOME";
  297. #endif
  298. string candidateDirectory = Environment.GetEnvironmentVariable(variable);
  299. if (IsValidFolder(candidateDirectory))
  300. directory = candidateDirectory;
  301. }
  302. directory = EditorUtility.OpenFolderPanel(title, directory, string.Empty);
  303. EditorWindow.FocusWindowIfItsOpen(typeof(CodeCoverageWindow));
  304. if (!IsValidFolder(directory))
  305. return string.Empty;
  306. return directory;
  307. }
  308. [ExcludeFromCoverage]
  309. public static string BrowseForFile(string directory, string title)
  310. {
  311. if (string.IsNullOrEmpty(directory))
  312. {
  313. string variable = "ProgramFiles";
  314. #if UNITY_EDITOR_OSX
  315. variable = "HOME";
  316. #endif
  317. string candidateDirectory = Environment.GetEnvironmentVariable(variable);
  318. if (IsValidFolder(candidateDirectory))
  319. directory = candidateDirectory;
  320. }
  321. string file = EditorUtility.OpenFilePanel(title, directory, "cs");
  322. EditorWindow.FocusWindowIfItsOpen(typeof(CodeCoverageWindow));
  323. if (!IsValidFile(file))
  324. return string.Empty;
  325. return file;
  326. }
  327. }
  328. }