Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flag for xml report #57

Merged
merged 8 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/slipcover/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .version import __version__
from .slipcover import Slipcover, merge_coverage, print_coverage
from .slipcover import Slipcover, merge_coverage, print_coverage, print_xml
from .importer import FileMatcher, ImportManager, wrap_pytest
from .fuzz import wrap_function
8 changes: 8 additions & 0 deletions src/slipcover/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ def main():
ap.add_argument('--branch', action='store_true', help="measure both branch and line coverage")
ap.add_argument('--json', action='store_true', help="select JSON output")
ap.add_argument('--pretty-print', action='store_true', help="pretty-print JSON output")
ap.add_argument('--xml', action='store_true', help="select XML output")
ap.add_argument('--xml-package-depth', type=int, default=99, help=(
"Controls which directories are identified as packages in the report. "
"Directories deeper than this depth are not reported as packages. "
"The default is that all directories are reported as packages."))
ap.add_argument('--out', type=Path, help="specify output file name")
ap.add_argument('--source', help="specify directories to cover")
ap.add_argument('--omit', help="specify file(s) to omit")
Expand Down Expand Up @@ -205,6 +210,9 @@ def sci_atexit():
def printit(coverage, outfile):
if args.json:
print(json.dumps(coverage, indent=(4 if args.pretty_print else None)), file=outfile)
elif args.xml:
sc.print_xml(coverage, source_paths=[str(base_path)], with_branches=args.branch,
xml_package_depth=args.xml_package_depth, outfile=outfile)
else:
sc.print_coverage(coverage, outfile=outfile, skip_covered=args.skip_covered,
missing_width=args.missing_width)
Expand Down
58 changes: 52 additions & 6 deletions src/slipcover/slipcover.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
from __future__ import annotations
import sys

import dis
import types
from typing import Dict, Set, List, Tuple
from collections import defaultdict, Counter
import sys
import threading
import types
from collections import Counter, defaultdict
from typing import TYPE_CHECKING

if sys.version_info[0:2] < (3,12):
from . import probe
from . import bytecode as bc
from . import probe

from pathlib import Path

from . import branch as br
from .version import __version__
from .xmlreport import XmlReporter
Fixed Show fixed Hide fixed

# FIXME provide __all__

Expand All @@ -38,6 +41,34 @@ def findlinestarts(co: types.CodeType):
else:
findlinestarts = dis.findlinestarts

if TYPE_CHECKING:
from typing import Dict, Iterable, Iterator, List, NotRequired, Tuple, TypedDict

class CoverageMeta(TypedDict):
software: str
version: str
timestamp: str
branch_coverage: bool
show_contexts: bool

class CoverageSummary(TypedDict):
covered_lines: int
missing_lines: int
covered_branches: NotRequired[int]
missing_branches: NotRequired[int]
percent_covered: float

class CoverageFile(TypedDict):
executed_lines: List[int]
missing_lines: List[int]
executed_branches: NotRequired[List[Tuple[int, int]]]
missing_branches: NotRequired[List[Tuple[int, int]]]
summary: CoverageSummary

class Coverage(TypedDict):
meta: CoverageMeta
files: Dict[str, CoverageFile]
summary: CoverageSummary

class SlipcoverError(Exception):
pass
Expand All @@ -56,7 +87,7 @@ def simplify(self, path : str) -> str:


def format_missing(missing_lines: List[int], executed_lines: List[int],
missing_branches: List[tuple]) -> List[str]:
missing_branches: List[tuple]) -> str:
"""Formats ranges of missing lines, including non-code (e.g., comments) ones that fall
between missed ones"""

Expand Down Expand Up @@ -92,6 +123,21 @@ def find_ranges():

return ", ".join(find_ranges())

def print_xml(
coverage: Coverage,
source_paths: Iterable[str],
*,
with_branches: bool = False,
xml_package_depth: int = 99,
outfile=sys.stdout
) -> None:
XmlReporter(
coverage=coverage,
source=source_paths,
with_branches=with_branches,
xml_package_depth=xml_package_depth,
).report(outfile=outfile)


def print_coverage(coverage, *, outfile=sys.stdout, missing_width=None, skip_covered=False) -> None:
"""Prints coverage information for human consumption."""
Expand Down
1 change: 1 addition & 0 deletions src/slipcover/version.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
__version__ = "1.0.15"
__url__ = f"https://github.com/plasma-umass/slipcover/tree/v{__version__}"
Loading
Loading