Example #1
0
        /// <summary>
        /// Extracts the methods/properties of the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfFile">The methods of the file.</param>
        /// <param name="numberOrLines">The number of lines in the file.</param>
        private static void SetCodeElements(CodeFile codeFile, IEnumerable <XElement> methodsOfFile, int numberOrLines)
        {
            var codeElements = new List <CodeElementBase>();

            foreach (var method in methodsOfFile)
            {
                var signature = method.Attribute("signature");

                if (signature == null)
                {
                    continue;
                }

                string methodName = signature.Value;
                int    lineNumber = int.Parse(method.Attribute("num").Value, CultureInfo.InvariantCulture);

                codeElements.Add(new CodeElementBase(methodName, lineNumber));

                var complexity = method.Attribute("complexity");

                if (complexity != null)
                {
                    var metrics = new List <Metric>()
                    {
                        new Metric(
                            ReportResources.CyclomaticComplexity,
                            ParserBase.CyclomaticComplexityUri,
                            MetricType.CodeQuality,
                            decimal.Parse(complexity.Value, CultureInfo.InvariantCulture),
                            MetricMergeOrder.LowerIsBetter)
                    };

                    var methodMetric = new MethodMetric(methodName, methodName, metrics)
                    {
                        Line = lineNumber
                    };

                    codeFile.AddMethodMetric(methodMetric);
                }
            }

            for (int i = 0; i < codeElements.Count; i++)
            {
                var codeElement = codeElements[i];

                int lastLine = numberOrLines;
                if (i < codeElements.Count - 1)
                {
                    lastLine = codeElements[i + 1].FirstLine - 1;
                }

                codeFile.AddCodeElement(new CodeElement(
                                            codeElement.Name,
                                            CodeElementType.Method,
                                            codeElement.FirstLine,
                                            lastLine,
                                            codeFile.CoverageQuota(codeElement.FirstLine, lastLine)));
            }
        }
        public void Merge_MergeOneMethodMetric_MethodMetricIsStored()
        {
            var sut          = new CodeFile("C:\\temp\\Program.cs", new int[] { -1, -1, -1, 0, 0, 0, 1, 1, 1 }, new LineVisitStatus[] { LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.NotCovered, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.Covered, LineVisitStatus.Covered });
            var methodMetric = new MethodMetric("Test", "Test", Enumerable.Empty <Metric>());

            sut.AddMethodMetric(methodMetric);

            var codeFileToMerge = new CodeFile("C:\\temp\\Program.cs", new int[] { -1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1 }, new LineVisitStatus[] { LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered, LineVisitStatus.NotCoverable, LineVisitStatus.NotCovered, LineVisitStatus.Covered });

            sut.Merge(codeFileToMerge);

            Assert.Equal(methodMetric, sut.MethodMetrics.First());
            Assert.Single(sut.MethodMetrics);
        }
Example #3
0
        /// <summary>
        /// Extracts the metrics from the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfFile">The methods of the file.</param>
        private static void SetMethodMetrics(CodeFile codeFile, IEnumerable <XElement> methodsOfFile)
        {
            foreach (var method in methodsOfFile)
            {
                string fullName = method.Element("MethodName").Value;

                // Exclude properties and lambda expressions
                if (fullName.StartsWith("get_", StringComparison.Ordinal) ||
                    fullName.StartsWith("set_", StringComparison.Ordinal) ||
                    lambdaMethodNameRegex.IsMatch(fullName))
                {
                    continue;
                }

                fullName = ExtractMethodName(fullName, method.Element("MethodKeyName").Value);
                string shortName = methodRegex.Replace(fullName, m => string.Format(CultureInfo.InvariantCulture, "{0}({1})", m.Groups["MethodName"].Value, m.Groups["Arguments"].Value.Length > 0 ? "..." : string.Empty));

                var metrics = new[]
                {
                    new Metric(
                        ReportResources.BlocksCovered,
                        ParserBase.CodeCoverageUri,
                        MetricType.CoverageAbsolute,
                        int.Parse(method.Element("BlocksCovered").Value, CultureInfo.InvariantCulture)),
                    new Metric(
                        ReportResources.BlocksNotCovered,
                        ParserBase.CodeCoverageUri,
                        MetricType.CoverageAbsolute,
                        int.Parse(method.Element("BlocksNotCovered").Value, CultureInfo.InvariantCulture),
                        MetricMergeOrder.LowerIsBetter)
                };

                var methodMetric = new MethodMetric(fullName, shortName, metrics);

                var seqpnt = method
                             .Elements("Lines")
                             .Elements("LnStart")
                             .FirstOrDefault();

                if (seqpnt != null)
                {
                    methodMetric.Line = int.Parse(seqpnt.Value, CultureInfo.InvariantCulture);
                }

                codeFile.AddMethodMetric(methodMetric);
            }
        }
Example #4
0
        /// <summary>
        /// Extracts the methods/properties of the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfFile">The methods of the file.</param>
        private static void SetCodeElements(CodeFile codeFile, IEnumerable <XElement> methodsOfFile)
        {
            foreach (var method in methodsOfFile)
            {
                var signature = method.Attribute("signature");

                if (signature == null)
                {
                    continue;
                }

                string methodName = signature.Value;
                int    lineNumber = int.Parse(method.Attribute("num").Value, CultureInfo.InvariantCulture);

                codeFile.AddCodeElement(new CodeElement(methodName, CodeElementType.Method, lineNumber, lineNumber));

                var complexity = method.Attribute("complexity");

                if (complexity != null)
                {
                    var metrics = new List <Metric>()
                    {
                        new Metric(
                            ReportResources.CyclomaticComplexity,
                            ParserBase.CyclomaticComplexityUri,
                            MetricType.CodeQuality,
                            decimal.Parse(complexity.Value, CultureInfo.InvariantCulture),
                            MetricMergeOrder.LowerIsBetter)
                    };

                    var methodMetric = new MethodMetric(methodName, methodName, metrics)
                    {
                        Line = lineNumber
                    };

                    codeFile.AddMethodMetric(methodMetric);
                }
            }
        }
Example #5
0
        /// <summary>
        /// Extracts the metrics from the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfFile">The methods of the file.</param>
        private static void SetMethodMetrics(CodeFile codeFile, IEnumerable <XElement> methodsOfFile)
        {
            foreach (var method in methodsOfFile)
            {
                string fullName = method.Attribute("name").Value + method.Attribute("desc").Value;

                if (fullName.StartsWith("lambda$"))
                {
                    continue;
                }

                string shortName = methodRegex.Replace(fullName, m => string.Format(CultureInfo.InvariantCulture, "{0}({1})", m.Groups["MethodName"].Value, m.Groups["Arguments"].Value.Length > 0 ? "..." : string.Empty));

                var metrics = new List <Metric>();

                var lineRate = method.Elements("counter")
                               .Where(e => e.Attribute("type") != null && e.Attribute("type").Value == "LINE")
                               .FirstOrDefault();

                if (lineRate != null)
                {
                    decimal missed  = decimal.Parse(lineRate.Attribute("missed").Value, CultureInfo.InvariantCulture);
                    decimal covered = decimal.Parse(lineRate.Attribute("covered").Value, CultureInfo.InvariantCulture);
                    decimal total   = missed + covered;

                    metrics.Add(new Metric(
                                    ReportResources.Coverage,
                                    ParserBase.CodeCoverageUri,
                                    MetricType.CoveragePercentual,
                                    total == 0 ? (decimal?)null : Math.Round((100 * covered) / total, 2, MidpointRounding.AwayFromZero)));
                }
                else
                {
                    // If no line rate available, do not add branch coverage too
                    continue;
                }

                var branchRate = method.Elements("counter")
                                 .Where(e => e.Attribute("type") != null && e.Attribute("type").Value == "BRANCH")
                                 .FirstOrDefault();

                if (branchRate != null)
                {
                    decimal missed  = decimal.Parse(branchRate.Attribute("missed").Value, CultureInfo.InvariantCulture);
                    decimal covered = decimal.Parse(branchRate.Attribute("covered").Value, CultureInfo.InvariantCulture);
                    decimal total   = missed + covered;

                    metrics.Add(new Metric(
                                    ReportResources.BranchCoverage,
                                    ParserBase.CodeCoverageUri,
                                    MetricType.CoveragePercentual,
                                    total == 0 ? (decimal?)null : Math.Round((100 * covered) / total, 2, MidpointRounding.AwayFromZero)));
                }
                else
                {
                    // If no branch coverage is available, add default to avoid empty columns
                    metrics.Add(new Metric(
                                    ReportResources.BranchCoverage,
                                    ParserBase.CodeCoverageUri,
                                    MetricType.CoveragePercentual,
                                    null));
                }

                var methodMetric = new MethodMetric(fullName, shortName, metrics);
                methodMetric.Line = method.Attribute("line") != null?int.Parse(method.Attribute("line").Value, CultureInfo.InvariantCulture) : default(int?);

                codeFile.AddMethodMetric(methodMetric);
            }
        }
        /// <summary>
        /// Extracts the metrics from the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfFile">The methods of the file.</param>
        private static void SetMethodMetrics(CodeFile codeFile, IEnumerable <XElement> methodsOfFile)
        {
            foreach (var method in methodsOfFile)
            {
                string fullName = method.Attribute("name").Value + method.Attribute("signature").Value;
                fullName = ExtractMethodName(fullName, method.Parent.Parent.Attribute("name").Value);

                if (fullName.Contains("__") && lambdaMethodNameRegex.IsMatch(fullName))
                {
                    continue;
                }

                string shortName = GetShortMethodName(fullName);

                var metrics = new List <Metric>();

                var lineRate = method.Attribute("line-rate");

                if (lineRate != null)
                {
                    decimal?value = null;

                    if (!"NaN".Equals(lineRate.Value, StringComparison.OrdinalIgnoreCase))
                    {
                        value = Math.Round(100 * decimal.Parse(lineRate.Value, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture), 2, MidpointRounding.AwayFromZero);
                    }

                    metrics.Add(new Metric(
                                    ReportResources.Coverage,
                                    ParserBase.CodeCoverageUri,
                                    MetricType.CoveragePercentual,
                                    value));
                }

                var branchRate = method.Attribute("branch-rate");

                if (branchRate != null)
                {
                    decimal?value = null;

                    if (!"NaN".Equals(branchRate.Value, StringComparison.OrdinalIgnoreCase))
                    {
                        value = Math.Round(100 * decimal.Parse(branchRate.Value, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture), 2, MidpointRounding.AwayFromZero);
                    }

                    metrics.Add(new Metric(
                                    ReportResources.BranchCoverage,
                                    ParserBase.CodeCoverageUri,
                                    MetricType.CoveragePercentual,
                                    value));
                }

                var cyclomaticComplexityAttribute = method.Attribute("complexity");

                if (cyclomaticComplexityAttribute != null)
                {
                    decimal?value = null;

                    if (!"NaN".Equals(cyclomaticComplexityAttribute.Value, StringComparison.OrdinalIgnoreCase))
                    {
                        value = Math.Round(decimal.Parse(cyclomaticComplexityAttribute.Value, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture), 2, MidpointRounding.AwayFromZero);
                    }

                    metrics.Insert(
                        0,
                        new Metric(
                            ReportResources.CyclomaticComplexity,
                            ParserBase.CyclomaticComplexityUri,
                            MetricType.CodeQuality,
                            value,
                            MetricMergeOrder.LowerIsBetter));
                }

                var methodMetric = new MethodMetric(fullName, shortName, metrics);

                var line = method
                           .Elements("lines")
                           .Elements("line")
                           .FirstOrDefault();

                if (line != null)
                {
                    methodMetric.Line = int.Parse(line.Attribute("number").Value, CultureInfo.InvariantCulture);
                }

                codeFile.AddMethodMetric(methodMetric);
            }
        }
Example #7
0
        /// <summary>
        /// Extracts the metrics from the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfFile">The methods of the file.</param>
        private static void SetMethodMetrics(CodeFile codeFile, IEnumerable <XElement> methodsOfFile)
        {
            foreach (var method in methodsOfFile)
            {
                string fullName = method.Attribute("name").Value + method.Attribute("signature").Value;
                fullName = ExtractMethodName(fullName, method.Parent.Parent.Attribute("name").Value);

                if (lambdaMethodNameRegex.IsMatch(fullName))
                {
                    continue;
                }

                string shortName = methodRegex.Replace(fullName, m => string.Format(CultureInfo.InvariantCulture, "{0}({1})", m.Groups["MethodName"].Value, m.Groups["Arguments"].Value.Length > 0 ? "..." : string.Empty));

                var metrics = new List <Metric>();

                var lineRate = method.Attribute("line-rate");

                if (lineRate != null)
                {
                    decimal?value = null;

                    if (!"NaN".Equals(lineRate.Value, StringComparison.OrdinalIgnoreCase))
                    {
                        value = Math.Round(100 * decimal.Parse(lineRate.Value, CultureInfo.InvariantCulture), 2, MidpointRounding.AwayFromZero);
                    }

                    metrics.Add(new Metric(
                                    ReportResources.Coverage,
                                    ParserBase.CodeCoverageUri,
                                    MetricType.CoveragePercentual,
                                    value));
                }

                var branchRate = method.Attribute("branch-rate");

                if (branchRate != null)
                {
                    decimal?value = null;

                    if (!"NaN".Equals(branchRate.Value, StringComparison.OrdinalIgnoreCase))
                    {
                        value = Math.Round(100 * decimal.Parse(branchRate.Value, CultureInfo.InvariantCulture), 2, MidpointRounding.AwayFromZero);
                    }

                    metrics.Add(new Metric(
                                    ReportResources.BranchCoverage,
                                    ParserBase.CodeCoverageUri,
                                    MetricType.CoveragePercentual,
                                    value));
                }

                var cyclomaticComplexityAttribute = method.Attribute("complexity");

                if (cyclomaticComplexityAttribute != null)
                {
                    decimal?value = null;

                    if (!"NaN".Equals(cyclomaticComplexityAttribute.Value, StringComparison.OrdinalIgnoreCase))
                    {
                        value = Math.Round(decimal.Parse(cyclomaticComplexityAttribute.Value, CultureInfo.InvariantCulture), 2, MidpointRounding.AwayFromZero);
                    }

                    metrics.Insert(
                        0,
                        new Metric(
                            ReportResources.CyclomaticComplexity,
                            ParserBase.CyclomaticComplexityUri,
                            MetricType.CodeQuality,
                            value));
                }

                var methodMetric = new MethodMetric(fullName, shortName, metrics);

                var line = method
                           .Elements("lines")
                           .Elements("line")
                           .FirstOrDefault();

                if (line != null)
                {
                    methodMetric.Line = int.Parse(line.Attribute("number").Value, CultureInfo.InvariantCulture);
                }

                /* If cobertura file is merged from different files, a class and therefore method can exist several times.
                 * The first result is used. */
                if (codeFile.MethodMetrics.Any(m => m.Equals(methodMetric)))
                {
                    continue;
                }

                codeFile.AddMethodMetric(methodMetric);
            }
        }
        /// <summary>
        /// Extracts the metrics from the given <see cref="XElement">XElements</see>.
        /// </summary>
        /// <param name="codeFile">The code file.</param>
        /// <param name="methodsOfFile">The methods of the file.</param>
        private static void SetMethodMetrics(CodeFile codeFile, IEnumerable <XElement> methodsOfFile)
        {
            foreach (var methodGroup in methodsOfFile.GroupBy(m => m.Element("Name").Value))
            {
                var method = methodGroup.First();

                // Exclude properties and lambda expressions
                if (method.Attribute("skippedDueTo") != null ||
                    method.HasAttributeWithValue("isGetter", "true") ||
                    method.HasAttributeWithValue("isSetter", "true") ||
                    lambdaMethodNameRegex.IsMatch(methodGroup.Key))
                {
                    continue;
                }

                var metrics = new List <Metric>()
                {
                    new Metric(
                        ReportResources.CyclomaticComplexity,
                        ParserBase.CyclomaticComplexityUri,
                        MetricType.CodeQuality,
                        methodGroup.Max(m => int.Parse(m.Attribute("cyclomaticComplexity").Value, CultureInfo.InvariantCulture))),
                    new Metric(
                        ReportResources.SequenceCoverage,
                        ParserBase.CodeCoverageUri,
                        MetricType.CoveragePercentual,
                        methodGroup.Max(m => decimal.Parse(m.Attribute("sequenceCoverage").Value, CultureInfo.InvariantCulture))),
                    new Metric(
                        ReportResources.BranchCoverage,
                        ParserBase.CodeCoverageUri,
                        MetricType.CoveragePercentual,
                        methodGroup.Max(m => decimal.Parse(m.Attribute("branchCoverage").Value, CultureInfo.InvariantCulture)))
                };

                var npathComplexityAttributes = methodGroup.Select(m => m.Attribute("nPathComplexity")).Where(a => a != null).ToArray();

                if (npathComplexityAttributes.Length > 0)
                {
                    metrics.Insert(
                        1,
                        new Metric(
                            ReportResources.NPathComplexity,
                            ParserBase.NPathComplexityUri,
                            MetricType.CodeQuality,
                            npathComplexityAttributes
                            .Select(a => int.Parse(a.Value, CultureInfo.InvariantCulture))
                            .Max(a => a < 0 ? int.MaxValue : a)));
                }

                var crapScoreAttributes = methodGroup.Select(m => m.Attribute("crapScore")).Where(a => a != null).ToArray();
                if (crapScoreAttributes.Length > 0)
                {
                    metrics.Add(new Metric(
                                    ReportResources.CrapScore,
                                    ParserBase.CrapScoreUri,
                                    MetricType.CodeQuality,
                                    crapScoreAttributes.Max(a => decimal.Parse(a.Value, CultureInfo.InvariantCulture))));
                }

                string fullName  = ExtractMethodName(methodGroup.Key);
                string shortName = methodRegex.Replace(fullName, m => string.Format(CultureInfo.InvariantCulture, "{0}({1})", m.Groups["MethodName"].Value, m.Groups["Arguments"].Value.Length > 0 ? "..." : string.Empty));

                var methodMetric = new MethodMetric(fullName, shortName, metrics);

                var seqpnt = method
                             .Elements("SequencePoints")
                             .Elements("SequencePoint")
                             .FirstOrDefault();

                if (seqpnt != null)
                {
                    methodMetric.Line = int.Parse(seqpnt.Attribute("sl").Value, CultureInfo.InvariantCulture);
                }

                codeFile.AddMethodMetric(methodMetric);
            }
        }