Skip to content
Merged
61 changes: 61 additions & 0 deletions PolyShim.Tests/NetCore10/ProgressTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using System.Threading;
using FluentAssertions;
using Xunit;

namespace PolyShim.Tests.NetCore10;

public class ProgressTests
Comment thread
Tyrrrz marked this conversation as resolved.
{
[Fact]
public void Report_WithHandler_Test()
{
// Arrange
using var received = new ManualResetEventSlim();
var receivedValue = default(int);
var progress = new Progress<int>(v =>
{
receivedValue = v;
received.Set();
});

// Act
((IProgress<int>)progress).Report(42);

// Assert
received.Wait(TimeSpan.FromSeconds(5)).Should().BeTrue();
receivedValue.Should().Be(42);
}

[Fact]
public void Report_WithEvent_Test()
{
// Arrange
using var received = new ManualResetEventSlim();
var receivedValue = default(int);
var progress = new Progress<int>();
progress.ProgressChanged += (_, v) =>
{
receivedValue = v;
received.Set();
};

// Act
((IProgress<int>)progress).Report(99);

// Assert
received.Wait(TimeSpan.FromSeconds(5)).Should().BeTrue();
receivedValue.Should().Be(99);
}

[Fact]
public void Report_NoHandler_Test()
{
// Arrange
var progress = new Progress<int>();

// Act & assert
var act = () => ((IProgress<int>)progress).Report(1);
act.Should().NotThrow();
}
}
9 changes: 9 additions & 0 deletions PolyShim/NetCore10/EventHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#if NETFRAMEWORK && !NET45_OR_GREATER
#nullable enable
#pragma warning disable CS0436

namespace System;

// https://learn.microsoft.com/dotnet/api/system.eventhandler-1
internal delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
#endif
12 changes: 12 additions & 0 deletions PolyShim/NetCore10/IProgress.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#if (NETFRAMEWORK && !NET45_OR_GREATER) || (NETSTANDARD && !NETSTANDARD1_1_OR_GREATER)
#nullable enable
#pragma warning disable CS0436

namespace System;

// https://learn.microsoft.com/dotnet/api/system.iprogress-1
internal interface IProgress<in T>
{
void Report(T value);
}
#endif
50 changes: 50 additions & 0 deletions PolyShim/NetCore10/Progress.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#if (NETFRAMEWORK && !NET45_OR_GREATER) || (NETSTANDARD && !NETSTANDARD1_3_OR_GREATER)
#nullable enable
#pragma warning disable CS0436

using System.Diagnostics.CodeAnalysis;
using System.Threading;

namespace System;

// https://learn.microsoft.com/dotnet/api/system.progress-1
#if !POLYSHIM_INCLUDE_COVERAGE
[ExcludeFromCodeCoverage]
#endif
internal class Progress<T> : IProgress<T>
{
private readonly SynchronizationContext _synchronizationContext;
private readonly Action<T>? _handler;

public event EventHandler<T>? ProgressChanged;

public Progress()
{
_synchronizationContext = SynchronizationContext.Current ?? new();
Comment thread
Tyrrrz marked this conversation as resolved.
}

public Progress(Action<T> handler)
: this() => _handler = handler;

protected virtual void OnReport(T value)
{
var handler = _handler;
var progressChanged = ProgressChanged;

if (handler is not null || progressChanged is not null)
{
_synchronizationContext.Post(
s =>
{
var (v, h, e) = ((T, Action<T>?, EventHandler<T>?))s!;
h?.Invoke(v);
e?.Invoke(this, v);
},
(value, handler, progressChanged)
);
}
}

void IProgress<T>.Report(T value) => OnReport(value);
}
#endif
10 changes: 8 additions & 2 deletions Signatures.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Signatures

- **Total:** 488
- **Types:** 106
- **Total:** 491
- **Types:** 109
- **Members:** 382

___
Expand Down Expand Up @@ -122,6 +122,8 @@ ___
- [`static string? ProcessPath`](https://learn.microsoft.com/dotnet/api/system.environment.processpath) <sup><sub>.NET 6.0</sub></sup>
- `EqualityComparer<T>`
- [`static EqualityComparer<T> Create(Func<T?, T?, bool>, Func<T, int>?)`](https://learn.microsoft.com/dotnet/api/system.collections.generic.equalitycomparer-1.create) <sup><sub>.NET 8.0</sub></sup>
- `EventHandler<T>`
- [**[delegate]**](https://learn.microsoft.com/dotnet/api/system.eventhandler-1) <sup><sub>.NET Core 1.0</sub></sup>
- `ExcludeFromCodeCoverageAttribute`
- [**[class]**](https://learn.microsoft.com/dotnet/api/system.diagnostics.codeanalysis.excludefromcodecoverageattribute) <sup><sub>.NET Core 2.0</sub></sup>
- `ExtensionAttribute`
Expand Down Expand Up @@ -260,6 +262,8 @@ ___
- [`static IntPtr Parse(string, IFormatProvider?)`](https://learn.microsoft.com/dotnet/api/system.intptr.parse#system-intptr-parse(system-string-system-iformatprovider)) <sup><sub>.NET 5.0</sub></sup>
- [`static IntPtr Parse(string, NumberStyles)`](https://learn.microsoft.com/dotnet/api/system.intptr.parse#system-intptr-parse(system-string-system-globalization-numberstyles)) <sup><sub>.NET 5.0</sub></sup>
- [`static IntPtr Parse(string, NumberStyles, IFormatProvider?)`](https://learn.microsoft.com/dotnet/api/system.intptr.parse#system-intptr-parse(system-string-system-globalization-numberstyles-system-iformatprovider)) <sup><sub>.NET 5.0</sub></sup>
- `IProgress<T>`
- [**[interface]**](https://learn.microsoft.com/dotnet/api/system.iprogress-1) <sup><sub>.NET Core 1.0</sub></sup>
- `IReadOnlyDictionary<TKey, TValue>`
- [`TValue? GetValueOrDefault(TKey)`](https://learn.microsoft.com/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0)) <sup><sub>.NET Core 2.0</sub></sup>
- [`TValue? GetValueOrDefault(TKey, TValue?)`](https://learn.microsoft.com/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) <sup><sub>.NET Core 2.0</sub></sup>
Expand Down Expand Up @@ -372,6 +376,8 @@ ___
- [`bool WaitForExit(TimeSpan)`](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.waitforexit#system-diagnostics-process-waitforexit(system-timespan)) <sup><sub>.NET 7.0</sub></sup>
- [`Task WaitForExitAsync(CancellationToken)`](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.waitforexitasync) <sup><sub>.NET 5.0</sub></sup>
- [`void Kill(bool)`](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.kill#system-diagnostics-process-kill(system-boolean)) <sup><sub>.NET Core 3.0</sub></sup>
- `Progress<T>`
- [**[class]**](https://learn.microsoft.com/dotnet/api/system.progress-1) <sup><sub>.NET Core 1.0</sub></sup>
- `Queue<T>`
- [`bool TryDequeue(out T?)`](https://learn.microsoft.com/dotnet/api/system.collections.generic.queue-1.trydequeue) <sup><sub>.NET Core 2.0</sub></sup>
- [`bool TryPeek(out T?)`](https://learn.microsoft.com/dotnet/api/system.collections.generic.queue-1.trypeek) <sup><sub>.NET Core 2.0</sub></sup>
Expand Down
Loading