public bool IsPathIncluded(string name)
        {
            if (!m_HasIncludePaths && !m_HasExcludePaths)
            {
                return(true);
            }

            name = name.ToLowerInvariant();
            name = CoverageUtils.NormaliseFolderSeparators(name, true);

            if (m_ExcludePaths.Any(f => f.IsMatch(name)))
            {
                return(false);
            }
            else
            {
                return(m_HasIncludePaths ? m_IncludePaths.Any(f => f.IsMatch(name)) : true);
            }
        }
        internal CoverageSession GenerateOpenCoverSession()
        {
            ResultsLogger.LogSessionItem("Started OpenCover Session", LogVerbosityLevel.Info);
            CoverageSession coverageSession = null;

            UInt32        fileUID    = 0;
            List <Module> moduleList = new List <Module>();

            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();

            float progressInterval = 0.9f / assemblies.Length;
            float currentProgress  = 0.0f;

            bool shouldGenerateAdditionalMetrics = m_ReporterFilter.ShouldGenerateAdditionalMetrics();

            foreach (Assembly assembly in assemblies)
            {
                string assemblyName = assembly.GetName().Name.ToLower();

                ResultsLogger.LogSessionItem($"Processing assembly: {assemblyName}", LogVerbosityLevel.Verbose);

                try
                {
                    if (assembly.GetCustomAttribute <ExcludeFromCoverageAttribute>() != null ||
                        assembly.GetCustomAttribute <ExcludeFromCodeCoverageAttribute>() != null)
                    {
                        ResultsLogger.LogSessionItem($"Excluded assembly (ExcludeFromCoverage): {assemblyName}", LogVerbosityLevel.Verbose);
                        continue;
                    }
                }
                catch
                {
                    ResultsLogger.Log(ResultID.Warning_ExcludeAttributeAssembly, assemblyName);
                }

                if (!CommandLineManager.instance.batchmode)
                {
                    EditorUtility.DisplayProgressBar(Styles.ProgressTitle.text, Styles.ProgressGatheringResults.text, currentProgress);
                }
                currentProgress += progressInterval;

                if (!m_ReporterFilter.ShouldProcessAssembly(assemblyName))
                {
                    ResultsLogger.LogSessionItem($"Excluded assembly (Assembly Filtering): {assemblyName}", LogVerbosityLevel.Verbose);
                    continue;
                }

                List <Class>  coveredClasses         = new List <Class>();
                List <string> filesNotFound          = new List <string>();
                Dictionary <string, UInt32> fileList = new Dictionary <string, UInt32>();
                Type[] assemblyTypes = null;
                m_ExcludedMethods = null;
                m_ExcludedTypes   = null;

                try
                {
                    assemblyTypes = assembly.GetTypes();
                }
                catch (ReflectionTypeLoadException ex)
                {
                    // This exception can be thrown if some of the types from this assembly can't be loaded. If this
                    // happens, the Types property array contains a Type for all loaded types and null for each
                    // type that couldn't be loaded.
                    assemblyTypes = ex.Types;
                    m_ReporterFilter.ShouldProcessAssembly(assemblyName);
                }

                // Debug.Assert(assemblyTypes != null)
                ResultsLogger.Log(ResultID.Assert_NullAssemblyTypes, assemblyTypes == null ? "0" : "1");

                ResultsLogger.LogSessionItem($"Processing included assembly: {assemblyName}", LogVerbosityLevel.Info);

                foreach (Type type in assemblyTypes)
                {
                    // The type can be null if the ReflectionTypeLoadException has been thrown previously.
                    if (type == null)
                    {
                        continue;
                    }

                    string className = type.FullName;
                    ResultsLogger.LogSessionItem($"Processing class: {className}", LogVerbosityLevel.Verbose);

                    try
                    {
                        if (type.GetCustomAttribute <ExcludeFromCoverageAttribute>() != null ||
                            type.GetCustomAttribute <ExcludeFromCodeCoverageAttribute>() != null ||
                            CheckIfParentMemberIsExcluded(type))
                        {
                            ResultsLogger.LogSessionItem($"Excluded class (ExcludeFromCoverage): {className}", LogVerbosityLevel.Verbose);
                            if (m_ExcludedTypes == null)
                            {
                                m_ExcludedTypes = new List <string>();
                            }
                            m_ExcludedTypes.Add(type.FullName);
                            continue;
                        }
                    }
                    catch
                    {
                        ResultsLogger.Log(ResultID.Warning_ExcludeAttributeClass, className, assemblyName);
                    }

                    ResultsLogger.LogSessionItem($"Processing included class: {className}", LogVerbosityLevel.Info);

                    CoveredMethodStats[] classMethodStatsArray = Coverage.GetStatsFor(type);
                    if (classMethodStatsArray.Length > 0)
                    {
                        List <Method> coveredMethods = new List <Method>();

                        foreach (CoveredMethodStats classMethodStats in classMethodStatsArray)
                        {
                            MethodBase method = classMethodStats.method;

                            if (method == null)
                            {
                                continue;
                            }

                            string methodName = method.Name;

                            ResultsLogger.LogSessionItem($"Processing method: {methodName}", LogVerbosityLevel.Verbose);

                            try
                            {
                                if (method.GetCustomAttribute <ExcludeFromCoverageAttribute>() != null ||
                                    method.GetCustomAttribute <ExcludeFromCodeCoverageAttribute>() != null ||
                                    CheckIfParentMemberIsExcluded(method))
                                {
                                    ResultsLogger.LogSessionItem($"Excluded method (ExcludeFromCoverage): {methodName}", LogVerbosityLevel.Verbose);
                                    if (m_ExcludedMethods == null)
                                    {
                                        m_ExcludedMethods = new List <MethodBase>();
                                    }
                                    m_ExcludedMethods.Add(method);
                                    continue;
                                }
                            }
                            catch
                            {
                                ResultsLogger.Log(ResultID.Warning_ExcludeAttributeMethod, methodName, className, assemblyName);
                            }

                            if (IsGetterSetterPropertyExcluded(method, type))
                            {
                                ResultsLogger.LogSessionItem($"Excluded method (ExcludeFromCoverage): {methodName}", LogVerbosityLevel.Verbose);
                                continue;
                            }

                            if (classMethodStats.totalSequencePoints > 0)
                            {
                                List <SequencePoint> coveredSequencePoints = new List <SequencePoint>();

                                uint fileId = 0;
                                CoveredSequencePoint[] classMethodSequencePointsArray = Coverage.GetSequencePointsFor(method);
                                foreach (CoveredSequencePoint classMethodSequencePoint in classMethodSequencePointsArray)
                                {
                                    string filename = classMethodSequencePoint.filename;
                                    if (filesNotFound.Contains(filename) || !m_ReporterFilter.ShouldProcessFile(filename))
                                    {
                                        ResultsLogger.LogSessionItem($"Excluded method (Path Filtering): {methodName}", LogVerbosityLevel.Verbose);
                                        continue;
                                    }

                                    if (!fileList.TryGetValue(filename, out fileId))
                                    {
                                        if (!File.Exists(filename))
                                        {
                                            filesNotFound.Add(filename);
                                            continue;
                                        }
                                        else
                                        {
                                            fileId = ++fileUID;
                                            fileList.Add(filename, fileId);
                                        }
                                    }

                                    SequencePoint coveredSequencePoint = new SequencePoint();
                                    coveredSequencePoint.FileId      = fileId;
                                    coveredSequencePoint.StartLine   = (int)classMethodSequencePoint.line;
                                    coveredSequencePoint.StartColumn = (int)classMethodSequencePoint.column;
                                    coveredSequencePoint.EndLine     = (int)classMethodSequencePoint.line;
                                    coveredSequencePoint.EndColumn   = (int)classMethodSequencePoint.column;
                                    coveredSequencePoint.VisitCount  = (int)classMethodSequencePoint.hitCount;
                                    coveredSequencePoint.Offset      = (int)classMethodSequencePoint.ilOffset;
                                    coveredSequencePoints.Add(coveredSequencePoint);
                                }

                                if (coveredSequencePoints.Count > 0)
                                {
                                    Method coveredMethod = new Method();
                                    coveredMethod.MetadataToken = method.MetadataToken;
                                    coveredMethod.FullName      = GenerateMethodName(method);
                                    coveredMethod.FileRef       = new FileRef()
                                    {
                                        UniqueId = fileId
                                    };
                                    coveredMethod.IsConstructor  = IsConstructor(method) || IsStaticConstructor(method);
                                    coveredMethod.IsStatic       = method.IsStatic;
                                    coveredMethod.IsSetter       = IsPropertySetter(method);
                                    coveredMethod.IsGetter       = IsPropertyGetter(method);
                                    coveredMethod.SequencePoints = coveredSequencePoints.ToArray();
                                    if (shouldGenerateAdditionalMetrics)
                                    {
                                        coveredMethod.CyclomaticComplexity = method.CalculateCyclomaticComplexity();
                                    }

                                    ResultsLogger.LogSessionItem($"Processing included method: {coveredMethod.FullName}", LogVerbosityLevel.Verbose);

                                    coveredMethods.Add(coveredMethod);
                                }
                            }
                        }

                        if (coveredMethods.Count > 0)
                        {
                            Class coveredClass = new Class();
                            coveredClass.FullName = GenerateTypeName(type);
                            coveredClass.Methods  = coveredMethods.ToArray();
                            coveredClasses.Add(coveredClass);
                        }
                    }
                }

                if (coveredClasses.Count != 0)
                {
                    Module module = new Module();
                    module.ModuleName = assembly.GetName().Name;
                    List <ModelFile> coveredFileList = new List <ModelFile>();
                    foreach (KeyValuePair <string, UInt32> fileEntry in fileList)
                    {
                        ModelFile coveredFile = new ModelFile();
                        coveredFile.FullPath = CoverageUtils.NormaliseFolderSeparators(fileEntry.Key);
                        if (CommandLineManager.instance.pathStrippingSpecified)
                        {
                            coveredFile.FullPath = CommandLineManager.instance.pathStripping.StripPath(coveredFile.FullPath);
                        }
                        coveredFile.UniqueId = fileEntry.Value;

                        coveredFileList.Add(coveredFile);
                    }
                    module.Files   = coveredFileList.ToArray();
                    module.Classes = coveredClasses.ToArray();
                    moduleList.Add(module);
                }
            }

            if (moduleList.Count > 0)
            {
                coverageSession         = new CoverageSession();
                coverageSession.Modules = moduleList.ToArray();
                ProcessGenericMethods(coverageSession);

                foreach (Module coveredModule in moduleList)
                {
                    foreach (Class coveredClass in coveredModule.Classes)
                    {
                        foreach (Method coveredMethod in coveredClass.Methods)
                        {
                            UpdateMethodSummary(coveredMethod);
                        }
                        UpdateClassSummary(coveredClass);
                    }
                    UpdateModuleSummary(coveredModule);
                }

                UpdateSessionSummary(coverageSession);
            }

            ResultsLogger.LogSessionItem("Finished OpenCover Session", LogVerbosityLevel.Info);

            return(coverageSession);
        }
Exemple #3
0
 public void SetStringForPaths(string key, string value, SettingsScope scope = SettingsScope.Project)
 {
     value = CoverageUtils.NormaliseFolderSeparators(value, false);
     value = value.Replace(CoverageUtils.GetProjectPath(), k_ProjectPathAlias);
     SetString(key, value, scope);
 }
        static CoverageReporterStarter()
        {
#if NO_COV_EDITORPREF
            if (!CommandLineManager.instance.runFromCommandLine)
            {
                bool localCoverageEnabled = CoveragePreferences.instance.GetBool("EnableCodeCoverage", false);
                if (localCoverageEnabled != Coverage.enabled)
                {
                    Coverage.enabled = localCoverageEnabled;
                }

                PackageManager.Events.registeringPackages += OnRegisteringPackages;
            }
#endif
            if (!Coverage.enabled)
            {
                return;
            }

#if CONDITIONAL_IGNORE_SUPPORTED
            ConditionalIgnoreAttribute.AddConditionalIgnoreMapping("IgnoreForCoverage", true);
#endif
            CoverageReporterListener listener = ScriptableObject.CreateInstance <CoverageReporterListener>();

#if TEST_FRAMEWORK_1_2_OR_NEWER
            TestRunnerApi.RegisterTestCallback(listener);
#else
            TestRunnerApi api = ScriptableObject.CreateInstance <TestRunnerApi>();
            api.RegisterCallbacks(listener);
#endif

            CoverageSettings coverageSettings = new CoverageSettings()
            {
                resultsPathFromCommandLine = CommandLineManager.instance.coverageResultsPath,
                historyPathFromCommandLine = CommandLineManager.instance.coverageHistoryPath
            };

            CoverageReporterManager = new CoverageReporterManager(coverageSettings);

            listener.CoverageReporterManager = CoverageReporterManager;

            AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload;
            AssemblyReloadEvents.afterAssemblyReload  += OnAfterAssemblyReload;

            // Generate a report if running from the command line,
            // generateHTMLReport or generateBadgeReport is passed to -coverageOptions
            // and -runTests has not been passed to the command line,
            // regardless if AutoGenerate is selected in the UI
            if (CommandLineManager.instance.runFromCommandLine &&
                CoverageReporterManager.ShouldAutoGenerateReport(false) &&
                !CommandLineManager.instance.runTests &&
                !CoverageRunData.instance.reportWasGenerated)
            {
                // Start the timer for analytics for Report only
                CoverageAnalytics.instance.StartTimer();
                CoverageAnalytics.instance.CurrentCoverageEvent.actionID = ActionID.ReportOnly;

                coverageSettings.rootFolderPath    = CoverageUtils.GetRootFolderPath(coverageSettings);
                coverageSettings.historyFolderPath = CoverageUtils.GetHistoryFolderPath(coverageSettings);

                CoverageReporterManager.ReportGenerator.Generate(coverageSettings);
            }
        }
 public void ClearCoverageFolderIfExists()
 {
     CoverageUtils.ClearFolderIfExists(m_CoverageSettings.resultsFolderPath, "*.xml");
 }
        public void SendCoverageEvent(bool success)
        {
            CurrentCoverageEvent.success   = success;
            CurrentCoverageEvent.duration  = CoverageTimer.elapsedTimeMs;
            CurrentCoverageEvent.resultIds = s_ResultsIdsList.ToArray();

            bool runFromCommandLine = CommandLineManager.instance.runFromCommandLine;
            bool batchmode          = CommandLineManager.instance.batchmode;
            bool useProjectSettings = CommandLineManager.instance.useProjectSettings;

            CurrentCoverageEvent.runFromCommandLine = runFromCommandLine;
            CurrentCoverageEvent.batchmode          = batchmode;
            CurrentCoverageEvent.useProjectSettings = useProjectSettings;

            if (batchmode && !useProjectSettings)
            {
                CurrentCoverageEvent.autogenerate              = CommandLineManager.instance.generateBadgeReport || CommandLineManager.instance.generateHTMLReport;
                CurrentCoverageEvent.createBadges              = CommandLineManager.instance.generateBadgeReport;
                CurrentCoverageEvent.generateHistory           = CommandLineManager.instance.generateHTMLReportHistory;
                CurrentCoverageEvent.generateHTMLReport        = CommandLineManager.instance.generateHTMLReport;
                CurrentCoverageEvent.generateMetrics           = CommandLineManager.instance.generateAdditionalMetrics;
                CurrentCoverageEvent.useDefaultAssemblyFilters = !CommandLineManager.instance.assemblyFiltersSpecified;
                CurrentCoverageEvent.useDefaultPathFilters     = !CommandLineManager.instance.pathFiltersSpecified;
                CurrentCoverageEvent.useDefaultResultsLoc      = CommandLineManager.instance.coverageResultsPath.Length == 0;
                CurrentCoverageEvent.useDefaultHistoryLoc      = CommandLineManager.instance.coverageHistoryPath.Length == 0;
                CurrentCoverageEvent.usePathStrippingPatterns  = CommandLineManager.instance.pathStrippingSpecified;
                CurrentCoverageEvent.useSourcePaths            = CommandLineManager.instance.sourcePathsSpecified;
            }
            else
            {
                CurrentCoverageEvent.autogenerate             = CommandLineManager.instance.generateBadgeReport || CommandLineManager.instance.generateHTMLReport || CoveragePreferences.instance.GetBool("AutoGenerateReport", true);
                CurrentCoverageEvent.createBadges             = CommandLineManager.instance.generateBadgeReport || CoveragePreferences.instance.GetBool("GenerateBadge", true);
                CurrentCoverageEvent.generateHistory          = CommandLineManager.instance.generateHTMLReportHistory || CoveragePreferences.instance.GetBool("IncludeHistoryInReport", true);
                CurrentCoverageEvent.generateHTMLReport       = CommandLineManager.instance.generateHTMLReport || CoveragePreferences.instance.GetBool("GenerateHTMLReport", true);
                CurrentCoverageEvent.generateMetrics          = CommandLineManager.instance.generateAdditionalMetrics || CoveragePreferences.instance.GetBool("GenerateAdditionalMetrics", false);
                CurrentCoverageEvent.usePathStrippingPatterns = CommandLineManager.instance.pathStrippingSpecified;
                CurrentCoverageEvent.useSourcePaths           = CommandLineManager.instance.sourcePathsSpecified;

                CurrentCoverageEvent.useDefaultAssemblyFilters = !CommandLineManager.instance.assemblyFiltersSpecified;
                if (!CommandLineManager.instance.assemblyFiltersSpecified)
                {
                    CurrentCoverageEvent.useDefaultAssemblyFilters = string.Equals(CoveragePreferences.instance.GetString("IncludeAssemblies", AssemblyFiltering.GetUserOnlyAssembliesString()), AssemblyFiltering.GetUserOnlyAssembliesString(), StringComparison.InvariantCultureIgnoreCase);
                }

                CurrentCoverageEvent.useDefaultPathFilters = !CommandLineManager.instance.pathFiltersSpecified;
                if (!CommandLineManager.instance.pathFiltersSpecified)
                {
                    CurrentCoverageEvent.useDefaultPathFilters = string.Equals(CoveragePreferences.instance.GetString("PathsToInclude", string.Empty), string.Empty) && string.Equals(CoveragePreferences.instance.GetString("PathsToExclude", string.Empty), string.Empty);
                }

                CurrentCoverageEvent.useDefaultResultsLoc = CommandLineManager.instance.coverageResultsPath.Length == 0;
                if (CommandLineManager.instance.coverageResultsPath.Length == 0)
                {
                    CurrentCoverageEvent.useDefaultResultsLoc = string.Equals(CoveragePreferences.instance.GetStringForPaths("Path", string.Empty), CoverageUtils.GetProjectPath(), StringComparison.InvariantCultureIgnoreCase);
                }

                CurrentCoverageEvent.useDefaultHistoryLoc = CommandLineManager.instance.coverageHistoryPath.Length == 0;
                if (CommandLineManager.instance.coverageHistoryPath.Length == 0)
                {
                    CurrentCoverageEvent.useDefaultHistoryLoc = string.Equals(CoveragePreferences.instance.GetStringForPaths("HistoryPath", string.Empty), CoverageUtils.GetProjectPath(), StringComparison.InvariantCultureIgnoreCase);
                }
            }

#if UNITY_2020_1_OR_NEWER
            CurrentCoverageEvent.inDebugMode = Compilation.CompilationPipeline.codeOptimization == Compilation.CodeOptimization.Debug;
#else
            CurrentCoverageEvent.inDebugMode = true;
#endif
            if (!runFromCommandLine || (runFromCommandLine && !batchmode && !CommandLineManager.instance.assemblyFiltersSpecified))
            {
                if (CurrentCoverageEvent.actionID == ActionID.ReportOnly)
                {
                    string   includeAssemblies      = CoveragePreferences.instance.GetString("IncludeAssemblies", AssemblyFiltering.GetUserOnlyAssembliesString());
                    string[] includeAssembliesArray = includeAssemblies.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    CurrentCoverageEvent.includedAssemblies = includeAssembliesArray;
                }
            }

            Send(EventName.codeCoverage, CurrentCoverageEvent);

            ResetEvents();
        }
        public void SetupCoveragePaths()
        {
            string folderName = CoverageUtils.GetProjectFolderName();
            string resultsRootDirectoryName = string.Concat(folderName, m_CoverageSettings.resultsFolderSuffix);

            bool isRecording = CoverageRunData.instance.isRecording;

            // We want to save in the 'Recording' subdirectory of the results folder when recording
#if TEST_FRAMEWORK_1_2_OR_NEWER
            string testSuite = isRecording ? "Recording" : "Automated";
#else
            string testSuite = isRecording ? "Recording" : TestContext.Parameters.Get("platform");
#endif
            string directoryName = CoverageUtils.JoinPaths(resultsRootDirectoryName, testSuite != null ? testSuite : "");

            m_CoverageSettings.rootFolderPath    = CoverageUtils.GetRootFolderPath(m_CoverageSettings);
            m_CoverageSettings.historyFolderPath = CoverageUtils.GetHistoryFolderPath(m_CoverageSettings);

            string filePath = CoverageUtils.JoinPaths(directoryName, m_CoverageSettings.resultsFileName);
            filePath = CoverageUtils.JoinPaths(m_CoverageSettings.rootFolderPath, filePath);
            filePath = CoverageUtils.NormaliseFolderSeparators(filePath);
            CoverageUtils.EnsureFolderExists(Path.GetDirectoryName(filePath));

            m_CoverageSettings.resultsRootFolderPath = CoverageUtils.NormaliseFolderSeparators(CoverageUtils.JoinPaths(m_CoverageSettings.rootFolderPath, resultsRootDirectoryName));
            m_CoverageSettings.resultsFolderPath     = CoverageUtils.NormaliseFolderSeparators(CoverageUtils.JoinPaths(m_CoverageSettings.rootFolderPath, directoryName));
            m_CoverageSettings.resultsFilePath       = filePath;
        }
        private void ParseCoverageOptions()
        {
            m_CoverageOptions = m_CoverageOptionsArg.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string optionArgsStr in m_CoverageOptions)
            {
                if (optionArgsStr.Length == 0)
                {
                    continue;
                }

                string optionName = optionArgsStr;
                string optionArgs = string.Empty;

                int indexOfColon = optionArgsStr.IndexOf(':');
                if (indexOfColon > 0)
                {
                    optionName = optionArgsStr.Substring(0, indexOfColon);
                    optionArgs = optionArgsStr.Substring(indexOfColon + 1);
                }

                switch (optionName.ToUpperInvariant())
                {
                case "GENERATEADDITIONALMETRICS":
                    generateAdditionalMetrics = true;
                    break;

                case "GENERATEHTMLREPORTHISTORY":
                    generateHTMLReportHistory = true;
                    break;

                case "GENERATEHTMLREPORT":
                    generateHTMLReport = true;
                    break;

                case "GENERATEBADGEREPORT":
                    generateBadgeReport = true;
                    break;

                case "USEPROJECTSETTINGS":
                    if (batchmode)
                    {
                        useProjectSettings = true;
                    }
                    else
                    {
                        ResultsLogger.Log(ResultID.Warning_UseProjectSettingsNonBatchmode);
                    }
                    break;

                case "VERBOSITY":
                    if (optionArgs.Length > 0)
                    {
                        switch (optionArgs.ToUpperInvariant())
                        {
                        case "VERBOSE":
                            ResultsLogger.VerbosityLevel = LogVerbosityLevel.Verbose;
                            break;

                        case "INFO":
                            ResultsLogger.VerbosityLevel = LogVerbosityLevel.Info;
                            break;

                        case "WARNING":
                            ResultsLogger.VerbosityLevel = LogVerbosityLevel.Warning;
                            break;

                        case "ERROR":
                            ResultsLogger.VerbosityLevel = LogVerbosityLevel.Error;
                            break;

                        case "OFF":
                            ResultsLogger.VerbosityLevel = LogVerbosityLevel.Off;
                            break;
                        }
                    }
                    break;

                case "ASSEMBLYFILTERS":
                    if (optionArgs.Length > 0)
                    {
                        assemblyFiltersSpecified = true;

                        string[] assemblyFilters = optionArgs.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                        for (int i = 0; i < assemblyFilters.Length; ++i)
                        {
                            string filter     = assemblyFilters[i];
                            string filterBody = filter.Length > 1 ? filter.Substring(1) : string.Empty;

                            if (filter.StartsWith("+", StringComparison.OrdinalIgnoreCase))
                            {
                                if (m_IncludeAssemblies.Length > 0)
                                {
                                    m_IncludeAssemblies += ",";
                                }

                                if (filterBody.StartsWith("<", StringComparison.OrdinalIgnoreCase))
                                {
                                    if (string.Equals(filterBody, AssemblyFiltering.kUserAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_IncludeAssemblies += AssemblyFiltering.GetUserOnlyAssembliesString();
                                    }
                                    else if (string.Equals(filterBody, AssemblyFiltering.kProjectAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_IncludeAssemblies += AssemblyFiltering.GetAllProjectAssembliesString();
                                    }
                                    else if (string.Equals(filterBody, AssemblyFiltering.kPackagesAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_IncludeAssemblies += AssemblyFiltering.GetPackagesOnlyAssembliesString();
                                    }
                                    else if (string.Equals(filterBody, AssemblyFiltering.kAllAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_IncludeAssemblies += "*";
                                    }
                                }
                                else
                                {
                                    m_IncludeAssemblies += filterBody;
                                }
                            }
                            else if (filter.StartsWith("-", StringComparison.OrdinalIgnoreCase))
                            {
                                if (m_ExcludeAssemblies.Length > 0)
                                {
                                    m_ExcludeAssemblies += ",";
                                }

                                if (filterBody.StartsWith("<", StringComparison.OrdinalIgnoreCase))
                                {
                                    if (string.Equals(filterBody, AssemblyFiltering.kUserAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_ExcludeAssemblies += AssemblyFiltering.GetUserOnlyAssembliesString();
                                    }
                                    else if (string.Equals(filterBody, AssemblyFiltering.kProjectAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_ExcludeAssemblies += AssemblyFiltering.GetAllProjectAssembliesString();
                                    }
                                    else if (string.Equals(filterBody, AssemblyFiltering.kPackagesAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_ExcludeAssemblies += AssemblyFiltering.GetPackagesOnlyAssembliesString();
                                    }
                                    else if (string.Equals(filterBody, AssemblyFiltering.kAllAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_ExcludeAssemblies += "*";
                                    }
                                }
                                else
                                {
                                    m_ExcludeAssemblies += filterBody;
                                }
                            }
                            else
                            {
                                ResultsLogger.Log(ResultID.Warning_AssemblyFiltersNotPrefixed, filter);
                            }
                        }
                    }
                    break;

                case "PATHFILTERS":
                    if (optionArgs.Length > 0)
                    {
                        pathFiltersSpecified = true;

                        string[] pathFilters = optionArgs.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                        for (int i = 0; i < pathFilters.Length; ++i)
                        {
                            string filter     = pathFilters[i];
                            string filterBody = filter.Length > 1 ? filter.Substring(1) : string.Empty;

                            if (filter.StartsWith("+", StringComparison.OrdinalIgnoreCase))
                            {
                                if (m_IncludePaths.Length > 0)
                                {
                                    m_IncludePaths += ",";
                                }
                                m_IncludePaths += filterBody;
                            }
                            else if (filter.StartsWith("-", StringComparison.OrdinalIgnoreCase))
                            {
                                if (m_ExcludePaths.Length > 0)
                                {
                                    m_ExcludePaths += ",";
                                }
                                m_ExcludePaths += filterBody;
                            }
                            else
                            {
                                ResultsLogger.Log(ResultID.Warning_PathFiltersNotPrefixed, filter);
                            }
                        }
                    }
                    break;

                case "PATHSTRIPPINGPATTERNS":
                    if (optionArgs.Length > 0)
                    {
                        pathStrippingSpecified  = true;
                        m_PathStrippingPatterns = optionArgs;
                    }
                    break;

                case "SOURCEPATHS":
                    if (optionArgs.Length > 0)
                    {
                        sourcePathsSpecified = true;

                        string[] rawSourcePaths = optionArgs.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < rawSourcePaths.Length; ++i)
                        {
                            if (sourcePaths.Length > 0)
                            {
                                sourcePaths += ",";
                            }
                            sourcePaths += CoverageUtils.NormaliseFolderSeparators(rawSourcePaths[i]);
                        }
                    }
                    break;
                }
            }

            if (m_IncludeAssemblies.Length == 0)
            {
                // If there are no inlcudedAssemblies specified but there are includedPaths specified
                // then include all project assemblies so path filtering can take precedence over assembly filtering,
                // othewise if there are no includedPaths specified neither then inlcude just the user assemblies (found under the Assets folder)

                if (m_IncludePaths.Length > 0)
                {
                    m_IncludeAssemblies = AssemblyFiltering.GetAllProjectAssembliesString();
                }
                else
                {
                    m_IncludeAssemblies = AssemblyFiltering.GetUserOnlyAssembliesString();
                }
            }

            if (m_ExcludeAssemblies.Length > 0)
            {
                m_ExcludeAssemblies += ",";
            }

            m_ExcludeAssemblies += AssemblyFiltering.kDefaultExcludedAssemblies;

            assemblyFiltering.Parse(m_IncludeAssemblies, m_ExcludeAssemblies);
            pathFiltering.Parse(m_IncludePaths, m_ExcludePaths);
            pathStripping.Parse(m_PathStrippingPatterns);
        }
Exemple #9
0
        public static Regex CreateFilterRegex(string filter)
        {
            filter = filter.ToLowerInvariant();

            return(new Regex(CoverageUtils.GlobToRegex(filter), RegexOptions.Compiled));
        }
        Regex CreateFilterRegex(string filter)
        {
            filter = CoverageUtils.NormaliseFolderSeparators(filter);

            return(new Regex(CoverageUtils.GlobToRegex(filter, false), RegexOptions.Compiled | RegexOptions.IgnoreCase));
        }
        public void Generate(CoverageSettings coverageSettings)
        {
            CoverageRunData.instance.ReportGenerationStart();

            if (coverageSettings == null)
            {
                EditorUtility.ClearProgressBar();
                ResultsLogger.Log(ResultID.Warning_FailedReportNullCoverageSettings);
                CoverageRunData.instance.ReportGenerationEnd(false);
                return;
            }

            string includeAssemblies = string.Empty;

            if (CommandLineManager.instance.batchmode && !CommandLineManager.instance.useProjectSettings)
            {
                includeAssemblies = CommandLineManager.instance.assemblyFiltering.includedAssemblies;
            }
            else
            {
                includeAssemblies = CommandLineManager.instance.assemblyFiltersSpecified ?
                                    CommandLineManager.instance.assemblyFiltering.includedAssemblies :
                                    CoveragePreferences.instance.GetString("IncludeAssemblies", AssemblyFiltering.GetUserOnlyAssembliesString());
            }

            // If override for include assemblies is set in coverageSettings, use overrideIncludeAssemblies instead
            if (!String.IsNullOrEmpty(coverageSettings.overrideIncludeAssemblies))
            {
                includeAssemblies = coverageSettings.overrideIncludeAssemblies;
            }

            string[] includeAssembliesArray = includeAssemblies.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < includeAssembliesArray.Length; i++)
            {
                includeAssembliesArray[i] = "+" + includeAssembliesArray[i];
            }
            string assemblies = string.Join(",", includeAssembliesArray);

            string[] assemblyFilters = assemblies.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            if (assemblyFilters.Length == 0)
            {
                EditorUtility.ClearProgressBar();
                ResultsLogger.Log(ResultID.Error_FailedReportNoAssemblies);
                CoverageRunData.instance.ReportGenerationEnd(false);
                return;
            }

            string rootFolderPath = coverageSettings.rootFolderPath;

            if (!CoverageUtils.DoesFolderExistAndNotEmpty(rootFolderPath) || CoverageUtils.GetNumberOfFilesInFolder(rootFolderPath, "*.xml", SearchOption.AllDirectories) == 0)
            {
                EditorUtility.ClearProgressBar();
                ResultsLogger.Log(ResultID.Error_FailedReportNoTests);
                CoverageRunData.instance.ReportGenerationEnd(false);
                return;
            }

            // Only include xml files with the correct filename format
            string sourceXmlPath           = CoverageUtils.JoinPaths(rootFolderPath, "**");
            string testResultsXmlPath      = CoverageUtils.JoinPaths(sourceXmlPath, "TestCoverageResults_????.xml");
            string recordingResultsXmlPath = CoverageUtils.JoinPaths(sourceXmlPath, "RecordingCoverageResults_????.xml");

            string[] reportFilePatterns = new string[] { testResultsXmlPath, recordingResultsXmlPath };

            bool includeHistoryInReport = CommandLineManager.instance.batchmode && !CommandLineManager.instance.useProjectSettings ?
                                          CommandLineManager.instance.generateHTMLReportHistory :
                                          CommandLineManager.instance.generateHTMLReportHistory || CoveragePreferences.instance.GetBool("IncludeHistoryInReport", true);

            string historyDirectory = includeHistoryInReport ? coverageSettings.historyFolderPath : null;

            string targetDirectory = CoverageUtils.JoinPaths(rootFolderPath, CoverageSettings.ReportFolderName);

            string[] sourceDirectories = CommandLineManager.instance.sourcePathsSpecified ? CommandLineManager.instance.sourcePaths.Split(',') : new string[] { };

            bool generateHTMLReport = CommandLineManager.instance.batchmode && !CommandLineManager.instance.useProjectSettings ?
                                      CommandLineManager.instance.generateHTMLReport :
                                      CommandLineManager.instance.generateHTMLReport || CoveragePreferences.instance.GetBool("GenerateHTMLReport", true);

            if (coverageSettings.overrideGenerateReport)
            {
                generateHTMLReport = true;
            }

            bool generateBadge = CommandLineManager.instance.batchmode && !CommandLineManager.instance.useProjectSettings ?
                                 CommandLineManager.instance.generateBadgeReport :
                                 CommandLineManager.instance.generateBadgeReport || CoveragePreferences.instance.GetBool("GenerateBadge", true);

            string reportTypesString = "xmlSummary,";

            if (generateHTMLReport)
            {
                reportTypesString += "Html,";
            }
            if (generateBadge)
            {
                reportTypesString += "Badges,";
            }

            string[] reportTypes = reportTypesString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            string[] plugins     = new string[] { };

            bool includeAdditionalMetrics = CommandLineManager.instance.batchmode && !CommandLineManager.instance.useProjectSettings ?
                                            CommandLineManager.instance.generateAdditionalMetrics :
                                            CommandLineManager.instance.generateAdditionalMetrics || CoveragePreferences.instance.GetBool("GenerateAdditionalMetrics", false);

            string[] classFilters   = new string[] { };
            string[] fileFilters    = new string[] { };
            string   verbosityLevel = null;
            string   tag            = null;

            ReportConfiguration config = new ReportConfiguration(
                reportFilePatterns,
                targetDirectory,
                sourceDirectories,
                historyDirectory,
                reportTypes,
                plugins,
                assemblyFilters,
                classFilters,
                fileFilters,
                verbosityLevel,
                tag);

            DebugFactory loggerFactory = new DebugFactory();

            LoggerFactory.Configure(loggerFactory);

            try
            {
                if (!CommandLineManager.instance.batchmode)
                {
                    EditorUtility.DisplayProgressBar(ReportGeneratorStyles.ProgressTitle.text, ReportGeneratorStyles.ProgressInfo.text, 0.4f);
                }

                if (Directory.Exists(targetDirectory))
                {
                    Directory.Delete(targetDirectory, true);
                }

                Generator generator = new Generator();
                if (generator.GenerateReport(config, new Settings()
                {
                    DisableRiskHotspots = !includeAdditionalMetrics
                }, new RiskHotspotsAnalysisThresholds()))
                {
                    ResultsLogger.Log(ResultID.Log_ReportSaved, targetDirectory);

                    CoverageRunData.instance.ReportGenerationEnd(true);

                    // Send Analytics event (Report Only / Data & Report)
                    CoverageAnalytics.instance.SendCoverageEvent(true);

                    if (!CommandLineManager.instance.batchmode &&
                        coverageSettings.revealReportInFinder)
                    {
                        string indexHtm = CoverageUtils.JoinPaths(targetDirectory, "index.htm");
                        if (File.Exists(indexHtm))
                        {
                            EditorUtility.RevealInFinder(indexHtm);
                        }
                        else
                        {
                            EditorUtility.RevealInFinder(targetDirectory);
                        }
                    }
                }
                else
                {
                    ResultsLogger.Log(ResultID.Error_FailedReport);

                    CoverageRunData.instance.ReportGenerationEnd(false);
                }
            }
            finally
            {
                EditorUtility.ClearProgressBar();
            }
        }