Skip to content

Conversation

@github-actions
Copy link
Contributor

Summary

Successfully implemented quotation-based testing for VectorModule inline functions, following the maintainer's recommendation from Discussion #5 about using F# quotation evaluation to track inline function execution in coverage tools.

Changes Made

Added 50 comprehensive quotation-based tests in new file VectorModuleQuotationTests.fs covering:

  • Collection operations: foldi, mapi, filter, init, slice
  • Search operations: argmax, argmin, argmaxBy, argminBy, tryFindIndex, findIndex
  • Transformation operations: padRight, zip, split, chunk, windowed, enumerateNonZero
  • Utility operations: ofSeq, pow, sub

Quotation Evaluation Technique

Following maintainer guidance, tests use FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation to dynamically execute inline functions:

let inline evalQ<'T> (expr: Microsoft.FSharp.Quotations.Expr<'T>) : 'T =
    LeafExpressionConverter.EvaluateQuotation expr :?> 'T

[<Fact>]
let ``foldi_Q: performs indexed fold`` () =
    let v = [| 1.0; 2.0; 3.0; 4.0 |]
    let result = evalQ <@ Vector.foldi (fun i acc x -> acc + float i * x) 0.0 v @>
    floatEqual 20.0 result 1e-10

This forces the inline functions to be evaluated dynamically, making them visible to coverage tools.

Test Coverage Results

Metric Before After Change
Overall Line Coverage 32.09% (657/2047) 35.46% (726/2047) +3.37% (+69 lines)
VectorModule Coverage 23.3% (42/180) 100.0% (180/180) +76.7% (+138 lines)
Overall Branch Coverage 11.77% 12.92% +1.15%
Total Tests 767 817 +50 tests
Tests Passing 765 815 +50
Tests Skipped 2 2 0

Why VectorModule Had Low Coverage

VectorModule functions are all marked inline, which means they're inlined at compile-time by the F# compiler. Coverage tools like coverlet don't track inline functions because there's no actual function call to instrument - the code is directly inserted at the call site. The quotation evaluation technique forces runtime evaluation, allowing coverage measurement.

Replicating the Test Coverage Measurements

Prerequisites

dotnet restore

Before Measurements (from main branch)

git checkout main
rm -rf ./coverage
dotnet test tests/FsMath.Tests/FsMath.Tests.fsproj \
  --collect:"XPlat Code Coverage" \
  --results-directory ./coverage \
  -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura

Check ./coverage/*/coverage.cobertura.xml for baseline metrics.

After Measurements (from this PR branch)

git checkout daily-test-improver-vector-module-quotation-20251012-c33968fd9aba
rm -rf ./coverage
dotnet test tests/FsMath.Tests/FsMath.Tests.fsproj \
  --collect:"XPlat Code Coverage" \
  --results-directory ./coverage \
  -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura

Extracting Coverage Numbers

import xml.etree.ElementTree as ET
tree = ET.parse('./coverage/[guid]/coverage.cobertura.xml')
root = tree.getroot()
line_rate = float(root.get('line-rate', 0))
lines_covered = int(root.get('lines-covered', 0))
lines_valid = int(root.get('lines-valid', 0))
print(f"Coverage: {line_rate*100:.2f}% ({lines_covered}/{lines_valid})")

Possible Future Improvements

Based on coverage analysis, these areas remain priorities:

  1. Low/Zero Coverage Modules (by priority):

    • FsMath.Algebra.LinearAlgebra - 0% (0/518 lines) - Despite existing tests!
    • FsMath.SpanINumberPrimitives - 0% (0/366 lines)
    • FsMath.SIMDUtils - 0% (0/206 lines)
    • FsMath.SpanMath - 0% (0/160 lines)
    • FsMath.GenericMath - 0% (0/30 lines)
    • FsMath.VectorOps - 0% (0/24 lines) - Has tests but all inline!
  2. Apply Quotation Technique to Other Inline Modules:

    • VectorOps (0% coverage, has tests)
    • MatrixModule (80% but likely has inline functions)
    • AlgTypesTopLevelOps (50% coverage)
  3. Investigate LinearAlgebra Coverage Anomaly:

    • Has comprehensive test suite but shows 0% coverage
    • Likely all inline functions - prime candidate for quotation tests
  4. Low-Level Performance Modules:

    • SpanMath, SpanPrimitives, SIMDUtils need tests
    • May require specialized testing approaches

Commands Run

All bash commands executed during development
# Repository analysis
find ./coverage -name "coverage.cobertura.xml" -type f
grep '<class' ./coverage/coverage.cobertura.xml | grep -oP 'name="[^"]*"' | grep -oP 'FsMath\.[^"]*' | sort -u
python3 # [coverage analysis script]

# Test file discovery
find tests/FsMath.Tests -name "*.fs" -type f | xargs grep -l "VectorModule\|Vector\." | head -5

# Development
git checkout -b daily-test-improver-vector-module-quotation-20251012-c33968fd9aba
dotnet build tests/FsMath.Tests/FsMath.Tests.fsproj
dotnet test tests/FsMath.Tests/FsMath.Tests.fsproj --no-build --logger "console;verbosity=normal"

# Coverage verification
rm -rf ./coverage && dotnet test tests/FsMath.Tests/FsMath.Tests.fsproj --collect:"XPlat Code Coverage" --results-directory ./coverage -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura
python3 # [coverage comparison script]

# Commit
git add tests/FsMath.Tests/VectorModuleQuotationTests.fs tests/FsMath.Tests/FsMath.Tests.fsproj
git commit -m "Add quotation-based tests for VectorModule inline functions"
Web searches performed

None - used existing documentation and maintainer guidance from Discussion #5.

Web pages fetched

None - all information from local repository and previous discussion.


🤖 Generated with Claude Code

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

AI generated by Daily Test Coverage Improver

Implements quotation evaluation technique to ensure inline functions
in VectorModule are tracked by coverage tools. Following maintainer's
recommendation from discussion #5, uses FSharp.Linq.RuntimeHelpers
to dynamically evaluate quotations of inline function calls.

Added 50 quotation-based tests covering all VectorModule functions:
- foldi, mapi, filter, init, slice
- argmax, argmin, argmaxBy, argminBy
- padRight, zip, split, chunk, windowed
- tryFindIndex, findIndex, enumerateNonZero
- ofSeq, pow, sub

Coverage improvements:
- VectorModule: 23.3% → 100.0% (+138 lines)
- Overall: 32.09% → 35.46% (+69 lines, +3.37%)
- Total tests: 767 → 817 (+50 tests)

All 815 tests passing (2 skipped).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@dsyme dsyme closed this Oct 12, 2025
@dsyme dsyme reopened this Oct 12, 2025
@dsyme dsyme marked this pull request as ready for review October 12, 2025 20:21
@dsyme dsyme merged commit 7940a55 into main Oct 12, 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.

2 participants