diff --git a/Source/Testably.Abstractions.Testing/AwaitableCallbackExtensions.cs b/Source/Testably.Abstractions.Testing/AwaitableCallbackExtensions.cs
new file mode 100644
index 00000000..19097c80
--- /dev/null
+++ b/Source/Testably.Abstractions.Testing/AwaitableCallbackExtensions.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+#if NET6_0_OR_GREATER
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+#endif
+
+namespace Testably.Abstractions.Testing;
+
+///
+/// Extension methods on .
+///
+public static class AwaitableCallbackExtensions
+{
+ ///
+ /// Blocks the current thread until the callback is executed.
+ ///
+ /// Throws a if the expired before the callback was
+ /// executed.
+ ///
+ /// The callback.
+ ///
+ /// (optional) The number of callbacks to wait.
+ /// Defaults to 1
+ ///
+ ///
+ /// (optional) The timeout in milliseconds to wait on the callback.
+ /// Defaults to 30000ms (30 seconds).
+ ///
+ public static TValue[] Wait(this IAwaitableCallback callback,
+ int count = 1,
+ int timeout = 30000)
+ => callback.Wait(count, TimeSpan.FromMilliseconds(timeout));
+
+ ///
+ /// Waits asynchronously until the callback is executed.
+ ///
+ /// The callback.
+ ///
+ /// (optional) The number of callbacks to wait.
+ /// Defaults to 1
+ ///
+ ///
+ /// (optional) The timeout in milliseconds to wait on the callback.
+ /// Defaults to 30000ms (30 seconds).
+ ///
+ ///
+ /// (optional) A to cancel waiting.
+ /// Throws a if the token was canceled before the callback was executed.
+ ///
+ public static Task WaitAsync(this IAwaitableCallback callback,
+ int count = 1,
+ int timeout = 30000,
+ CancellationToken? cancellationToken = null)
+ => callback.WaitAsync(count, TimeSpan.FromMilliseconds(timeout), cancellationToken);
+
+#if NET6_0_OR_GREATER
+ ///
+ /// Converts the to an that yields a
+ /// value each time the callback is executed.
+ ///
+ ///
+ /// Uses a default timeout of 30 seconds to prevent infinite waiting if the callback is never executed.
+ ///
+ public static IAsyncEnumerable ToAsyncEnumerable(
+ this IAwaitableCallback source,
+ CancellationToken cancellationToken = default)
+ => ToAsyncEnumerable(source, null, cancellationToken);
+
+ ///
+ /// Converts the to an that yields a
+ /// value each time the callback is executed.
+ ///
+ ///
+ /// If no is specified (), a default timeout of 30 seconds is used
+ /// to prevent infinite waiting if the callback is never executed.
+ ///
+ public static async IAsyncEnumerable ToAsyncEnumerable(
+ this IAwaitableCallback source,
+ TimeSpan? timeout,
+ [EnumeratorCancellation] CancellationToken cancellationToken = default)
+ {
+ using CancellationTokenSource cts =
+ CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
+ cts.CancelAfter(timeout ?? TimeSpan.FromSeconds(30));
+ CancellationToken token = cts.Token;
+
+ while (!token.IsCancellationRequested)
+ {
+ TValue item;
+ try
+ {
+ TValue[] items = await source.WaitAsync(cancellationToken: token);
+ if (items.Length == 0)
+ {
+ continue;
+ }
+
+ item = items[0];
+ }
+ catch (OperationCanceledException)
+ {
+ yield break;
+ }
+
+ yield return item;
+ }
+ }
+
+ ///
+ /// Converts the to an that yields a
+ /// value each time the callback is executed.
+ ///
+ public static IAsyncEnumerable ToAsyncEnumerable(
+ this IAwaitableCallback source,
+ int timeout,
+ CancellationToken cancellationToken = default)
+ => ToAsyncEnumerable(source, TimeSpan.FromMilliseconds(timeout), cancellationToken);
+#endif
+}
diff --git a/Source/Testably.Abstractions.Testing/FileSystem/INotificationHandler.cs b/Source/Testably.Abstractions.Testing/FileSystem/INotificationHandler.cs
index 3b0632e1..ae30b28b 100644
--- a/Source/Testably.Abstractions.Testing/FileSystem/INotificationHandler.cs
+++ b/Source/Testably.Abstractions.Testing/FileSystem/INotificationHandler.cs
@@ -11,7 +11,7 @@ public interface INotificationHandler : IFileSystemEntity
/// Callback executed when any change in the matching the
/// occurred.
///
- /// The callback to execute after the change occurred.
+ /// (optional) The callback to execute after the change occurred.
///
/// (optional) A predicate used to filter which callbacks should be notified.
/// If set to (default value) all callbacks are notified.
diff --git a/Source/Testably.Abstractions.Testing/Helpers/ExceptionFactory.cs b/Source/Testably.Abstractions.Testing/Helpers/ExceptionFactory.cs
index 6f027030..e39ca8d0 100644
--- a/Source/Testably.Abstractions.Testing/Helpers/ExceptionFactory.cs
+++ b/Source/Testably.Abstractions.Testing/Helpers/ExceptionFactory.cs
@@ -293,6 +293,9 @@ internal static TimeoutException TimeoutExpired(int timeoutMilliseconds)
=> new(
$"The timeout of {timeoutMilliseconds}ms expired in the awaitable callback.");
+ internal static TimeoutException TimeoutExpired(TimeSpan timeout)
+ => new($"The timeout of {timeout} expired in the awaitable callback.");
+
internal static ArgumentOutOfRangeException TimerArgumentOutOfRange(string propertyName)
=> new(propertyName,
"Number must be either non-negative and less than or equal to Int32.MaxValue or -1")
diff --git a/Source/Testably.Abstractions.Testing/IAwaitableCallback.cs b/Source/Testably.Abstractions.Testing/IAwaitableCallback.cs
index 5a071ce8..ad6673d0 100644
--- a/Source/Testably.Abstractions.Testing/IAwaitableCallback.cs
+++ b/Source/Testably.Abstractions.Testing/IAwaitableCallback.cs
@@ -1,4 +1,6 @@
using System;
+using System.Threading;
+using System.Threading.Tasks;
namespace Testably.Abstractions.Testing;
@@ -7,7 +9,7 @@ namespace Testably.Abstractions.Testing;
/// - un-registering a callback by calling
/// - blocking for the callback to be executed
///
-public interface IAwaitableCallback : IDisposable
+public interface IAwaitableCallback : IDisposable
{
///
/// Blocks the current thread until the callback is executed.
@@ -30,8 +32,47 @@ public interface IAwaitableCallback : IDisposable
///
/// (optional) A callback to execute when waiting started.
///
+#if MarkExecuteWhileWaitingNotificationObsolete
+ [Obsolete("Use another `Wait` or `WaitAsync` overload and move the filter to the creation of the awaitable callback.")]
+#endif
void Wait(Func? filter = null,
int timeout = 30000,
int count = 1,
Action? executeWhenWaiting = null);
+
+ ///
+ /// Blocks the current thread until the callback is executed.
+ ///
+ /// Throws a if the expired before the callback was
+ /// executed.
+ ///
+ ///
+ /// (optional) The number of callbacks to wait.
+ /// Defaults to 1
+ ///
+ ///
+ /// (optional) The timeout to wait on the callback.
+ /// If not specified (), defaults to 30 seconds.
+ ///
+ TValue[] Wait(int count, TimeSpan? timeout = null);
+
+ ///
+ /// Waits asynchronously until the callback is executed.
+ ///
+ ///
+ /// (optional) The number of callbacks to wait.
+ /// Defaults to 1
+ ///
+ ///
+ /// (optional) The timeout to wait on the callback.
+ /// If not specified (), defaults to 30 seconds.
+ ///
+ ///
+ /// (optional) A to cancel waiting.
+ /// Throws a if the token was canceled before the callback was executed.
+ ///
+ Task WaitAsync(
+ int count = 1,
+ TimeSpan? timeout = null,
+ CancellationToken? cancellationToken = null);
}
diff --git a/Source/Testably.Abstractions.Testing/Notification.cs b/Source/Testably.Abstractions.Testing/Notification.cs
index 5e38aa39..557a8cd5 100644
--- a/Source/Testably.Abstractions.Testing/Notification.cs
+++ b/Source/Testably.Abstractions.Testing/Notification.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.Concurrent;
+using System.Collections.Generic;
using System.Threading;
+using System.Threading.Channels;
using System.Threading.Tasks;
using Testably.Abstractions.Testing.Helpers;
@@ -15,6 +17,9 @@ public static class Notification
/// Executes the while waiting for the notification.
///
/// The callback.
+#if MarkExecuteWhileWaitingNotificationObsolete
+ [Obsolete("Execute the callback before calling `Wait` or `WaitAsync` instead.")]
+#endif
public static IAwaitableCallback ExecuteWhileWaiting(
this IAwaitableCallback awaitable, Action callback)
{
@@ -29,6 +34,9 @@ public static IAwaitableCallback ExecuteWhileWaiting(
/// Executes the while waiting for the notification.
///
/// The callback.
+#if MarkExecuteWhileWaitingNotificationObsolete
+ [Obsolete("Execute the callback before calling `Wait` or `WaitAsync` instead.")]
+#endif
public static IAwaitableCallback ExecuteWhileWaiting(
this IAwaitableCallback awaitable, Func callback)
{
@@ -75,15 +83,18 @@ private void UnRegisterCallback(Guid key)
private sealed class CallbackWaiter : IAwaitableCallback
{
private readonly Action? _callback;
- private int _count;
+ private readonly Channel _channel = Channel.CreateUnbounded();
private readonly NotificationFactory _factory;
private Func? _filter;
+ private volatile bool _isDisposed;
private readonly Guid _key;
private readonly Func _predicate;
private readonly ManualResetEventSlim _reset;
+ private readonly ChannelWriter _writer;
public CallbackWaiter(NotificationFactory factory,
- Guid key, Action? callback,
+ Guid key,
+ Action? callback,
Func? predicate)
{
_factory = factory;
@@ -91,6 +102,7 @@ public CallbackWaiter(NotificationFactory factory,
_callback = callback;
_predicate = predicate ?? (_ => true);
_reset = new ManualResetEventSlim();
+ _writer = _channel.Writer;
}
#region IAwaitableCallback Members
@@ -99,7 +111,9 @@ public CallbackWaiter(NotificationFactory factory,
public void Dispose()
{
_factory.UnRegisterCallback(_key);
+ _writer.TryComplete();
_reset.Dispose();
+ _isDisposed = true;
}
///
@@ -108,22 +122,127 @@ public void Wait(Func? filter = null,
int count = 1,
Action? executeWhenWaiting = null)
{
- _count = count;
+ if (_isDisposed)
+ {
+ throw new ObjectDisposedException(null, "The awaitable callback is already disposed.");
+ }
+
_filter = filter;
_reset.Reset();
- Task? task = null;
if (executeWhenWaiting != null)
{
- task = Task.Run(executeWhenWaiting.Invoke);
+ executeWhenWaiting();
}
+ TValue[]? result = null;
+ _ = Task.Run(async () =>
+ {
+ try
+ {
+ result = await WaitAsync(count, TimeSpan.FromMilliseconds(timeout));
+ }
+ catch
+ {
+ // Ignore exceptions as they will be handled by the timeout or cancellation token
+ }
+ finally
+ {
+ _reset.Set();
+ }
+ });
+
if (!_reset.Wait(timeout) ||
- task?.Wait(timeout) == false)
+ result is null)
{
throw ExceptionFactory.TimeoutExpired(timeout);
}
}
+ ///
+ public TValue[] Wait(int count, TimeSpan? timeout = null)
+ {
+ if (_isDisposed)
+ {
+ throw new ObjectDisposedException(null, "The awaitable callback is already disposed.");
+ }
+
+ _reset.Reset();
+
+ TValue[]? result = null;
+ Task task = Task.Run(async () =>
+ {
+ try
+ {
+ result = await WaitAsync(count, timeout);
+ }
+ finally
+ {
+ _reset.Set();
+ }
+ });
+
+ TimeSpan timeoutOrDefault = timeout ?? TimeSpan.FromSeconds(30);
+ if (!_reset.Wait(timeoutOrDefault) ||
+ result is null)
+ {
+ throw task.Exception?.InnerException ??
+ ExceptionFactory.TimeoutExpired(timeoutOrDefault);
+ }
+
+ return result;
+ }
+
+ ///
+ public async Task WaitAsync(
+ int count = 1,
+ TimeSpan? timeout = null,
+ CancellationToken? cancellationToken = null)
+ {
+ if (_isDisposed)
+ {
+ throw new ObjectDisposedException(null, "The awaitable callback is already disposed.");
+ }
+
+ List values = [];
+ ChannelReader reader = _channel.Reader;
+
+ CancellationTokenSource? cts = null;
+ if (cancellationToken is null)
+ {
+ cts = new CancellationTokenSource(timeout ?? TimeSpan.FromSeconds(30));
+ cancellationToken = cts.Token;
+ }
+ else if (timeout is not null)
+ {
+ cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken.Value);
+ cts.CancelAfter(timeout.Value);
+ cancellationToken = cts.Token;
+ }
+
+ try
+ {
+ do
+ {
+ TValue value = await reader.ReadAsync(cancellationToken.Value)
+ .ConfigureAwait(false);
+ if (_filter?.Invoke(value) != false)
+ {
+ values.Add(value);
+ if (--count <= 0)
+ {
+ break;
+ }
+ }
+ } while (!cancellationToken.Value.IsCancellationRequested);
+ }
+ finally
+ {
+ cts?.Dispose();
+ }
+
+ return values.ToArray();
+ }
+
#endregion
///
@@ -138,11 +257,7 @@ internal void Invoke(TValue value)
}
_callback?.Invoke(value);
- if (_filter?.Invoke(value) != false &&
- Interlocked.Decrement(ref _count) <= 0)
- {
- _reset.Set();
- }
+ _writer.TryWrite(value);
}
}
}
@@ -161,7 +276,10 @@ IAwaitableCallback RegisterCallback(
/// - un-registering a callback by calling
/// - blocking for the callback to be executed
///
- public interface IAwaitableCallback
+#if MarkExecuteWhileWaitingNotificationObsolete
+ [Obsolete("Will be removed when `ExecuteWhileWaiting` is removed.")]
+#endif
+ public interface IAwaitableCallback
: IAwaitableCallback
{
///
@@ -193,6 +311,9 @@ public interface IAwaitableCallback
Action? executeWhenWaiting = null);
}
+#if MarkExecuteWhileWaitingNotificationObsolete
+ [Obsolete("Will be removed when `ExecuteWhileWaiting` is removed.")]
+#endif
private sealed class CallbackWaiterWithValue
: IAwaitableCallback
{
@@ -213,6 +334,10 @@ public void Dispose()
=> _awaitableCallback.Dispose();
///
+#if MarkExecuteWhileWaitingNotificationObsolete
+ [Obsolete(
+ "Use another `Wait` or `WaitAsync` overload and move the filter to the creation of the awaitable callback.")]
+#endif
public TFunc Wait(Func? filter = null,
int timeout = 30000,
int count = 1,
@@ -227,6 +352,21 @@ public TFunc Wait(Func? filter = null,
return value;
}
+ ///
+ public TValue[] Wait(int count, TimeSpan? timeout = null)
+ {
+ _valueProvider();
+ return _awaitableCallback.Wait(count, timeout);
+ }
+
+ ///
+ public Task WaitAsync(int count = 1, TimeSpan? timeout = null,
+ CancellationToken? cancellationToken = null)
+ {
+ _valueProvider();
+ return _awaitableCallback.WaitAsync(count, timeout, cancellationToken);
+ }
+
///
void IAwaitableCallback.Wait(Func? filter,
int timeout,
diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net10.0.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net10.0.txt
index 1158dfa7..b95e0ef5 100644
--- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net10.0.txt
+++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net10.0.txt
@@ -2,82 +2,17 @@
[assembly: System.Reflection.AssemblyMetadata("RepositoryUrl", "https://github.com/Testably/Testably.Abstractions.git")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Testably.Abstractions.Testing.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001006104741100251820044d92b34b0519a1de0bccd80d6199aadbdcd5931d035462d42f70b0ae7a7db37bab63afb8a8ad0dc21392bb01f1243bfc51df4b5f1975b1b9746fecbed88913b783fccb69efc59e23b0e019e065abd38731711a2d6ac2569ab57d4b4d529f5903f5bee0f4388b2a5f4d5e0fddab6aac18d96aa78c2e73e0")]
[assembly: System.Runtime.Versioning.TargetFramework(".NETCoreApp,Version=v10.0", FrameworkDisplayName=".NET 10.0")]
-namespace Testably.Abstractions.Testing.FileSystem
+namespace Testably.Abstractions.Testing
{
- public class ChangeDescription
- {
- public System.IO.WatcherChangeTypes ChangeType { get; }
- public Testably.Abstractions.Testing.FileSystemTypes FileSystemType { get; }
- public string? Name { get; }
- public System.IO.NotifyFilters NotifyFilters { get; }
- public string? OldName { get; }
- public string? OldPath { get; }
- public string Path { get; }
- public override string ToString() { }
- }
- public class DefaultAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
- {
- public DefaultAccessControlStrategy(System.Func callback) { }
- public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
- }
- public class DefaultSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
- {
- public DefaultSafeFileHandleStrategy(System.Func callback) { }
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
- public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
- }
- public interface IAccessControlStrategy
- {
- bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility);
- }
- public interface IInterceptionHandler : System.IO.Abstractions.IFileSystemEntity
- {
- Testably.Abstractions.Testing.IAwaitableCallback Event(System.Action interceptionCallback, System.Func? predicate = null);
- }
- public interface INotificationHandler : System.IO.Abstractions.IFileSystemEntity
- {
- Testably.Abstractions.Testing.IAwaitableCallback OnEvent(System.Action? notificationCallback = null, System.Func? predicate = null);
- }
- public interface ISafeFileHandleStrategy
+ public static class AwaitableCallbackExtensions
{
- Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle);
- }
- public interface IUnixFileModeStrategy
- {
- bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode, System.IO.FileAccess requestedAccess);
- void OnSetUnixFileMode(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode);
- }
- public interface IWatcherTriggeredHandler : System.IO.Abstractions.IFileSystemEntity
- {
- Testably.Abstractions.Testing.IAwaitableCallback OnTriggered(System.Action? triggerCallback = null, System.Func? predicate = null);
+ public static System.Collections.Generic.IAsyncEnumerable ToAsyncEnumerable(this Testably.Abstractions.Testing.IAwaitableCallback source, System.Threading.CancellationToken cancellationToken = default) { }
+ [System.Runtime.CompilerServices.AsyncIteratorStateMachine(typeof(Testably.Abstractions.Testing.AwaitableCallbackExtensions.d__3))]
+ public static System.Collections.Generic.IAsyncEnumerable ToAsyncEnumerable(this Testably.Abstractions.Testing.IAwaitableCallback source, System.TimeSpan? timeout, [System.Runtime.CompilerServices.EnumeratorCancellation] System.Threading.CancellationToken cancellationToken = default) { }
+ public static System.Collections.Generic.IAsyncEnumerable ToAsyncEnumerable(this Testably.Abstractions.Testing.IAwaitableCallback source, int timeout, System.Threading.CancellationToken cancellationToken = default) { }
+ public static TValue[] Wait(this Testably.Abstractions.Testing.IAwaitableCallback callback, int count = 1, int timeout = 30000) { }
+ public static System.Threading.Tasks.Task WaitAsync(this Testably.Abstractions.Testing.IAwaitableCallback callback, int count = 1, int timeout = 30000, System.Threading.CancellationToken? cancellationToken = default) { }
}
- public class NullAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
- {
- public NullAccessControlStrategy() { }
- public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
- }
- public class NullSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
- {
- public NullSafeFileHandleStrategy() { }
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
- public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
- }
- public class NullUnixFileModeStrategy : Testably.Abstractions.Testing.FileSystem.IUnixFileModeStrategy
- {
- public NullUnixFileModeStrategy() { }
- public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode, System.IO.FileAccess requestedAccess) { }
- public void OnSetUnixFileMode(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode) { }
- }
- public class SafeFileHandleMock
- {
- public SafeFileHandleMock(string path, System.IO.FileMode mode = 3, System.IO.FileShare share = 0) { }
- public System.IO.FileMode Mode { get; }
- public string Path { get; }
- public System.IO.FileShare Share { get; }
- }
-}
-namespace Testably.Abstractions.Testing
-{
public static class FileSystemInitializerExtensions
{
public static Testably.Abstractions.Testing.Initializer.IFileSystemInitializer Initialize(this TFileSystem fileSystem, System.Action? options = null)
@@ -99,9 +34,11 @@ namespace Testably.Abstractions.Testing
File = 2,
DirectoryOrFile = 3,
}
- public interface IAwaitableCallback : System.IDisposable
+ public interface IAwaitableCallback : System.IDisposable
{
+ TValue[] Wait(int count, System.TimeSpan? timeout = default);
void Wait(System.Func? filter = null, int timeout = 30000, int count = 1, System.Action? executeWhenWaiting = null);
+ System.Threading.Tasks.Task WaitAsync(int count = 1, System.TimeSpan? timeout = default, System.Threading.CancellationToken? cancellationToken = default);
}
public static class InterceptionHandlerExtensions
{
@@ -179,7 +116,7 @@ namespace Testably.Abstractions.Testing
{
public static Testably.Abstractions.Testing.IAwaitableCallback ExecuteWhileWaiting(this Testably.Abstractions.Testing.IAwaitableCallback awaitable, System.Action callback) { }
public static Testably.Abstractions.Testing.Notification.IAwaitableCallback ExecuteWhileWaiting(this Testably.Abstractions.Testing.IAwaitableCallback awaitable, System.Func callback) { }
- public interface IAwaitableCallback : System.IDisposable, Testably.Abstractions.Testing.IAwaitableCallback
+ public interface IAwaitableCallback : System.IDisposable, Testably.Abstractions.Testing.IAwaitableCallback
{
TFunc Wait(System.Func? filter = null, int timeout = 30000, int count = 1, System.Action? executeWhenWaiting = null);
}
@@ -225,6 +162,80 @@ namespace Testably.Abstractions.Testing
public static Testably.Abstractions.Testing.TimeSystem.ITimeProvider Use(System.DateTime time) { }
}
}
+namespace Testably.Abstractions.Testing.FileSystem
+{
+ public class ChangeDescription
+ {
+ public System.IO.WatcherChangeTypes ChangeType { get; }
+ public Testably.Abstractions.Testing.FileSystemTypes FileSystemType { get; }
+ public string? Name { get; }
+ public System.IO.NotifyFilters NotifyFilters { get; }
+ public string? OldName { get; }
+ public string? OldPath { get; }
+ public string Path { get; }
+ public override string ToString() { }
+ }
+ public class DefaultAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
+ {
+ public DefaultAccessControlStrategy(System.Func callback) { }
+ public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
+ }
+ public class DefaultSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
+ {
+ public DefaultSafeFileHandleStrategy(System.Func callback) { }
+ [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
+ public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
+ }
+ public interface IAccessControlStrategy
+ {
+ bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility);
+ }
+ public interface IInterceptionHandler : System.IO.Abstractions.IFileSystemEntity
+ {
+ Testably.Abstractions.Testing.IAwaitableCallback Event(System.Action interceptionCallback, System.Func? predicate = null);
+ }
+ public interface INotificationHandler : System.IO.Abstractions.IFileSystemEntity
+ {
+ Testably.Abstractions.Testing.IAwaitableCallback OnEvent(System.Action? notificationCallback = null, System.Func? predicate = null);
+ }
+ public interface ISafeFileHandleStrategy
+ {
+ Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle);
+ }
+ public interface IUnixFileModeStrategy
+ {
+ bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode, System.IO.FileAccess requestedAccess);
+ void OnSetUnixFileMode(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode);
+ }
+ public interface IWatcherTriggeredHandler : System.IO.Abstractions.IFileSystemEntity
+ {
+ Testably.Abstractions.Testing.IAwaitableCallback OnTriggered(System.Action? triggerCallback = null, System.Func? predicate = null);
+ }
+ public class NullAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
+ {
+ public NullAccessControlStrategy() { }
+ public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
+ }
+ public class NullSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
+ {
+ public NullSafeFileHandleStrategy() { }
+ [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
+ public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
+ }
+ public class NullUnixFileModeStrategy : Testably.Abstractions.Testing.FileSystem.IUnixFileModeStrategy
+ {
+ public NullUnixFileModeStrategy() { }
+ public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode, System.IO.FileAccess requestedAccess) { }
+ public void OnSetUnixFileMode(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode) { }
+ }
+ public class SafeFileHandleMock
+ {
+ public SafeFileHandleMock(string path, System.IO.FileMode mode = 3, System.IO.FileShare share = 0) { }
+ public System.IO.FileMode Mode { get; }
+ public string Path { get; }
+ public System.IO.FileShare Share { get; }
+ }
+}
namespace Testably.Abstractions.Testing.Initializer
{
public class DirectoryDescription : Testably.Abstractions.Testing.Initializer.FileSystemInfoDescription
diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net6.0.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net6.0.txt
index 9081cbde..5fe7bb85 100644
--- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net6.0.txt
+++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net6.0.txt
@@ -2,71 +2,17 @@
[assembly: System.Reflection.AssemblyMetadata("RepositoryUrl", "https://github.com/Testably/Testably.Abstractions.git")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Testably.Abstractions.Testing.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001006104741100251820044d92b34b0519a1de0bccd80d6199aadbdcd5931d035462d42f70b0ae7a7db37bab63afb8a8ad0dc21392bb01f1243bfc51df4b5f1975b1b9746fecbed88913b783fccb69efc59e23b0e019e065abd38731711a2d6ac2569ab57d4b4d529f5903f5bee0f4388b2a5f4d5e0fddab6aac18d96aa78c2e73e0")]
[assembly: System.Runtime.Versioning.TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName=".NET 6.0")]
-namespace Testably.Abstractions.Testing.FileSystem
+namespace Testably.Abstractions.Testing
{
- public class ChangeDescription
- {
- public System.IO.WatcherChangeTypes ChangeType { get; }
- public Testably.Abstractions.Testing.FileSystemTypes FileSystemType { get; }
- public string? Name { get; }
- public System.IO.NotifyFilters NotifyFilters { get; }
- public string? OldName { get; }
- public string? OldPath { get; }
- public string Path { get; }
- public override string ToString() { }
- }
- public class DefaultAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
- {
- public DefaultAccessControlStrategy(System.Func callback) { }
- public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
- }
- public class DefaultSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
- {
- public DefaultSafeFileHandleStrategy(System.Func callback) { }
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
- public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
- }
- public interface IAccessControlStrategy
- {
- bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility);
- }
- public interface IInterceptionHandler : System.IO.Abstractions.IFileSystemEntity
+ public static class AwaitableCallbackExtensions
{
- Testably.Abstractions.Testing.IAwaitableCallback Event(System.Action interceptionCallback, System.Func? predicate = null);
+ public static System.Collections.Generic.IAsyncEnumerable ToAsyncEnumerable(this Testably.Abstractions.Testing.IAwaitableCallback source, System.Threading.CancellationToken cancellationToken = default) { }
+ [System.Runtime.CompilerServices.AsyncIteratorStateMachine(typeof(Testably.Abstractions.Testing.AwaitableCallbackExtensions.d__3))]
+ public static System.Collections.Generic.IAsyncEnumerable ToAsyncEnumerable(this Testably.Abstractions.Testing.IAwaitableCallback source, System.TimeSpan? timeout, [System.Runtime.CompilerServices.EnumeratorCancellation] System.Threading.CancellationToken cancellationToken = default) { }
+ public static System.Collections.Generic.IAsyncEnumerable ToAsyncEnumerable(this Testably.Abstractions.Testing.IAwaitableCallback source, int timeout, System.Threading.CancellationToken cancellationToken = default) { }
+ public static TValue[] Wait(this Testably.Abstractions.Testing.IAwaitableCallback callback, int count = 1, int timeout = 30000) { }
+ public static System.Threading.Tasks.Task WaitAsync(this Testably.Abstractions.Testing.IAwaitableCallback callback, int count = 1, int timeout = 30000, System.Threading.CancellationToken? cancellationToken = default) { }
}
- public interface INotificationHandler : System.IO.Abstractions.IFileSystemEntity
- {
- Testably.Abstractions.Testing.IAwaitableCallback OnEvent(System.Action? notificationCallback = null, System.Func? predicate = null);
- }
- public interface ISafeFileHandleStrategy
- {
- Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle);
- }
- public interface IWatcherTriggeredHandler : System.IO.Abstractions.IFileSystemEntity
- {
- Testably.Abstractions.Testing.IAwaitableCallback OnTriggered(System.Action? triggerCallback = null, System.Func? predicate = null);
- }
- public class NullAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
- {
- public NullAccessControlStrategy() { }
- public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
- }
- public class NullSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
- {
- public NullSafeFileHandleStrategy() { }
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
- public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
- }
- public class SafeFileHandleMock
- {
- public SafeFileHandleMock(string path, System.IO.FileMode mode = 3, System.IO.FileShare share = 0) { }
- public System.IO.FileMode Mode { get; }
- public string Path { get; }
- public System.IO.FileShare Share { get; }
- }
-}
-namespace Testably.Abstractions.Testing
-{
public static class FileSystemInitializerExtensions
{
public static Testably.Abstractions.Testing.Initializer.IFileSystemInitializer Initialize(this TFileSystem fileSystem, System.Action? options = null)
@@ -88,9 +34,11 @@ namespace Testably.Abstractions.Testing
File = 2,
DirectoryOrFile = 3,
}
- public interface IAwaitableCallback : System.IDisposable
+ public interface IAwaitableCallback : System.IDisposable
{
+ TValue[] Wait(int count, System.TimeSpan? timeout = default);
void Wait(System.Func? filter = null, int timeout = 30000, int count = 1, System.Action? executeWhenWaiting = null);
+ System.Threading.Tasks.Task WaitAsync(int count = 1, System.TimeSpan? timeout = default, System.Threading.CancellationToken? cancellationToken = default);
}
public static class InterceptionHandlerExtensions
{
@@ -167,7 +115,7 @@ namespace Testably.Abstractions.Testing
{
public static Testably.Abstractions.Testing.IAwaitableCallback ExecuteWhileWaiting(this Testably.Abstractions.Testing.IAwaitableCallback awaitable, System.Action callback) { }
public static Testably.Abstractions.Testing.Notification.IAwaitableCallback ExecuteWhileWaiting(this Testably.Abstractions.Testing.IAwaitableCallback awaitable, System.Func callback) { }
- public interface IAwaitableCallback : System.IDisposable, Testably.Abstractions.Testing.IAwaitableCallback
+ public interface IAwaitableCallback : System.IDisposable, Testably.Abstractions.Testing.IAwaitableCallback
{
TFunc Wait(System.Func? filter = null, int timeout = 30000, int count = 1, System.Action? executeWhenWaiting = null);
}
@@ -213,6 +161,69 @@ namespace Testably.Abstractions.Testing
public static Testably.Abstractions.Testing.TimeSystem.ITimeProvider Use(System.DateTime time) { }
}
}
+namespace Testably.Abstractions.Testing.FileSystem
+{
+ public class ChangeDescription
+ {
+ public System.IO.WatcherChangeTypes ChangeType { get; }
+ public Testably.Abstractions.Testing.FileSystemTypes FileSystemType { get; }
+ public string? Name { get; }
+ public System.IO.NotifyFilters NotifyFilters { get; }
+ public string? OldName { get; }
+ public string? OldPath { get; }
+ public string Path { get; }
+ public override string ToString() { }
+ }
+ public class DefaultAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
+ {
+ public DefaultAccessControlStrategy(System.Func callback) { }
+ public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
+ }
+ public class DefaultSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
+ {
+ public DefaultSafeFileHandleStrategy(System.Func callback) { }
+ [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
+ public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
+ }
+ public interface IAccessControlStrategy
+ {
+ bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility);
+ }
+ public interface IInterceptionHandler : System.IO.Abstractions.IFileSystemEntity
+ {
+ Testably.Abstractions.Testing.IAwaitableCallback Event(System.Action interceptionCallback, System.Func? predicate = null);
+ }
+ public interface INotificationHandler : System.IO.Abstractions.IFileSystemEntity
+ {
+ Testably.Abstractions.Testing.IAwaitableCallback OnEvent(System.Action? notificationCallback = null, System.Func? predicate = null);
+ }
+ public interface ISafeFileHandleStrategy
+ {
+ Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle);
+ }
+ public interface IWatcherTriggeredHandler : System.IO.Abstractions.IFileSystemEntity
+ {
+ Testably.Abstractions.Testing.IAwaitableCallback OnTriggered(System.Action? triggerCallback = null, System.Func? predicate = null);
+ }
+ public class NullAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
+ {
+ public NullAccessControlStrategy() { }
+ public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
+ }
+ public class NullSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
+ {
+ public NullSafeFileHandleStrategy() { }
+ [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
+ public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
+ }
+ public class SafeFileHandleMock
+ {
+ public SafeFileHandleMock(string path, System.IO.FileMode mode = 3, System.IO.FileShare share = 0) { }
+ public System.IO.FileMode Mode { get; }
+ public string Path { get; }
+ public System.IO.FileShare Share { get; }
+ }
+}
namespace Testably.Abstractions.Testing.Initializer
{
public class DirectoryDescription : Testably.Abstractions.Testing.Initializer.FileSystemInfoDescription
diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net8.0.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net8.0.txt
index 2164c13d..e311aeb0 100644
--- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net8.0.txt
+++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net8.0.txt
@@ -2,82 +2,17 @@
[assembly: System.Reflection.AssemblyMetadata("RepositoryUrl", "https://github.com/Testably/Testably.Abstractions.git")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Testably.Abstractions.Testing.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001006104741100251820044d92b34b0519a1de0bccd80d6199aadbdcd5931d035462d42f70b0ae7a7db37bab63afb8a8ad0dc21392bb01f1243bfc51df4b5f1975b1b9746fecbed88913b783fccb69efc59e23b0e019e065abd38731711a2d6ac2569ab57d4b4d529f5903f5bee0f4388b2a5f4d5e0fddab6aac18d96aa78c2e73e0")]
[assembly: System.Runtime.Versioning.TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName=".NET 8.0")]
-namespace Testably.Abstractions.Testing.FileSystem
+namespace Testably.Abstractions.Testing
{
- public class ChangeDescription
- {
- public System.IO.WatcherChangeTypes ChangeType { get; }
- public Testably.Abstractions.Testing.FileSystemTypes FileSystemType { get; }
- public string? Name { get; }
- public System.IO.NotifyFilters NotifyFilters { get; }
- public string? OldName { get; }
- public string? OldPath { get; }
- public string Path { get; }
- public override string ToString() { }
- }
- public class DefaultAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
- {
- public DefaultAccessControlStrategy(System.Func callback) { }
- public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
- }
- public class DefaultSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
- {
- public DefaultSafeFileHandleStrategy(System.Func callback) { }
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
- public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
- }
- public interface IAccessControlStrategy
- {
- bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility);
- }
- public interface IInterceptionHandler : System.IO.Abstractions.IFileSystemEntity
- {
- Testably.Abstractions.Testing.IAwaitableCallback Event(System.Action interceptionCallback, System.Func? predicate = null);
- }
- public interface INotificationHandler : System.IO.Abstractions.IFileSystemEntity
- {
- Testably.Abstractions.Testing.IAwaitableCallback OnEvent(System.Action? notificationCallback = null, System.Func? predicate = null);
- }
- public interface ISafeFileHandleStrategy
+ public static class AwaitableCallbackExtensions
{
- Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle);
- }
- public interface IUnixFileModeStrategy
- {
- bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode, System.IO.FileAccess requestedAccess);
- void OnSetUnixFileMode(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode);
- }
- public interface IWatcherTriggeredHandler : System.IO.Abstractions.IFileSystemEntity
- {
- Testably.Abstractions.Testing.IAwaitableCallback OnTriggered(System.Action? triggerCallback = null, System.Func? predicate = null);
+ public static System.Collections.Generic.IAsyncEnumerable ToAsyncEnumerable(this Testably.Abstractions.Testing.IAwaitableCallback source, System.Threading.CancellationToken cancellationToken = default) { }
+ [System.Runtime.CompilerServices.AsyncIteratorStateMachine(typeof(Testably.Abstractions.Testing.AwaitableCallbackExtensions.d__3))]
+ public static System.Collections.Generic.IAsyncEnumerable ToAsyncEnumerable(this Testably.Abstractions.Testing.IAwaitableCallback source, System.TimeSpan? timeout, [System.Runtime.CompilerServices.EnumeratorCancellation] System.Threading.CancellationToken cancellationToken = default) { }
+ public static System.Collections.Generic.IAsyncEnumerable ToAsyncEnumerable(this Testably.Abstractions.Testing.IAwaitableCallback source, int timeout, System.Threading.CancellationToken cancellationToken = default) { }
+ public static TValue[] Wait(this Testably.Abstractions.Testing.IAwaitableCallback callback, int count = 1, int timeout = 30000) { }
+ public static System.Threading.Tasks.Task WaitAsync(this Testably.Abstractions.Testing.IAwaitableCallback callback, int count = 1, int timeout = 30000, System.Threading.CancellationToken? cancellationToken = default) { }
}
- public class NullAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
- {
- public NullAccessControlStrategy() { }
- public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
- }
- public class NullSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
- {
- public NullSafeFileHandleStrategy() { }
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
- public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
- }
- public class NullUnixFileModeStrategy : Testably.Abstractions.Testing.FileSystem.IUnixFileModeStrategy
- {
- public NullUnixFileModeStrategy() { }
- public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode, System.IO.FileAccess requestedAccess) { }
- public void OnSetUnixFileMode(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode) { }
- }
- public class SafeFileHandleMock
- {
- public SafeFileHandleMock(string path, System.IO.FileMode mode = 3, System.IO.FileShare share = 0) { }
- public System.IO.FileMode Mode { get; }
- public string Path { get; }
- public System.IO.FileShare Share { get; }
- }
-}
-namespace Testably.Abstractions.Testing
-{
public static class FileSystemInitializerExtensions
{
public static Testably.Abstractions.Testing.Initializer.IFileSystemInitializer Initialize(this TFileSystem fileSystem, System.Action? options = null)
@@ -99,9 +34,11 @@ namespace Testably.Abstractions.Testing
File = 2,
DirectoryOrFile = 3,
}
- public interface IAwaitableCallback : System.IDisposable
+ public interface IAwaitableCallback : System.IDisposable
{
+ TValue[] Wait(int count, System.TimeSpan? timeout = default);
void Wait(System.Func? filter = null, int timeout = 30000, int count = 1, System.Action? executeWhenWaiting = null);
+ System.Threading.Tasks.Task WaitAsync(int count = 1, System.TimeSpan? timeout = default, System.Threading.CancellationToken? cancellationToken = default);
}
public static class InterceptionHandlerExtensions
{
@@ -179,7 +116,7 @@ namespace Testably.Abstractions.Testing
{
public static Testably.Abstractions.Testing.IAwaitableCallback ExecuteWhileWaiting(this Testably.Abstractions.Testing.IAwaitableCallback awaitable, System.Action callback) { }
public static Testably.Abstractions.Testing.Notification.IAwaitableCallback ExecuteWhileWaiting(this Testably.Abstractions.Testing.IAwaitableCallback awaitable, System.Func callback) { }
- public interface IAwaitableCallback : System.IDisposable, Testably.Abstractions.Testing.IAwaitableCallback
+ public interface IAwaitableCallback : System.IDisposable, Testably.Abstractions.Testing.IAwaitableCallback
{
TFunc Wait(System.Func? filter = null, int timeout = 30000, int count = 1, System.Action? executeWhenWaiting = null);
}
@@ -225,6 +162,80 @@ namespace Testably.Abstractions.Testing
public static Testably.Abstractions.Testing.TimeSystem.ITimeProvider Use(System.DateTime time) { }
}
}
+namespace Testably.Abstractions.Testing.FileSystem
+{
+ public class ChangeDescription
+ {
+ public System.IO.WatcherChangeTypes ChangeType { get; }
+ public Testably.Abstractions.Testing.FileSystemTypes FileSystemType { get; }
+ public string? Name { get; }
+ public System.IO.NotifyFilters NotifyFilters { get; }
+ public string? OldName { get; }
+ public string? OldPath { get; }
+ public string Path { get; }
+ public override string ToString() { }
+ }
+ public class DefaultAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
+ {
+ public DefaultAccessControlStrategy(System.Func callback) { }
+ public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
+ }
+ public class DefaultSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
+ {
+ public DefaultSafeFileHandleStrategy(System.Func callback) { }
+ [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
+ public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
+ }
+ public interface IAccessControlStrategy
+ {
+ bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility);
+ }
+ public interface IInterceptionHandler : System.IO.Abstractions.IFileSystemEntity
+ {
+ Testably.Abstractions.Testing.IAwaitableCallback Event(System.Action interceptionCallback, System.Func? predicate = null);
+ }
+ public interface INotificationHandler : System.IO.Abstractions.IFileSystemEntity
+ {
+ Testably.Abstractions.Testing.IAwaitableCallback OnEvent(System.Action? notificationCallback = null, System.Func? predicate = null);
+ }
+ public interface ISafeFileHandleStrategy
+ {
+ Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle);
+ }
+ public interface IUnixFileModeStrategy
+ {
+ bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode, System.IO.FileAccess requestedAccess);
+ void OnSetUnixFileMode(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode);
+ }
+ public interface IWatcherTriggeredHandler : System.IO.Abstractions.IFileSystemEntity
+ {
+ Testably.Abstractions.Testing.IAwaitableCallback OnTriggered(System.Action? triggerCallback = null, System.Func? predicate = null);
+ }
+ public class NullAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
+ {
+ public NullAccessControlStrategy() { }
+ public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
+ }
+ public class NullSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
+ {
+ public NullSafeFileHandleStrategy() { }
+ [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
+ public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
+ }
+ public class NullUnixFileModeStrategy : Testably.Abstractions.Testing.FileSystem.IUnixFileModeStrategy
+ {
+ public NullUnixFileModeStrategy() { }
+ public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode, System.IO.FileAccess requestedAccess) { }
+ public void OnSetUnixFileMode(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode) { }
+ }
+ public class SafeFileHandleMock
+ {
+ public SafeFileHandleMock(string path, System.IO.FileMode mode = 3, System.IO.FileShare share = 0) { }
+ public System.IO.FileMode Mode { get; }
+ public string Path { get; }
+ public System.IO.FileShare Share { get; }
+ }
+}
namespace Testably.Abstractions.Testing.Initializer
{
public class DirectoryDescription : Testably.Abstractions.Testing.Initializer.FileSystemInfoDescription
diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net9.0.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net9.0.txt
index c23262e1..d57e60d7 100644
--- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net9.0.txt
+++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions.Testing_net9.0.txt
@@ -2,82 +2,17 @@
[assembly: System.Reflection.AssemblyMetadata("RepositoryUrl", "https://github.com/Testably/Testably.Abstractions.git")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(@"Testably.Abstractions.Testing.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001006104741100251820044d92b34b0519a1de0bccd80d6199aadbdcd5931d035462d42f70b0ae7a7db37bab63afb8a8ad0dc21392bb01f1243bfc51df4b5f1975b1b9746fecbed88913b783fccb69efc59e23b0e019e065abd38731711a2d6ac2569ab57d4b4d529f5903f5bee0f4388b2a5f4d5e0fddab6aac18d96aa78c2e73e0")]
[assembly: System.Runtime.Versioning.TargetFramework(".NETCoreApp,Version=v9.0", FrameworkDisplayName=".NET 9.0")]
-namespace Testably.Abstractions.Testing.FileSystem
+namespace Testably.Abstractions.Testing
{
- public class ChangeDescription
- {
- public System.IO.WatcherChangeTypes ChangeType { get; }
- public Testably.Abstractions.Testing.FileSystemTypes FileSystemType { get; }
- public string? Name { get; }
- public System.IO.NotifyFilters NotifyFilters { get; }
- public string? OldName { get; }
- public string? OldPath { get; }
- public string Path { get; }
- public override string ToString() { }
- }
- public class DefaultAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
- {
- public DefaultAccessControlStrategy(System.Func callback) { }
- public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
- }
- public class DefaultSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
- {
- public DefaultSafeFileHandleStrategy(System.Func callback) { }
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
- public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
- }
- public interface IAccessControlStrategy
- {
- bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility);
- }
- public interface IInterceptionHandler : System.IO.Abstractions.IFileSystemEntity
- {
- Testably.Abstractions.Testing.IAwaitableCallback Event(System.Action interceptionCallback, System.Func? predicate = null);
- }
- public interface INotificationHandler : System.IO.Abstractions.IFileSystemEntity
- {
- Testably.Abstractions.Testing.IAwaitableCallback OnEvent(System.Action? notificationCallback = null, System.Func? predicate = null);
- }
- public interface ISafeFileHandleStrategy
+ public static class AwaitableCallbackExtensions
{
- Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle);
- }
- public interface IUnixFileModeStrategy
- {
- bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode, System.IO.FileAccess requestedAccess);
- void OnSetUnixFileMode(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode);
- }
- public interface IWatcherTriggeredHandler : System.IO.Abstractions.IFileSystemEntity
- {
- Testably.Abstractions.Testing.IAwaitableCallback OnTriggered(System.Action? triggerCallback = null, System.Func? predicate = null);
+ public static System.Collections.Generic.IAsyncEnumerable ToAsyncEnumerable(this Testably.Abstractions.Testing.IAwaitableCallback source, System.Threading.CancellationToken cancellationToken = default) { }
+ [System.Runtime.CompilerServices.AsyncIteratorStateMachine(typeof(Testably.Abstractions.Testing.AwaitableCallbackExtensions.d__3))]
+ public static System.Collections.Generic.IAsyncEnumerable ToAsyncEnumerable(this Testably.Abstractions.Testing.IAwaitableCallback source, System.TimeSpan? timeout, [System.Runtime.CompilerServices.EnumeratorCancellation] System.Threading.CancellationToken cancellationToken = default) { }
+ public static System.Collections.Generic.IAsyncEnumerable ToAsyncEnumerable(this Testably.Abstractions.Testing.IAwaitableCallback source, int timeout, System.Threading.CancellationToken cancellationToken = default) { }
+ public static TValue[] Wait(this Testably.Abstractions.Testing.IAwaitableCallback callback, int count = 1, int timeout = 30000) { }
+ public static System.Threading.Tasks.Task WaitAsync(this Testably.Abstractions.Testing.IAwaitableCallback callback, int count = 1, int timeout = 30000, System.Threading.CancellationToken? cancellationToken = default) { }
}
- public class NullAccessControlStrategy : Testably.Abstractions.Testing.FileSystem.IAccessControlStrategy
- {
- public NullAccessControlStrategy() { }
- public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility) { }
- }
- public class NullSafeFileHandleStrategy : Testably.Abstractions.Testing.FileSystem.ISafeFileHandleStrategy
- {
- public NullSafeFileHandleStrategy() { }
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification="SafeFileHandle cannot be unit tested.")]
- public Testably.Abstractions.Testing.FileSystem.SafeFileHandleMock MapSafeFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle fileHandle) { }
- }
- public class NullUnixFileModeStrategy : Testably.Abstractions.Testing.FileSystem.IUnixFileModeStrategy
- {
- public NullUnixFileModeStrategy() { }
- public bool IsAccessGranted(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode, System.IO.FileAccess requestedAccess) { }
- public void OnSetUnixFileMode(string fullPath, Testably.Abstractions.Helpers.IFileSystemExtensibility extensibility, System.IO.UnixFileMode mode) { }
- }
- public class SafeFileHandleMock
- {
- public SafeFileHandleMock(string path, System.IO.FileMode mode = 3, System.IO.FileShare share = 0) { }
- public System.IO.FileMode Mode { get; }
- public string Path { get; }
- public System.IO.FileShare Share { get; }
- }
-}
-namespace Testably.Abstractions.Testing
-{
public static class FileSystemInitializerExtensions
{
public static Testably.Abstractions.Testing.Initializer.IFileSystemInitializer