Parsers¶
Multi-framework mutation report parsers and framework auto-detection.
Unified mutation testing parser interface.
This module provides a single entry point for parsing mutation testing output from multiple frameworks (Stryker, mutmut, etc.) with automatic framework detection.
- Usage:
from curate_ipsum.parsers import parse_mutation_output
# Auto-detect framework result = parse_mutation_output(working_directory=”/path/to/project”)
# Explicit framework result = parse_mutation_output(
working_directory=”/path/to/project”, tool=”mutmut”
)
- curate_ipsum.parsers.parse_mutation_output(working_directory, tool=None, report_path=None)[source]¶
Parse mutation testing output, auto-detecting framework if not specified.
This is the main entry point for all mutation testing parsers. It routes to the appropriate parser based on the tool parameter or auto-detection.
- Parameters:
- Returns:
Tuple of (total_mutants, killed, survived, no_coverage, score, by_file)
total_mutants: Total number of mutants processed
killed: Number of mutants killed by tests
survived: Number of mutants that survived
no_coverage: Number of mutants with no test coverage
score: Mutation score as killed/(killed+survived)
by_file: Per-file breakdown as FileMutationStats list
- Raises:
UnsupportedFrameworkError – If framework is not supported
FileNotFoundError – If report/cache not found
- Return type:
Examples
# Auto-detect framework >>> total, killed, survived, no_cov, score, by_file = parse_mutation_output(“./”)
# Explicit Stryker >>> parse_mutation_output(“./”, tool=”stryker”)
# Explicit mutmut with custom cache path >>> parse_mutation_output(“./”, tool=”mutmut”, report_path=”./.mutmut-cache”)
- exception curate_ipsum.parsers.UnsupportedFrameworkError[source]¶
Bases:
ExceptionRaised when a mutation framework is not supported.
- class curate_ipsum.parsers.MutationFramework(*values)[source]¶
Bases:
StrEnumSupported mutation testing frameworks.
- STRYKER = 'stryker'¶
- MUTMUT = 'mutmut'¶
- COSMIC_RAY = 'cosmic-ray'¶
- POODLE = 'poodle'¶
- UNIVERSALMUTATOR = 'universalmutator'¶
- MUTPY = 'mutpy'¶
- UNKNOWN = 'unknown'¶
- class curate_ipsum.parsers.FrameworkDetection(framework, confidence, evidence)[source]¶
Bases:
objectResult of framework detection.
- Parameters:
framework (MutationFramework)
confidence (float)
evidence (str)
- framework: MutationFramework¶
- class curate_ipsum.parsers.ProjectLanguage(primary, secondary, confidence)[source]¶
Bases:
objectDetected project language(s).
- curate_ipsum.parsers.detect_language(working_directory)[source]¶
Detect primary language of a project.
Examines file extensions and configuration files to determine the project’s primary programming language.
- Parameters:
working_directory (str) – Project directory to analyze
- Returns:
ProjectLanguage with primary language and confidence
- Return type:
- curate_ipsum.parsers.detect_available_frameworks(working_directory)[source]¶
Detect which mutation frameworks have been run or are configured.
Checks for: - Output files/directories from each framework - Configuration files - Cache files
- Parameters:
working_directory (str) – Project directory to analyze
- Returns:
List of detected frameworks with confidence scores
- Return type:
- curate_ipsum.parsers.recommend_framework(working_directory)[source]¶
Recommend the best mutation framework for a project.
Priority: 1. Already-run frameworks (have output/cache) 2. Configured frameworks 3. Language-based recommendation
- Parameters:
working_directory (str) – Project directory
- Returns:
Recommended framework with confidence and reasoning
- Return type:
- curate_ipsum.parsers.parse_stryker_output(report_path, working_directory)[source]¶
Parse Stryker mutation testing output.
This is the main entry point for Stryker parsing.
- Parameters:
- Returns:
Tuple of (total_mutants, killed, survived, no_coverage, score, by_file)
- Raises:
FileNotFoundError – If report not found
ValueError – If report format is invalid
- Return type:
- curate_ipsum.parsers.parse_mutmut_output(working_directory, cache_path=None)[source]¶
Parse mutmut results from cache.
This is the main entry point for mutmut parsing, matching the signature of parse_stryker_output for unified interface compatibility.
- Parameters:
- Returns:
Tuple of (total, killed, survived, no_coverage, score, by_file)
- Raises:
FileNotFoundError – If cache not found
- Return type:
- curate_ipsum.parsers.parse_cosmic_ray_output(working_directory, report_path=None)[source]¶
Parse cosmic-ray mutation testing output.
Main entry point matching the unified parser interface (D-009).
- Parameters:
- Returns:
Tuple of (total, killed, survived, no_coverage, score, by_file)
- Raises:
FileNotFoundError – If session/report not found
- Return type:
- curate_ipsum.parsers.parse_poodle_output(working_directory, report_path=None)[source]¶
Parse poodle mutation testing output.
Main entry point matching the unified parser interface (D-009).
- Parameters:
- Returns:
Tuple of (total, killed, survived, no_coverage, score, by_file)
- Raises:
FileNotFoundError – If report not found
ValueError – If report format is invalid
- Return type:
- curate_ipsum.parsers.parse_universalmutator_output(working_directory, report_path=None)[source]¶
Parse universalmutator results from killed.txt / not-killed.txt.
Main entry point matching the unified parser interface (D-009).
- Parameters:
- Returns:
Tuple of (total, killed, survived, no_coverage, score, by_file)
- Raises:
FileNotFoundError – If result files not found
- Return type:
Mutation framework and language detection.
Detects: - Project language (Python, JavaScript, etc.) - Available/configured mutation frameworks - Recommends the best framework for a project
- class curate_ipsum.parsers.detection.MutationFramework(*values)[source]¶
Bases:
StrEnumSupported mutation testing frameworks.
- STRYKER = 'stryker'¶
- MUTMUT = 'mutmut'¶
- COSMIC_RAY = 'cosmic-ray'¶
- POODLE = 'poodle'¶
- UNIVERSALMUTATOR = 'universalmutator'¶
- MUTPY = 'mutpy'¶
- UNKNOWN = 'unknown'¶
- class curate_ipsum.parsers.detection.FrameworkDetection(framework, confidence, evidence)[source]¶
Bases:
objectResult of framework detection.
- Parameters:
framework (MutationFramework)
confidence (float)
evidence (str)
- framework: MutationFramework¶
- class curate_ipsum.parsers.detection.ProjectLanguage(primary, secondary, confidence)[source]¶
Bases:
objectDetected project language(s).
- curate_ipsum.parsers.detection.detect_language(working_directory)[source]¶
Detect primary language of a project.
Examines file extensions and configuration files to determine the project’s primary programming language.
- Parameters:
working_directory (str) – Project directory to analyze
- Returns:
ProjectLanguage with primary language and confidence
- Return type:
- curate_ipsum.parsers.detection.detect_available_frameworks(working_directory)[source]¶
Detect which mutation frameworks have been run or are configured.
Checks for: - Output files/directories from each framework - Configuration files - Cache files
- Parameters:
working_directory (str) – Project directory to analyze
- Returns:
List of detected frameworks with confidence scores
- Return type:
- curate_ipsum.parsers.detection.recommend_framework(working_directory)[source]¶
Recommend the best mutation framework for a project.
Priority: 1. Already-run frameworks (have output/cache) 2. Configured frameworks 3. Language-based recommendation
- Parameters:
working_directory (str) – Project directory
- Returns:
Recommended framework with confidence and reasoning
- Return type:
Stryker mutation testing report parser.
Stryker is a mutation testing framework primarily for JavaScript/TypeScript. This parser handles Stryker’s JSON report format.
Report locations searched (in order): 1. Explicit reportPath argument 2. reports/mutation/mutation.json 3. reports/stryker-report.json
- curate_ipsum.parsers.stryker_parser.find_stryker_report(working_directory, report_path=None)[source]¶
Locate the Stryker report file.
- curate_ipsum.parsers.stryker_parser.parse_stryker_report(report_path)[source]¶
Parse a Stryker JSON report file.
- Parameters:
report_path (Path) – Path to the report file
- Returns:
Parsed JSON data
- Raises:
FileNotFoundError – If report doesn’t exist
ValueError – If report is not valid JSON or wrong format
- Return type:
- curate_ipsum.parsers.stryker_parser.parse_stryker_output(report_path, working_directory)[source]¶
Parse Stryker mutation testing output.
This is the main entry point for Stryker parsing.
- Parameters:
- Returns:
Tuple of (total_mutants, killed, survived, no_coverage, score, by_file)
- Raises:
FileNotFoundError – If report not found
ValueError – If report format is invalid
- Return type:
Mutmut mutation testing cache parser.
Mutmut is a popular Python mutation testing tool. It stores results in a SQLite database (.mutmut-cache) rather than JSON reports.
- Cache schema (mutmut 2.x):
SourceFile: filename, hash Line: sourcefile_id, line, line_number Mutant: line_id, index, tested_against_hash, status
- Status values:
ok_killed: Mutant was killed by tests
bad_survived: Mutant survived (not detected)
bad_timeout: Test execution timed out
ok_suspicious: Suspicious result
untested: Not yet tested
skipped: Skipped (pragma or config)
- class curate_ipsum.parsers.mutmut_parser.MutmutStatus[source]¶
Bases:
objectMutmut status values (lowercase for comparison).
- OK_KILLED = 'ok_killed'¶
- BAD_SURVIVED = 'bad_survived'¶
- BAD_TIMEOUT = 'bad_timeout'¶
- OK_SUSPICIOUS = 'ok_suspicious'¶
- UNTESTED = 'untested'¶
- SKIPPED = 'skipped'¶
- class curate_ipsum.parsers.mutmut_parser.MutmutMutant(id, file_path, line_number, status, index)[source]¶
Bases:
objectA single mutant from mutmut cache.
- curate_ipsum.parsers.mutmut_parser.find_mutmut_cache(working_directory)[source]¶
Locate the mutmut cache file.
Searches in order: 1. .mutmut-cache in working directory 2. .mutmut-cache in parent directories (up to 3 levels)
- curate_ipsum.parsers.mutmut_parser.parse_mutmut_cache(cache_path)[source]¶
Parse mutmut SQLite cache and extract all mutants.
Handles multiple schema versions by trying v2 first, then v1.
- Parameters:
cache_path (Path) – Path to .mutmut-cache file
- Returns:
List of all mutants in the cache
- Raises:
FileNotFoundError – If cache doesn’t exist
sqlite3.Error – If cache is corrupted
- Return type:
- curate_ipsum.parsers.mutmut_parser.aggregate_mutmut_stats(mutants)[source]¶
Aggregate mutant list into summary statistics.
Groups mutants by file and computes per-file and overall statistics.
- Parameters:
mutants (list[MutmutMutant]) – List of mutants to aggregate
- Returns:
Tuple of (total, killed, survived, no_coverage, score, by_file)
- Return type:
- curate_ipsum.parsers.mutmut_parser.parse_mutmut_output(working_directory, cache_path=None)[source]¶
Parse mutmut results from cache.
This is the main entry point for mutmut parsing, matching the signature of parse_stryker_output for unified interface compatibility.
- Parameters:
- Returns:
Tuple of (total, killed, survived, no_coverage, score, by_file)
- Raises:
FileNotFoundError – If cache not found
- Return type:
- curate_ipsum.parsers.mutmut_parser.get_mutmut_region_mutants(working_directory, region, cache_path=None)[source]¶
Get mutants within a specific region.
Useful for region-level mutation score calculation.
- Parameters:
- Returns:
List of mutants within the region
- Return type:
- curate_ipsum.parsers.mutmut_parser.get_region_mutation_stats(working_directory, region, cache_path=None)[source]¶
Get mutation statistics for a specific region.
- Parameters:
- Returns:
FileMutationStats for the region, or None if no mutants found
- Return type:
FileMutationStats | None
Cosmic-ray mutation testing parser.
Cosmic-ray is a Python mutation testing tool that stores results in a SQLite session database. Results can also be exported via cosmic-ray dump <session> to JSON.
- Session DB schema:
- WorkItem: job_id, module, operator_name, occurrence, start_pos, end_pos,
worker_outcome (int), test_outcome (int), diff
- JSON dump format (from cosmic-ray dump):
- [
- {
“module”: “mypackage.mymodule”, “operator”: “core/NumberReplacer”, “occurrence”: 0, “line_number”: 42, “job_id”: “abc123”, “test_outcome”: “TestOutcome.KILLED”, “worker_outcome”: “WorkerOutcome.NORMAL”, “diff”: “— a/mymodule.py
- +++ …”
]
- Worker outcomes:
NORMAL = 0 # Worker completed normally TIMEOUT = 1 # Worker timed out EXCEPTION = 2 # Worker raised an exception
- Test outcomes:
SURVIVED = 0 # Mutant survived (tests passed) KILLED = 1 # Mutant killed (tests failed) INCOMPETENT = 2 # Mutant was incompetent (couldn’t apply)
- class curate_ipsum.parsers.cosmic_ray_parser.CosmicRayMutant(job_id, module, operator, occurrence, line_number, worker_outcome, test_outcome)[source]¶
Bases:
objectA single mutant from cosmic-ray results.
- Parameters:
- curate_ipsum.parsers.cosmic_ray_parser.find_cosmic_ray_session(working_directory)[source]¶
Locate the cosmic-ray session database or JSON dump.
Searches for: 1. *.sqlite session databases 2. cosmic-ray.json dump files 3. .cosmic-ray.toml config (to find session path)
- curate_ipsum.parsers.cosmic_ray_parser.parse_cosmic_ray_session(session_path)[source]¶
Parse cosmic-ray results from session file (SQLite or JSON).
Auto-detects format based on file content.
- Parameters:
session_path (Path) – Path to session DB or JSON dump
- Returns:
List of all mutants
- Raises:
FileNotFoundError – If session file doesn’t exist
- Return type:
- curate_ipsum.parsers.cosmic_ray_parser.aggregate_cosmic_ray_stats(mutants)[source]¶
Aggregate cosmic-ray mutants into summary statistics.
Groups mutants by module (converted to file path) and computes per-file and overall statistics.
Classification: - killed: test_outcome == “killed” AND worker_outcome == “normal” - survived: test_outcome == “survived” AND worker_outcome == “normal” - no_coverage: worker_outcome in (“timeout”, “exception”)
OR test_outcome == “incompetent”
- Parameters:
mutants (list[CosmicRayMutant]) – List of mutants to aggregate
- Returns:
Tuple of (total, killed, survived, no_coverage, score, by_file)
- Return type:
- curate_ipsum.parsers.cosmic_ray_parser.parse_cosmic_ray_output(working_directory, report_path=None)[source]¶
Parse cosmic-ray mutation testing output.
Main entry point matching the unified parser interface (D-009).
- Parameters:
- Returns:
Tuple of (total, killed, survived, no_coverage, score, by_file)
- Raises:
FileNotFoundError – If session/report not found
- Return type:
Poodle (poodle-test) mutation testing parser.
Poodle is a Python mutation testing tool that outputs JSON reports following the mutation-testing-report-schema (same schema used by Stryker).
- Report format:
- {
“schemaVersion”: “1”, “thresholds”: {“high”: 80, “low”: 60}, “files”: {
- “src/module.py”: {
“language”: “python”, “source”: “…”, “mutants”: [
- {
“id”: “1”, “mutatorName”: “ConditionalsBoundary”, “replacement”: “>=”, “location”: {
“start”: {“line”: 10, “column”: 5}, “end”: {“line”: 10, “column”: 6}
}, “status”: “Killed”, “description”: “…”
]
}
}
- Status values (mutation-testing-report-schema):
Killed: Mutant was detected by tests
Survived: Mutant was not detected
NoCoverage: No tests cover this mutant
CompileError: Mutant caused a compilation error
RuntimeError: Mutant caused a runtime error
Timeout: Test execution timed out
Ignored: Mutant was ignored (pragma, config)
Pending: Mutant has not been tested yet
- curate_ipsum.parsers.poodle_parser.find_poodle_report(working_directory)[source]¶
Locate the poodle mutation testing report.
Searches for common poodle report locations: 1. mutation-report.json (poodle default) 2. poodle-report.json 3. reports/mutation/mutation.json 4. .poodle-report.json
- curate_ipsum.parsers.poodle_parser.parse_poodle_report(report_path)[source]¶
Parse a poodle JSON report file.
The report follows the mutation-testing-report-schema, which is the same schema used by Stryker. This parser handles poodle-specific nuances (Python file paths, poodle status values).
- Parameters:
report_path (Path) – Path to the report file
- Returns:
Parsed JSON data
- Raises:
FileNotFoundError – If report doesn’t exist
ValueError – If report is not valid JSON or wrong format
- Return type:
- curate_ipsum.parsers.poodle_parser.parse_poodle_output(working_directory, report_path=None)[source]¶
Parse poodle mutation testing output.
Main entry point matching the unified parser interface (D-009).
- Parameters:
- Returns:
Tuple of (total, killed, survived, no_coverage, score, by_file)
- Raises:
FileNotFoundError – If report not found
ValueError – If report format is invalid
- Return type:
universalmutator mutation testing parser.
universalmutator is a language-agnostic mutation tool that works by applying regex-based mutations to source files. It outputs results as plain text files.
- Output files:
killed.txt - One mutant filename per line (mutants detected by tests) not-killed.txt - One mutant filename per line (mutants NOT detected) notkilled.txt - Alternative name for not-killed.txt
- Mutant filenames typically follow the pattern:
<original_file>.mutant.<number>.<mutation_type> or <original_file>_mutant_<number>
Examples
src/main.py.mutant.1.AOR src/utils.py.mutant.2.ROR src/main.py.mutant.3.CRP
- curate_ipsum.parsers.universalmutator_parser.find_universalmutator_results(working_directory)[source]¶
Locate universalmutator result files.
Searches for killed.txt / not-killed.txt in common locations.
- curate_ipsum.parsers.universalmutator_parser.parse_universalmutator_output(working_directory, report_path=None)[source]¶
Parse universalmutator results from killed.txt / not-killed.txt.
Main entry point matching the unified parser interface (D-009).
- Parameters:
- Returns:
Tuple of (total, killed, survived, no_coverage, score, by_file)
- Raises:
FileNotFoundError – If result files not found
- Return type: