From f603086cd278908d77bb85b40e9838f0f0867597 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 9 Mar 2026 01:28:30 +0000 Subject: [PATCH 1/2] test: add missing side-effect and Seq-equivalence tests for sum/average The SideEffects module previously tested only sum, sumBy, and averageBy. This adds the 3 missing variants: - sumByAsync iterates exactly once - average iterates exactly once - averageByAsync iterates exactly once Plus 2 tests verifying side-effect sequences yield next values on re-iteration: - sum second iteration sees side-effect values - averageBy second iteration sees side-effect values Also adds 4 new Immutable Fact tests confirming results match Seq equivalents: - TaskSeq.sum matches Seq.sum - TaskSeq.average matches Seq.average - TaskSeq.sumBy matches Seq.sumBy - TaskSeq.averageBy matches Seq.averageBy Total new tests: 44 (from 28 to 72 in the SumBy module, 191 passed total in this file including Theory variants). Full suite: 4574 passed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../TaskSeq.SumBy.Tests.fs | 81 ++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/src/FSharp.Control.TaskSeq.Test/TaskSeq.SumBy.Tests.fs b/src/FSharp.Control.TaskSeq.Test/TaskSeq.SumBy.Tests.fs index 3c59300..4dd63d5 100644 --- a/src/FSharp.Control.TaskSeq.Test/TaskSeq.SumBy.Tests.fs +++ b/src/FSharp.Control.TaskSeq.Test/TaskSeq.SumBy.Tests.fs @@ -175,7 +175,7 @@ module Immutable = } [] - let ``TaskSeq-sumBy works with float projection`` () = task { + let ``TaskSeq-sum works with float projection`` () = task { let! result = TaskSeq.ofSeq [ 1; 2; 3; 4; 5 ] |> TaskSeq.sumBy float result |> should (equalWithin 0.001) 15.0 @@ -195,6 +195,42 @@ module Immutable = result |> should (equalWithin 0.001f) 2.0f } + [] + let ``TaskSeq-sum result matches Seq-sum`` () = task { + let items = [ 3; 1; 4; 1; 5; 9; 2; 6; 5; 3 ] + let expected = Seq.sum items + + let! result = TaskSeq.ofList items |> TaskSeq.sum + result |> should equal expected + } + + [] + let ``TaskSeq-average result matches Seq-average`` () = task { + let items = [ 3.0; 1.0; 4.0; 1.0; 5.0; 9.0; 2.0; 6.0; 5.0; 3.0 ] + let expected = Seq.average items + + let! result = TaskSeq.ofList items |> TaskSeq.average + result |> should (equalWithin 0.0001) expected + } + + [] + let ``TaskSeq-sumBy result matches Seq-sumBy`` () = task { + let items = [ 1; 2; 3; 4; 5 ] + let expected = Seq.sumBy (fun x -> x * x) items + + let! result = TaskSeq.ofList items |> TaskSeq.sumBy (fun x -> x * x) + result |> should equal expected + } + + [] + let ``TaskSeq-averageBy result matches Seq-averageBy`` () = task { + let items = [ 1; 2; 3; 4; 5 ] + let expected = Seq.averageBy float items + + let! result = TaskSeq.ofList items |> TaskSeq.averageBy float + result |> should (equalWithin 0.0001) expected + } + module SideEffects = [)>] let ``TaskSeq-sum iterates exactly once`` variant = task { @@ -210,9 +246,52 @@ module SideEffects = result |> should equal 55 } + [)>] + let ``TaskSeq-sumByAsync iterates exactly once`` variant = task { + let ts = Gen.getSeqWithSideEffect variant + let! result = ts |> TaskSeq.sumByAsync Task.fromResult + result |> should equal 55 + } + + [)>] + let ``TaskSeq-average iterates exactly once`` variant = task { + let ts = Gen.getSeqWithSideEffect variant + let! result = ts |> TaskSeq.map float |> TaskSeq.average + result |> should (equalWithin 0.001) 5.5 + } + [)>] let ``TaskSeq-averageBy iterates exactly once`` variant = task { let ts = Gen.getSeqWithSideEffect variant let! result = ts |> TaskSeq.averageBy float result |> should (equalWithin 0.001) 5.5 } + + [)>] + let ``TaskSeq-averageByAsync iterates exactly once`` variant = task { + let ts = Gen.getSeqWithSideEffect variant + let! result = ts |> TaskSeq.averageByAsync (float >> Task.fromResult) + result |> should (equalWithin 0.001) 5.5 + } + + [)>] + let ``TaskSeq-sum second iteration sees side-effect values`` variant = task { + let ts = Gen.getSeqWithSideEffect variant + let! first = ts |> TaskSeq.sum + first |> should equal 55 // 1+2+...+10 + + // side-effect sequences yield next 10 items (11..20) on second consumption + let! second = ts |> TaskSeq.sum + second |> should equal 155 // 11+12+...+20 + } + + [)>] + let ``TaskSeq-averageBy second iteration sees side-effect values`` variant = task { + let ts = Gen.getSeqWithSideEffect variant + let! first = ts |> TaskSeq.averageBy float + first |> should (equalWithin 0.001) 5.5 // avg(1..10) = 5.5 + + // side-effect sequences yield next 10 items (11..20) on second consumption + let! second = ts |> TaskSeq.averageBy float + second |> should (equalWithin 0.001) 15.5 // avg(11..20) = 15.5 + } From 4b97bb1ad6677fb2c8c584405e481ceb80d48a41 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 9 Mar 2026 01:33:27 +0000 Subject: [PATCH 2/2] ci: trigger checks