Skip to content

Commit 38de2a4

Browse files
authored
Merge branch 'main' into daily-test-improver-matrix-formatcell-20251013-8eb5d5912085d9cd-855fc44fef5fbe47
2 parents 5da2aa3 + dec882e commit 38de2a4

18 files changed

+674
-58
lines changed

.github/workflows/build-and-test.yml

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,59 @@ jobs:
4848
fail_below_min: false
4949
format: markdown
5050
hide_branch_rate: false
51-
hide_complexity: true
51+
hide_complexity: false
5252
indicators: true
5353
output: both
5454
thresholds: '60 80'
5555

56-
- name: Add Coverage PR Comment
56+
- name: Create Enhanced Coverage Report
57+
run: |
58+
echo "# 📊 Code Coverage Report" > enhanced-coverage-results.md
59+
echo "" >> enhanced-coverage-results.md
60+
echo "## Summary" >> enhanced-coverage-results.md
61+
cat code-coverage-results.md >> enhanced-coverage-results.md
62+
echo "" >> enhanced-coverage-results.md
63+
echo "## 📈 Coverage Analysis" >> enhanced-coverage-results.md
64+
echo "" >> enhanced-coverage-results.md
65+
66+
# Extract coverage percentage for analysis
67+
COVERAGE=$(grep -o '[0-9]\+%' code-coverage-results.md | head -1 | tr -d '%')
68+
69+
if [ "$COVERAGE" -ge 80 ]; then
70+
echo "🟢 **Excellent Coverage!** Your code coverage is above 80%, which is considered very good practice." >> enhanced-coverage-results.md
71+
elif [ "$COVERAGE" -ge 60 ]; then
72+
echo "🟡 **Good Coverage** Your code coverage is above 60%. Consider adding more tests to reach 80%." >> enhanced-coverage-results.md
73+
else
74+
echo "🔴 **Low Coverage** Your code coverage is below 60%. Please add more tests to improve coverage." >> enhanced-coverage-results.md
75+
fi
76+
77+
echo "" >> enhanced-coverage-results.md
78+
echo "## 🎯 Coverage Goals" >> enhanced-coverage-results.md
79+
echo "- **Target**: 80% line coverage" >> enhanced-coverage-results.md
80+
echo "- **Minimum**: 60% line coverage" >> enhanced-coverage-results.md
81+
echo "- **Current**: ${COVERAGE}% line coverage" >> enhanced-coverage-results.md
82+
echo "" >> enhanced-coverage-results.md
83+
echo "## 📋 What These Numbers Mean" >> enhanced-coverage-results.md
84+
echo "" >> enhanced-coverage-results.md
85+
echo "- **Line Rate**: Percentage of code lines that were executed during tests" >> enhanced-coverage-results.md
86+
echo "- **Branch Rate**: Percentage of code branches (if/else, switch cases) that were tested" >> enhanced-coverage-results.md
87+
echo "- **Health**: Overall assessment combining line and branch coverage" >> enhanced-coverage-results.md
88+
echo "" >> enhanced-coverage-results.md
89+
echo "## 🔗 Detailed Reports" >> enhanced-coverage-results.md
90+
echo "" >> enhanced-coverage-results.md
91+
echo "📋 [Download Full Coverage Report](../actions/runs/${{ github.run_id }}) - Check the 'coverage-report' artifact for detailed HTML coverage report" >> enhanced-coverage-results.md
92+
echo "" >> enhanced-coverage-results.md
93+
echo "---" >> enhanced-coverage-results.md
94+
echo "*Coverage report generated on $(date '+%Y-%m-%d at %H:%M:%S UTC')*" >> enhanced-coverage-results.md
95+
echo "" >> enhanced-coverage-results.md
96+
echo "<!-- Sticky Pull Request Comment -->" >> enhanced-coverage-results.md
97+
98+
- name: Add Enhanced Coverage PR Comment
5799
uses: marocchino/sticky-pull-request-comment@v2
58100
if: github.event_name == 'pull_request'
59101
with:
60102
recreate: true
61-
path: code-coverage-results.md
103+
path: enhanced-coverage-results.md
62104

63105
- name: Upload coverage report
64106
uses: actions/upload-artifact@v4
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
namespace FsMath.Tests.AlgTypesTopLevelOps
2+
3+
open System
4+
open Xunit
5+
open FsMath
6+
open Microsoft.FSharp.Linq.RuntimeHelpers
7+
8+
/// <summary>
9+
/// Quotation-based tests for AlgTypesTopLevelOps inline helper functions.
10+
///
11+
/// These tests use F# quotation evaluation to ensure that inline functions
12+
/// are properly tracked by coverage tools. This technique was recommended
13+
/// by maintainers in discussion #5.
14+
/// </summary>
15+
module AlgTypesTopLevelOpsQuotationTests =
16+
17+
/// Helper to evaluate quotations for coverage tracking
18+
let inline eval<'T> q = LeafExpressionConverter.EvaluateQuotation q :?> 'T
19+
20+
// ========================================
21+
// matrix function tests
22+
// ========================================
23+
24+
[<Fact>]
25+
let ``matrix: creates 2x2 matrix from list of lists`` () =
26+
let m = eval<Matrix<float>> <@ matrix [[1.0; 2.0]; [3.0; 4.0]] @>
27+
Assert.Equal(2, m.NumRows)
28+
Assert.Equal(2, m.NumCols)
29+
Assert.Equal(1.0, m.[0, 0])
30+
Assert.Equal(2.0, m.[0, 1])
31+
Assert.Equal(3.0, m.[1, 0])
32+
Assert.Equal(4.0, m.[1, 1])
33+
34+
[<Fact>]
35+
let ``matrix: creates 3x3 identity-like matrix`` () =
36+
let m = eval<Matrix<float>> <@ matrix [[1.0; 0.0; 0.0]; [0.0; 1.0; 0.0]; [0.0; 0.0; 1.0]] @>
37+
Assert.Equal(3, m.NumRows)
38+
Assert.Equal(3, m.NumCols)
39+
// Check diagonal
40+
Assert.Equal(1.0, m.[0, 0])
41+
Assert.Equal(1.0, m.[1, 1])
42+
Assert.Equal(1.0, m.[2, 2])
43+
// Check off-diagonal zeros
44+
Assert.Equal(0.0, m.[0, 1])
45+
Assert.Equal(0.0, m.[1, 0])
46+
47+
[<Fact>]
48+
let ``matrix: creates 1x1 matrix with single element`` () =
49+
let m = eval<Matrix<float>> <@ matrix [[42.0]] @>
50+
Assert.Equal(1, m.NumRows)
51+
Assert.Equal(1, m.NumCols)
52+
Assert.Equal(42.0, m.[0, 0])
53+
54+
[<Fact>]
55+
let ``matrix: creates 1x3 row matrix`` () =
56+
let m = eval<Matrix<int>> <@ matrix [[1; 2; 3]] @>
57+
Assert.Equal(1, m.NumRows)
58+
Assert.Equal(3, m.NumCols)
59+
Assert.Equal(1, m.[0, 0])
60+
Assert.Equal(2, m.[0, 1])
61+
Assert.Equal(3, m.[0, 2])
62+
63+
[<Fact>]
64+
let ``matrix: creates 3x1 column matrix`` () =
65+
let m = eval<Matrix<int>> <@ matrix [[1]; [2]; [3]] @>
66+
Assert.Equal(3, m.NumRows)
67+
Assert.Equal(1, m.NumCols)
68+
Assert.Equal(1, m.[0, 0])
69+
Assert.Equal(2, m.[1, 0])
70+
Assert.Equal(3, m.[2, 0])
71+
72+
[<Fact>]
73+
let ``matrix: creates matrix with negative values`` () =
74+
let m = eval<Matrix<float>> <@ matrix [[-1.0; -2.0]; [-3.0; -4.0]] @>
75+
Assert.Equal(-1.0, m.[0, 0])
76+
Assert.Equal(-2.0, m.[0, 1])
77+
Assert.Equal(-3.0, m.[1, 0])
78+
Assert.Equal(-4.0, m.[1, 1])
79+
80+
[<Fact>]
81+
let ``matrix: creates matrix with mixed positive and negative`` () =
82+
let m = eval<Matrix<float>> <@ matrix [[1.0; -2.0]; [-3.0; 4.0]] @>
83+
Assert.Equal(1.0, m.[0, 0])
84+
Assert.Equal(-2.0, m.[0, 1])
85+
Assert.Equal(-3.0, m.[1, 0])
86+
Assert.Equal(4.0, m.[1, 1])
87+
88+
[<Fact>]
89+
let ``matrix: works with integer type`` () =
90+
let m = eval<Matrix<int>> <@ matrix [[1; 2]; [3; 4]] @>
91+
Assert.Equal(2, m.NumRows)
92+
Assert.Equal(2, m.NumCols)
93+
Assert.Equal(1, m.[0, 0])
94+
Assert.Equal(4, m.[1, 1])
95+
96+
[<Fact>]
97+
let ``matrix: creates zero matrix`` () =
98+
let m = eval<Matrix<float>> <@ matrix [[0.0; 0.0]; [0.0; 0.0]] @>
99+
Assert.Equal(2, m.NumRows)
100+
Assert.Equal(2, m.NumCols)
101+
Assert.Equal(0.0, m.[0, 0])
102+
Assert.Equal(0.0, m.[0, 1])
103+
Assert.Equal(0.0, m.[1, 0])
104+
Assert.Equal(0.0, m.[1, 1])
105+
106+
[<Fact>]
107+
let ``matrix: creates large matrix 5x5`` () =
108+
let m = eval<Matrix<float>> <@ matrix [
109+
[1.0; 2.0; 3.0; 4.0; 5.0]
110+
[6.0; 7.0; 8.0; 9.0; 10.0]
111+
[11.0; 12.0; 13.0; 14.0; 15.0]
112+
[16.0; 17.0; 18.0; 19.0; 20.0]
113+
[21.0; 22.0; 23.0; 24.0; 25.0]
114+
] @>
115+
Assert.Equal(5, m.NumRows)
116+
Assert.Equal(5, m.NumCols)
117+
Assert.Equal(1.0, m.[0, 0])
118+
Assert.Equal(25.0, m.[4, 4])
119+
Assert.Equal(13.0, m.[2, 2])
120+
121+
// ========================================
122+
// vector function tests
123+
// ========================================
124+
125+
[<Fact>]
126+
let ``vector: creates vector from 3-element list`` () =
127+
let v = eval<Vector<float>> <@ vector [1.0; 2.0; 3.0] @>
128+
Assert.Equal(3, v.Length)
129+
Assert.Equal(1.0, v.[0])
130+
Assert.Equal(2.0, v.[1])
131+
Assert.Equal(3.0, v.[2])
132+
133+
[<Fact>]
134+
let ``vector: creates vector from single element`` () =
135+
let v = eval<Vector<float>> <@ vector [42.0] @>
136+
Assert.Equal(1, v.Length)
137+
Assert.Equal(42.0, v.[0])
138+
139+
[<Fact>]
140+
let ``vector: creates vector with negative values`` () =
141+
let v = eval<Vector<float>> <@ vector [-1.0; -2.0; -3.0] @>
142+
Assert.Equal(3, v.Length)
143+
Assert.Equal(-1.0, v.[0])
144+
Assert.Equal(-2.0, v.[1])
145+
Assert.Equal(-3.0, v.[2])
146+
147+
[<Fact>]
148+
let ``vector: creates vector with mixed positive and negative`` () =
149+
let v = eval<Vector<float>> <@ vector [1.0; -2.0; 3.0; -4.0] @>
150+
Assert.Equal(4, v.Length)
151+
Assert.Equal(1.0, v.[0])
152+
Assert.Equal(-2.0, v.[1])
153+
Assert.Equal(3.0, v.[2])
154+
Assert.Equal(-4.0, v.[3])
155+
156+
[<Fact>]
157+
let ``vector: works with integer type`` () =
158+
let v = eval<Vector<int>> <@ vector [1; 2; 3; 4; 5] @>
159+
Assert.Equal(5, v.Length)
160+
Assert.Equal(1, v.[0])
161+
Assert.Equal(5, v.[4])
162+
163+
[<Fact>]
164+
let ``vector: creates zero vector`` () =
165+
let v = eval<Vector<float>> <@ vector [0.0; 0.0; 0.0] @>
166+
Assert.Equal(3, v.Length)
167+
Assert.Equal(0.0, v.[0])
168+
Assert.Equal(0.0, v.[1])
169+
Assert.Equal(0.0, v.[2])
170+
171+
[<Fact>]
172+
let ``vector: creates large vector`` () =
173+
let v = eval<Vector<float>> <@ vector [1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0; 8.0; 9.0; 10.0] @>
174+
Assert.Equal(10, v.Length)
175+
Assert.Equal(1.0, v.[0])
176+
Assert.Equal(10.0, v.[9])
177+
Assert.Equal(5.0, v.[4])
178+
179+
[<Fact>]
180+
let ``vector: creates vector with decimal values`` () =
181+
let v = eval<Vector<float>> <@ vector [1.5; 2.7; 3.9] @>
182+
Assert.Equal(3, v.Length)
183+
Assert.Equal(1.5, v.[0])
184+
Assert.Equal(2.7, v.[1])
185+
Assert.Equal(3.9, v.[2])
186+
187+
[<Fact>]
188+
let ``vector: result type is Vector`` () =
189+
let v = eval<Vector<float>> <@ vector [1.0; 2.0] @>
190+
Assert.IsType<Vector<float>>(v) |> ignore
191+
192+
[<Fact>]
193+
let ``matrix: result type is Matrix`` () =
194+
let m = eval<Matrix<float>> <@ matrix [[1.0; 2.0]] @>
195+
Assert.IsType<Matrix<float>>(m) |> ignore

0 commit comments

Comments
 (0)