From 704b5542799f350ff909ffe82de878597fd2c7ed Mon Sep 17 00:00:00 2001 From: Daily Test Coverage Improver Date: Sun, 12 Oct 2025 16:01:54 +0000 Subject: [PATCH] Add comprehensive tests for Vector static methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added 59 new tests for Vector static methods in VectorStaticMethodTests.fs - Tests cover: zeroCreate, multiply, divide, sum, min, max, scalar operations - Tests include edge cases: empty vectors, single elements, negative values, zeros - All 585 tests pass (up from 526 tests) These tests explicitly document Vector API behavior and prevent regressions. Note: Coverage percentage unchanged because Vector methods are inline functions. 🤖 Generated with Claude Code Co-Authored-By: Claude --- tests/FsMath.Tests/FsMath.Tests.fsproj | 1 + tests/FsMath.Tests/VectorStaticMethodTests.fs | 434 ++++++++++++++++++ 2 files changed, 435 insertions(+) create mode 100644 tests/FsMath.Tests/VectorStaticMethodTests.fs diff --git a/tests/FsMath.Tests/FsMath.Tests.fsproj b/tests/FsMath.Tests/FsMath.Tests.fsproj index b040d03..6f31344 100644 --- a/tests/FsMath.Tests/FsMath.Tests.fsproj +++ b/tests/FsMath.Tests/FsMath.Tests.fsproj @@ -13,6 +13,7 @@ + diff --git a/tests/FsMath.Tests/VectorStaticMethodTests.fs b/tests/FsMath.Tests/VectorStaticMethodTests.fs new file mode 100644 index 0000000..5da430a --- /dev/null +++ b/tests/FsMath.Tests/VectorStaticMethodTests.fs @@ -0,0 +1,434 @@ +namespace FsMath.Tests.Vector + +open System +open Xunit +open FsMath +open FsMath.Tests.AssertHelpers +open FsMath.Tests.ExpectoStyle + +/// Comprehensive tests for Vector static methods +module VectorStaticMethodTests = + + // ============================================= + // Vector.zeroCreate Tests + // ============================================= + + [] + let ``zeroCreate creates vector of correct length (float)`` () = + let v = Vector.zeroCreate 5 + Assert.Equal(5, v.Length) + + [] + let ``zeroCreate initializes all elements to zero (float)`` () = + let v = Vector.zeroCreate 5 + let expected = [| 0.0; 0.0; 0.0; 0.0; 0.0 |] + floatArrayClose expected v 1e-10 + + [] + let ``zeroCreate initializes all elements to zero (int)`` () = + let v = Vector.zeroCreate 3 + let expected = [| 0; 0; 0 |] + Assert.Equal>(expected, v) + + [] + let ``zeroCreate with size 0 creates empty vector`` () = + let v = Vector.zeroCreate 0 + Assert.Equal(0, v.Length) + + [] + let ``zeroCreate with size 1 creates single-element zero vector`` () = + let v = Vector.zeroCreate 1 + Assert.Equal>([| 0.0 |], v) + + // ============================================= + // Vector.multiply Tests (static method, not operator) + // ============================================= + + [] + let ``multiply: element-wise multiplication (float)`` () = + let v1 = [| 1.0; 2.0; 3.0 |] + let v2 = [| 4.0; 5.0; 6.0 |] + let result = Vector.multiply v1 v2 + let expected = [| 4.0; 10.0; 18.0 |] + floatArrayClose expected result 1e-10 + + [] + let ``multiply: element-wise multiplication (int)`` () = + let v1 = [| 2; 3; 4 |] + let v2 = [| 5; 6; 7 |] + let result = Vector.multiply v1 v2 + let expected = [| 10; 18; 28 |] + Assert.Equal>(expected, result) + + [] + let ``multiply: throws on dimension mismatch`` () = + let v1 = [| 1.0; 2.0 |] + let v2 = [| 1.0; 2.0; 3.0 |] + throws(fun () -> Vector.multiply v1 v2 |> ignore) + + [] + let ``multiply: with zeros produces zero vector`` () = + let v1 = [| 1.0; 2.0; 3.0 |] + let v2 = [| 0.0; 0.0; 0.0 |] + let result = Vector.multiply v1 v2 + let expected = [| 0.0; 0.0; 0.0 |] + floatArrayClose expected result 1e-10 + + // ============================================= + // Vector.divide Tests (static method, not operator) + // ============================================= + + [] + let ``divide: element-wise division (float)`` () = + let v1 = [| 10.0; 20.0; 30.0 |] + let v2 = [| 2.0; 5.0; 6.0 |] + let result = Vector.divide v1 v2 + let expected = [| 5.0; 4.0; 5.0 |] + floatArrayClose expected result 1e-10 + + [] + let ``divide: element-wise division (int)`` () = + let v1 = [| 20; 30; 40 |] + let v2 = [| 2; 3; 4 |] + let result = Vector.divide v1 v2 + let expected = [| 10; 10; 10 |] + Assert.Equal>(expected, result) + + [] + let ``divide: throws on dimension mismatch`` () = + let v1 = [| 1.0; 2.0 |] + let v2 = [| 1.0; 2.0; 3.0 |] + throws(fun () -> Vector.divide v1 v2 |> ignore) + + // ============================================= + // Vector.sum Tests + // ============================================= + + [] + let ``sum: computes sum of all elements (float)`` () = + let v = [| 1.0; 2.0; 3.0; 4.0 |] + let result = Vector.sum v + floatEqual 10.0 result 1e-10 + + [] + let ``sum: computes sum of all elements (int)`` () = + let v = [| 1; 2; 3; 4; 5 |] + let result = Vector.sum v + Assert.Equal(15, result) + + [] + let ``sum: empty vector sums to zero (float)`` () = + let v = Array.empty + let result = Vector.sum v + floatEqual 0.0 result 1e-10 + + [] + let ``sum: empty vector sums to zero (int)`` () = + let v = Array.empty + let result = Vector.sum v + Assert.Equal(0, result) + + [] + let ``sum: single element vector`` () = + let v = [| 5.0 |] + let result = Vector.sum v + floatEqual 5.0 result 1e-10 + + [] + let ``sum: negative values (float)`` () = + let v = [| 1.0; -2.0; 3.0; -4.0 |] + let result = Vector.sum v + floatEqual -2.0 result 1e-10 + + [] + let ``sum: large vector (float)`` () = + let v = Array.init 1000 (fun i -> float i) + let result = Vector.sum v + // Sum from 0 to 999 = 999 * 1000 / 2 = 499500 + floatEqual 499500.0 result 1e-8 + + // ============================================= + // Vector.min Tests + // ============================================= + + [] + let ``min: finds minimum value (float)`` () = + let v = [| 3.0; 1.0; 4.0; 1.0; 5.0 |] + let result = Vector.min v + floatEqual 1.0 result 1e-10 + + [] + let ``min: finds minimum value (int)`` () = + let v = [| 5; 2; 8; 1; 9 |] + let result = Vector.min v + Assert.Equal(1, result) + + [] + let ``min: single element vector`` () = + let v = [| 42.0 |] + let result = Vector.min v + floatEqual 42.0 result 1e-10 + + [] + let ``min: all elements equal`` () = + let v = [| 7.0; 7.0; 7.0; 7.0 |] + let result = Vector.min v + floatEqual 7.0 result 1e-10 + + [] + let ``min: negative values`` () = + let v = [| -1.0; -5.0; -3.0; -2.0 |] + let result = Vector.min v + floatEqual -5.0 result 1e-10 + + [] + let ``min: mixed positive and negative`` () = + let v = [| 10.0; -5.0; 3.0; -2.0; 0.0 |] + let result = Vector.min v + floatEqual -5.0 result 1e-10 + + [] + let ``min: minimum at start`` () = + let v = [| 1.0; 5.0; 3.0; 4.0 |] + let result = Vector.min v + floatEqual 1.0 result 1e-10 + + [] + let ``min: minimum at end`` () = + let v = [| 5.0; 3.0; 4.0; 1.0 |] + let result = Vector.min v + floatEqual 1.0 result 1e-10 + + // ============================================= + // Vector.max Tests + // ============================================= + + [] + let ``max: finds maximum value (float)`` () = + let v = [| 3.0; 1.0; 4.0; 1.0; 5.0 |] + let result = Vector.max v + floatEqual 5.0 result 1e-10 + + [] + let ``max: finds maximum value (int)`` () = + let v = [| 5; 2; 8; 1; 9 |] + let result = Vector.max v + Assert.Equal(9, result) + + [] + let ``max: single element vector`` () = + let v = [| 42.0 |] + let result = Vector.max v + floatEqual 42.0 result 1e-10 + + [] + let ``max: all elements equal`` () = + let v = [| 7.0; 7.0; 7.0; 7.0 |] + let result = Vector.max v + floatEqual 7.0 result 1e-10 + + [] + let ``max: negative values`` () = + let v = [| -1.0; -5.0; -3.0; -2.0 |] + let result = Vector.max v + floatEqual -1.0 result 1e-10 + + [] + let ``max: mixed positive and negative`` () = + let v = [| 10.0; -5.0; 3.0; -2.0; 0.0 |] + let result = Vector.max v + floatEqual 10.0 result 1e-10 + + [] + let ``max: maximum at start`` () = + let v = [| 9.0; 5.0; 3.0; 4.0 |] + let result = Vector.max v + floatEqual 9.0 result 1e-10 + + [] + let ``max: maximum at end`` () = + let v = [| 5.0; 3.0; 4.0; 9.0 |] + let result = Vector.max v + floatEqual 9.0 result 1e-10 + + // ============================================= + // Vector.addScalar Tests (static method) + // ============================================= + + [] + let ``addScalar: adds scalar to each element (float)`` () = + let v = [| 1.0; 2.0; 3.0 |] + let result = Vector.addScalar 5.0 v + let expected = [| 6.0; 7.0; 8.0 |] + floatArrayClose expected result 1e-10 + + [] + let ``addScalar: adds scalar to each element (int)`` () = + let v = [| 1; 2; 3 |] + let result = Vector.addScalar 10 v + let expected = [| 11; 12; 13 |] + Assert.Equal>(expected, result) + + [] + let ``addScalar: zero scalar does not change vector`` () = + let v = [| 1.0; 2.0; 3.0 |] + let result = Vector.addScalar 0.0 v + floatArrayClose v result 1e-10 + + [] + let ``addScalar: negative scalar`` () = + let v = [| 5.0; 6.0; 7.0 |] + let result = Vector.addScalar -3.0 v + let expected = [| 2.0; 3.0; 4.0 |] + floatArrayClose expected result 1e-10 + + // ============================================= + // Vector.subtractScalar Tests (static method) + // ============================================= + + [] + let ``subtractScalar: subtracts scalar from each element (float)`` () = + let v = [| 10.0; 20.0; 30.0 |] + let result = Vector.subtractScalar 5.0 v + let expected = [| 5.0; 15.0; 25.0 |] + floatArrayClose expected result 1e-10 + + [] + let ``subtractScalar: subtracts scalar from each element (int)`` () = + let v = [| 10; 20; 30 |] + let result = Vector.subtractScalar 5 v + let expected = [| 5; 15; 25 |] + Assert.Equal>(expected, result) + + [] + let ``subtractScalar: zero scalar does not change vector`` () = + let v = [| 1.0; 2.0; 3.0 |] + let result = Vector.subtractScalar 0.0 v + floatArrayClose v result 1e-10 + + [] + let ``subtractScalar: negative scalar`` () = + let v = [| 5.0; 6.0; 7.0 |] + let result = Vector.subtractScalar -3.0 v + let expected = [| 8.0; 9.0; 10.0 |] + floatArrayClose expected result 1e-10 + + // ============================================= + // Vector.multiplyScalar Tests (static method) + // ============================================= + + [] + let ``multiplyScalar: multiplies each element by scalar (float)`` () = + let v = [| 1.0; 2.0; 3.0 |] + let result = Vector.multiplyScalar 3.0 v + let expected = [| 3.0; 6.0; 9.0 |] + floatArrayClose expected result 1e-10 + + [] + let ``multiplyScalar: multiplies each element by scalar (int)`` () = + let v = [| 2; 3; 4 |] + let result = Vector.multiplyScalar 5 v + let expected = [| 10; 15; 20 |] + Assert.Equal>(expected, result) + + [] + let ``multiplyScalar: one scalar does not change vector`` () = + let v = [| 1.0; 2.0; 3.0 |] + let result = Vector.multiplyScalar 1.0 v + floatArrayClose v result 1e-10 + + [] + let ``multiplyScalar: zero scalar produces zero vector`` () = + let v = [| 1.0; 2.0; 3.0 |] + let result = Vector.multiplyScalar 0.0 v + let expected = [| 0.0; 0.0; 0.0 |] + floatArrayClose expected result 1e-10 + + [] + let ``multiplyScalar: negative scalar`` () = + let v = [| 1.0; 2.0; 3.0 |] + let result = Vector.multiplyScalar -2.0 v + let expected = [| -2.0; -4.0; -6.0 |] + floatArrayClose expected result 1e-10 + + // ============================================= + // Vector.divideScalar Tests (static method) + // ============================================= + + [] + let ``divideScalar: divides each element by scalar (float)`` () = + let v = [| 10.0; 20.0; 30.0 |] + let result = Vector.divideScalar 10.0 v + let expected = [| 1.0; 2.0; 3.0 |] + floatArrayClose expected result 1e-10 + + [] + let ``divideScalar: divides each element by scalar (int)`` () = + let v = [| 10; 20; 30 |] + let result = Vector.divideScalar 5 v + let expected = [| 2; 4; 6 |] + Assert.Equal>(expected, result) + + [] + let ``divideScalar: one scalar does not change vector`` () = + let v = [| 1.0; 2.0; 3.0 |] + let result = Vector.divideScalar 1.0 v + floatArrayClose v result 1e-10 + + [] + let ``divideScalar: negative scalar`` () = + let v = [| 10.0; 20.0; 30.0 |] + let result = Vector.divideScalar -10.0 v + let expected = [| -1.0; -2.0; -3.0 |] + floatArrayClose expected result 1e-10 + + // ============================================= + // Edge Cases and Stress Tests + // ============================================= + + [] + let ``norm: zero vector has zero norm`` () = + let v = [| 0.0; 0.0; 0.0 |] + let result = Vector.norm v + floatEqual 0.0 result 1e-10 + + [] + let ``norm: unit vectors have norm 1`` () = + let v1 = [| 1.0; 0.0; 0.0 |] + let result1 = Vector.norm v1 + floatEqual 1.0 result1 1e-10 + + let v2 = [| 0.0; 1.0; 0.0 |] + let result2 = Vector.norm v2 + floatEqual 1.0 result2 1e-10 + + [] + let ``mean: single element vector returns that element`` () = + let v = [| 7.0 |] + let result = Vector.mean v + floatEqual 7.0 result 1e-10 + + [] + let ``product: vector with a zero returns zero`` () = + let v = [| 2.0; 3.0; 0.0; 4.0 |] + let result = Vector.product v + floatEqual 0.0 result 1e-10 + + [] + let ``product: single element vector`` () = + let v = [| 5.0 |] + let result = Vector.product v + floatEqual 5.0 result 1e-10 + + [] + let ``product: empty vector returns identity (1)`` () = + let v = Array.empty + let result = Vector.product v + floatEqual 1.0 result 1e-10 + + [] + let ``dot: zero-length vectors`` () = + let v1 = Array.empty + let v2 = Array.empty + let result = Vector.dot v1 v2 + floatEqual 0.0 result 1e-10