Ejemplo n.º 1
0
 public string FormatConsole()
 {
     var table = new ConsoleTable();
     table.AddColumn(this.headers.ToArray());
     foreach (var row in this.rows)
     {
         table.AddRow(row);
     }
     return table.ToString();
 }
Ejemplo n.º 2
0
    public static string Dump <T>(ref T value, DumpOptions options, InspectorOptions options2)
    {
        switch (options)
        {
        case DumpOptions.Info:
            //

            var addrTable = new ConsoleTable("Addresses", "");

            var addr = Mem.AddressOf(ref value);
            addrTable.AddRow("Address", addr);

            if (Mem.TryGetAddressOfHeap(value, out var heap))
            {
                addrTable.AddRow("Address (heap)", heap);
            }

            addrTable.Write(ConsoleTableFormat.Minimal);

            //

            var infoTable = new ConsoleTable("Sizes", "");

            infoTable.AddRow("Intrinsic", Mem.SizeOf <T>());
            infoTable.AddRow("Auto", Mem.SizeOf(value, SizeOfOptions.Auto));

            infoTable.Write(ConsoleTableFormat.Minimal);

            //

            var propTable = new ConsoleTable("Runtime info", "");

            propTable.AddRow("Pinnable", RuntimeProperties.IsPinnable(value));
            propTable.AddRow("Blittable", RuntimeProperties.IsBlittable(value));
            propTable.AddRow("Boxed", RuntimeProperties.IsBoxed(value));
            propTable.AddRow("Nil", RuntimeProperties.IsDefault(value));
            propTable.AddRow("Uninitialized", RuntimeProperties.IsNullMemory(value));


            propTable.AddRow("In GC heap", GCHeap.IsHeapPointer(Mem.AddressOfData(ref value)));

            return(propTable.ToMinimalString());

        case DumpOptions.Sizes:
            var layoutTable = new ConsoleTable("Size Type", "Value");

            var options1 = Enum.GetValues <SizeOfOptions>().ToList();

            options1.Remove(SizeOfOptions.Heap);


            foreach (var option in options1)
            {
                var sizeOf = Mem.SizeOf(value, option);

                if (sizeOf == Native.INVALID)
                {
                    continue;
                }

                layoutTable.AddRow(Enum.GetName(option), sizeOf);
            }

            var mt = value.GetMetaType();

            if (!mt.RuntimeType.IsValueType)
            {
                layoutTable.AddRow(nameof(SizeOfOptions.Heap), Mem.SizeOf(value, SizeOfOptions.Heap));
            }

            return(layoutTable.ToString());

        case DumpOptions.Layout:
            var layoutTable1 = new ConsoleTable();

            var flags = EnumHelper.GetSetFlags(options2);

            if (options2 == InspectorOptions.All)
            {
                flags.Remove(InspectorOptions.All);
            }

            layoutTable1.AddColumn(flags.Select(Enum.GetName));


            // Rewrite options

            options2 = default;

            foreach (var flag in flags)
            {
                options2 |= flag;
            }

            var mt1    = value.GetMetaType();
            var fields = mt1.Fields.Where(x => !x.IsStatic);

            int s = Mem.SizeOf(value, SizeOfOptions.Auto);
            var p = Mem.AddressOf(ref value);


            foreach (var metaField in fields)
            {
                var rowValues = new List <object>();


                if (options2.HasFlag(InspectorOptions.Offset))
                {
                    rowValues.Add($"{metaField.Offset:X}");
                }

                if (options2.HasFlag(InspectorOptions.Size))
                {
                    rowValues.Add(metaField.Size);
                }

                if (options2.HasFlag(InspectorOptions.Type))
                {
                    rowValues.Add(metaField.FieldType.Name);
                }

                if (options2.HasFlag(InspectorOptions.Name))
                {
                    rowValues.Add(metaField.Name);
                }

                if (options2.HasFlag(InspectorOptions.Address))
                {
                    var addr1 = Mem.AddressOfData(ref value) + metaField.Offset;
                    rowValues.Add(addr1.ToString());
                }

                if (options2.HasFlag(InspectorOptions.Value))
                {
                    object fieldVal;

                    if (!mt1.RuntimeType.IsConstructedGenericType)
                    {
                        fieldVal = metaField.Info.GetValue(value);
                    }
                    else
                    {
                        fieldVal = "?";
                    }

                    rowValues.Add($"{fieldVal}");
                }

                layoutTable1.AddRow(rowValues.ToArray());
            }


            if (value is string str)
            {
                for (int i = 1; i < str.Length; i++)
                {
                    char c          = str[i];
                    var  rowValues  = new List <object>();
                    int  offsetBase = (i * sizeof(char));

                    if (options2.HasFlag(InspectorOptions.Offset))
                    {
                        rowValues.Add($"{offsetBase + RuntimeProperties.StringOverhead - sizeof(char):X}");
                    }

                    if (options2.HasFlag(InspectorOptions.Size))
                    {
                        rowValues.Add(sizeof(char));
                    }

                    if (options2.HasFlag(InspectorOptions.Type))
                    {
                        rowValues.Add(nameof(Char));
                    }

                    if (options2.HasFlag(InspectorOptions.Name))
                    {
                        rowValues.Add($"Char #{i + 1}");
                    }

                    if (options2.HasFlag(InspectorOptions.Address))
                    {
                        if (Mem.TryGetAddressOfHeap(value, OffsetOptions.StringData, out var addr2))
                        {
                            addr2 += offsetBase;
                            rowValues.Add(addr2.ToString());
                        }
                    }

                    if (options2.HasFlag(InspectorOptions.Value))
                    {
                        rowValues.Add($"{c}");
                    }

                    layoutTable1.AddRow(rowValues.ToArray());
                }
            }


            return(layoutTable1.ToString());

        default:
            throw new ArgumentOutOfRangeException(nameof(options));
        }
    }
Ejemplo n.º 3
0
        static int Main(string[] args)
        {
            IServiceCollection serviceCollection = new ServiceCollection();

            serviceCollection.AddTransient <IRetryHelper, RetryHelper>();
            serviceCollection.AddTransient <IProcessExitHandler, ProcessExitHandler>();
            serviceCollection.AddTransient <IFileSystem, FileSystem>();
            serviceCollection.AddTransient <ILogger, ConsoleLogger>();
            // We need to keep singleton/static semantics
            serviceCollection.AddSingleton <IInstrumentationHelper, InstrumentationHelper>();
            serviceCollection.AddSingleton <ISourceRootTranslator, SourceRootTranslator>(provider => new SourceRootTranslator(provider.GetRequiredService <ILogger>(), provider.GetRequiredService <IFileSystem>()));
            serviceCollection.AddSingleton <ICecilSymbolHelper, CecilSymbolHelper>();

            ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();

            var logger     = (ConsoleLogger)serviceProvider.GetService <ILogger>();
            var fileSystem = serviceProvider.GetService <IFileSystem>();

            var app = new CommandLineApplication();

            app.Name     = "coverlet";
            app.FullName = "Cross platform .NET Core code coverage tool";
            app.HelpOption("-h|--help");
            app.VersionOption("-v|--version", GetAssemblyVersion());
            int exitCode = (int)CommandExitCodes.Success;

            CommandArgument          module              = app.Argument("<ASSEMBLY>", "Path to the test assembly.");
            CommandOption            target              = app.Option("-t|--target", "Path to the test runner application.", CommandOptionType.SingleValue);
            CommandOption            targs               = app.Option("-a|--targetargs", "Arguments to be passed to the test runner.", CommandOptionType.SingleValue);
            CommandOption            output              = app.Option("-o|--output", "Output of the generated coverage report", CommandOptionType.SingleValue);
            CommandOption <LogLevel> verbosity           = app.Option <LogLevel>("-v|--verbosity", "Sets the verbosity level of the command. Allowed values are quiet, minimal, normal, detailed.", CommandOptionType.SingleValue);
            CommandOption            formats             = app.Option("-f|--format", "Format of the generated coverage report.", CommandOptionType.MultipleValue);
            CommandOption            threshold           = app.Option("--threshold", "Exits with error if the coverage % is below value.", CommandOptionType.SingleValue);
            CommandOption            thresholdTypes      = app.Option("--threshold-type", "Coverage type to apply the threshold to.", CommandOptionType.MultipleValue);
            CommandOption            thresholdStat       = app.Option("--threshold-stat", "Coverage statistic used to enforce the threshold value.", CommandOptionType.SingleValue);
            CommandOption            excludeFilters      = app.Option("--exclude", "Filter expressions to exclude specific modules and types.", CommandOptionType.MultipleValue);
            CommandOption            includeFilters      = app.Option("--include", "Filter expressions to include only specific modules and types.", CommandOptionType.MultipleValue);
            CommandOption            excludedSourceFiles = app.Option("--exclude-by-file", "Glob patterns specifying source files to exclude.", CommandOptionType.MultipleValue);
            CommandOption            includeDirectories  = app.Option("--include-directory", "Include directories containing additional assemblies to be instrumented.", CommandOptionType.MultipleValue);
            CommandOption            excludeAttributes   = app.Option("--exclude-by-attribute", "Attributes to exclude from code coverage.", CommandOptionType.MultipleValue);
            CommandOption            includeTestAssembly = app.Option("--include-test-assembly", "Specifies whether to report code coverage of the test assembly.", CommandOptionType.NoValue);
            CommandOption            singleHit           = app.Option("--single-hit", "Specifies whether to limit code coverage hit reporting to a single hit for each location", CommandOptionType.NoValue);
            CommandOption            skipAutoProp        = app.Option("--skipautoprops", "Neither track nor record auto-implemented properties.", CommandOptionType.NoValue);
            CommandOption            mergeWith           = app.Option("--merge-with", "Path to existing coverage result to merge.", CommandOptionType.SingleValue);
            CommandOption            useSourceLink       = app.Option("--use-source-link", "Specifies whether to use SourceLink URIs in place of file system paths.", CommandOptionType.NoValue);

            app.OnExecute(() =>
            {
                if (string.IsNullOrEmpty(module.Value) || string.IsNullOrWhiteSpace(module.Value))
                {
                    throw new CommandParsingException(app, "No test assembly specified.");
                }

                if (!target.HasValue())
                {
                    throw new CommandParsingException(app, "Target must be specified.");
                }

                if (verbosity.HasValue())
                {
                    // Adjust log level based on user input.
                    logger.Level = verbosity.ParsedValue;
                }

                CoverageParameters parameters = new CoverageParameters
                {
                    IncludeFilters      = includeFilters.Values.ToArray(),
                    IncludeDirectories  = includeDirectories.Values.ToArray(),
                    ExcludeFilters      = excludeFilters.Values.ToArray(),
                    ExcludedSourceFiles = excludedSourceFiles.Values.ToArray(),
                    ExcludeAttributes   = excludeAttributes.Values.ToArray(),
                    IncludeTestAssembly = includeTestAssembly.HasValue(),
                    SingleHit           = singleHit.HasValue(),
                    MergeWith           = mergeWith.Value(),
                    UseSourceLink       = useSourceLink.HasValue(),
                    SkipAutoProps       = skipAutoProp.HasValue()
                };

                Coverage coverage = new Coverage(module.Value,
                                                 parameters,
                                                 logger,
                                                 serviceProvider.GetRequiredService <IInstrumentationHelper>(),
                                                 fileSystem,
                                                 serviceProvider.GetRequiredService <ISourceRootTranslator>(),
                                                 serviceProvider.GetRequiredService <ICecilSymbolHelper>());
                coverage.PrepareModules();

                Process process                          = new Process();
                process.StartInfo.FileName               = target.Value();
                process.StartInfo.Arguments              = targs.HasValue() ? targs.Value() : string.Empty;
                process.StartInfo.CreateNoWindow         = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardError  = true;
                process.OutputDataReceived              += (sender, eventArgs) =>
                {
                    if (!string.IsNullOrEmpty(eventArgs.Data))
                    {
                        logger.LogInformation(eventArgs.Data, important: true);
                    }
                };

                process.ErrorDataReceived += (sender, eventArgs) =>
                {
                    if (!string.IsNullOrEmpty(eventArgs.Data))
                    {
                        logger.LogError(eventArgs.Data);
                    }
                };

                process.Start();

                process.BeginErrorReadLine();
                process.BeginOutputReadLine();

                process.WaitForExit();

                var dOutput         = output.HasValue() ? output.Value() : Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar.ToString();
                var dThreshold      = threshold.HasValue() ? double.Parse(threshold.Value()) : 0;
                var dThresholdTypes = thresholdTypes.HasValue() ? thresholdTypes.Values : new List <string>(new string[] { "line", "branch", "method" });
                var dThresholdStat  = thresholdStat.HasValue() ? Enum.Parse <ThresholdStatistic>(thresholdStat.Value(), true) : Enum.Parse <ThresholdStatistic>("minimum", true);

                logger.LogInformation("\nCalculating coverage result...");

                var result    = coverage.GetCoverageResult();
                var directory = Path.GetDirectoryName(dOutput);
                if (directory == string.Empty)
                {
                    directory = Directory.GetCurrentDirectory();
                }
                else if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                foreach (var format in (formats.HasValue() ? formats.Values : new List <string>(new string[] { "json" })))
                {
                    var reporter = new ReporterFactory(format).CreateReporter();
                    if (reporter == null)
                    {
                        throw new Exception($"Specified output format '{format}' is not supported");
                    }

                    if (reporter.OutputType == ReporterOutputType.Console)
                    {
                        // Output to console
                        logger.LogInformation("  Outputting results to console", important: true);
                        logger.LogInformation(reporter.Report(result), important: true);
                    }
                    else
                    {
                        // Output to file
                        var filename = Path.GetFileName(dOutput);
                        filename     = (filename == string.Empty) ? $"coverage.{reporter.Extension}" : filename;
                        filename     = Path.HasExtension(filename) ? filename : $"{filename}.{reporter.Extension}";

                        var report = Path.Combine(directory, filename);
                        logger.LogInformation($"  Generating report '{report}'", important: true);
                        fileSystem.WriteAllText(report, reporter.Report(result));
                    }
                }

                var thresholdTypeFlags = ThresholdTypeFlags.None;

                foreach (var thresholdType in dThresholdTypes)
                {
                    if (thresholdType.Equals("line", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Line;
                    }
                    else if (thresholdType.Equals("branch", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Branch;
                    }
                    else if (thresholdType.Equals("method", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Method;
                    }
                }

                var coverageTable = new ConsoleTable("Module", "Line", "Branch", "Method");
                var summary       = new CoverageSummary();
                int numModules    = result.Modules.Count;

                var linePercentCalculation   = summary.CalculateLineCoverage(result.Modules);
                var branchPercentCalculation = summary.CalculateBranchCoverage(result.Modules);
                var methodPercentCalculation = summary.CalculateMethodCoverage(result.Modules);

                var totalLinePercent   = linePercentCalculation.Percent;
                var totalBranchPercent = branchPercentCalculation.Percent;
                var totalMethodPercent = methodPercentCalculation.Percent;

                var averageLinePercent   = linePercentCalculation.AverageModulePercent;
                var averageBranchPercent = branchPercentCalculation.AverageModulePercent;
                var averageMethodPercent = methodPercentCalculation.AverageModulePercent;

                foreach (var _module in result.Modules)
                {
                    var linePercent   = summary.CalculateLineCoverage(_module.Value).Percent;
                    var branchPercent = summary.CalculateBranchCoverage(_module.Value).Percent;
                    var methodPercent = summary.CalculateMethodCoverage(_module.Value).Percent;

                    coverageTable.AddRow(Path.GetFileNameWithoutExtension(_module.Key), $"{linePercent}%", $"{branchPercent}%", $"{methodPercent}%");
                }

                logger.LogInformation(coverageTable.ToStringAlternative());

                coverageTable.Columns.Clear();
                coverageTable.Rows.Clear();

                coverageTable.AddColumn(new[] { "", "Line", "Branch", "Method" });
                coverageTable.AddRow("Total", $"{totalLinePercent}%", $"{totalBranchPercent}%", $"{totalMethodPercent}%");
                coverageTable.AddRow("Average", $"{averageLinePercent}%", $"{averageBranchPercent}%", $"{averageMethodPercent}%");

                logger.LogInformation(coverageTable.ToStringAlternative());
                if (process.ExitCode > 0)
                {
                    exitCode += (int)CommandExitCodes.TestFailed;
                }
                thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, dThreshold, thresholdTypeFlags, dThresholdStat);
                if (thresholdTypeFlags != ThresholdTypeFlags.None)
                {
                    exitCode += (int)CommandExitCodes.CoverageBelowThreshold;
                    var exceptionMessageBuilder = new StringBuilder();
                    if ((thresholdTypeFlags & ThresholdTypeFlags.Line) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {dThresholdStat.ToString().ToLower()} line coverage is below the specified {dThreshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Branch) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {dThresholdStat.ToString().ToLower()} branch coverage is below the specified {dThreshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Method) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {dThresholdStat.ToString().ToLower()} method coverage is below the specified {dThreshold}");
                    }

                    throw new Exception(exceptionMessageBuilder.ToString());
                }

                return(exitCode);
            });

            try
            {
                return(app.Execute(args));
            }
            catch (CommandParsingException ex)
            {
                logger.LogError(ex.Message);
                app.ShowHelp();
                return((int)CommandExitCodes.CommandParsingException);
            }
            catch (Win32Exception we) when(we.Source == "System.Diagnostics.Process")
            {
                logger.LogError($"Start process '{target.Value()}' failed with '{we.Message}'");
                return(exitCode > 0 ? exitCode : (int)CommandExitCodes.Exception);
            }
            catch (Exception ex)
            {
                logger.LogError(ex.Message);
                return(exitCode > 0 ? exitCode : (int)CommandExitCodes.Exception);
            }
        }
Ejemplo n.º 4
0
        public override bool Execute()
        {
            try
            {
                Console.WriteLine("\nCalculating coverage result...");

                IFileSystem fileSystem = ServiceProvider.GetService <IFileSystem>();
                if (InstrumenterState is null || !fileSystem.Exists(InstrumenterState.ItemSpec))
                {
                    _logger.LogError("Result of instrumentation task not found");
                    return(false);
                }

                Coverage coverage = null;
                using (Stream instrumenterStateStream = fileSystem.NewFileStream(InstrumenterState.ItemSpec, FileMode.Open))
                {
                    var instrumentationHelper = ServiceProvider.GetService <IInstrumentationHelper>();
                    // Task.Log is teared down after a task and thus the new MSBuildLogger must be passed to the InstrumentationHelper
                    // https://github.com/microsoft/msbuild/issues/5153
                    instrumentationHelper.SetLogger(_logger);
                    coverage = new Coverage(CoveragePrepareResult.Deserialize(instrumenterStateStream), this._logger, ServiceProvider.GetService <IInstrumentationHelper>(), fileSystem, ServiceProvider.GetService <ISourceRootTranslator>());
                }

                try
                {
                    fileSystem.Delete(InstrumenterState.ItemSpec);
                }
                catch (Exception ex)
                {
                    // We don't want to block coverage for I/O errors
                    _logger.LogWarning($"Exception during instrument state deletion, file name '{InstrumenterState.ItemSpec}' exception message '{ex.Message}'");
                }

                CoverageResult result = coverage.GetCoverageResult();

                var directory = Path.GetDirectoryName(Output);
                if (directory == string.Empty)
                {
                    directory = Directory.GetCurrentDirectory();
                }
                else if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                var formats = OutputFormat.Split(',');
                foreach (var format in formats)
                {
                    var reporter = new ReporterFactory(format).CreateReporter();
                    if (reporter == null)
                    {
                        throw new Exception($"Specified output format '{format}' is not supported");
                    }

                    if (reporter.OutputType == ReporterOutputType.Console)
                    {
                        // Output to console
                        Console.WriteLine("  Outputting results to console");
                        Console.WriteLine(reporter.Report(result));
                    }
                    else
                    {
                        ReportWriter writer = new ReportWriter(CoverletMultiTargetFrameworksCurrentTFM,
                                                               directory,
                                                               Output,
                                                               reporter,
                                                               fileSystem,
                                                               ServiceProvider.GetService <IConsole>(),
                                                               result);
                        writer.WriteReport();
                    }
                }

                var thresholdTypeFlags = ThresholdTypeFlags.None;
                var thresholdStat      = ThresholdStatistic.Minimum;

                foreach (var thresholdType in ThresholdType.Split(',').Select(t => t.Trim()))
                {
                    if (thresholdType.Equals("line", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Line;
                    }
                    else if (thresholdType.Equals("branch", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Branch;
                    }
                    else if (thresholdType.Equals("method", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Method;
                    }
                }

                if (ThresholdStat.Equals("average", StringComparison.OrdinalIgnoreCase))
                {
                    thresholdStat = ThresholdStatistic.Average;
                }
                else if (ThresholdStat.Equals("total", StringComparison.OrdinalIgnoreCase))
                {
                    thresholdStat = ThresholdStatistic.Total;
                }

                var coverageTable = new ConsoleTable("Module", "Line", "Branch", "Method");
                var summary       = new CoverageSummary();
                int numModules    = result.Modules.Count;

                var linePercentCalculation   = summary.CalculateLineCoverage(result.Modules);
                var branchPercentCalculation = summary.CalculateBranchCoverage(result.Modules);
                var methodPercentCalculation = summary.CalculateMethodCoverage(result.Modules);

                var totalLinePercent   = linePercentCalculation.Percent;
                var totalBranchPercent = branchPercentCalculation.Percent;
                var totalMethodPercent = methodPercentCalculation.Percent;

                var averageLinePercent   = linePercentCalculation.AverageModulePercent;
                var averageBranchPercent = branchPercentCalculation.AverageModulePercent;
                var averageMethodPercent = methodPercentCalculation.AverageModulePercent;

                foreach (var module in result.Modules)
                {
                    var linePercent   = summary.CalculateLineCoverage(module.Value).Percent;
                    var branchPercent = summary.CalculateBranchCoverage(module.Value).Percent;
                    var methodPercent = summary.CalculateMethodCoverage(module.Value).Percent;

                    coverageTable.AddRow(Path.GetFileNameWithoutExtension(module.Key), $"{linePercent}%", $"{branchPercent}%", $"{methodPercent}%");
                }

                Console.WriteLine();
                Console.WriteLine(coverageTable.ToStringAlternative());

                coverageTable.Columns.Clear();
                coverageTable.Rows.Clear();

                coverageTable.AddColumn(new[] { "", "Line", "Branch", "Method" });
                coverageTable.AddRow("Total", $"{totalLinePercent}%", $"{totalBranchPercent}%", $"{totalMethodPercent}%");
                coverageTable.AddRow("Average", $"{averageLinePercent}%", $"{averageBranchPercent}%", $"{averageMethodPercent}%");

                Console.WriteLine(coverageTable.ToStringAlternative());

                thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, Threshold, thresholdTypeFlags, thresholdStat);
                if (thresholdTypeFlags != ThresholdTypeFlags.None)
                {
                    var exceptionMessageBuilder = new StringBuilder();
                    if ((thresholdTypeFlags & ThresholdTypeFlags.Line) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} line coverage is below the specified {Threshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Branch) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} branch coverage is below the specified {Threshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Method) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} method coverage is below the specified {Threshold}");
                    }

                    throw new Exception(exceptionMessageBuilder.ToString());
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex);
                return(false);
            }

            return(true);
        }
Ejemplo n.º 5
0
        static int Main(string[] args)
        {
            var logger = new ConsoleLogger();
            var app    = new CommandLineApplication();

            app.Name     = "coverlet";
            app.FullName = "Cross platform .NET Core code coverage tool";
            app.HelpOption("-h|--help");
            app.VersionOption("-v|--version", GetAssemblyVersion());

            CommandArgument module              = app.Argument("<ASSEMBLY>", "Path to the test assembly.");
            CommandOption   target              = app.Option("-t|--target", "Path to the test runner application.", CommandOptionType.SingleValue);
            CommandOption   targs               = app.Option("-a|--targetargs", "Arguments to be passed to the test runner.", CommandOptionType.SingleValue);
            CommandOption   output              = app.Option("-o|--output", "Output of the generated coverage report", CommandOptionType.SingleValue);
            CommandOption   formats             = app.Option("-f|--format", "Format of the generated coverage report.", CommandOptionType.MultipleValue);
            CommandOption   threshold           = app.Option("--threshold", "Exits with error if the coverage % is below value.", CommandOptionType.SingleValue);
            CommandOption   thresholdTypes      = app.Option("--threshold-type", "Coverage type to apply the threshold to.", CommandOptionType.MultipleValue);
            CommandOption   thresholdStat       = app.Option("--threshold-stat", "Coverage statistic used to enforce the threshold value.", CommandOptionType.SingleValue);
            CommandOption   excludeFilters      = app.Option("--exclude", "Filter expressions to exclude specific modules and types.", CommandOptionType.MultipleValue);
            CommandOption   includeFilters      = app.Option("--include", "Filter expressions to include only specific modules and types.", CommandOptionType.MultipleValue);
            CommandOption   excludedSourceFiles = app.Option("--exclude-by-file", "Glob patterns specifying source files to exclude.", CommandOptionType.MultipleValue);
            CommandOption   includeDirectories  = app.Option("--include-directory", "Include directories containing additional assemblies to be instrumented.", CommandOptionType.MultipleValue);
            CommandOption   excludeAttributes   = app.Option("--exclude-by-attribute", "Attributes to exclude from code coverage.", CommandOptionType.MultipleValue);
            CommandOption   includeTestAssembly = app.Option("--include-test-assembly", "Specifies whether to report code coverage of the test assembly", CommandOptionType.NoValue);
            CommandOption   singleHit           = app.Option("--single-hit", "Specifies whether to limit code coverage hit reporting to a single hit for each location", CommandOptionType.NoValue);
            CommandOption   mergeWith           = app.Option("--merge-with", "Path to existing coverage result to merge.", CommandOptionType.SingleValue);
            CommandOption   useSourceLink       = app.Option("--use-source-link", "Specifies whether to use SourceLink URIs in place of file system paths.", CommandOptionType.NoValue);

            app.OnExecute(() =>
            {
                if (string.IsNullOrEmpty(module.Value) || string.IsNullOrWhiteSpace(module.Value))
                {
                    throw new CommandParsingException(app, "No test assembly specified.");
                }

                if (!target.HasValue())
                {
                    throw new CommandParsingException(app, "Target must be specified.");
                }

                Coverage coverage = new Coverage(module.Value,
                                                 includeFilters.Values.ToArray(),
                                                 includeDirectories.Values.ToArray(),
                                                 excludeFilters.Values.ToArray(),
                                                 excludedSourceFiles.Values.ToArray(),
                                                 excludeAttributes.Values.ToArray(),
                                                 includeTestAssembly.HasValue(),
                                                 singleHit.HasValue(),
                                                 mergeWith.Value(),
                                                 useSourceLink.HasValue(),
                                                 logger);
                coverage.PrepareModules();

                Process process                          = new Process();
                process.StartInfo.FileName               = target.Value();
                process.StartInfo.Arguments              = targs.HasValue() ? targs.Value() : string.Empty;
                process.StartInfo.CreateNoWindow         = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardError  = true;
                process.OutputDataReceived              += (sender, eventArgs) =>
                {
                    if (!string.IsNullOrEmpty(eventArgs.Data))
                    {
                        logger.LogInformation(eventArgs.Data);
                    }
                };

                process.ErrorDataReceived += (sender, eventArgs) =>
                {
                    if (!string.IsNullOrEmpty(eventArgs.Data))
                    {
                        logger.LogError(eventArgs.Data);
                    }
                };

                process.Start();

                process.BeginErrorReadLine();
                process.BeginOutputReadLine();

                process.WaitForExit();

                var dOutput         = output.HasValue() ? output.Value() : Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar.ToString();
                var dThreshold      = threshold.HasValue() ? double.Parse(threshold.Value()) : 0;
                var dThresholdTypes = thresholdTypes.HasValue() ? thresholdTypes.Values : new List <string>(new string[] { "line", "branch", "method" });
                var dThresholdStat  = thresholdStat.HasValue() ? Enum.Parse <ThresholdStatistic>(thresholdStat.Value(), true) : Enum.Parse <ThresholdStatistic>("minimum", true);

                logger.LogInformation("\nCalculating coverage result...");

                var result    = coverage.GetCoverageResult();
                var directory = Path.GetDirectoryName(dOutput);
                if (directory == string.Empty)
                {
                    directory = Directory.GetCurrentDirectory();
                }
                else if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                foreach (var format in (formats.HasValue() ? formats.Values : new List <string>(new string[] { "json" })))
                {
                    var reporter = new ReporterFactory(format).CreateReporter();
                    if (reporter == null)
                    {
                        throw new Exception($"Specified output format '{format}' is not supported");
                    }

                    if (reporter.OutputType == ReporterOutputType.Console)
                    {
                        // Output to console
                        logger.LogInformation("  Outputting results to console");
                        logger.LogInformation(reporter.Report(result));
                    }
                    else
                    {
                        // Output to file
                        var filename = Path.GetFileName(dOutput);
                        filename     = (filename == string.Empty) ? $"coverage.{reporter.Extension}" : filename;
                        filename     = Path.HasExtension(filename) ? filename : $"{filename}.{reporter.Extension}";

                        var report = Path.Combine(directory, filename);
                        logger.LogInformation($"  Generating report '{report}'");
                        File.WriteAllText(report, reporter.Report(result));
                    }
                }

                var thresholdTypeFlags = ThresholdTypeFlags.None;

                foreach (var thresholdType in dThresholdTypes)
                {
                    if (thresholdType.Equals("line", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Line;
                    }
                    else if (thresholdType.Equals("branch", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Branch;
                    }
                    else if (thresholdType.Equals("method", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Method;
                    }
                }

                var coverageTable = new ConsoleTable("Module", "Line", "Branch", "Method");
                var summary       = new CoverageSummary();
                int numModules    = result.Modules.Count;

                var totalLinePercent   = summary.CalculateLineCoverage(result.Modules).Percent * 100;
                var totalBranchPercent = summary.CalculateBranchCoverage(result.Modules).Percent * 100;
                var totalMethodPercent = summary.CalculateMethodCoverage(result.Modules).Percent * 100;

                foreach (var _module in result.Modules)
                {
                    var linePercent   = summary.CalculateLineCoverage(_module.Value).Percent * 100;
                    var branchPercent = summary.CalculateBranchCoverage(_module.Value).Percent * 100;
                    var methodPercent = summary.CalculateMethodCoverage(_module.Value).Percent * 100;

                    coverageTable.AddRow(Path.GetFileNameWithoutExtension(_module.Key), $"{linePercent}%", $"{branchPercent}%", $"{methodPercent}%");
                }

                logger.LogInformation(coverageTable.ToStringAlternative());

                coverageTable.Columns.Clear();
                coverageTable.Rows.Clear();

                coverageTable.AddColumn(new[] { "", "Line", "Branch", "Method" });
                coverageTable.AddRow("Total", $"{totalLinePercent}%", $"{totalBranchPercent}%", $"{totalMethodPercent}%");
                coverageTable.AddRow("Average", $"{totalLinePercent / numModules}%", $"{totalBranchPercent / numModules}%", $"{totalMethodPercent / numModules}%");

                logger.LogInformation(coverageTable.ToStringAlternative());

                thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, dThreshold, thresholdTypeFlags, dThresholdStat);
                if (thresholdTypeFlags != ThresholdTypeFlags.None)
                {
                    var exceptionMessageBuilder = new StringBuilder();
                    if ((thresholdTypeFlags & ThresholdTypeFlags.Line) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {dThresholdStat.ToString().ToLower()} line coverage is below the specified {dThreshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Branch) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {dThresholdStat.ToString().ToLower()} branch coverage is below the specified {dThreshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Method) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {dThresholdStat.ToString().ToLower()} method coverage is below the specified {dThreshold}");
                    }

                    throw new Exception(exceptionMessageBuilder.ToString());
                }

                return(process.ExitCode == 0 ? 0 : process.ExitCode);
            });

            try
            {
                return(app.Execute(args));
            }
            catch (CommandParsingException ex)
            {
                logger.LogError(ex.Message);
                app.ShowHelp();
                return(1);
            }
            catch (Exception ex)
            {
                logger.LogError(ex.Message);
                return(1);
            }
        }
Ejemplo n.º 6
0
        public override bool Execute()
        {
            try
            {
                Console.WriteLine("\nCalculating coverage result...");

                IFileSystem fileSystem = (IFileSystem)DependencyInjection.Current.GetService(typeof(IFileSystem));
                if (InstrumenterState is null || !fileSystem.Exists(InstrumenterState.ItemSpec))
                {
                    _logger.LogError("Result of instrumentation task not found");
                    return(false);
                }

                Coverage coverage = null;
                using (Stream instrumenterStateStream = fileSystem.NewFileStream(InstrumenterState.ItemSpec, FileMode.Open))
                {
                    coverage = new Coverage(CoveragePrepareResult.Deserialize(instrumenterStateStream), this._logger, (IInstrumentationHelper)DependencyInjection.Current.GetService(typeof(IInstrumentationHelper)), fileSystem);
                }

                CoverageResult result = coverage.GetCoverageResult();

                var directory = Path.GetDirectoryName(_output);
                if (directory == string.Empty)
                {
                    directory = Directory.GetCurrentDirectory();
                }
                else if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                var formats = _format.Split(',');
                foreach (var format in formats)
                {
                    var reporter = new ReporterFactory(format).CreateReporter();
                    if (reporter == null)
                    {
                        throw new Exception($"Specified output format '{format}' is not supported");
                    }

                    if (reporter.OutputType == ReporterOutputType.Console)
                    {
                        // Output to console
                        Console.WriteLine("  Outputting results to console");
                        Console.WriteLine(reporter.Report(result));
                    }
                    else
                    {
                        // Output to file
                        var filename = Path.GetFileName(_output);
                        filename = (filename == string.Empty) ? $"coverage.{reporter.Extension}" : filename;
                        filename = Path.HasExtension(filename) ? filename : $"{filename}.{reporter.Extension}";

                        var report = Path.Combine(directory, filename);
                        Console.WriteLine($"  Generating report '{report}'");
                        fileSystem.WriteAllText(report, reporter.Report(result));
                    }
                }

                var thresholdTypeFlags = ThresholdTypeFlags.None;
                var thresholdStat      = ThresholdStatistic.Minimum;

                foreach (var thresholdType in _thresholdType.Split(',').Select(t => t.Trim()))
                {
                    if (thresholdType.Equals("line", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Line;
                    }
                    else if (thresholdType.Equals("branch", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Branch;
                    }
                    else if (thresholdType.Equals("method", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Method;
                    }
                }

                if (_thresholdStat.Equals("average", StringComparison.OrdinalIgnoreCase))
                {
                    thresholdStat = ThresholdStatistic.Average;
                }
                else if (_thresholdStat.Equals("total", StringComparison.OrdinalIgnoreCase))
                {
                    thresholdStat = ThresholdStatistic.Total;
                }

                var coverageTable = new ConsoleTable("Module", "Line", "Branch", "Method");
                var summary       = new CoverageSummary();
                int numModules    = result.Modules.Count;

                var linePercentCalculation   = summary.CalculateLineCoverage(result.Modules);
                var branchPercentCalculation = summary.CalculateBranchCoverage(result.Modules);
                var methodPercentCalculation = summary.CalculateMethodCoverage(result.Modules);

                var totalLinePercent   = linePercentCalculation.Percent;
                var totalBranchPercent = branchPercentCalculation.Percent;
                var totalMethodPercent = methodPercentCalculation.Percent;

                var averageLinePercent   = linePercentCalculation.AverageModulePercent;
                var averageBranchPercent = branchPercentCalculation.AverageModulePercent;
                var averageMethodPercent = methodPercentCalculation.AverageModulePercent;

                foreach (var module in result.Modules)
                {
                    var linePercent   = summary.CalculateLineCoverage(module.Value).Percent;
                    var branchPercent = summary.CalculateBranchCoverage(module.Value).Percent;
                    var methodPercent = summary.CalculateMethodCoverage(module.Value).Percent;

                    coverageTable.AddRow(Path.GetFileNameWithoutExtension(module.Key), $"{linePercent}%", $"{branchPercent}%", $"{methodPercent}%");
                }

                Console.WriteLine();
                Console.WriteLine(coverageTable.ToStringAlternative());

                coverageTable.Columns.Clear();
                coverageTable.Rows.Clear();

                coverageTable.AddColumn(new[] { "", "Line", "Branch", "Method" });
                coverageTable.AddRow("Total", $"{totalLinePercent}%", $"{totalBranchPercent}%", $"{totalMethodPercent}%");
                coverageTable.AddRow("Average", $"{averageLinePercent}%", $"{averageBranchPercent}%", $"{averageMethodPercent}%");

                Console.WriteLine(coverageTable.ToStringAlternative());

                thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, _threshold, thresholdTypeFlags, thresholdStat);
                if (thresholdTypeFlags != ThresholdTypeFlags.None)
                {
                    var exceptionMessageBuilder = new StringBuilder();
                    if ((thresholdTypeFlags & ThresholdTypeFlags.Line) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} line coverage is below the specified {_threshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Branch) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} branch coverage is below the specified {_threshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Method) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} method coverage is below the specified {_threshold}");
                    }

                    throw new Exception(exceptionMessageBuilder.ToString());
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex);
                return(false);
            }

            return(true);
        }
Ejemplo n.º 7
0
        // **************************************************************************************************************************************
        // DisplayTable
        //
        // Convenience routine to layout columns and rows of data contained within the response.  Data is echoed to the console.
        // **************************************************************************************************************************************
        public static void DisplayTable(IDataSetResponse response, string header)
        {
            Console.WriteLine("\n******************************************************************************************************************");
            if (response.IsSuccess)
            {
                Console.Write($"{Environment.NewLine}{header}");
                if (response.Data.Universe != null)
                {
                    Console.Write($" for item(s):\n{string.Join("\n", response.Data.Universe.Select(w => $"\tItem: {w.Instrument} {w.CommonName}"))}");
                }

                Console.WriteLine();

                if (response.Data?.Table != null)
                {
                    var console = new ConsoleTable();

                    IList <string> columns = new List <string>();
                    foreach (DataColumn col in response.Data.Table.Columns)
                    {
                        columns.Add(col.ColumnName);
                    }

                    console.AddColumn(columns);

                    IList <object> rowData = new List <object>();
                    foreach (DataRow dataRow in response.Data.Table.Rows)
                    {
                        foreach (object item in dataRow.ItemArray)
                        {
                            rowData.Add(item);
                        }

                        console.AddRow(rowData.ToArray());
                        rowData.Clear();
                    }

                    if (console.Columns.Count > 0)
                    {
                        Console.WriteLine("\n");
                        console.Write(Format.MarkDown);
                    }
                }
                else
                {
                    Console.WriteLine($"Response contains an empty data set: {response.Data?.Raw}");
                }

                Console.WriteLine($"Fields:\n{string.Join("\n", response.Data.Fields?.Select(f => $"\t{f.Name} ({f.Type})"))}");
            }
            else
            {
                Console.WriteLine($"IsSuccess: {response.IsSuccess}\n{response.Status}");
            }

            // Was there a Closure included with the request?  If so, display it.
            if (response.Closure != null)
            {
                Console.WriteLine($"{Environment.NewLine}Closure included: {response.Closure}");
            }
        }
Ejemplo n.º 8
0
        public override CmdResult Execute()
        {
            if (string.IsNullOrWhiteSpace(Query))
            {
                return CmdResult.Failure("Query is null or empty");
            }

            try
            {
                //Fix bug that EEM will cut sting at the equal sign
                Query = Query.Replace("#", "=");

                var result = new StringBuilder();

                using (var con = new SqlConnection(ConfigUtil.GetAppDBConnStr(DB)))
                {
                    using (var cmd = con.CreateCommand())
                    {
                        con.Open();

                        cmd.CommandText = Query;

                        var reader = cmd.ExecuteReader();

                        DataTable dt = new DataTable();
                        dt.Load(reader);
                        if (dt.Rows.Count == 0)
                        {
                            return CmdResult.Failure("Query return no data");
                        }

                        result.AppendLine("Query Result " +Limit +"/"+ dt.Rows.Count);

                        var ct = new ConsoleTable();
                        var _ctCol = new List<string>();
                        foreach (var column in dt.Columns)
                        {
                            _ctCol.Add(column.ToString());
                        }
                        ct.AddColumn(_ctCol);

                        foreach (DataRow dataRow in dt.Rows)
                        {
                            if (Limit-- <= 0)
                            {
                                break;
                            }

                            ct.AddRow(dataRow.ItemArray);
                        }
                        result.AppendLine(ct.ToString());
                        result.AppendLine("===================================");
                        result.AppendLine(Query);
                        result.AppendLine("===================================");
                        return CmdResult.Success(result.ToString());
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("Exception while running DumpDBCommand: {0}, {1}", ex.Message, Query);
                return CmdResult.Failure(ex.Message);
            }
        }
Ejemplo n.º 9
0
        public override bool Execute()
        {
            try
            {
                Console.WriteLine("\nCalculating coverage result...");

                var coverage = InstrumentationTask.Coverage;
                var result   = coverage.GetCoverageResult();

                var directory = Path.GetDirectoryName(_output);
                if (directory == string.Empty)
                {
                    directory = Directory.GetCurrentDirectory();
                }
                else if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                var formats = _format.Split(',');
                foreach (var format in formats)
                {
                    var reporter = new ReporterFactory(format).CreateReporter();
                    if (reporter == null)
                    {
                        throw new Exception($"Specified output format '{format}' is not supported");
                    }

                    if (reporter.OutputType == ReporterOutputType.Console)
                    {
                        // Output to console
                        Console.WriteLine("  Outputting results to console");
                        Console.WriteLine(reporter.Report(result));
                    }
                    else
                    {
                        // Output to file
                        var filename = Path.GetFileName(_output);
                        filename = (filename == string.Empty) ? $"coverage.{reporter.Extension}" : filename;
                        filename = Path.HasExtension(filename) ? filename : $"{filename}.{reporter.Extension}";

                        var report = Path.Combine(directory, filename);
                        Console.WriteLine($"  Generating report '{report}'");

                        var resultContent = reporter.Report(result);

                        // Possible concurrency access to merge file between write/read on parallel testing
                        RetryHelper.Retry(() =>
                        {
                            using (var file = File.Open(report, FileMode.Create, FileAccess.Write, FileShare.None))
                            {
                                using (var writer = new StreamWriter(file))
                                {
                                    writer.Write(resultContent);
                                }
                            }
                        }, () => TimeSpan.FromMilliseconds(100), 5);
                    }
                }

                var thresholdTypeFlags = ThresholdTypeFlags.None;
                var thresholdStat      = ThresholdStatistic.Minimum;

                foreach (var thresholdType in _thresholdType.Split(',').Select(t => t.Trim()))
                {
                    if (thresholdType.Equals("line", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Line;
                    }
                    else if (thresholdType.Equals("branch", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Branch;
                    }
                    else if (thresholdType.Equals("method", StringComparison.OrdinalIgnoreCase))
                    {
                        thresholdTypeFlags |= ThresholdTypeFlags.Method;
                    }
                }

                if (_thresholdStat.Equals("average", StringComparison.OrdinalIgnoreCase))
                {
                    thresholdStat = ThresholdStatistic.Average;
                }
                else if (_thresholdStat.Equals("total", StringComparison.OrdinalIgnoreCase))
                {
                    thresholdStat = ThresholdStatistic.Total;
                }

                var coverageTable = new ConsoleTable("Module", "Line", "Branch", "Method");
                var summary       = new CoverageSummary();
                int numModules    = result.Modules.Count;

                var totalLinePercent   = summary.CalculateLineCoverage(result.Modules).Percent * 100;
                var totalBranchPercent = summary.CalculateBranchCoverage(result.Modules).Percent * 100;
                var totalMethodPercent = summary.CalculateMethodCoverage(result.Modules).Percent * 100;

                foreach (var module in result.Modules)
                {
                    var linePercent   = summary.CalculateLineCoverage(module.Value).Percent * 100;
                    var branchPercent = summary.CalculateBranchCoverage(module.Value).Percent * 100;
                    var methodPercent = summary.CalculateMethodCoverage(module.Value).Percent * 100;

                    coverageTable.AddRow(Path.GetFileNameWithoutExtension(module.Key), $"{linePercent}%", $"{branchPercent}%", $"{methodPercent}%");
                }

                Console.WriteLine();
                Console.WriteLine(coverageTable.ToStringAlternative());

                coverageTable.Columns.Clear();
                coverageTable.Rows.Clear();

                coverageTable.AddColumn(new[] { "", "Line", "Branch", "Method" });
                coverageTable.AddRow("Total", $"{totalLinePercent}%", $"{totalBranchPercent}%", $"{totalMethodPercent}%");
                coverageTable.AddRow("Average", $"{totalLinePercent / numModules}%", $"{totalBranchPercent / numModules}%", $"{totalMethodPercent / numModules}%");

                Console.WriteLine(coverageTable.ToStringAlternative());

                thresholdTypeFlags = result.GetThresholdTypesBelowThreshold(summary, _threshold, thresholdTypeFlags, thresholdStat);
                if (thresholdTypeFlags != ThresholdTypeFlags.None)
                {
                    var exceptionMessageBuilder = new StringBuilder();
                    if ((thresholdTypeFlags & ThresholdTypeFlags.Line) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} line coverage is below the specified {_threshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Branch) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} branch coverage is below the specified {_threshold}");
                    }

                    if ((thresholdTypeFlags & ThresholdTypeFlags.Method) != ThresholdTypeFlags.None)
                    {
                        exceptionMessageBuilder.AppendLine($"The {thresholdStat.ToString().ToLower()} method coverage is below the specified {_threshold}");
                    }

                    throw new Exception(exceptionMessageBuilder.ToString());
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex);
                return(false);
            }

            return(true);
        }
Ejemplo n.º 10
0
        private static void PrintResult(IEnumerable <FileCabinetRecord> records, IEnumerable <string> arguments)
        {
            var table = new ConsoleTable();

            table.AddColumn(arguments);

            foreach (var record in records)
            {
                var fields = new List <object>();
                foreach (var column in arguments)
                {
                    if (column.Equals("id", StringComparison.InvariantCultureIgnoreCase))
                    {
                        fields.Add(record.Id);
                        continue;
                    }

                    if (column.Equals("firstname", StringComparison.InvariantCultureIgnoreCase))
                    {
                        fields.Add(record.FirstName);
                        continue;
                    }

                    if (column.Equals("lastname", StringComparison.InvariantCultureIgnoreCase))
                    {
                        fields.Add(record.LastName);
                        continue;
                    }

                    if (column.Equals("dateofbirth", StringComparison.InvariantCultureIgnoreCase))
                    {
                        fields.Add(record.DateOfBirth.ToShortDateString());
                        continue;
                    }

                    if (column.Equals("sex", StringComparison.InvariantCultureIgnoreCase))
                    {
                        fields.Add(record.Sex);
                        continue;
                    }

                    if (column.Equals("weight", StringComparison.InvariantCultureIgnoreCase))
                    {
                        fields.Add(record.Weight);
                        continue;
                    }

                    if (column.Equals("height", StringComparison.InvariantCultureIgnoreCase))
                    {
                        fields.Add(record.Height);
                        continue;
                    }

                    return;
                }

                table.AddRow(fields.ToArray());
            }

            table.Write(format: Format.Alternative);
        }