Skip to content

Commit

Permalink
Add support for Opencover format based on opencover plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
jonesbusy committed Oct 26, 2023
1 parent 276491c commit ed8ed23
Show file tree
Hide file tree
Showing 7 changed files with 7,753 additions and 0 deletions.
92 changes: 92 additions & 0 deletions src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package edu.hm.hafner.coverage.parser;

import java.io.IOException;

Check warning on line 3 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / PMD

UnnecessaryImport

NORMAL: Unused import 'java.io.IOException'.
Raw output
Reports import statements that can be removed. They are either unused, duplicated, or the members they import are already implicitly in scope, because they're in java.lang, or the current package. <pre> <code> import java.io.File; // not used, can be removed import java.util.Collections; // used below import java.util.*; // so this one is not used import java.lang.Object; // imports from java.lang, unnecessary import java.lang.Object; // duplicate, unnecessary public class Foo { static Object emptyList() { return Collections.emptyList(); } } </code> </pre> <a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_codestyle.html#unnecessaryimport"> See PMD documentation. </a>
import java.io.Reader;
import java.io.StringWriter;

Check warning on line 5 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / PMD

UnnecessaryImport

NORMAL: Unused import 'java.io.StringWriter'.
Raw output
Reports import statements that can be removed. They are either unused, duplicated, or the members they import are already implicitly in scope, because they're in java.lang, or the current package. <pre> <code> import java.io.File; // not used, can be removed import java.util.Collections; // used below import java.util.*; // so this one is not used import java.lang.Object; // imports from java.lang, unnecessary import java.lang.Object; // duplicate, unnecessary public class Foo { static Object emptyList() { return Collections.emptyList(); } } </code> </pre> <a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_codestyle.html#unnecessaryimport"> See PMD documentation. </a>
import java.nio.file.Paths;
import java.util.NoSuchElementException;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLOutputFactory;

Check warning on line 11 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / PMD

UnnecessaryImport

NORMAL: Unused import 'javax.xml.stream.XMLOutputFactory'.
Raw output
Reports import statements that can be removed. They are either unused, duplicated, or the members they import are already implicitly in scope, because they're in java.lang, or the current package. <pre> <code> import java.io.File; // not used, can be removed import java.util.Collections; // used below import java.util.*; // so this one is not used import java.lang.Object; // imports from java.lang, unnecessary import java.lang.Object; // duplicate, unnecessary public class Foo { static Object emptyList() { return Collections.emptyList(); } } </code> </pre> <a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_codestyle.html#unnecessaryimport"> See PMD documentation. </a>
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import org.apache.commons.io.IOUtils;

Check warning on line 16 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / PMD

UnnecessaryImport

NORMAL: Unused import 'org.apache.commons.io.IOUtils'.
Raw output
Reports import statements that can be removed. They are either unused, duplicated, or the members they import are already implicitly in scope, because they're in java.lang, or the current package. <pre> <code> import java.io.File; // not used, can be removed import java.util.Collections; // used below import java.util.*; // so this one is not used import java.lang.Object; // imports from java.lang, unnecessary import java.lang.Object; // duplicate, unnecessary public class Foo { static Object emptyList() { return Collections.emptyList(); } } </code> </pre> <a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_codestyle.html#unnecessaryimport"> See PMD documentation. </a>

import edu.hm.hafner.coverage.CoverageParser;
import edu.hm.hafner.coverage.ModuleNode;
import edu.hm.hafner.util.FilteredLog;
import edu.hm.hafner.util.PathUtil;
import edu.hm.hafner.util.SecureXmlParserFactory;
import edu.hm.hafner.util.SecureXmlParserFactory.ParsingException;

/**
* A parser which parses reports made by OpenCover into a Java Object Model.
*
*/
public class OpenCoverParser extends CoverageParser {

private static final long serialVersionUID = 1L;

private static final PathUtil PATH_UTIL = new PathUtil();

/** XML elements. */
private static final QName MODULE = new QName("Module");
private static final QName CLASS = new QName("Class");

@Override
protected ModuleNode parseReport(final Reader reader, final FilteredLog log) {
try {
var eventReader = new SecureXmlParserFactory().createXmlEventReader(reader);
var root = new ModuleNode("-");
boolean isEmpty = true;
while (eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
if (event.isStartElement()) {
var startElement = event.asStartElement();
var tagName = startElement.getName();
if (MODULE.equals(tagName)) {

Check warning on line 50 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / Mutation Coverage

Mutation survived

One mutation survived in line 50 (NegateConditionalsMutator)
Raw output
Survived mutations:
- negated conditional (org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator)
readModule(eventReader, root, startElement, log);

Check warning on line 51 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / Mutation Coverage

Mutation survived

One mutation survived in line 51 (VoidMethodCallMutator)
Raw output
Survived mutations:
- removed call to edu/hm/hafner/coverage/parser/OpenCoverParser::readModule (org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator)
isEmpty = false;
}

Check warning on line 53 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / CPD

CPD

LOW: Found duplicated code.
Raw output
<pre><code>&#64;Override protected ModuleNode parseReport(final Reader reader, final FilteredLog log) { try { var eventReader &#61; new SecureXmlParserFactory().createXmlEventReader(reader); var root &#61; new ModuleNode(&#34;-&#34;); boolean isEmpty &#61; true; while (eventReader.hasNext()) { XMLEvent event &#61; eventReader.nextEvent(); if (event.isStartElement()) { var startElement &#61; event.asStartElement(); var tagName &#61; startElement.getName(); if (SOURCE.equals(tagName)) {<!-- --></code></pre>
}
}
if (isEmpty) {

Check warning on line 56 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 56 is only partially covered, one branch is missing
throw new NoSuchElementException("No coverage information found in the specified file.");

Check warning on line 57 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 57 is not covered by tests
}
return root;

Check warning on line 59 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / Mutation Coverage

Mutation survived

One mutation survived in line 59 (NullReturnValsMutator)
Raw output
Survived mutations:
- replaced return value with null for edu/hm/hafner/coverage/parser/OpenCoverParser::parseReport (org.pitest.mutationtest.engine.gregor.mutators.returns.NullReturnValsMutator)
}
catch (XMLStreamException exception) {
throw new ParsingException(exception);

Check warning on line 62 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 61-62 are not covered by tests
}
}

private void readModule(final XMLEventReader reader, final ModuleNode root,

Check notice

Code scanning / CodeQL

Useless parameter Note

The parameter 'root' is never used.

Check warning on line 66 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / PMD

UnusedFormalParameter

NORMAL: Avoid unused method parameters such as 'root'.
Raw output
Reports parameters of methods and constructors that are not referenced them in the method body. Parameters whose name starts with `ignored` or `unused` are filtered out. Removing unused formal parameters from public methods could cause a ripple effect through the code base. Hence, by default, this rule only considers private methods. To include non-private methods, set the `checkAll` property to `true`. <pre> <code> public class Foo { private void bar(String howdy) { // howdy is not used } } </code> </pre> <a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_bestpractices.html#unusedformalparameter"> See PMD documentation. </a>
final StartElement currentStartElement, final FilteredLog log) throws XMLStreamException {

Check notice

Code scanning / CodeQL

Useless parameter Note

The parameter 'currentStartElement' is never used.

Check notice

Code scanning / CodeQL

Useless parameter Note

The parameter 'log' is never used.

Check warning on line 67 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / PMD

UnusedFormalParameter

NORMAL: Avoid unused method parameters such as 'currentStartElement'.
Raw output
Reports parameters of methods and constructors that are not referenced them in the method body. Parameters whose name starts with `ignored` or `unused` are filtered out. Removing unused formal parameters from public methods could cause a ripple effect through the code base. Hence, by default, this rule only considers private methods. To include non-private methods, set the `checkAll` property to `true`. <pre> <code> public class Foo { private void bar(String howdy) { // howdy is not used } } </code> </pre> <a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_bestpractices.html#unusedformalparameter"> See PMD documentation. </a>

Check warning on line 67 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / PMD

UnusedFormalParameter

NORMAL: Avoid unused method parameters such as 'log'.
Raw output
Reports parameters of methods and constructors that are not referenced them in the method body. Parameters whose name starts with `ignored` or `unused` are filtered out. Removing unused formal parameters from public methods could cause a ripple effect through the code base. Hence, by default, this rule only considers private methods. To include non-private methods, set the `checkAll` property to `true`. <pre> <code> public class Foo { private void bar(String howdy) { // howdy is not used } } </code> </pre> <a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_bestpractices.html#unusedformalparameter"> See PMD documentation. </a>

while (reader.hasNext()) {

Check warning on line 69 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 69 is only partially covered, one branch is missing

Check warning on line 69 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / Mutation Coverage

Mutation survived

One mutation survived in line 69 (NegateConditionalsMutator)
Raw output
Survived mutations:
- negated conditional (org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator)
XMLEvent event = reader.nextEvent();

if (event.isStartElement()) {
var nextElement = event.asStartElement();
if (CLASS.equals(nextElement.getName())) {

Check warning on line 74 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 74 is only partially covered, one branch is missing

Check warning on line 74 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / Mutation Coverage

Mutation survived

One mutation survived in line 74 (NegateConditionalsMutator)
Raw output
Survived mutations:
- negated conditional (org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator)

Check warning on line 74 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / SpotBugs

UCF_USELESS_CONTROL_FLOW

LOW: Useless control flow in edu.hm.hafner.coverage.parser.OpenCoverParser.readModule(XMLEventReader, ModuleNode, StartElement, FilteredLog)
Raw output
<p> This method contains a useless control flow statement, where control flow continues onto the same place regardless of whether or not the branch is taken. For example, this is caused by having an empty statement block for an <code>if</code> statement:</p> <pre><code>if (argv.length == 0) { // TODO: handle this case } </code></pre>

Check warning on line 74 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / CheckStyle

EmptyBlockCheck

NORMAL: Must have at least one statement.
Raw output
<p>Since Checkstyle 3.0</p><p> Checks for empty blocks. This check does not validate sequential blocks. </p><p> Sequential blocks won't be checked. Also, no violations for fallthrough: </p><pre><code> switch (a) { case 1: // no violation case 2: // no violation case 3: someMethod(); { } // no violation default: break; } </code></pre><p> This check processes LITERAL_CASE and LITERAL_DEFAULT separately. So, if tokens=LITERAL_DEFAULT, following code will not trigger any violation, as the empty block belongs to LITERAL_CASE: </p><p> Configuration: </p><pre><code> &lt;module name="EmptyBlock"&gt; &lt;property name="tokens" value="LITERAL_DEFAULT"/&gt; &lt;/module&gt; </code></pre><p> Result: </p><pre><code> switch (a) { default: // no violation for "default:" as empty block belong to "case 1:" case 1: { } } </code></pre>
// TODO: read class

Check warning on line 75 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / Open Tasks Scanner

TODO

NORMAL: read class
}
}
else if (event.isEndElement()) {

Check warning on line 78 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / Mutation Coverage

Mutation survived

One mutation survived in line 78 (NegateConditionalsMutator)
Raw output
Survived mutations:
- negated conditional (org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator)
return; // finish processing of package
}
}
}

private String getFileName(final String relativePath) {
var path = Paths.get(PATH_UTIL.getAbsolutePath(relativePath)).getFileName();
if (path == null) {
return relativePath;
}
return path.toString();

Check warning on line 89 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 82-89 are not covered by tests

Check warning on line 89 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / SpotBugs

UPM_UNCALLED_PRIVATE_METHOD

LOW: Private method edu.hm.hafner.coverage.parser.OpenCoverParser.getFileName(String) is never called
Raw output
<p> This private method is never called. Although it is possible that the method will be invoked through reflection, it is more likely that the method is never used, and should be removed. </p>
}

Check warning on line 90 in src/main/java/edu/hm/hafner/coverage/parser/OpenCoverParser.java

View check run for this annotation

ci.jenkins.io / CPD

CPD

LOW: Found duplicated code.
Raw output
<pre><code>} } else if (event.isEndElement()) { return; // finish processing of package } } } private String getFileName(final String relativePath) { var path &#61; Paths.get(PATH_UTIL.getAbsolutePath(relativePath)).getFileName(); if (path &#61;&#61; null) { return relativePath; } return path.toString(); }</code></pre>

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import edu.hm.hafner.coverage.CoverageParser.ProcessingMode;
import edu.hm.hafner.coverage.parser.CoberturaParser;
import edu.hm.hafner.coverage.parser.JacocoParser;
import edu.hm.hafner.coverage.parser.OpenCoverParser;
import edu.hm.hafner.coverage.parser.PitestParser;

/**
Expand All @@ -15,6 +16,7 @@ public class ParserRegistry {
/** Supported parsers. */
public enum CoverageParserType {
COBERTURA,
OPENCOVER,
JACOCO,
PIT
}
Expand Down Expand Up @@ -52,6 +54,8 @@ public CoverageParser getParser(final CoverageParserType parser, final Processin
switch (parser) {
case COBERTURA:
return new CoberturaParser(processingMode);
case OPENCOVER:
return new OpenCoverParser();
case JACOCO:
return new JacocoParser();
case PIT:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package edu.hm.hafner.coverage.parser;

import java.util.NoSuchElementException;

Check warning on line 3 in src/test/java/edu/hm/hafner/coverage/parser/OpenCoverParserTest.java

View check run for this annotation

ci.jenkins.io / PMD

UnnecessaryImport

NORMAL: Unused import 'java.util.NoSuchElementException'.
Raw output
Reports import statements that can be removed. They are either unused, duplicated, or the members they import are already implicitly in scope, because they're in java.lang, or the current package. <pre> <code> import java.io.File; // not used, can be removed import java.util.Collections; // used below import java.util.*; // so this one is not used import java.lang.Object; // imports from java.lang, unnecessary import java.lang.Object; // duplicate, unnecessary public class Foo { static Object emptyList() { return Collections.emptyList(); } } </code> </pre> <a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_codestyle.html#unnecessaryimport"> See PMD documentation. </a>

import org.junit.jupiter.api.Test;
import org.junitpioneer.jupiter.DefaultLocale;

import edu.hm.hafner.coverage.CoverageParser;
import edu.hm.hafner.coverage.ModuleNode;
import edu.hm.hafner.util.SecureXmlParserFactory.ParsingException;

Check warning on line 10 in src/test/java/edu/hm/hafner/coverage/parser/OpenCoverParserTest.java

View check run for this annotation

ci.jenkins.io / PMD

UnnecessaryImport

NORMAL: Unused import 'edu.hm.hafner.util.SecureXmlParserFactory.ParsingException'.
Raw output
Reports import statements that can be removed. They are either unused, duplicated, or the members they import are already implicitly in scope, because they're in java.lang, or the current package. <pre> <code> import java.io.File; // not used, can be removed import java.util.Collections; // used below import java.util.*; // so this one is not used import java.lang.Object; // imports from java.lang, unnecessary import java.lang.Object; // duplicate, unnecessary public class Foo { static Object emptyList() { return Collections.emptyList(); } } </code> </pre> <a href="https://pmd.github.io/pmd-6.55.0/pmd_rules_java_codestyle.html#unnecessaryimport"> See PMD documentation. </a>

@DefaultLocale("en")
class OpenCoverParserTest extends AbstractParserTest {

@Override
CoverageParser createParser() {
return new OpenCoverParser();
}

@Test
void shouldReadReport() {
readExampleReport();
}

@Override
@Test
void shouldFailWhenParsingInvalidFiles() {

}

private ModuleNode readExampleReport() {
return readReport("opencover.xml", new OpenCoverParser());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import edu.hm.hafner.coverage.CoverageParser.ProcessingMode;
import edu.hm.hafner.coverage.parser.CoberturaParser;
import edu.hm.hafner.coverage.parser.JacocoParser;
import edu.hm.hafner.coverage.parser.OpenCoverParser;
import edu.hm.hafner.coverage.registry.ParserRegistry.CoverageParserType;

import static org.assertj.core.api.Assertions.*;
Expand All @@ -16,6 +17,7 @@ void shouldCreateSomeParsers() {

assertThat(registry.getParser(CoverageParserType.COBERTURA.name(), ProcessingMode.FAIL_FAST)).isInstanceOf(CoberturaParser.class);
assertThat(registry.getParser(CoverageParserType.JACOCO, ProcessingMode.IGNORE_ERRORS)).isInstanceOf(JacocoParser.class);
assertThat(registry.getParser(CoverageParserType.OPENCOVER, ProcessingMode.IGNORE_ERRORS)).isInstanceOf(OpenCoverParser.class);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<CoverageSession>
<Summary numSequencePoints="15" visitedSequencePoints="9" numBranchPoints="6" visitedBranchPoints="3" sequenceCoverage="60" branchCoverage="50" maxCyclomaticComplexity="6" minCyclomaticComplexity="6" visitedClasses="1" numClasses="1" visitedMethods="1" numMethods="1" />
<Modules>
<Module hash="31750BAB-054A-4C4B-8763-D76F95F0353A">
<ModulePath>ClassLibrary.dll</ModulePath>
<ModuleTime>2019-12-13T01:36:13</ModuleTime>
<ModuleName>ClassLibrary</ModuleName>
<Files>
<File uid="1" fullPath="[PLACEHOLDER]" />
</Files>
<Classes>
<Class>
<Summary numSequencePoints="15" visitedSequencePoints="9" numBranchPoints="6" visitedBranchPoints="3" sequenceCoverage="60" branchCoverage="50" maxCyclomaticComplexity="6" minCyclomaticComplexity="6" visitedClasses="1" numClasses="1" visitedMethods="1" numMethods="1" />
<FullName>ClassLibrary.LibraryClass</FullName>
<Methods>
<Method cyclomaticComplexity="6" nPathComplexity="0" sequenceCoverage="60" branchCoverage="50" isConstructor="False" isGetter="False" isSetter="False" isStatic="True">
<Summary numSequencePoints="15" visitedSequencePoints="9" numBranchPoints="6" visitedBranchPoints="3" sequenceCoverage="60" branchCoverage="50" maxCyclomaticComplexity="6" minCyclomaticComplexity="6" visitedClasses="0" numClasses="0" visitedMethods="1" numMethods="1" />
<MetadataToken />
<Name>System.Int32 ClassLibrary.LibraryClass::Sum(System.Int32,System.Int32)</Name>
<FileRef uid="1" />
<SequencePoints>
<SequencePoint vc="2" uspid="8" ordinal="0" sl="8" sc="1" el="8" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="2" uspid="9" ordinal="1" sl="9" sc="1" el="9" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="2" uspid="10" ordinal="2" sl="10" sc="1" el="10" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="0" uspid="13" ordinal="3" sl="13" sc="1" el="13" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="0" uspid="14" ordinal="4" sl="14" sc="1" el="14" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="0" uspid="16" ordinal="5" sl="16" sc="1" el="16" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="0" uspid="17" ordinal="6" sl="17" sc="1" el="17" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="0" uspid="19" ordinal="7" sl="19" sc="1" el="19" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="0" uspid="20" ordinal="8" sl="20" sc="1" el="20" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="1" uspid="22" ordinal="9" sl="22" sc="1" el="22" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="1" uspid="23" ordinal="10" sl="23" sc="1" el="23" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="1" uspid="25" ordinal="11" sl="25" sc="1" el="25" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="1" uspid="26" ordinal="12" sl="26" sc="1" el="26" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="2" uspid="28" ordinal="13" sl="28" sc="1" el="28" ec="2" bec="0" bev="0" fileid="1" />
<SequencePoint vc="2" uspid="29" ordinal="14" sl="29" sc="1" el="29" ec="2" bec="0" bev="0" fileid="1" />
</SequencePoints>
<BranchPoints>
<BranchPoint vc="0" uspid="10" ordinal="1" path="1" offset="8" offsetend="35" sl="10" fileid="1" />
<BranchPoint vc="0" uspid="10" ordinal="2" path="2" offset="8" offsetend="44" sl="10" fileid="1" />
<BranchPoint vc="0" uspid="10" ordinal="3" path="3" offset="8" offsetend="53" sl="10" fileid="1" />
<BranchPoint vc="1" uspid="10" ordinal="4" path="4" offset="8" offsetend="62" sl="10" fileid="1" />
<BranchPoint vc="1" uspid="10" ordinal="5" path="5" offset="8" offsetend="71" sl="10" fileid="1" />
<BranchPoint vc="2" uspid="10" ordinal="0" path="0" offset="8" offsetend="80" sl="10" fileid="1" />
</BranchPoints>
<MethodPoint vc="9" uspid="0" p8:type="SequencePoint" ordinal="0" offset="0" sc="0" sl="8" ec="1" el="29" bec="0" bev="0" fileid="1" xmlns:p8="xsi" />
</Method>
</Methods>
</Class>
</Classes>
</Module>
</Modules>
</CoverageSession>
Loading

0 comments on commit ed8ed23

Please sign in to comment.