Skip to content

feat: replay prior change notifications via OnEventOrReplay#1013

Merged
vbreuss merged 2 commits into
mainfrom
feat/notification-history-replay
May 17, 2026
Merged

feat: replay prior change notifications via OnEventOrReplay#1013
vbreuss merged 2 commits into
mainfrom
feat/notification-history-replay

Conversation

@vbreuss
Copy link
Copy Markdown
Member

@vbreuss vbreuss commented May 17, 2026

Adds INotificationHandler.OnEventOrReplay, which registers a subscriber and atomically replays any matching ChangeDescription events that fired before the subscription. Enables late-subscriber assertion patterns (e.g. asserting against a MockFileSystem that has already mutated) without bracketing the trigger inside the assertion call.

Notification history is recorded by default and can be disabled via MockFileSystemOptions.WithoutNotificationHistory(); when disabled, OnEventOrReplay throws InvalidOperationException so misconfiguration cannot manifest as flaky tests.

Adds INotificationHandler.OnEventOrReplay, which registers a subscriber
and atomically replays any matching ChangeDescription events that fired
before the subscription. Enables late-subscriber assertion patterns
(e.g. asserting against a MockFileSystem that has already mutated)
without bracketing the trigger inside the assertion call.

Notification history is recorded by default and can be disabled via
MockFileSystemOptions.WithoutNotificationHistory(); when disabled,
OnEventOrReplay throws InvalidOperationException so misconfiguration
cannot manifest as flaky tests.
@vbreuss vbreuss self-assigned this May 17, 2026
Copilot AI review requested due to automatic review settings May 17, 2026 10:30
@vbreuss vbreuss added the enhancement New feature or request label May 17, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new subscription API to the mock file system notification system that can “catch up” late subscribers by replaying prior change notifications, with an opt-out switch to disable history recording.

Changes:

  • Introduces INotificationHandler.OnEventOrReplay(...) to register a callback and replay prior matching ChangeDescription events.
  • Adds optional notification history recording to ChangeHandler, enabled by default and disable-able via MockFileSystemOptions.WithoutNotificationHistory().
  • Extends tests to validate replay behavior and the opt-out exception.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Tests/Testably.Abstractions.Testing.Tests/FileSystem/ChangeHandlerTests.cs Adds test coverage for replaying prior events, predicate filtering, and opt-out behavior.
Source/Testably.Abstractions.Testing/Notification.cs Adds an internal factory Replay(...) helper used to deliver historical events to a registered callback.
Source/Testably.Abstractions.Testing/MockFileSystem.cs Wires the “record notification history” option into ChangeHandler and adds WithoutNotificationHistory() option.
Source/Testably.Abstractions.Testing/FileSystem/INotificationHandler.cs Adds the new public OnEventOrReplay(...) API with XML docs.
Source/Testably.Abstractions.Testing/FileSystem/ChangeHandler.cs Implements history storage + atomic replay semantics, and throws when history is disabled.

Comment thread Source/Testably.Abstractions.Testing/FileSystem/ChangeHandler.cs Outdated
Comment thread Source/Testably.Abstractions.Testing/FileSystem/ChangeHandler.cs
@github-actions
Copy link
Copy Markdown

Test Results

    101 files   -  1      101 suites   - 1   2h 24m 26s ⏱️ -59s
112 538 tests +46   99 922 ✅ +40  12 610 💤 ±0  6 ❌ +6 
268 658 runs  +68  231 964 ✅ +62  36 688 💤 ±0  6 ❌ +6 

For more details on these failures, see this check.

Results for commit 5709c92. ± Comparison against base commit a871ca4.

…se waiter on replay failure

Addresses two review issues on OnEventOrReplay:

- If a callback throws during replay of buffered changes, the newly
  registered waiter is now disposed before the exception propagates so
  it cannot keep receiving future events.
- NotifyCompletedChange no longer holds the history lock while invoking
  user callbacks. The callback set is snapshotted under the lock via
  SnapshotInvocations and invoked afterward, preserving exactly-once
  delivery across the live/replay boundary while avoiding callback-induced
  blocking and deadlock risk.

Regenerates the Testably.Abstractions.Testing public API baselines so
the ApiChecks task includes the OnEventOrReplay and
WithoutNotificationHistory additions.
@sonarqubecloud
Copy link
Copy Markdown

@vbreuss vbreuss merged commit 765f487 into main May 17, 2026
12 checks passed
@vbreuss vbreuss deleted the feat/notification-history-replay branch May 17, 2026 12:13
@github-actions
Copy link
Copy Markdown

This is addressed in release v6.4.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request state: released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants