Unity-jump-proj
This commit is contained in:
@ -0,0 +1,1096 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEditor.TestTools.CodeCoverage.Utils;
|
||||
using UnityEditor.TestTools.TestRunner;
|
||||
using UnityEditor.TestTools.CodeCoverage.Analytics;
|
||||
using UnityEditorInternal;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace UnityEditor.TestTools.CodeCoverage
|
||||
{
|
||||
[ExcludeFromCoverage]
|
||||
internal class CodeCoverageWindow : EditorWindow
|
||||
{
|
||||
private bool m_EnableCodeCoverage;
|
||||
#if !UNITY_2019_3_OR_NEWER
|
||||
private bool m_HasLatestScriptingRuntime;
|
||||
#endif
|
||||
private string m_CodeCoveragePath;
|
||||
private string m_CodeCoverageHistoryPath;
|
||||
private FolderDropDownMenu m_ResultsFolderDropDownMenu;
|
||||
private FolderDropDownMenu m_HistoryFolderDropDownMenu;
|
||||
private CoverageFormat m_CodeCoverageFormat;
|
||||
private bool m_IncludeHistoryInReport;
|
||||
private string m_AssembliesToInclude;
|
||||
private int m_AssembliesToIncludeLength;
|
||||
private string m_PathsToInclude;
|
||||
private string m_PathsToExclude;
|
||||
private PathToAddDropDownMenu m_AddPathToIncludeDropDownMenu;
|
||||
private PathToAddDropDownMenu m_AddPathToExcludeDropDownMenu;
|
||||
|
||||
private CoverageReportGenerator m_ReportGenerator;
|
||||
private bool m_GenerateHTMLReport;
|
||||
private bool m_GenerateAdditionalReports;
|
||||
private bool m_GenerateBadge;
|
||||
private bool m_GenerateAdditionalMetrics;
|
||||
private bool m_GenerateTestReferences;
|
||||
private bool m_AutoGenerateReport;
|
||||
private bool m_OpenReportWhenGenerated;
|
||||
|
||||
private CoverageSettings m_CoverageSettings;
|
||||
|
||||
private static readonly Vector2 s_WindowMinSizeNormal = new Vector2(445, 65);
|
||||
|
||||
private bool m_LoseFocus = false;
|
||||
|
||||
private bool m_GenerateReport = false;
|
||||
private bool m_StopRecording = false;
|
||||
|
||||
private ReorderableList m_PathsToIncludeReorderableList;
|
||||
private ReorderableList m_PathsToExcludeReorderableList;
|
||||
private List<string> m_PathsToIncludeList;
|
||||
private List<string> m_PathsToExcludeList;
|
||||
|
||||
private Vector2 m_WindowScrollPosition = new Vector2(0, 0);
|
||||
|
||||
private readonly string kLatestScriptingRuntimeMessage = L10n.Tr("Code Coverage requires the latest Scripting Runtime Version (.NET 4.x). You can set this in the Player Settings.");
|
||||
private readonly string kCodeCoverageDisabledNoRestartMessage = L10n.Tr("Code Coverage should be enabled in order to generate Coverage data and reports.\nNote that Code Coverage can affect the Editor performance.");
|
||||
private readonly string kEnablingCodeCoverageMessage = L10n.Tr("Enabling Code Coverage will not take effect until Unity is restarted.");
|
||||
private readonly string kDisablingCodeCoverageMessage = L10n.Tr("Disabling Code Coverage will not take effect until Unity is restarted.");
|
||||
private readonly string kCodeOptimizationMessage = L10n.Tr("Code Coverage requires Code Optimization to be set to debug mode in order to obtain accurate coverage information.");
|
||||
private readonly string kBurstCompilationOnMessage = L10n.Tr("Code Coverage requires Burst Compilation to be disabled in order to obtain accurate coverage information.");
|
||||
private readonly string kSelectCoverageDirectoryMessage = L10n.Tr("Select the Coverage results directory");
|
||||
private readonly string kSelectCoverageHistoryDirectoryMessage = L10n.Tr("Select the Coverage Report history directory");
|
||||
private readonly string kClearDataMessage = L10n.Tr("Are you sure you would like to clear the Coverage results from previous test runs or from previous Coverage Recording sessions? Note that you cannot undo this action.");
|
||||
private readonly string kClearHistoryMessage = L10n.Tr("Are you sure you would like to clear the coverage report history? Note that you cannot undo this action.");
|
||||
private readonly string kNoAssembliesSelectedMessage = L10n.Tr("Make sure you have included at least one assembly.");
|
||||
private readonly string kSettingOverriddenMessage = L10n.Tr("{0} is overridden by the {1} command line argument.");
|
||||
private readonly string kSettingsOverriddenMessage = L10n.Tr("{0} are overridden by the {1} command line argument.");
|
||||
|
||||
private readonly string[] kVerbosityLevelLabels = new string[]
|
||||
{
|
||||
"Verbose",
|
||||
"Info",
|
||||
"Warning",
|
||||
"Error",
|
||||
"Off"
|
||||
};
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (m_GenerateReport)
|
||||
{
|
||||
// Start the timer for analytics on 'Generate from Last' (report only)
|
||||
CoverageAnalytics.instance.StartTimer();
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.actionID = ActionID.ReportOnly;
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.generateFromLast = true;
|
||||
|
||||
m_ReportGenerator.Generate(m_CoverageSettings);
|
||||
m_GenerateReport = false;
|
||||
}
|
||||
|
||||
if (m_StopRecording)
|
||||
{
|
||||
CodeCoverage.StopRecordingInternal();
|
||||
m_StopRecording = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void LoseFocus()
|
||||
{
|
||||
m_LoseFocus = true;
|
||||
}
|
||||
|
||||
public string AssembliesToInclude
|
||||
{
|
||||
set
|
||||
{
|
||||
m_AssembliesToInclude = value.TrimStart(',').TrimEnd(',');
|
||||
m_AssembliesToIncludeLength = m_AssembliesToInclude.Length;
|
||||
CoveragePreferences.instance.SetString("IncludeAssemblies", m_AssembliesToInclude);
|
||||
}
|
||||
}
|
||||
|
||||
public string PathsToInclude
|
||||
{
|
||||
set
|
||||
{
|
||||
m_PathsToInclude = value.TrimStart(',').TrimEnd(',');
|
||||
m_PathsToInclude = CoverageUtils.NormaliseFolderSeparators(m_PathsToInclude, false);
|
||||
CoveragePreferences.instance.SetStringForPaths("PathsToInclude", m_PathsToInclude);
|
||||
|
||||
m_PathsToIncludeList = m_PathsToInclude.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
m_PathsToIncludeReorderableList.list = m_PathsToIncludeList;
|
||||
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.updateIncludedPaths = true;
|
||||
}
|
||||
}
|
||||
|
||||
public string PathsToExclude
|
||||
{
|
||||
set
|
||||
{
|
||||
m_PathsToExclude = value.TrimStart(',').TrimEnd(',');
|
||||
m_PathsToExclude = CoverageUtils.NormaliseFolderSeparators(m_PathsToExclude, false);
|
||||
CoveragePreferences.instance.SetStringForPaths("PathsToExclude", m_PathsToExclude);
|
||||
|
||||
m_PathsToExcludeList = new List<string>(m_PathsToExclude.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
|
||||
m_PathsToExcludeReorderableList.list = m_PathsToExcludeList;
|
||||
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.updateExcludedPaths = true;
|
||||
}
|
||||
}
|
||||
|
||||
static class Styles
|
||||
{
|
||||
static bool s_Initialized;
|
||||
|
||||
public static readonly GUIContent SwitchToDebugCodeOptimizationButton = EditorGUIUtility.TrTextContent("Switch to debug mode");
|
||||
public static readonly GUIContent SwitchBurstCompilationOffButton = EditorGUIUtility.TrTextContent("Disable Burst Compilation");
|
||||
public static readonly GUIContent CodeCoverageResultsLocationLabel = EditorGUIUtility.TrTextContent("Results Location", "Specify the folder where the coverage results and report are saved to. The default location is the Project's folder.\n\nClick the dropdown to open the containing folder, change the location or reset to the default location.");
|
||||
public static readonly GUIContent CodeCoverageHistoryLocationLabel = EditorGUIUtility.TrTextContent("Report History Location", "Specify the folder where the coverage report history is saved to. The default location is the Project's folder.\n\nClick the dropdown to open the containing folder, change the location or reset to the default location.");
|
||||
public static readonly GUIContent ResultsFolderButton = EditorGUIUtility.TrIconContent(EditorIcons.FolderOpened, "Specify the folder where the coverage results and report are saved to.\n\nClick this to open the containing folder, change the location or reset to the default location.");
|
||||
public static readonly GUIContent HistoryFolderButton = EditorGUIUtility.TrIconContent(EditorIcons.FolderOpened, "Specify the folder where the coverage report history is saved to.\n\nClick this to open the containing folder, change the location or reset to the default location.");
|
||||
public static readonly GUIContent CoverageSettingsLabel = EditorGUIUtility.TrTextContent("Settings");
|
||||
public static readonly GUIContent CoverageReportOptionsLabel = EditorGUIUtility.TrTextContent("Report Options");
|
||||
public static readonly GUIContent EnableCodeCoverageLabel = EditorGUIUtility.TrTextContent("Enable Code Coverage", "Check this to enable Code Coverage. This is required in order to generate Coverage data and reports. Note that Code Coverage can affect the Editor performance.");
|
||||
public static readonly GUIContent CodeCoverageFormat = EditorGUIUtility.TrTextContent("Coverage Format", "The Code Coverage format used when saving the results.");
|
||||
public static readonly GUIContent GenerateAdditionalMetricsLabel = EditorGUIUtility.TrTextContent("Additional Metrics", "Check this to generate and include additional metrics in the HTML report. These currently include Cyclomatic Complexity and Crap Score calculations for each method.");
|
||||
public static readonly GUIContent CoverageHistoryLabel = EditorGUIUtility.TrTextContent("Report History", "Check this to generate and include the coverage history in the HTML report.");
|
||||
public static readonly GUIContent AssembliesToIncludeLabel = EditorGUIUtility.TrTextContent("Included Assemblies", "Specify the assemblies that will be included in the coverage results.\n\nClick the dropdown to view and select or deselect the assemblies.");
|
||||
public static readonly GUIContent AssembliesToIncludeDropdownLabel = EditorGUIUtility.TrTextContent("<this will contain a list of the assemblies>", "<this will contain a list of the assemblies>");
|
||||
public static readonly GUIContent AssembliesToIncludeEmptyDropdownLabel = EditorGUIUtility.TrTextContent(" Select", "Click this to view and select or deselect the assemblies.");
|
||||
public static readonly GUIContent PathsToIncludeLabel = EditorGUIUtility.TrTextContent("Included Paths", "Click Add (+) to specify individual folders and files to include in coverage results. You can use globbing to filter the paths. If the list is empty, Unity includes all files in the Included Assemblies.\n\nTo remove an individual list entry, select the entry and then click Remove (-).");
|
||||
public static readonly GUIContent PathsToExcludeLabel = EditorGUIUtility.TrTextContent("Excluded Paths", "Click Add (+) to specify individual folders and files to exclude from coverage results. You can use globbing to filter the paths.\n\nTo remove an individual list entry, select the entry and then click Remove (-).");
|
||||
public static readonly GUIContent VerbosityLabel = EditorGUIUtility.TrTextContent("Log Verbosity Level", "Click the dropdown to set the verbosity level for the editor and console logs.\n\nVerbose: All logs\nInfo: Logs, Warnings and Errors\nWarning: Warnings and Errors\nError: Only Errors\nOff: No logs");
|
||||
public static readonly GUIContent GenerateHTMLReportLabel = EditorGUIUtility.TrTextContent("HTML Report", "Check this to generate an HTML report.");
|
||||
public static readonly GUIContent GenerateAdditionalReportsLabel = EditorGUIUtility.TrTextContent("Additional Reports", "Check this to generate SonarQube, Cobertura and LCOV reports.");
|
||||
public static readonly GUIContent GenerateBadgeReportLabel = EditorGUIUtility.TrTextContent("Summary Badges", "Check this to generate coverage summary badges in SVG and PNG format.");
|
||||
public static readonly GUIContent GenerateTestRunnerReferencesLabel = EditorGUIUtility.TrTextContent("Test Runner References", "Check this to include test references to the generated coverage results and enable the 'Coverage by test methods' section in the HTML report, allowing you to see how each test contributes to the overall coverage.");
|
||||
public static readonly GUIContent AutoGenerateReportLabel = EditorGUIUtility.TrTextContent("Auto Generate Report", "Check this to generate the report automatically after the Test Runner has finished running the tests or the Coverage Recording session has completed.");
|
||||
public static readonly GUIContent OpenReportWhenGeneratedLabel = EditorGUIUtility.TrTextContent("Auto Open Report", "Check this to open the coverage report automatically after it has been generated.");
|
||||
public static readonly GUIContent GenerateReportButtonLabel = EditorGUIUtility.TrTextContent("Generate Report", "Generates a coverage report from the last set of tests that were run in the Test Runner or from the last Coverage Recording session.");
|
||||
public static readonly GUIContent ClearCoverageButtonLabel = EditorGUIUtility.TrTextContent("Clear Results", "Clears the Coverage results from previous test runs or from previous Coverage Recording sessions, for the current project.");
|
||||
public static readonly GUIContent ClearHistoryButtonLabel = EditorGUIUtility.TrTextContent("Clear History", "Clears the coverage report history.");
|
||||
public static readonly GUIContent StartRecordingButton = EditorGUIUtility.TrIconContent("Record Off", "Record coverage data.");
|
||||
public static readonly GUIContent StopRecordingButton = EditorGUIUtility.TrIconContent("Record On", "Stop recording coverage data.");
|
||||
public static readonly GUIContent PauseRecordingButton = EditorGUIUtility.TrIconContent("PauseButton", "Pause recording coverage data.");
|
||||
public static readonly GUIContent UnpauseRecordingButton = EditorGUIUtility.TrIconContent("PlayButton", "Resume recording coverage data.");
|
||||
public static readonly GUIContent HelpIcon = EditorGUIUtility.TrIconContent("_Help", "Open Reference for Code Coverage.");
|
||||
|
||||
public static readonly GUIStyle settings = new GUIStyle();
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (s_Initialized)
|
||||
return;
|
||||
|
||||
s_Initialized = true;
|
||||
|
||||
settings.margin = new RectOffset(8, 4, 10, 4);
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Window/Analysis/Code Coverage")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
#if TEST_FRAMEWORK_1_1_18_OR_NEWER
|
||||
TestRunnerWindow.ShowWindow();
|
||||
#else
|
||||
TestRunnerWindow.ShowPlaymodeTestsRunnerWindowCodeBased();
|
||||
#endif
|
||||
CodeCoverageWindow window = GetWindow<CodeCoverageWindow>(typeof(TestRunnerWindow));
|
||||
window.Show();
|
||||
}
|
||||
|
||||
private void OnFocus()
|
||||
{
|
||||
Repaint();
|
||||
}
|
||||
|
||||
private void ResetWindow()
|
||||
{
|
||||
CodeCoverageWindow window = GetWindow<CodeCoverageWindow>(typeof(TestRunnerWindow));
|
||||
window.minSize = s_WindowMinSizeNormal;
|
||||
window.titleContent = EditorGUIUtility.TrTextContentWithIcon(L10n.Tr("Code Coverage"), EditorIcons.CoverageWindow);
|
||||
}
|
||||
|
||||
private void InitCodeCoverageWindow()
|
||||
{
|
||||
m_CoverageSettings = new CoverageSettings()
|
||||
{
|
||||
resultsPathFromCommandLine = CommandLineManager.instance.coverageResultsPath,
|
||||
historyPathFromCommandLine = CommandLineManager.instance.coverageHistoryPath
|
||||
};
|
||||
|
||||
m_CodeCoveragePath = CoveragePreferences.instance.GetStringForPaths("Path", string.Empty);
|
||||
m_CodeCoverageHistoryPath = CoveragePreferences.instance.GetStringForPaths("HistoryPath", string.Empty);
|
||||
m_CodeCoverageFormat = (CoverageFormat)CoveragePreferences.instance.GetInt("Format", 0);
|
||||
m_GenerateAdditionalMetrics = CoveragePreferences.instance.GetBool("GenerateAdditionalMetrics", false);
|
||||
m_GenerateTestReferences = CoveragePreferences.instance.GetBool("GenerateTestReferences", false);
|
||||
m_IncludeHistoryInReport = CoveragePreferences.instance.GetBool("IncludeHistoryInReport", true);
|
||||
m_AssembliesToInclude = GetIncludedAssemblies();
|
||||
m_AssembliesToIncludeLength = m_AssembliesToInclude.Length;
|
||||
m_PathsToInclude = CoveragePreferences.instance.GetStringForPaths("PathsToInclude", string.Empty);
|
||||
m_PathsToExclude = CoveragePreferences.instance.GetStringForPaths("PathsToExclude", string.Empty);
|
||||
CodeCoverage.VerbosityLevel = (LogVerbosityLevel)CoveragePreferences.instance.GetInt("VerbosityLevel", (int)LogVerbosityLevel.Info);
|
||||
m_ReportGenerator = new CoverageReportGenerator();
|
||||
m_GenerateHTMLReport = CoveragePreferences.instance.GetBool("GenerateHTMLReport", true);
|
||||
m_GenerateAdditionalReports = CoveragePreferences.instance.GetBool("GenerateAdditionalReports", false);
|
||||
m_GenerateBadge = CoveragePreferences.instance.GetBool("GenerateBadge", true);
|
||||
m_AutoGenerateReport = CoveragePreferences.instance.GetBool("AutoGenerateReport", true);
|
||||
m_OpenReportWhenGenerated = CoveragePreferences.instance.GetBool("OpenReportWhenGenerated", true);
|
||||
|
||||
m_ResultsFolderDropDownMenu = new FolderDropDownMenu(this, FolderType.Results);
|
||||
m_HistoryFolderDropDownMenu = new FolderDropDownMenu(this, FolderType.History);
|
||||
m_AddPathToIncludeDropDownMenu = new PathToAddDropDownMenu(this, PathFilterType.Include);
|
||||
m_AddPathToExcludeDropDownMenu = new PathToAddDropDownMenu(this, PathFilterType.Exclude);
|
||||
m_PathsToIncludeList = new List<string>(m_PathsToInclude.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
|
||||
m_PathsToIncludeReorderableList = new ReorderableList(m_PathsToIncludeList, typeof(String), true, false, true, true);
|
||||
m_PathsToIncludeReorderableList.headerHeight = 0;
|
||||
m_PathsToExcludeList = new List<string>(m_PathsToExclude.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
|
||||
m_PathsToExcludeReorderableList = new ReorderableList(m_PathsToExcludeList, typeof(String), true, false, true, true);
|
||||
m_PathsToExcludeReorderableList.headerHeight = 0;
|
||||
|
||||
UpdateCoverageSettings();
|
||||
|
||||
m_GenerateReport = false;
|
||||
m_StopRecording = false;
|
||||
|
||||
ResetWindow();
|
||||
}
|
||||
|
||||
void UpdateCoverageSettings()
|
||||
{
|
||||
if (m_CoverageSettings != null)
|
||||
{
|
||||
m_CoverageSettings.rootFolderPath = CoverageUtils.GetRootFolderPath(m_CoverageSettings);
|
||||
m_CoverageSettings.historyFolderPath = CoverageUtils.GetHistoryFolderPath(m_CoverageSettings);
|
||||
|
||||
if (m_CodeCoverageFormat == CoverageFormat.OpenCover)
|
||||
{
|
||||
m_CoverageSettings.resultsFolderSuffix = "-opencov";
|
||||
string folderName = CoverageUtils.GetProjectFolderName();
|
||||
string resultsRootDirectoryName = string.Concat(folderName, m_CoverageSettings.resultsFolderSuffix);
|
||||
m_CoverageSettings.resultsRootFolderPath = CoverageUtils.NormaliseFolderSeparators(CoverageUtils.JoinPaths(m_CoverageSettings.rootFolderPath, resultsRootDirectoryName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GetIncludedAssemblies()
|
||||
{
|
||||
string assembliesFromPreferences = CoveragePreferences.instance.GetString("IncludeAssemblies", AssemblyFiltering.GetUserOnlyAssembliesString());
|
||||
string filteredAssemblies = AssemblyFiltering.RemoveAssembliesThatNoLongerExist(assembliesFromPreferences);
|
||||
CoveragePreferences.instance.SetString("IncludeAssemblies", filteredAssemblies);
|
||||
|
||||
return filteredAssemblies;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
InitCodeCoverageWindow();
|
||||
}
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
Styles.Init();
|
||||
|
||||
EditorGUIUtility.labelWidth = 190f;
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
float toolbarHeight = 0;
|
||||
#if !UNITY_2019_3_OR_NEWER
|
||||
using (new EditorGUI.DisabledScope(!m_HasLatestScriptingRuntime))
|
||||
#endif
|
||||
{
|
||||
toolbarHeight = DrawToolbar();
|
||||
}
|
||||
|
||||
// Window scrollbar
|
||||
float maxHeight = Mathf.Max(position.height, 0) - toolbarHeight;
|
||||
m_WindowScrollPosition = EditorGUILayout.BeginScrollView(m_WindowScrollPosition, GUILayout.Height(maxHeight));
|
||||
|
||||
GUILayout.BeginVertical(Styles.settings);
|
||||
|
||||
#if !UNITY_2019_3_OR_NEWER
|
||||
CheckScriptingRuntimeVersion();
|
||||
#endif
|
||||
CheckCoverageEnabled();
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
CheckCodeOptimization();
|
||||
#endif
|
||||
#if BURST_INSTALLED
|
||||
CheckBurstCompilation();
|
||||
#endif
|
||||
|
||||
#if !UNITY_2019_3_OR_NEWER
|
||||
using (new EditorGUI.DisabledScope(!m_HasLatestScriptingRuntime))
|
||||
#endif
|
||||
{
|
||||
// Draw Settings
|
||||
EditorGUILayout.LabelField(Styles.CoverageSettingsLabel, EditorStyles.boldLabel);
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning))
|
||||
{
|
||||
DrawCoverageSettings();
|
||||
}
|
||||
|
||||
// Draw Coverage Report Options
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.LabelField(Styles.CoverageReportOptionsLabel, EditorStyles.boldLabel);
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning))
|
||||
{
|
||||
DrawCoverageReportOptions();
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
GUILayout.EndVertical();
|
||||
|
||||
HandleFocusRepaint();
|
||||
}
|
||||
|
||||
float DrawToolbar()
|
||||
{
|
||||
GUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
// Coverage Recording button
|
||||
bool isRunning = CoverageRunData.instance.isRunning;
|
||||
bool isRecording = CoverageRunData.instance.isRecording;
|
||||
bool isRecordingPaused = CoverageRunData.instance.isRecordingPaused;
|
||||
|
||||
using (new EditorGUI.DisabledScope((isRunning && !isRecording) || m_StopRecording || m_AssembliesToIncludeLength == 0 || !Coverage.enabled || m_EnableCodeCoverage != Coverage.enabled || EditorApplication.isCompiling))
|
||||
{
|
||||
if (EditorGUILayout.DropdownButton(isRecording ? Styles.StopRecordingButton : Styles.StartRecordingButton, FocusType.Keyboard, EditorStyles.toolbarButton))
|
||||
{
|
||||
if (isRecording)
|
||||
{
|
||||
m_StopRecording = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CodeCoverage.StartRecordingInternal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using (new EditorGUI.DisabledScope(!isRecording || m_StopRecording || m_AssembliesToIncludeLength == 0 || !Coverage.enabled || m_EnableCodeCoverage != Coverage.enabled || EditorApplication.isCompiling))
|
||||
{
|
||||
if (EditorGUILayout.DropdownButton(isRecordingPaused ? Styles.UnpauseRecordingButton : Styles.PauseRecordingButton, FocusType.Keyboard, EditorStyles.toolbarButton))
|
||||
{
|
||||
if (isRecordingPaused)
|
||||
{
|
||||
CodeCoverage.UnpauseRecordingInternal();
|
||||
}
|
||||
else
|
||||
{
|
||||
CodeCoverage.PauseRecordingInternal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using (new EditorGUI.DisabledScope((!m_GenerateHTMLReport && !m_GenerateBadge && !m_GenerateAdditionalReports) || !DoesResultsRootFolderExist() || CoverageRunData.instance.isRunning || m_GenerateReport || m_AssembliesToIncludeLength == 0 || !Coverage.enabled || m_EnableCodeCoverage != Coverage.enabled || EditorApplication.isCompiling))
|
||||
{
|
||||
if (EditorGUILayout.DropdownButton(Styles.GenerateReportButtonLabel, FocusType.Keyboard, EditorStyles.toolbarButton))
|
||||
{
|
||||
m_GenerateReport = true;
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
using (new EditorGUI.DisabledScope(!DoesResultsRootFolderExist() || CoverageRunData.instance.isRunning))
|
||||
{
|
||||
if (EditorGUILayout.DropdownButton(Styles.ClearCoverageButtonLabel, FocusType.Keyboard, EditorStyles.toolbarButton))
|
||||
{
|
||||
ClearResultsRootFolderIfExists();
|
||||
}
|
||||
}
|
||||
|
||||
using (new EditorGUI.DisabledScope(!DoesReportHistoryExist() || CoverageRunData.instance.isRunning))
|
||||
{
|
||||
if (EditorGUILayout.DropdownButton(Styles.ClearHistoryButtonLabel, FocusType.Keyboard, EditorStyles.toolbarButton))
|
||||
{
|
||||
ClearReportHistoryFolderIfExists();
|
||||
}
|
||||
}
|
||||
|
||||
DrawHelpIcon();
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
return EditorStyles.toolbar.fixedHeight;
|
||||
}
|
||||
|
||||
void DrawHelpIcon()
|
||||
{
|
||||
if (GUILayout.Button(Styles.HelpIcon, EditorStyles.toolbarButton))
|
||||
{
|
||||
PackageManager.PackageInfo packageInfo = PackageManager.PackageInfo.FindForAssetPath("Packages/com.unity.testtools.codecoverage");
|
||||
if (packageInfo != null)
|
||||
{
|
||||
string shortVersion = packageInfo.version.Substring(0, packageInfo.version.IndexOf('.', packageInfo.version.IndexOf('.') + 1));
|
||||
string documentationUrl = $"https://docs.unity3d.com/Packages/com.unity.testtools.codecoverage@{shortVersion}";
|
||||
Application.OpenURL(documentationUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleFocusRepaint()
|
||||
{
|
||||
Rect r = EditorGUILayout.GetControlRect();
|
||||
// Lose focus if mouse is down outside of UI elements
|
||||
if (Event.current.type == EventType.MouseDown && !r.Contains(Event.current.mousePosition))
|
||||
{
|
||||
m_LoseFocus = true;
|
||||
}
|
||||
|
||||
if (m_LoseFocus)
|
||||
{
|
||||
GUI.FocusControl("");
|
||||
m_PathsToIncludeReorderableList.ReleaseKeyboardFocus();
|
||||
m_PathsToExcludeReorderableList.ReleaseKeyboardFocus();
|
||||
m_LoseFocus = false;
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
#if !UNITY_2019_3_OR_NEWER
|
||||
void CheckScriptingRuntimeVersion()
|
||||
{
|
||||
m_HasLatestScriptingRuntime = PlayerSettings.scriptingRuntimeVersion == ScriptingRuntimeVersion.Latest;
|
||||
|
||||
if (!m_HasLatestScriptingRuntime)
|
||||
{
|
||||
EditorGUILayout.HelpBox(kLatestScriptingRuntimeMessage, MessageType.Warning);
|
||||
GUILayout.Space(5);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void CheckCoverageEnabled()
|
||||
{
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
m_EnableCodeCoverage = Coverage.enabled;
|
||||
#else
|
||||
m_EnableCodeCoverage = EditorPrefs.GetBool("CodeCoverageEnabled", false);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
void CheckCodeOptimization()
|
||||
{
|
||||
if (Compilation.CompilationPipeline.codeOptimization == Compilation.CodeOptimization.Release)
|
||||
{
|
||||
EditorGUILayout.HelpBox(kCodeOptimizationMessage, MessageType.Warning);
|
||||
|
||||
using (new EditorGUI.DisabledScope(EditorApplication.isCompiling))
|
||||
{
|
||||
if (GUILayout.Button(Styles.SwitchToDebugCodeOptimizationButton))
|
||||
{
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.switchToDebugMode = true;
|
||||
Compilation.CompilationPipeline.codeOptimization = Compilation.CodeOptimization.Debug;
|
||||
EditorPrefs.SetBool("ScriptDebugInfoEnabled", true);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.Space(5);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BURST_INSTALLED
|
||||
void CheckBurstCompilation()
|
||||
{
|
||||
if (EditorPrefs.GetBool("BurstCompilation", false))
|
||||
{
|
||||
EditorGUILayout.HelpBox(kBurstCompilationOnMessage, MessageType.Warning);
|
||||
|
||||
if (GUILayout.Button(Styles.SwitchBurstCompilationOffButton))
|
||||
{
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.switchBurstOff = true;
|
||||
EditorApplication.ExecuteMenuItem("Jobs/Burst/Enable Compilation");
|
||||
}
|
||||
|
||||
GUILayout.Space(5);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void CheckIfIncludedAssembliesIsEmpty()
|
||||
{
|
||||
if (m_AssembliesToIncludeLength == 0)
|
||||
{
|
||||
EditorGUILayout.HelpBox(kNoAssembliesSelectedMessage, MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCodeCoverageLocation()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
bool settingPassedInCmdLine = CommandLineManager.instance.runFromCommandLine && CommandLineManager.instance.coverageResultsPath.Length > 0;
|
||||
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning || settingPassedInCmdLine))
|
||||
{
|
||||
Rect textFieldPosition = EditorGUILayout.GetControlRect();
|
||||
textFieldPosition = EditorGUI.PrefixLabel(textFieldPosition, Styles.CodeCoverageResultsLocationLabel);
|
||||
EditorGUI.SelectableLabel(textFieldPosition, settingPassedInCmdLine ? CommandLineManager.instance.coverageResultsPath : m_CodeCoveragePath, EditorStyles.textField);
|
||||
|
||||
bool autoDetect = !CoverageUtils.EnsureFolderExists(m_CodeCoveragePath);
|
||||
|
||||
if (autoDetect)
|
||||
{
|
||||
SetDefaultCoverageLocation();
|
||||
}
|
||||
|
||||
Rect btnPosition = GUILayoutUtility.GetRect(Styles.ResultsFolderButton, EditorStyles.miniPullDown, GUILayout.MaxWidth(38));
|
||||
if (EditorGUI.DropdownButton(btnPosition, Styles.ResultsFolderButton, FocusType.Keyboard, EditorStyles.miniPullDown))
|
||||
{
|
||||
m_ResultsFolderDropDownMenu.Show(btnPosition, m_CodeCoveragePath, kSelectCoverageDirectoryMessage);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (settingPassedInCmdLine)
|
||||
{
|
||||
EditorGUILayout.HelpBox(string.Format(kSettingOverriddenMessage, "Results Location", "-coverageResultsPath"), MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCodeCoverageHistoryLocation()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
bool settingPassedInCmdLine = CommandLineManager.instance.runFromCommandLine && CommandLineManager.instance.coverageHistoryPath.Length > 0;
|
||||
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning || settingPassedInCmdLine))
|
||||
{
|
||||
Rect textFieldPosition = EditorGUILayout.GetControlRect();
|
||||
textFieldPosition = EditorGUI.PrefixLabel(textFieldPosition, Styles.CodeCoverageHistoryLocationLabel);
|
||||
EditorGUI.SelectableLabel(textFieldPosition, settingPassedInCmdLine ? CommandLineManager.instance.coverageHistoryPath : m_CodeCoverageHistoryPath, EditorStyles.textField);
|
||||
|
||||
bool autoDetect = !CoverageUtils.EnsureFolderExists(m_CodeCoverageHistoryPath);
|
||||
|
||||
if (autoDetect)
|
||||
{
|
||||
SetDefaultCoverageHistoryLocation();
|
||||
}
|
||||
|
||||
Rect btnPosition = GUILayoutUtility.GetRect(Styles.HistoryFolderButton, EditorStyles.miniPullDown, GUILayout.MaxWidth(38));
|
||||
if (EditorGUI.DropdownButton(btnPosition, Styles.HistoryFolderButton, FocusType.Keyboard, EditorStyles.miniPullDown))
|
||||
{
|
||||
m_HistoryFolderDropDownMenu.Show(btnPosition, m_CodeCoverageHistoryPath, kSelectCoverageHistoryDirectoryMessage);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (settingPassedInCmdLine)
|
||||
{
|
||||
EditorGUILayout.HelpBox(string.Format(kSettingOverriddenMessage, "History Location", "-coverageHistoryPath"), MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawIncludedAssemblies()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
bool settingPassedInCmdLine = CommandLineManager.instance.runFromCommandLine && CommandLineManager.instance.assemblyFiltersSpecified;
|
||||
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning || settingPassedInCmdLine))
|
||||
{
|
||||
EditorGUILayout.PrefixLabel(Styles.AssembliesToIncludeLabel);
|
||||
|
||||
Rect buttonRect = EditorGUILayout.GetControlRect(GUILayout.MinWidth(10));
|
||||
|
||||
Styles.AssembliesToIncludeDropdownLabel.text = string.Concat(" ", m_AssembliesToInclude);
|
||||
Styles.AssembliesToIncludeDropdownLabel.tooltip = m_AssembliesToInclude.Replace(",", "\n");
|
||||
|
||||
if (EditorGUI.DropdownButton(buttonRect, m_AssembliesToInclude.Length > 0 ? Styles.AssembliesToIncludeDropdownLabel : Styles.AssembliesToIncludeEmptyDropdownLabel, FocusType.Keyboard, EditorStyles.miniPullDown))
|
||||
{
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.enterAssembliesDialog = true;
|
||||
GUI.FocusControl("");
|
||||
PopupWindow.Show(buttonRect, new IncludedAssembliesPopupWindow(this, m_AssembliesToInclude) { Width = buttonRect.width });
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (settingPassedInCmdLine)
|
||||
{
|
||||
EditorGUILayout.HelpBox(string.Format(kSettingOverriddenMessage, "Included Assemblies", "-coverageOptions: assemblyFilters"), MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawPathFiltering()
|
||||
{
|
||||
bool settingPassedInCmdLine = CommandLineManager.instance.runFromCommandLine && CommandLineManager.instance.pathFiltersSpecified;
|
||||
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning || settingPassedInCmdLine))
|
||||
{
|
||||
DrawIncludedPaths();
|
||||
DrawExcludedPaths();
|
||||
}
|
||||
|
||||
if (settingPassedInCmdLine)
|
||||
{
|
||||
EditorGUILayout.HelpBox(string.Format(kSettingsOverriddenMessage, "Included/Excluded Paths", "-coverageOptions: pathFilters/pathFiltersFromFile"), MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawIncludedPaths()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
EditorGUILayout.PrefixLabel(Styles.PathsToIncludeLabel);
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
GUILayout.Space(4);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
m_PathsToIncludeReorderableList.drawElementCallback = DrawPathsToIncludeListItem;
|
||||
m_PathsToIncludeReorderableList.onChangedCallback = (rl) => { PathsToInclude = string.Join(",", rl.list as List<string>); };
|
||||
m_PathsToIncludeReorderableList.onAddDropdownCallback = (rect, rl) => { m_AddPathToIncludeDropDownMenu.Show(rect, m_PathsToInclude); };
|
||||
m_PathsToIncludeReorderableList.DoLayoutList();
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
OnPathsListChange(m_PathsToIncludeReorderableList, PathFilterType.Include);
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUILayout.Space(2);
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
void DrawExcludedPaths()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
EditorGUILayout.PrefixLabel(Styles.PathsToExcludeLabel);
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
GUILayout.Space(4);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
m_PathsToExcludeReorderableList.drawElementCallback = DrawPathsToExcludeListItem;
|
||||
m_PathsToExcludeReorderableList.onChangedCallback = (rl) => { PathsToExclude = string.Join(",", rl.list as List<string>); };
|
||||
m_PathsToExcludeReorderableList.onAddDropdownCallback = (rect, rl) => { m_AddPathToExcludeDropDownMenu.Show(rect, m_PathsToExclude); };
|
||||
m_PathsToExcludeReorderableList.DoLayoutList();
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
OnPathsListChange(m_PathsToExcludeReorderableList, PathFilterType.Exclude);
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUILayout.Space(2);
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
void DrawPathsToIncludeListItem(Rect rect, int index, bool isActive, bool isFocused)
|
||||
{
|
||||
if (index >= 0 && index < m_PathsToIncludeList.Count)
|
||||
{
|
||||
string pathToInclude = m_PathsToIncludeList[index].Replace(",", "");
|
||||
m_PathsToIncludeReorderableList.list[index] = EditorGUI.TextField(rect, pathToInclude);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawPathsToExcludeListItem(Rect rect, int index, bool isActive, bool isFocused)
|
||||
{
|
||||
if (index >= 0 && index < m_PathsToExcludeList.Count)
|
||||
{
|
||||
string pathToExclude = m_PathsToExcludeList[index];
|
||||
m_PathsToExcludeReorderableList.list[index] = EditorGUI.TextField(rect, pathToExclude);
|
||||
}
|
||||
}
|
||||
|
||||
void OnPathsListChange(ReorderableList rl, PathFilterType pathFilterType)
|
||||
{
|
||||
var pathsList = rl.list as List<string>;
|
||||
int listSize = pathsList.Count;
|
||||
|
||||
for (int i = 0; i < listSize; ++i)
|
||||
{
|
||||
var itemStr = pathsList[i];
|
||||
itemStr = itemStr.Replace(",", "");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(itemStr))
|
||||
{
|
||||
itemStr = "-";
|
||||
}
|
||||
|
||||
pathsList[i] = itemStr;
|
||||
}
|
||||
|
||||
if (pathFilterType == PathFilterType.Include)
|
||||
PathsToInclude = string.Join(",", pathsList);
|
||||
else if (pathFilterType == PathFilterType.Exclude)
|
||||
PathsToExclude = string.Join(",", pathsList);
|
||||
}
|
||||
|
||||
void CheckIfCodeCoverageIsDisabled()
|
||||
{
|
||||
if (!m_EnableCodeCoverage)
|
||||
{
|
||||
EditorGUILayout.HelpBox(kCodeCoverageDisabledNoRestartMessage, MessageType.Warning);
|
||||
}
|
||||
#if !UNITY_2020_2_OR_NEWER
|
||||
if (m_EnableCodeCoverage != Coverage.enabled)
|
||||
{
|
||||
if (m_EnableCodeCoverage)
|
||||
EditorGUILayout.HelpBox(kEnablingCodeCoverageMessage, MessageType.Warning);
|
||||
else
|
||||
EditorGUILayout.HelpBox(kDisablingCodeCoverageMessage, MessageType.Warning);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DrawVerbosityLevel()
|
||||
{
|
||||
GUILayout.Space(2);
|
||||
|
||||
bool settingPassedInCmdLine = CommandLineManager.instance.runFromCommandLine && CommandLineManager.instance.verbosityLevelSpecified;
|
||||
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning || settingPassedInCmdLine))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
int verbosityLevel = EditorGUILayout.Popup(Styles.VerbosityLabel, (int)CodeCoverage.VerbosityLevel, kVerbosityLevelLabels);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
CoveragePreferences.instance.SetInt("VerbosityLevel", verbosityLevel);
|
||||
CodeCoverage.VerbosityLevel = (LogVerbosityLevel)verbosityLevel;
|
||||
}
|
||||
}
|
||||
|
||||
if (settingPassedInCmdLine)
|
||||
{
|
||||
EditorGUILayout.HelpBox(string.Format(kSettingOverriddenMessage, "Logs Verbosity Level", "-coverageOptions: verbosity"), MessageType.Warning);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void DrawEnableCoverageCheckbox()
|
||||
{
|
||||
bool settingPassedInCmdLine = CommandLineManager.instance.runFromCommandLine;
|
||||
|
||||
using (new EditorGUI.DisabledScope(EditorApplication.isCompiling || settingPassedInCmdLine))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_EnableCodeCoverage = EditorGUILayout.Toggle(Styles.EnableCodeCoverageLabel, m_EnableCodeCoverage, GUILayout.ExpandWidth(false));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
CoveragePreferences.instance.SetBool("EnableCodeCoverage", m_EnableCodeCoverage);
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
Coverage.enabled = m_EnableCodeCoverage;
|
||||
#else
|
||||
EditorPrefs.SetBool("CodeCoverageEnabled", m_EnableCodeCoverage);
|
||||
EditorPrefs.SetBool("CodeCoverageEnabledMessageShown", false);
|
||||
SettingsService.NotifySettingsProviderChanged();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (settingPassedInCmdLine)
|
||||
{
|
||||
EditorGUILayout.HelpBox(string.Format(kSettingOverriddenMessage, "Enable Code Coverage", "-enableCodeCoverage"), MessageType.Warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckIfCodeCoverageIsDisabled();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawGenerateHTMLReportCheckbox()
|
||||
{
|
||||
bool settingPassedInCmdLine = CommandLineManager.instance.runFromCommandLine && CommandLineManager.instance.generateHTMLReport;
|
||||
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning || settingPassedInCmdLine))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_GenerateHTMLReport = EditorGUILayout.Toggle(Styles.GenerateHTMLReportLabel, m_GenerateHTMLReport, GUILayout.ExpandWidth(false));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
CoveragePreferences.instance.SetBool("GenerateHTMLReport", m_GenerateHTMLReport);
|
||||
}
|
||||
}
|
||||
|
||||
if (settingPassedInCmdLine)
|
||||
{
|
||||
EditorGUILayout.HelpBox(string.Format(kSettingOverriddenMessage, "HTML Report", "-coverageOptions: generateHtmlReport"), MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawGenerateAdditionalReportsCheckbox()
|
||||
{
|
||||
bool settingPassedInCmdLine = CommandLineManager.instance.runFromCommandLine && CommandLineManager.instance.generateAdditionalReports;
|
||||
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning || settingPassedInCmdLine))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_GenerateAdditionalReports = EditorGUILayout.Toggle(Styles.GenerateAdditionalReportsLabel, m_GenerateAdditionalReports, GUILayout.ExpandWidth(false));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
CoveragePreferences.instance.SetBool("GenerateAdditionalReports", m_GenerateAdditionalReports);
|
||||
}
|
||||
}
|
||||
|
||||
if (settingPassedInCmdLine)
|
||||
{
|
||||
EditorGUILayout.HelpBox(string.Format(kSettingOverriddenMessage, "Additional Reports", "-coverageOptions: generateAdditionalReports"), MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawGenerateBadgeReportCheckbox()
|
||||
{
|
||||
bool settingPassedInCmdLine = CommandLineManager.instance.runFromCommandLine && CommandLineManager.instance.generateBadgeReport;
|
||||
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning || settingPassedInCmdLine))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_GenerateBadge = EditorGUILayout.Toggle(Styles.GenerateBadgeReportLabel, m_GenerateBadge, GUILayout.ExpandWidth(false));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
CoveragePreferences.instance.SetBool("GenerateBadge", m_GenerateBadge);
|
||||
}
|
||||
}
|
||||
|
||||
if (settingPassedInCmdLine)
|
||||
{
|
||||
EditorGUILayout.HelpBox(string.Format(kSettingOverriddenMessage, "Summary Badges", "-coverageOptions: generateBadgeReport"), MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawGenerateHistoryCheckbox()
|
||||
{
|
||||
bool settingPassedInCmdLine = CommandLineManager.instance.runFromCommandLine && CommandLineManager.instance.generateHTMLReportHistory;
|
||||
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning || settingPassedInCmdLine))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
using (new EditorGUI.DisabledScope(!m_GenerateHTMLReport && !m_GenerateAdditionalReports))
|
||||
{
|
||||
m_IncludeHistoryInReport = EditorGUILayout.Toggle(Styles.CoverageHistoryLabel, m_IncludeHistoryInReport, GUILayout.ExpandWidth(false));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
CoveragePreferences.instance.SetBool("IncludeHistoryInReport", m_IncludeHistoryInReport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settingPassedInCmdLine)
|
||||
{
|
||||
EditorGUILayout.HelpBox(string.Format(kSettingOverriddenMessage, "Report History", "-coverageOptions: generateHtmlReportHistory"), MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawGenerateAdditionalMetricsCheckbox()
|
||||
{
|
||||
bool settingPassedInCmdLine = CommandLineManager.instance.runFromCommandLine && CommandLineManager.instance.generateAdditionalMetrics;
|
||||
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning || settingPassedInCmdLine))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_GenerateAdditionalMetrics = EditorGUILayout.Toggle(Styles.GenerateAdditionalMetricsLabel, m_GenerateAdditionalMetrics, GUILayout.ExpandWidth(false));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
CoveragePreferences.instance.SetBool("GenerateAdditionalMetrics", m_GenerateAdditionalMetrics);
|
||||
}
|
||||
}
|
||||
|
||||
if (settingPassedInCmdLine)
|
||||
{
|
||||
EditorGUILayout.HelpBox(string.Format(kSettingOverriddenMessage, "Additional Metrics", "-coverageOptions: generateAdditionalMetrics"), MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawGenerateTestRunnerReferencesCheckbox()
|
||||
{
|
||||
bool settingPassedInCmdLine = CommandLineManager.instance.runFromCommandLine && CommandLineManager.instance.generateTestReferences;
|
||||
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning || settingPassedInCmdLine))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_GenerateTestReferences = EditorGUILayout.Toggle(Styles.GenerateTestRunnerReferencesLabel, m_GenerateTestReferences, GUILayout.ExpandWidth(false));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
CoveragePreferences.instance.SetBool("GenerateTestReferences", m_GenerateTestReferences);
|
||||
}
|
||||
}
|
||||
|
||||
if (settingPassedInCmdLine)
|
||||
{
|
||||
EditorGUILayout.HelpBox(string.Format(kSettingOverriddenMessage, "Test Runner References", "-coverageOptions: generateTestReferences"), MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawAutoGenerateReportCheckbox()
|
||||
{
|
||||
bool settingPassedInCmdLine = CommandLineManager.instance.runFromCommandLine && (CommandLineManager.instance.generateHTMLReport || CommandLineManager.instance.generateBadgeReport);
|
||||
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning || settingPassedInCmdLine))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_AutoGenerateReport = EditorGUILayout.Toggle(Styles.AutoGenerateReportLabel, m_AutoGenerateReport, GUILayout.ExpandWidth(false));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
CoveragePreferences.instance.SetBool("AutoGenerateReport", m_AutoGenerateReport);
|
||||
}
|
||||
}
|
||||
|
||||
if (settingPassedInCmdLine)
|
||||
{
|
||||
EditorGUILayout.HelpBox(string.Format(kSettingOverriddenMessage, "Auto Generate Report", CommandLineManager.instance.generateHTMLReport ? "-coverageOptions: generateHtmlReport" : "-coverageOptions: generateBadgeReport"), MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawOpenReportWhenGeneratedCheckbox()
|
||||
{
|
||||
using (new EditorGUI.DisabledScope(CoverageRunData.instance.isRunning))
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_OpenReportWhenGenerated = EditorGUILayout.Toggle(Styles.OpenReportWhenGeneratedLabel, m_OpenReportWhenGenerated, GUILayout.ExpandWidth(false));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
CoveragePreferences.instance.SetBool("OpenReportWhenGenerated", m_OpenReportWhenGenerated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawCoverageSettings()
|
||||
{
|
||||
DrawEnableCoverageCheckbox();
|
||||
DrawCodeCoverageLocation();
|
||||
DrawCodeCoverageHistoryLocation();
|
||||
DrawIncludedAssemblies();
|
||||
CheckIfIncludedAssembliesIsEmpty();
|
||||
DrawPathFiltering();
|
||||
DrawVerbosityLevel();
|
||||
}
|
||||
|
||||
void DrawCoverageReportOptions()
|
||||
{
|
||||
DrawGenerateHTMLReportCheckbox();
|
||||
DrawGenerateAdditionalReportsCheckbox();
|
||||
DrawGenerateHistoryCheckbox();
|
||||
DrawGenerateBadgeReportCheckbox();
|
||||
DrawGenerateAdditionalMetricsCheckbox();
|
||||
DrawGenerateTestRunnerReferencesCheckbox();
|
||||
DrawAutoGenerateReportCheckbox();
|
||||
DrawOpenReportWhenGeneratedCheckbox();
|
||||
}
|
||||
|
||||
private bool DoesResultsRootFolderExist()
|
||||
{
|
||||
if (m_CoverageSettings == null)
|
||||
return false;
|
||||
|
||||
string resultsRootFolderPath = m_CoverageSettings.resultsRootFolderPath;
|
||||
return CoverageUtils.GetNumberOfFilesInFolder(resultsRootFolderPath, "*.xml", SearchOption.AllDirectories) > 0;
|
||||
}
|
||||
|
||||
private void ClearResultsRootFolderIfExists()
|
||||
{
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.clearData = true;
|
||||
|
||||
if (!EditorUtility.DisplayDialog(L10n.Tr("Clear Results"), kClearDataMessage, L10n.Tr("Clear"), L10n.Tr("Cancel")))
|
||||
return;
|
||||
|
||||
if (m_CoverageSettings == null)
|
||||
return;
|
||||
|
||||
string resultsRootFolderPath = m_CoverageSettings.resultsRootFolderPath;
|
||||
|
||||
CoverageUtils.ClearFolderIfExists(resultsRootFolderPath, "*.xml");
|
||||
}
|
||||
|
||||
public string GetResultsRootFolder()
|
||||
{
|
||||
if (m_CoverageSettings == null)
|
||||
return m_CodeCoveragePath;
|
||||
|
||||
string resultsRootFolderPath = m_CoverageSettings.resultsRootFolderPath;
|
||||
CoverageUtils.EnsureFolderExists(resultsRootFolderPath);
|
||||
return resultsRootFolderPath;
|
||||
}
|
||||
|
||||
private bool DoesReportHistoryExist()
|
||||
{
|
||||
if (m_CoverageSettings == null)
|
||||
return false;
|
||||
|
||||
string historyFolderPath = m_CoverageSettings.historyFolderPath;
|
||||
|
||||
return CoverageUtils.GetNumberOfFilesInFolder(historyFolderPath, "????-??-??_??-??-??_CoverageHistory.xml", SearchOption.TopDirectoryOnly) > 0;
|
||||
}
|
||||
|
||||
private void ClearReportHistoryFolderIfExists()
|
||||
{
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.clearHistory = true;
|
||||
|
||||
if (!EditorUtility.DisplayDialog(L10n.Tr("Clear Report History"), kClearHistoryMessage, L10n.Tr("Clear"), L10n.Tr("Cancel")))
|
||||
return;
|
||||
|
||||
if (m_CoverageSettings == null)
|
||||
return;
|
||||
|
||||
string historyFolderPath = m_CoverageSettings.historyFolderPath;
|
||||
|
||||
CoverageUtils.ClearFolderIfExists(historyFolderPath, "????-??-??_??-??-??_CoverageHistory.xml");
|
||||
}
|
||||
|
||||
public string GetReportHistoryFolder()
|
||||
{
|
||||
if (m_CoverageSettings == null)
|
||||
return m_CodeCoverageHistoryPath;
|
||||
|
||||
string historyFolderPath = m_CoverageSettings.historyFolderPath;
|
||||
CoverageUtils.EnsureFolderExists(historyFolderPath);
|
||||
return historyFolderPath;
|
||||
}
|
||||
|
||||
public void SetCoverageLocation(string folderPath)
|
||||
{
|
||||
if (CoverageUtils.IsValidFolder(folderPath))
|
||||
{
|
||||
m_CodeCoveragePath = folderPath;
|
||||
CoveragePreferences.instance.SetStringForPaths("Path", m_CodeCoveragePath);
|
||||
UpdateCoverageSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDefaultCoverageLocation()
|
||||
{
|
||||
SetCoverageLocation(CoverageUtils.GetProjectPath());
|
||||
}
|
||||
|
||||
public void SetCoverageHistoryLocation(string folderPath)
|
||||
{
|
||||
if (CoverageUtils.IsValidFolder(folderPath))
|
||||
{
|
||||
m_CodeCoverageHistoryPath = folderPath;
|
||||
CoveragePreferences.instance.SetStringForPaths("HistoryPath", m_CodeCoverageHistoryPath);
|
||||
UpdateCoverageSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDefaultCoverageHistoryLocation()
|
||||
{
|
||||
SetCoverageHistoryLocation(CoverageUtils.GetProjectPath());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5115ff20f1ea204dac14fa49c0e8f69
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,78 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor.TestTools.CodeCoverage.Utils;
|
||||
|
||||
namespace UnityEditor.TestTools.CodeCoverage
|
||||
{
|
||||
internal class FolderDropDownMenu
|
||||
{
|
||||
GenericMenu m_Menu;
|
||||
string m_Path;
|
||||
string m_Message;
|
||||
readonly CodeCoverageWindow m_Parent;
|
||||
readonly FolderType m_FolderType;
|
||||
|
||||
static class Styles
|
||||
{
|
||||
public static readonly GUIContent ShowInExplorerLabel = EditorGUIUtility.TrTextContent("Open Containing Folder");
|
||||
public static readonly GUIContent ChangeLocationLabel = EditorGUIUtility.TrTextContent("Change Location");
|
||||
public static readonly GUIContent ResetToDefaultLabel = EditorGUIUtility.TrTextContent("Reset to Default Location");
|
||||
}
|
||||
|
||||
public FolderDropDownMenu(CodeCoverageWindow parent, FolderType type)
|
||||
{
|
||||
m_Parent = parent;
|
||||
m_FolderType = type;
|
||||
}
|
||||
|
||||
private void PopulateMenu()
|
||||
{
|
||||
m_Menu = new GenericMenu();
|
||||
|
||||
m_Menu.AddItem(Styles.ShowInExplorerLabel, false, () => ShowInExplorer());
|
||||
m_Menu.AddItem(Styles.ChangeLocationLabel, false, () => ChangeLocation());
|
||||
|
||||
if (m_Path.Equals(CoverageUtils.GetProjectPath()))
|
||||
m_Menu.AddDisabledItem(Styles.ResetToDefaultLabel);
|
||||
else
|
||||
m_Menu.AddItem(Styles.ResetToDefaultLabel, false, () => ResetToDefault());
|
||||
}
|
||||
|
||||
public void Show(Rect position, string folderPath, string message)
|
||||
{
|
||||
m_Path = folderPath;
|
||||
m_Message = message;
|
||||
|
||||
PopulateMenu();
|
||||
|
||||
m_Menu.DropDown(position);
|
||||
}
|
||||
|
||||
private void ShowInExplorer()
|
||||
{
|
||||
string path = m_FolderType == FolderType.Results ?
|
||||
m_Parent.GetResultsRootFolder() :
|
||||
m_Parent.GetReportHistoryFolder();
|
||||
|
||||
EditorUtility.RevealInFinder(path);
|
||||
}
|
||||
|
||||
private void ChangeLocation()
|
||||
{
|
||||
string candidate = CoverageUtils.BrowseForDir(m_Path, m_Message);
|
||||
if (m_FolderType == FolderType.Results)
|
||||
m_Parent.SetCoverageLocation(candidate);
|
||||
else
|
||||
m_Parent.SetCoverageHistoryLocation(candidate);
|
||||
m_Parent.LoseFocus();
|
||||
}
|
||||
|
||||
private void ResetToDefault()
|
||||
{
|
||||
if (m_FolderType == FolderType.Results)
|
||||
m_Parent.SetDefaultCoverageLocation();
|
||||
else
|
||||
m_Parent.SetDefaultCoverageHistoryLocation();
|
||||
m_Parent.LoseFocus();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efa0ff6842a348049864f8312e42ec4b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
namespace UnityEditor.TestTools.CodeCoverage
|
||||
{
|
||||
internal enum FolderType
|
||||
{
|
||||
Results = 0,
|
||||
History = 1
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f4b403c98301c44da49e4df4c5cb5b4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,90 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
|
||||
namespace UnityEditor.TestTools.CodeCoverage
|
||||
{
|
||||
class IncludedAssembliesPopupWindow : PopupWindowContent
|
||||
{
|
||||
readonly SearchField m_SearchField;
|
||||
readonly IncludedAssembliesTreeView m_TreeView;
|
||||
|
||||
const float kWindowHeight = 221;
|
||||
|
||||
public float Width { get; set; }
|
||||
|
||||
static class Styles
|
||||
{
|
||||
public static readonly GUIContent SelectLabel = EditorGUIUtility.TrTextContent("Select:");
|
||||
public static readonly GUIContent SelectAllButtonLabel = EditorGUIUtility.TrTextContent("All", "Click this to select and include all the assemblies in the project. This includes both the assemblies under the 'Assets' folder and packages.\n\nIf searching, it will apply only to the assemblies visible in the list.");
|
||||
public static readonly GUIContent SelectAssetsButtonLabel = EditorGUIUtility.TrTextContent("Assets", "Click this to select and include only the assemblies under the 'Assets' folder.\n\nIf searching, it will apply only to the assemblies visible in the list.");
|
||||
public static readonly GUIContent SelectPackagesButtonLabel = EditorGUIUtility.TrTextContent("Packages", "Click this to select and include only the Packages' assemblies.\n\nIf searching, it will apply only to the assemblies visible in the list.");
|
||||
public static readonly GUIContent DeselectAllButtonLabel = EditorGUIUtility.TrTextContent("Deselect All", "Click this to deselect and exclude all the assemblies.\n\nIf searching, it will apply only to the assemblies visible in the list.");
|
||||
}
|
||||
|
||||
public IncludedAssembliesPopupWindow(CodeCoverageWindow parent, string assembliesToInclude)
|
||||
{
|
||||
m_SearchField = new SearchField();
|
||||
m_TreeView = new IncludedAssembliesTreeView(parent, assembliesToInclude);
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect rect)
|
||||
{
|
||||
const int border = 4;
|
||||
const int topPadding = 12;
|
||||
const int searchHeight = 20;
|
||||
const int buttonHeight = 16;
|
||||
const int remainTop = topPadding + searchHeight + buttonHeight + border + border;
|
||||
|
||||
float selectLabelWidth = EditorStyles.boldLabel.CalcSize(Styles.SelectLabel).x;
|
||||
float selectAllWidth = EditorStyles.miniButton.CalcSize(Styles.SelectAllButtonLabel).x;
|
||||
float selectAssetsWidth = EditorStyles.miniButton.CalcSize(Styles.SelectAssetsButtonLabel).x;
|
||||
float selectPackagesWidth = EditorStyles.miniButton.CalcSize(Styles.SelectPackagesButtonLabel).x;
|
||||
float deselectAllWidth = EditorStyles.miniButton.CalcSize(Styles.DeselectAllButtonLabel).x;
|
||||
|
||||
Rect searchRect = new Rect(border, topPadding, rect.width - border * 2, searchHeight);
|
||||
Rect selectLabelRect = new Rect(border, topPadding + searchHeight + border, selectLabelWidth, searchHeight);
|
||||
Rect selectAllRect = new Rect(border + selectLabelWidth + border, topPadding + searchHeight + border, selectAllWidth, buttonHeight);
|
||||
Rect selectAssetsRect = new Rect(border + selectLabelWidth + border + selectAllWidth + border, topPadding + searchHeight + border, selectAssetsWidth, buttonHeight);
|
||||
Rect selectPackagesRect = new Rect(border + selectLabelWidth + border + selectAllWidth + border + selectAssetsWidth + border, topPadding + searchHeight + border, selectPackagesWidth, buttonHeight);
|
||||
Rect deselectAllRect = new Rect(rect.width - border - deselectAllWidth, topPadding + searchHeight + border, deselectAllWidth, buttonHeight);
|
||||
Rect remainingRect = new Rect(border, remainTop, rect.width - border * 2, rect.height - remainTop - border);
|
||||
|
||||
m_TreeView.searchString = m_SearchField.OnGUI(searchRect, m_TreeView.searchString);
|
||||
|
||||
GUI.Label(selectLabelRect, Styles.SelectLabel, EditorStyles.boldLabel);
|
||||
|
||||
if (GUI.Button(selectAllRect, Styles.SelectAllButtonLabel, EditorStyles.miniButton))
|
||||
{
|
||||
m_TreeView.SelectAll();
|
||||
}
|
||||
|
||||
if (GUI.Button(deselectAllRect, Styles.DeselectAllButtonLabel, EditorStyles.miniButton))
|
||||
{
|
||||
m_TreeView.DeselectAll();
|
||||
}
|
||||
|
||||
if (GUI.Button(selectAssetsRect, Styles.SelectAssetsButtonLabel, EditorStyles.miniButton))
|
||||
{
|
||||
m_TreeView.SelectAssets();
|
||||
}
|
||||
|
||||
if (GUI.Button(selectPackagesRect, Styles.SelectPackagesButtonLabel, EditorStyles.miniButton))
|
||||
{
|
||||
m_TreeView.SelectPackages();
|
||||
}
|
||||
|
||||
m_TreeView.OnGUI(remainingRect);
|
||||
}
|
||||
|
||||
public override Vector2 GetWindowSize()
|
||||
{
|
||||
return new Vector2(Mathf.Max(Width, m_TreeView.Width), kWindowHeight);
|
||||
}
|
||||
|
||||
public override void OnOpen()
|
||||
{
|
||||
m_SearchField.SetFocus();
|
||||
base.OnOpen();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b706bbc1f4c2d0c4d8c44630579b20cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,184 @@
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEditor.Compilation;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEditor.TestTools.CodeCoverage.Analytics;
|
||||
|
||||
namespace UnityEditor.TestTools.CodeCoverage
|
||||
{
|
||||
class IncludedAssembliesTreeView : TreeView
|
||||
{
|
||||
string m_AssembliesToInclude;
|
||||
readonly CodeCoverageWindow m_Parent;
|
||||
const float kCheckBoxWidth = 42f;
|
||||
|
||||
public float Width { get; set; } = 100f;
|
||||
|
||||
public IncludedAssembliesTreeView(CodeCoverageWindow parent, string assembliesToInclude)
|
||||
: base(new TreeViewState())
|
||||
{
|
||||
m_AssembliesToInclude = assembliesToInclude;
|
||||
m_Parent = parent;
|
||||
showAlternatingRowBackgrounds = true;
|
||||
showBorder = true;
|
||||
Reload();
|
||||
}
|
||||
|
||||
protected override bool CanMultiSelect(TreeViewItem item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override TreeViewItem BuildRoot()
|
||||
{
|
||||
string[] includeAssemblyFilters = m_AssembliesToInclude.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
Regex[] includeAssemblies = includeAssemblyFilters
|
||||
.Select(f => AssemblyFiltering.CreateFilterRegex(f))
|
||||
.ToArray();
|
||||
|
||||
TreeViewItem root = new TreeViewItem(-1, -1);
|
||||
|
||||
bool developerMode = EditorPrefs.GetBool("DeveloperMode", false);
|
||||
|
||||
if (developerMode)
|
||||
{
|
||||
System.Reflection.Assembly[] assemblies = AssemblyFiltering.GetAllProjectAssembliesInternal();
|
||||
int assembliesLength = assemblies.Length;
|
||||
|
||||
GUIContent textContent = new GUIContent();
|
||||
for (int i = 0; i < assembliesLength; ++i)
|
||||
{
|
||||
System.Reflection.Assembly assembly = assemblies[i];
|
||||
bool enabled = includeAssemblies.Any(f => f.IsMatch(assembly.GetName().Name.ToLowerInvariant()));
|
||||
root.AddChild(new AssembliesTreeViewItem() { id = i + 1, displayName = assembly.GetName().Name, Enabled = enabled });
|
||||
|
||||
textContent.text = assembly.GetName().Name;
|
||||
float itemWidth = TreeView.DefaultStyles.label.CalcSize(textContent).x + kCheckBoxWidth;
|
||||
if (Width < itemWidth)
|
||||
Width = itemWidth;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Assembly[] assemblies = AssemblyFiltering.GetAllProjectAssemblies();
|
||||
int assembliesLength = assemblies.Length;
|
||||
|
||||
GUIContent textContent = new GUIContent();
|
||||
for (int i = 0; i < assembliesLength; ++i)
|
||||
{
|
||||
Assembly assembly = assemblies[i];
|
||||
bool enabled = includeAssemblies.Any(f => f.IsMatch(assembly.name.ToLowerInvariant()));
|
||||
root.AddChild(new AssembliesTreeViewItem() { id = i + 1, displayName = assembly.name, Enabled = enabled });
|
||||
|
||||
textContent.text = assembly.name;
|
||||
float itemWidth = TreeView.DefaultStyles.label.CalcSize(textContent).x + kCheckBoxWidth;
|
||||
if (Width < itemWidth)
|
||||
Width = itemWidth;
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
protected override void RowGUI(RowGUIArgs args)
|
||||
{
|
||||
AssembliesTreeViewItem item = args.item as AssembliesTreeViewItem;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
bool enabled = EditorGUI.ToggleLeft(args.rowRect, args.label, item.Enabled);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
item.Enabled = enabled;
|
||||
ApplyChanges();
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectAll()
|
||||
{
|
||||
ToggleAll(true);
|
||||
}
|
||||
|
||||
public void DeselectAll()
|
||||
{
|
||||
ToggleAll(false);
|
||||
}
|
||||
|
||||
public void SelectAssets()
|
||||
{
|
||||
m_AssembliesToInclude = AssemblyFiltering.GetUserOnlyAssembliesString();
|
||||
SelectFromString(m_AssembliesToInclude);
|
||||
}
|
||||
|
||||
public void SelectPackages()
|
||||
{
|
||||
m_AssembliesToInclude = AssemblyFiltering.GetPackagesOnlyAssembliesString();
|
||||
SelectFromString(m_AssembliesToInclude);
|
||||
}
|
||||
|
||||
private void SelectFromString(string assembliesToInclude)
|
||||
{
|
||||
string[] includeAssemblyFilters = assembliesToInclude.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
Regex[] includeAssemblies = includeAssemblyFilters
|
||||
.Select(f => AssemblyFiltering.CreateFilterRegex(f))
|
||||
.ToArray();
|
||||
|
||||
foreach (var child in rootItem.children)
|
||||
{
|
||||
AssembliesTreeViewItem childItem = child as AssembliesTreeViewItem;
|
||||
|
||||
bool enabled = includeAssemblies.Any(f => f.IsMatch(childItem.displayName.ToLowerInvariant()));
|
||||
if (searchString == null)
|
||||
childItem.Enabled = enabled;
|
||||
else if (DoesItemMatchSearch(child, searchString))
|
||||
childItem.Enabled = enabled;
|
||||
}
|
||||
|
||||
ApplyChanges();
|
||||
}
|
||||
|
||||
private void ToggleAll(bool enabled)
|
||||
{
|
||||
foreach (var child in rootItem.children)
|
||||
{
|
||||
AssembliesTreeViewItem childItem = child as AssembliesTreeViewItem;
|
||||
if (searchString == null)
|
||||
childItem.Enabled = enabled;
|
||||
else if (DoesItemMatchSearch(child, searchString))
|
||||
childItem.Enabled = enabled;
|
||||
}
|
||||
|
||||
ApplyChanges();
|
||||
}
|
||||
|
||||
void ApplyChanges()
|
||||
{
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.updateAssembliesDialog = true;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach(var child in rootItem.children)
|
||||
{
|
||||
AssembliesTreeViewItem childItem = child as AssembliesTreeViewItem;
|
||||
if (childItem.Enabled)
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
sb.Append(",");
|
||||
|
||||
sb.Append(childItem.displayName);
|
||||
}
|
||||
}
|
||||
|
||||
m_Parent.AssembliesToInclude = sb.ToString();
|
||||
m_Parent.Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
class AssembliesTreeViewItem : TreeViewItem
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5a93638351266e418ccf0b46460a46e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
namespace UnityEditor.TestTools.CodeCoverage
|
||||
{
|
||||
internal enum PathFilterType
|
||||
{
|
||||
Include = 0,
|
||||
Exclude = 1
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e885c435119d8f4ebb060111a1fa3d8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,73 @@
|
||||
using UnityEditor.TestTools.CodeCoverage.Analytics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.CodeCoverage
|
||||
{
|
||||
internal class PathToAddDropDownMenu
|
||||
{
|
||||
GenericMenu m_Menu;
|
||||
string m_PathsToFilter;
|
||||
readonly PathToAddHandler m_AddPathToIncludeHandler;
|
||||
readonly PathToAddHandler m_AddPathToExcludeHandler;
|
||||
readonly PathFilterType m_PathFilterType;
|
||||
|
||||
static class Styles
|
||||
{
|
||||
public static readonly GUIContent AddFolderLabel = EditorGUIUtility.TrTextContent("Add Folder");
|
||||
public static readonly GUIContent AddFileLabel = EditorGUIUtility.TrTextContent("Add File");
|
||||
}
|
||||
|
||||
public PathToAddDropDownMenu(CodeCoverageWindow parent, PathFilterType type)
|
||||
{
|
||||
m_PathFilterType = type;
|
||||
|
||||
m_AddPathToIncludeHandler = new PathToAddHandler(parent, PathFilterType.Include);
|
||||
m_AddPathToExcludeHandler = new PathToAddHandler(parent, PathFilterType.Exclude);
|
||||
}
|
||||
|
||||
private void PopulateMenu()
|
||||
{
|
||||
m_Menu = new GenericMenu();
|
||||
|
||||
m_Menu.AddItem(Styles.AddFolderLabel, false, () => AddFolder());
|
||||
m_Menu.AddItem(Styles.AddFileLabel, false, () => AddFile());
|
||||
}
|
||||
|
||||
public void Show(Rect position, string pathsToFilter)
|
||||
{
|
||||
m_PathsToFilter = pathsToFilter;
|
||||
|
||||
PopulateMenu();
|
||||
|
||||
m_Menu.DropDown(position);
|
||||
}
|
||||
|
||||
private void AddFolder()
|
||||
{
|
||||
if (m_PathFilterType == PathFilterType.Include)
|
||||
{
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.selectAddFolder_IncludedPaths = true;
|
||||
m_AddPathToIncludeHandler.BrowseForDir(m_PathsToFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.selectAddFolder_ExcludedPaths = true;
|
||||
m_AddPathToExcludeHandler.BrowseForDir(m_PathsToFilter);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddFile()
|
||||
{
|
||||
if (m_PathFilterType == PathFilterType.Include)
|
||||
{
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.selectAddFile_IncludedPaths = true;
|
||||
m_AddPathToIncludeHandler.BrowseForFile(m_PathsToFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
CoverageAnalytics.instance.CurrentCoverageEvent.selectAddFile_ExcludedPaths = true;
|
||||
m_AddPathToExcludeHandler.BrowseForFile(m_PathsToFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e69bc8675774d1741834a4ff82846748
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,73 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEditor.TestTools.CodeCoverage.Utils;
|
||||
|
||||
namespace UnityEditor.TestTools.CodeCoverage
|
||||
{
|
||||
internal class PathToAddHandler
|
||||
{
|
||||
string m_PathsToFilter;
|
||||
readonly CodeCoverageWindow m_Parent;
|
||||
readonly PathFilterType m_PathFilterType;
|
||||
|
||||
private readonly string kSelectIncludedDirectoryMessage = L10n.Tr($"Select directory to include");
|
||||
private readonly string kSelectIncludedFileMessage = L10n.Tr("Select file to include");
|
||||
private readonly string kSelectExcludedDirectoryMessage = L10n.Tr($"Select directory to exclude");
|
||||
private readonly string kSelectExcludedFileMessage = L10n.Tr("Select file to exclude");
|
||||
|
||||
public PathToAddHandler(CodeCoverageWindow parent, PathFilterType type)
|
||||
{
|
||||
m_Parent = parent;
|
||||
m_PathFilterType = type;
|
||||
}
|
||||
|
||||
public void BrowseForDir(string pathsToFilter)
|
||||
{
|
||||
m_PathsToFilter = pathsToFilter;
|
||||
|
||||
string candidate = CoverageUtils.BrowseForDir(Application.dataPath, m_PathFilterType == PathFilterType.Include ? kSelectIncludedDirectoryMessage : kSelectExcludedDirectoryMessage);
|
||||
if (CoverageUtils.IsValidFolder(candidate))
|
||||
{
|
||||
candidate = string.Concat(candidate, "/**");
|
||||
|
||||
UpdatePathToFilter(candidate);
|
||||
}
|
||||
}
|
||||
|
||||
public void BrowseForFile(string pathsToFilter)
|
||||
{
|
||||
m_PathsToFilter = pathsToFilter;
|
||||
|
||||
string candidate = CoverageUtils.BrowseForFile(Application.dataPath, m_PathFilterType == PathFilterType.Include ? kSelectIncludedFileMessage : kSelectExcludedFileMessage);
|
||||
if (CoverageUtils.IsValidFile(candidate))
|
||||
{
|
||||
UpdatePathToFilter(candidate);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePathToFilter(string candidate)
|
||||
{
|
||||
string[] pathFilters = m_PathsToFilter.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
candidate = CoverageUtils.NormaliseFolderSeparators(candidate);
|
||||
|
||||
if (!pathFilters.Contains(candidate))
|
||||
{
|
||||
if (m_PathsToFilter.Length > 0)
|
||||
m_PathsToFilter += ",";
|
||||
m_PathsToFilter += candidate;
|
||||
|
||||
if (m_PathFilterType == PathFilterType.Include)
|
||||
{
|
||||
m_Parent.PathsToInclude = m_PathsToFilter;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Parent.PathsToExclude = m_PathsToFilter;
|
||||
}
|
||||
|
||||
m_Parent.LoseFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b5c2f62cdd9230479f2ad68d036975a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user