WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Conversation

@vlad-ko
Copy link
Contributor

@vlad-ko vlad-ko commented Aug 6, 2025

This commit adds support for the partials_as_hits configuration option to the LCOV parser, bringing it in line with other coverage parsers (JaCoCo, Cobertura, Go).

Changes Made

Core Implementation

  • lcov.py: Added partials_as_hits configuration reading and conversion logic
  • _process_file(): Updated to accept partials_as_hits parameter
  • Branch processing: Convert partial coverage (e.g., '1/2') to hits (1) when enabled

Configuration Schema

  • user_schema.py: Added LCOV parser configuration validation
  • Supports: parsers.lcov.partials_as_hits (boolean, default: false)

Test Coverage

  • test_lcov.py: Added comprehensive test cases:
    • test_lcov_partials_as_hits_enabled(): Tests conversion of partials to hits
    • test_lcov_partials_as_hits_disabled(): Tests default behavior preservation
    • test_lcov_partials_as_hits_mixed_coverage(): Tests mixed scenarios
  • test_validation.py: Added schema validation tests

Documentation

  • LCOV_PARTIALS_AS_HITS.md: Comprehensive feature documentation including:
    • Implementation details and logic
    • Usage examples and migration guide
    • Consistency with other parsers
    • Test coverage overview

Behavior

With partials_as_hits: true

  • '1/2' partial coverage → 1 (hit)
  • '2/3' partial coverage → 1 (hit)
  • '2/2' full hit → '2/2' (unchanged)
  • '0/2' miss → '0/2' (unchanged)

With partials_as_hits: false (default)

  • All coverage types remain unchanged (backward compatible)

Configuration Example

Implementation Details

  • Follows established patterns from JaCoCo, Cobertura, and Go parsers
  • Minimal performance impact (single boolean check per branch line)
  • Comprehensive test coverage with realistic LCOV data
  • Backward compatible (defaults to false)

Closes: #[issue-number] (if applicable)
Co-authored-by: TDD Implementation Process

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. In 2022 this entity acquired Codecov and as result Sentry is going to need some rights from me in order to utilize my contributions in this PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.

This commit adds support for the partials_as_hits configuration option to the LCOV parser,
bringing it in line with other coverage parsers (JaCoCo, Cobertura, Go).

## Changes Made

### Core Implementation
- **lcov.py**: Added partials_as_hits configuration reading and conversion logic
- **_process_file()**: Updated to accept partials_as_hits parameter
- **Branch processing**: Convert partial coverage (e.g., '1/2') to hits (1) when enabled

### Configuration Schema
- **user_schema.py**: Added LCOV parser configuration validation
- Supports: parsers.lcov.partials_as_hits (boolean, default: false)

### Test Coverage
- **test_lcov.py**: Added comprehensive test cases:
  - test_lcov_partials_as_hits_enabled(): Tests conversion of partials to hits
  - test_lcov_partials_as_hits_disabled(): Tests default behavior preservation
  - test_lcov_partials_as_hits_mixed_coverage(): Tests mixed scenarios
- **test_validation.py**: Added schema validation tests

### Documentation
- **LCOV_PARTIALS_AS_HITS.md**: Comprehensive feature documentation including:
  - Implementation details and logic
  - Usage examples and migration guide
  - Consistency with other parsers
  - Test coverage overview

## Behavior

### With partials_as_hits: true
- '1/2' partial coverage → 1 (hit)
- '2/3' partial coverage → 1 (hit)
- '2/2' full hit → '2/2' (unchanged)
- '0/2' miss → '0/2' (unchanged)

### With partials_as_hits: false (default)
- All coverage types remain unchanged (backward compatible)

## Configuration Example

## Implementation Details
- Follows established patterns from JaCoCo, Cobertura, and Go parsers
- Minimal performance impact (single boolean check per branch line)
- Comprehensive test coverage with realistic LCOV data
- Backward compatible (defaults to false)

Closes: #[issue-number] (if applicable)
Co-authored-by: TDD Implementation Process
@codecov
Copy link

codecov bot commented Aug 6, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.85%. Comparing base (6e7c83f) to head (6cba48a).
⚠️ Report is 160 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #383      +/-   ##
==========================================
- Coverage   94.19%   93.85%   -0.34%     
==========================================
  Files        1254     1284      +30     
  Lines       46238    46450     +212     
  Branches     1455     1522      +67     
==========================================
+ Hits        43554    43597      +43     
- Misses       2379     2543     +164     
- Partials      305      310       +5     
Flag Coverage Δ
apiunit 96.55% <ø> (+0.44%) ⬆️
sharedintegration 38.75% <ø> (-1.62%) ⬇️
sharedunit 88.76% <ø> (-0.07%) ⬇️
workerintegration 58.61% <50.00%> (-2.97%) ⬇️
workerunit 91.18% <100.00%> (+0.67%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@codspeed-hq
Copy link

codspeed-hq bot commented Aug 6, 2025

CodSpeed Performance Report

Merging #383 will not alter performance

Comparing vlad-ko:feature/implement-partials-as-hits-lcov (6cba48a) with main (2a2ca6e)

Summary

✅ 9 untouched

vlad-ko added 4 commits August 6, 2025 16:13
Critical bug fix addressing incorrect branch counting when partials_as_hits is enabled.

## Problem
When partials_as_hits was enabled, partial branches were converted from:
- coverage: '1/2' -> 1 ✅ (correct)
- coverage_type: CoverageType.branch -> CoverageType.line ❌ (incorrect)

This caused get_line_totals() to exclude converted partials from branch counts
since it only counts lines with type='b' (CoverageType.branch maps to 'b').

## Solution
- Keep coverage_type as CoverageType.branch for converted partials
- This maintains proper branch counting: line.type = 'b'
- Aligns behavior with JaCoCo parser (preserves branch type)
- Ensures accurate branch coverage metrics

## Changes
- lcov.py: Remove incorrect coverage_type change to CoverageType.line
- test_lcov.py: Update test expectations to expect 'b' type for converted partials
- LCOV_PARTIALS_AS_HITS.md: Correct documentation

## Verification
- Converted partials now maintain branch type for proper counting
- Tests updated to reflect correct behavior
- Branch coverage metrics will be accurate

Fixes: Branch count inconsistency when partials_as_hits enabled
Severity: Critical - affects coverage metrics accuracy
Auto-formatting applied by pre-commit hooks to match project style guidelines.
The tuple formatting was changed to multi-line format for better readability.
The original tests incorrectly expected both line coverage AND branch coverage
to exist as separate entries when both DA: and BRDA: exist for the same line.

LCOV parser behavior (confirmed by existing test_regression_partial_branch):
- When both DA:10,5 and BRDA:10,0,0,1 exist for line 10
- Branch coverage overwrites line coverage
- Result: Only one entry (10, '1/2', 'b', ...) not two separate entries

Fixed test expectations to match actual LCOV parser behavior:
- test_lcov_partials_as_hits_enabled: Expect only branch entry with hit conversion
- test_lcov_partials_as_hits_disabled: Expect only branch entry with partial preserved
- test_lcov_partials_as_hits_mixed_coverage: Expect only branch entries

This aligns with how the existing LCOV parser works and maintains backward compatibility.
Auto-formatting applied by pre-commit hooks:
- Remove trailing whitespace after triple quotes
- Multi-line format for long tuple in test_lcov_partials_as_hits_mixed_coverage

This prevents CI formatting loops by applying the formatting locally.
- Fix issue where string 'false' would be truthy in YAML config
- Add robust boolean casting to handle 'false', 'true', '0', '1', etc.
- Add test to verify string 'false' correctly behaves as boolean False
- Refactor tests to eliminate duplication using class properties
- Move repeated LCOV test data to PARTIAL_BRANCH_LCOV_DATA class property
- Add reusable partial_test_path_fixer static method

This prevents configuration bugs where users specify boolean values as
strings in YAML, ensuring partials_as_hits works correctly regardless
of how the boolean is specified in the configuration.
@vlad-ko
Copy link
Contributor Author

vlad-ko commented Aug 11, 2025

Summary for the latest commit (c0ad00641):

🐛 Boolean Type Casting Fix + Test Refactoring

Latest Commit Summary:

Fix: Boolean Type Casting for LCOV partials_as_hits Configuration

🐛 Problem Solved

  • Critical Bug: String "false" in YAML config was being treated as truthy
  • Root Cause: partials_as_hits: "false" would enable the feature instead of disabling it

🔧 Solution Implemented

  • Robust Boolean Casting: Added type checking and conversion logic
  • String Handling: Properly converts "false", "true", "0", "1" to correct boolean values
  • Backward Compatible: Existing boolean configs continue to work unchanged

🧪 Testing Added

  • New Test: test_lcov_partials_as_hits_string_false_not_truthy()
  • Verification: Ensures partials_as_hits: "false" correctly behaves as False

🧹 Code Quality Improvements

  • Eliminated Duplication: Moved repeated LCOV test data to PARTIAL_BRANCH_LCOV_DATA class property
  • Reusable Components: Added partial_test_path_fixer static method
  • Cleaner Tests: Removed ~30 lines of duplicated code

📁 Files Changed (2)

  • apps/worker/services/report/languages/lcov.py - Boolean casting logic
  • apps/worker/services/report/languages/tests/unit/test_lcov.py - Test + refactoring

⚡ Impact

Prevents configuration bugs where users specify boolean values as strings in YAML, ensuring partials_as_hits works correctly regardless of how the boolean is specified.

This commit specifically addresses the boolean casting issue @adrianviquez identified and cleans up the test code duplication.

@vlad-ko vlad-ko requested a review from adrianviquez August 11, 2025 20:14
@calvin-codecov calvin-codecov force-pushed the feature/implement-partials-as-hits-lcov branch from c0ad006 to a440c14 Compare August 13, 2025 23:43
auto-merge was automatically disabled August 14, 2025 15:12

Head branch was pushed to by a user without write access

@vlad-ko vlad-ko force-pushed the feature/implement-partials-as-hits-lcov branch from a440c14 to 083a6ef Compare August 14, 2025 15:12
@drazisil-codecov drazisil-codecov merged commit 8c98cb5 into codecov:main Nov 24, 2025
50 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants