Skip to content

[Repo Assist] feat/test: add TaskSeq.pairwise; expand distinctUntilChanged tests#293

Merged
dsyme merged 6 commits intomainfrom
repo-assist/test-forward-pairwise-2026-03-d616df479e0a20e4
Mar 7, 2026
Merged

[Repo Assist] feat/test: add TaskSeq.pairwise; expand distinctUntilChanged tests#293
dsyme merged 6 commits intomainfrom
repo-assist/test-forward-pairwise-2026-03-d616df479e0a20e4

Conversation

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented Mar 7, 2026

🤖 This PR was created by Repo Assist, an automated AI assistant.

Summary

Two improvements: a new TaskSeq.pairwise function (addressing #289), and substantially expanded tests for TaskSeq.distinctUntilChanged.


Task 10 — Forward: TaskSeq.pairwise (ref #289)

Implements pairwise to align with FSharp.Control.AsyncSeq.pairwise, as requested in #289. This is the first of what should be multiple incremental PRs toward full AsyncSeq alignment.

Semantics: Returns a task sequence of consecutive overlapping pairs (a₀,a₁), (a₁,a₂), …. Returns empty if the source has fewer than two elements. Mirrors Seq.pairwise.

Implementation (TaskSeqInternal.fs): uses the same ValueNone/ValueSome state pattern as distinctUntilChanged — no heap allocation beyond the single ValueOption slot:

let pairwise (source: TaskSeq<_>) =
    checkNonNull (nameof source) source
    taskSeq {
        let mutable maybePrevious = ValueNone
        for current in source do
            match maybePrevious with
            | ValueNone -> maybePrevious <- ValueSome current
            | ValueSome previous ->
                yield previous, current
                maybePrevious <- ValueSome current
    }

Changes: TaskSeqInternal.fs (impl), TaskSeq.fs (static member), TaskSeq.fsi (signature + XML doc).


Task 9 — Testing: expand distinctUntilChanged + new pairwise tests

TaskSeq.DistinctUntilChanged.Tests.fs — from 39 → ~110 lines

The file previously had only 2 tests (one null, one functionality). Added:

Functionality module:

  • Singleton input → singleton output
  • All identical elements → single element output
  • All distinct elements → all returned
  • Alternating pairs [A;A;B;B;A;A][A;B;A]
  • TestImmTaskSeq variant test (1..10 all unique, all preserved)

SideEffects module:

  • Verifies every source element is consumed exactly once
  • Verifies duplicate elements are skipped without extra evaluation (counter stays at 5 for [1;1;2;2;3])
  • TestSideEffectTaskSeq variant test

TaskSeq.Pairwise.Tests.fs — new file

Full coverage following the established module structure:

  • EmptySeq: null arg, empty variants, singleton → empty
  • Immutable: two-element, 1..5 sequence, length formula, shared elements ((A,B),(B,C) — right of pair i = left of pair i+1), TestImmTaskSeq variants
  • SideEffects: exact consumption count, TestSideEffectTaskSeq variants

Test Status

  • Build: ✅ succeeded (Release, .NET 9 / netstandard2.1)
  • Tests: ✅ 3597 passed, 2 skipped, 0 failed (up from 3564 prior to this branch — 33 new tests)
  • Formatting: ✅ Fantomas check passed

Generated by Repo Assist ·

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@ec7d342403c9912c87320110f8822a8fbb817a0c

Task 10 — Add TaskSeq.pairwise (ref #289):
- Implement Internal.pairwise in TaskSeqInternal.fs using the same
  ValueNone/ValueSome pattern as distinctUntilChanged
- Expose as TaskSeq.pairwise static member in TaskSeq.fs + TaskSeq.fsi
- Mirrors FSharp.Control.AsyncSeq.pairwise semantics: yields each
  element paired with its successor; empty for <2 elements

Task 9 — Expand distinctUntilChanged tests:
- Add Functionality tests: singleton, all-same, all-distinct, alternating
- Add Immutable module with TestImmTaskSeq variants
- Add SideEffects module: verify element consumption count, correct output
- Add TestSideEffectTaskSeq variant test
- New test file TaskSeq.Pairwise.Tests.fs: empty/singleton/two-element/
  consecutive-pairs/length/boundary/side-effects/variant coverage

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dsyme dsyme marked this pull request as ready for review March 7, 2026 20:42
@dsyme
Copy link
Contributor

dsyme commented Mar 7, 2026

/repo-assist Update the release notes please

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Contributor Author

github-actions bot commented Mar 7, 2026

Commit pushed: b96a5ab

Generated by Repo Assist

Added a section for release notes in AGENTS.md.
@github-actions
Copy link
Contributor Author

github-actions bot commented Mar 7, 2026

Commit pushed: 9aa0b3d

Generated by Repo Assist

@dsyme dsyme merged commit e7dbf26 into main Mar 7, 2026
4 checks passed
@dsyme dsyme deleted the repo-assist/test-forward-pairwise-2026-03-d616df479e0a20e4 branch March 7, 2026 22:05
github-actions bot pushed a commit that referenced this pull request Mar 7, 2026
…289)

- TaskSeq.chunkBySize: divides a task sequence into non-overlapping chunks of
  at most chunkSize elements. Uses a fixed-size array buffer (vs. ResizeArray)
  to avoid intermediate allocations and resizing.

- TaskSeq.windowed: returns overlapping sliding windows of a fixed size.
  Uses a ring buffer internally so that only a single allocation (per window)
  is needed; no redundant element copies on each step.

Both functions validate their size argument eagerly (before enumeration starts),
raise ArgumentException for non-positive sizes, and are fully documented in the
.fsi signature file.

Also:
- Update README.md to mark chunkBySize, windowed, pairwise, scan/scanAsync,
  reduce/reduceAsync, and unfold/unfoldAsync as implemented (these were merged
  in PRs #293, #296, #299, #300 respectively).
- Update release-notes.txt for 0.5.0.
- 171 new tests across TaskSeq.ChunkBySize.Tests.fs and TaskSeq.Windowed.Tests.fs.
  All 4021 existing tests continue to pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant