Skip to content

Daily Test Coverage Improver - Fix PermutationTests Incomplete Assertions#68

Merged
dsyme merged 1 commit intomainfrom
daily-test-improver-permutation-throws-fix-20251013-cb94c0deea9e499b-353e1cb4f0480f77
Oct 13, 2025
Merged

Daily Test Coverage Improver - Fix PermutationTests Incomplete Assertions#68
dsyme merged 1 commit intomainfrom
daily-test-improver-permutation-throws-fix-20251013-cb94c0deea9e499b-353e1cb4f0480f77

Conversation

@github-actions
Copy link
Contributor

Summary

Fixed incomplete test assertions in PermutationTests.fs that were preventing proper test execution and leaving critical error handling code paths uncovered. All 21 throws<> assertions were missing the required message parameter, causing them to compile with warnings but never actually validate exception throwing behavior.

Problems Found

Test Code Bug: The throws<'ex> helper function in ExpectoStyle.fs requires two parameters:

let throws<'ex when 'ex :> exn> (action: unit -> unit) (message: string)

However, all 21 calls to throws<> in PermutationTests.fs were only providing the action parameter, which resulted in:

  1. 14 FS0193 compiler warnings: "This expression is a function value, i.e. is missing arguments. Its type is string -> unit."
  2. Tests never executed: The tests compiled to partial functions that were never invoked
  3. Uncovered error paths: Critical validation logic in Permutation.fs remained untested

Uncovered Lines Before Fix:

  • Line 43 (Permutation.fs): Out-of-range index error in ofFreshArray - "Permutation array contains out-of-range index."
  • Line 45 (Permutation.fs): Duplicate indices error in ofFreshArray - "Permutation array contains duplicate indices."
  • Line 51 (Permutation.fs): Permutation function bounds checking - "Permutation function called with out-of-range index."

Actions Taken

  1. Fixed all 21 throws<> assertions by adding descriptive message parameters
  2. Eliminated all 14 compiler warnings (FS0193)
  3. Verified tests execute correctly and validate exception behavior
  4. Re-ran coverage to confirm error paths are now covered

Example Fix:

Before:

throws<ArgumentException>(fun () -> Permutation.ofFreshArray arr |> ignore)

After:

throws<ArgumentException>(fun () -> Permutation.ofFreshArray arr |> ignore) "should throw on duplicate indices"

Test Coverage Results

Metric Before After Change
Overall Line Coverage 77.33% (1583/2047) 77.47% (1586/2047) +0.14% (+3 lines)
PermutationModule Coverage 93.93% (62/66) 100.00% (66/66) +6.07% (+4 lines)
ofFreshArray@49 Coverage 66.66% (4/6) 100.00% (6/6) +33.34% (+2 lines)
Compiler Warnings 14 FS0193 warnings 0 warnings -14 warnings
Total Tests 1347 passing 1347 passing No change

Replicating the Test Coverage Measurements

Prerequisites

cd /path/to/FsMath

Before Coverage (from main branch)

git checkout main
dotnet restore
dotnet build

# Note the 14 FS0193 warnings about missing function arguments
# in PermutationTests.fs during build

# Run tests with coverage
dotnet test tests/FsMath.Tests/FsMath.Tests.fsproj \
  --collect:"XPlat Code Coverage" \
  --results-directory ./coverage-before \
  -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura

# Check PermutationModule coverage: 93.93%
# Check warnings: 14 FS0193 warnings

After Coverage (from this branch)

git checkout daily-test-improver-permutation-throws-fix-20251013-cb94c0deea9e499b
dotnet restore
dotnet build

# Note: 0 FS0193 warnings now!

# Run tests with coverage
dotnet test tests/FsMath.Tests/FsMath.Tests.fsproj \
  --collect:"XPlat Code Coverage" \
  --results-directory ./coverage-after \
  -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura

# Check PermutationModule coverage: 100.00%
# Check warnings: 0 warnings

Display Coverage Comparison

python3 << 'PYTHON_EOF'
import xml.etree.ElementTree as ET
import glob

# Parse before and after coverage reports
before_file = glob.glob('./coverage-before/*/coverage.cobertura.xml')[0]
after_file = glob.glob('./coverage-after/*/coverage.cobertura.xml')[0]

tree_before = ET.parse(before_file)
tree_after = ET.parse(after_file)

# Overall coverage
before_rate = float(tree_before.getroot().get('line-rate', 0)) * 100
after_rate = float(tree_after.getroot().get('line-rate', 0)) * 100
print(f"Overall: {before_rate:.2f}% → {after_rate:.2f}% (+{after_rate - before_rate:.2f}%)")

# PermutationModule coverage
for cls in tree_after.getroot().iter('class'):
    if cls.get('name') == 'FsMath.PermutationModule':
        rate = float(cls.get('line-rate', 0)) * 100
        print(f"PermutationModule: {rate:.2f}%")
PYTHON_EOF

Verify Warnings Fixed

# On main branch (before)
dotnet build tests/FsMath.Tests/FsMath.Tests.fsproj 2>&1 | grep -c "FS0193"
# Should output: 14

# On this branch (after)
dotnet build tests/FsMath.Tests/FsMath.Tests.fsproj 2>&1 | grep -c "FS0193"
# Should output: 0

Future Areas for Improvement

Based on remaining coverage gaps in the codebase:

  1. SpanPrimitives.fs - 0% coverage (366 lines) - Inline Span functions (quotation technique doesn't work with Span/byref)
  2. SpanMath.fs - 0% coverage (160 lines) - Inline span-based math
  3. SIMDUtils.fs - 0% coverage (206 lines) - Inline SIMD operations
  4. SVD.fs - 85.9% coverage (72 uncovered lines) - Complex SVD algorithm edge cases
  5. Matrix.fs - 88.6% coverage (82 uncovered lines) - Currently being addressed in PR Daily Test Coverage Improver - Matrix Edge Case Tests #67

Note: This PR demonstrates the importance of carefully reviewing compiler warnings and ensuring test assertions are properly configured. The fix was straightforward but had significant impact on coverage and code quality.

Significance

This fix is particularly important because:

  1. Security/Correctness: The uncovered error paths validate critical input constraints (array bounds, duplicate detection)
  2. Test Quality: Tests appeared to exist but weren't actually executing validation logic
  3. Maintainability: Compiler warnings now eliminated, making future issues more visible
  4. Coverage Accuracy: Previous coverage numbers understated actual test gaps

Commands Executed

Analysis

# Read coverage report
cat coverage-steps.log
python3 coverage_analysis.py  # Analyzed coverage for uncovered areas

# Check PermutationModule coverage details
python3 find_uncovered_permutation_lines.py

Git Operations

git checkout -b daily-test-improver-permutation-throws-fix-20251013-cb94c0deea9e499b
# Made 21 edits to PermutationTests.fs
git add tests/FsMath.Tests/PermutationTests.fs
git commit -m "Fix PermutationTests: Add missing message parameters..."

Build and Test

# Build with 0 warnings (previously 14)
dotnet build tests/FsMath.Tests/FsMath.Tests.fsproj

# Run tests - all pass
dotnet test tests/FsMath.Tests/FsMath.Tests.fsproj --no-build
# Result: Passed: 1347, Skipped: 8

Coverage Measurement

# Original coverage (from workflow)
# Already in ./coverage/coverage.cobertura.xml
# PermutationModule: 93.93%

# New coverage
dotnet test tests/FsMath.Tests/FsMath.Tests.fsproj \
  --no-build \
  --collect:"XPlat Code Coverage" \
  --results-directory ./coverage-new \
  -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura

# Comparison
python3 compare_permutation_coverage.py
# PermutationModule: 100.00% (+6.07%)
Web Searches Performed

None - the issue was identified through coverage analysis and examination of compiler warnings.

Web Pages Fetched

None - all work done through local code analysis.


🤖 Generated with Claude Code by Daily Test Coverage Improver

Co-Authored-By: Claude noreply@anthropic.com

AI generated by Daily Test Coverage Improver

AI generated by Daily Test Coverage Improver

…ions

Fixed incomplete throws<> assertions that were missing the required message
parameter, which caused tests to compile with warnings but never actually
execute the exception validation logic.

This resulted in uncovered error handling paths in Permutation.fs:
- Line 43: Out-of-range index validation
- Line 45: Duplicate index validation
- Line 51: Permutation function bounds checking

Changes:
- Added descriptive message parameters to all 21 throws<> calls
- Eliminated all 14 FS0193 compiler warnings about missing function arguments
- Tests now properly validate exception throwing behavior

Coverage improvements:
- PermutationModule: 93.93% → 100.00% (+6.07%, +4 lines)
- ofFreshArray@49: 66.66% → 100.00% (+33.34%, +2 lines)
- Overall: 77.33% → 77.47% (+0.14%, +3 lines)

🤖 Generated with Claude Code by Daily Test Coverage Improver

Co-Authored-By: Claude <noreply@anthropic.com>
@dsyme dsyme closed this Oct 13, 2025
@dsyme dsyme reopened this Oct 13, 2025
@github-actions
Copy link
Contributor Author

📊 Code Coverage Report

Summary

Code Coverage

Package Line Rate Branch Rate Complexity Health
FsMath 77% 49% 4409
FsMath 77% 49% 4409
Summary 77% (3072 / 3992) 49% (4260 / 8686) 8818

📈 Coverage Analysis

🟡 Good Coverage Your code coverage is above 60%. Consider adding more tests to reach 80%.

🎯 Coverage Goals

  • Target: 80% line coverage
  • Minimum: 60% line coverage
  • Current: 77% line coverage

📋 What These Numbers Mean

  • Line Rate: Percentage of code lines that were executed during tests
  • Branch Rate: Percentage of code branches (if/else, switch cases) that were tested
  • Health: Overall assessment combining line and branch coverage

🔗 Detailed Reports

📋 Download Full Coverage Report - Check the 'coverage-report' artifact for detailed HTML coverage report


Coverage report generated on 2025-10-13 at 15:50:00 UTC

@dsyme dsyme marked this pull request as ready for review October 13, 2025 20:35
@dsyme dsyme merged commit 7ca6706 into main Oct 13, 2025
2 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.

1 participant