-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feature: cant log things out * feature: add Listener * add notifier interface for testing * feature: getting these tests in order * feature: not broke
- Loading branch information
1 parent
a047477
commit 333c252
Showing
11 changed files
with
265 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using System; | ||
using System.Reactive.Disposables; | ||
|
||
namespace Rocket.Surgery.Airframe; | ||
|
||
/// <summary> | ||
/// Represents a disposable base object. | ||
/// </summary> | ||
public abstract class DisposableBase : IDisposable | ||
{ | ||
/// <inheritdoc/> | ||
public void Dispose() | ||
{ | ||
Dispose(true); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the garbage disposables. | ||
/// </summary> | ||
protected CompositeDisposable Garbage { get; } = new(); | ||
|
||
/// <summary> | ||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. | ||
/// </summary> | ||
/// <param name="disposing">Is disposing.</param> | ||
protected virtual void Dispose(bool disposing) | ||
{ | ||
if (disposing) | ||
{ | ||
Garbage.Dispose(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using System; | ||
using System.Reactive; | ||
|
||
namespace Rocket.Surgery.Airframe; | ||
|
||
/// <summary> | ||
/// Interface that represents an object that can connect and disconnect from as observable sequence. | ||
/// </summary> | ||
public interface IListener : IListener<Unit>; | ||
|
||
/// <summary> | ||
/// Interface that represents an object that can connect and disconnect from as observable sequence. | ||
/// </summary> | ||
/// <typeparam name="T">The type of object to listen for.</typeparam> | ||
public interface IListener<out T> | ||
{ | ||
/// <summary> | ||
/// Start listening. | ||
/// </summary> | ||
/// <returns>A observable sequence of <see cref="T"/>.</returns> | ||
IObservable<T> Listen(); | ||
|
||
/// <summary> | ||
/// Ignore the information. | ||
/// </summary> | ||
/// <returns>A completion notification.</returns> | ||
IObservable<Unit> Ignore(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using System; | ||
using System.Reactive; | ||
using System.Reactive.Disposables; | ||
using System.Reactive.Linq; | ||
using System.Reactive.Subjects; | ||
using JetBrains.Annotations; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace Rocket.Surgery.Airframe; | ||
|
||
/// <summary> | ||
/// Base extension point for an <see cref="IListener"/>. | ||
/// </summary> | ||
[PublicAPI] | ||
public abstract class Listener : Listener<Unit>, IListener | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="Listener"/> class. | ||
/// </summary> | ||
/// <param name="loggerFactory">The logger factory.</param> | ||
protected Listener(ILoggerFactory loggerFactory) | ||
: base(loggerFactory) | ||
{ | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Base extension point for an <see cref="IListener{T}"/>. | ||
/// </summary> | ||
/// <typeparam name="T">The observable sequence type.</typeparam> | ||
[PublicAPI] | ||
public abstract class Listener<T> : DisposableBase, IListener<T> | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="Listener{T}"/> class. | ||
/// </summary> | ||
/// <param name="loggerFactory">The logger factory.</param> | ||
protected Listener(ILoggerFactory loggerFactory) | ||
{ | ||
_stop = Disposable.Empty; | ||
_stop.DisposeWith(Garbage); | ||
Logger = loggerFactory.CreateLogger(GetType()); | ||
Listening = Observable.Empty<T>().Publish(); | ||
} | ||
|
||
/// <inheritdoc /> | ||
IObservable<T> IListener<T>.Listen() => StartListening(); | ||
|
||
/// <inheritdoc cref="IListener"/> | ||
IObservable<Unit> IListener<T>.Ignore() => StopListening(); | ||
|
||
/// <summary> | ||
/// Connect to the observable sequence. | ||
/// </summary> | ||
/// <returns>Returns a signal.</returns> | ||
protected virtual IConnectableObservable<T> Listen() => Listening; | ||
|
||
/// <summary> | ||
/// Disconnects from the observable sequence. | ||
/// </summary> | ||
/// <returns>Returns a signal.</returns> | ||
protected virtual IObservable<Unit> Ignore() => Observable.Return(Unit.Default); | ||
|
||
/// <summary> | ||
/// Gets or sets the <see cref="IConnectableObservable{T}"/> that the listener listens to. | ||
/// </summary> | ||
protected IConnectableObservable<T> Listening { get; set; } | ||
|
||
/// <summary> | ||
/// Gets the logger. | ||
/// </summary> | ||
protected ILogger Logger { get; } | ||
|
||
private IObservable<T> StartListening() => Observable.Create<T>(observer => | ||
{ | ||
_stop = Listen().Connect(); | ||
return Listen().Subscribe(observer); | ||
}); | ||
|
||
private IObservable<Unit> StopListening() => Ignore().Finally(() => _stop.Dispose()); | ||
|
||
private IDisposable _stop; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
namespace Airframe.Testing; | ||
|
||
/// <summary> | ||
/// Interface representing a thing™ that can notify. | ||
/// </summary> | ||
/// <typeparam name="T">The notification type.</typeparam> | ||
public interface INotifier<T> | ||
{ | ||
/// <summary> | ||
/// Notifies an item to a subscriber. | ||
/// </summary> | ||
/// <param name="item">The item.</param> | ||
void Notify(T item); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using FluentAssertions; | ||
using System; | ||
using System.Reactive; | ||
using Xunit; | ||
|
||
namespace Rocket.Surgery.Airframe.Core.Tests.Listeners; | ||
|
||
public class ListenerTests | ||
{ | ||
[Fact] | ||
public void GivenListen_When_ThenResultNotNull() | ||
{ | ||
// Given | ||
Unit? result = null; | ||
TestListener sut = new TestListenerFixture(); | ||
using var _ = sut.As<IListener>().Listen().Subscribe(actual => result = actual); | ||
|
||
// When | ||
sut.Notify(Unit.Default); | ||
|
||
// Then | ||
result.Should().NotBeNull(); | ||
} | ||
|
||
[Fact] | ||
public void GivenListen_WhenIgnore_ThenResultNull() | ||
{ | ||
// Given | ||
Unit? result = null; | ||
TestListener sut = new TestListenerFixture(); | ||
using var _ = sut.As<IListener>().Listen().Subscribe(actual => result = actual); | ||
|
||
// When | ||
using var __ = sut.As<IListener>().Ignore().Subscribe(); | ||
sut.Notify(Unit.Default); | ||
|
||
// Then | ||
result.Should().BeNull(); | ||
} | ||
|
||
[Fact] | ||
public void GivenIgnore_WhenListen_ThenResultNotNull() | ||
{ | ||
// Given | ||
Unit? result = null; | ||
TestListener sut = new TestListenerFixture(); | ||
using var _ = sut.As<IListener>().Ignore().Subscribe(); | ||
|
||
// When | ||
using var __ = sut.As<IListener>().Listen().Subscribe(actual => result = actual); | ||
sut.Notify(Unit.Default); | ||
|
||
// Then | ||
result.Should().NotBeNull(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using Airframe.Testing; | ||
using Microsoft.Extensions.Logging; | ||
using ReactiveMarbles.Extensions; | ||
using System.Reactive; | ||
using System.Reactive.Linq; | ||
using System.Reactive.Subjects; | ||
|
||
namespace Rocket.Surgery.Airframe.Core.Tests.Listeners; | ||
|
||
internal class TestListener : Listener, INotifier<Unit> | ||
{ | ||
public TestListener(ILoggerFactory loggerFactory) | ||
: base(loggerFactory) | ||
{ | ||
_subject = new Subject<Unit>().DisposeWith(Garbage); | ||
Listening = _subject.AsObservable().Publish(); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public void Notify(Unit item) => _subject.OnNext(item); | ||
|
||
private readonly ISubject<Unit> _subject; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Logging.Abstractions; | ||
using Rocket.Surgery.Extensions.Testing.Fixtures; | ||
|
||
namespace Rocket.Surgery.Airframe.Core.Tests.Listeners; | ||
|
||
internal class TestListenerFixture : ITestFixtureBuilder | ||
{ | ||
public static implicit operator TestListener(TestListenerFixture fixture) => fixture.Build(); | ||
|
||
private TestListener Build() => new TestListener(_loggerFactory); | ||
|
||
private ILoggerFactory _loggerFactory = NullLoggerFactory.Instance; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,3 @@ | ||
<Project> | ||
<ItemGroup> | ||
<PackageReference Include="Rocket.Surgery.Extensions.Testing.Fixtures" /> | ||
<PackageReference Include="coverlet.collector" /> | ||
<PackageReference Include="coverlet.msbuild" /> | ||
<PackageReference Include="NSubstitute" /> | ||
<PackageReference Include="FluentAssertions" /> | ||
<PackageReference Include="xunit" /> | ||
<PackageReference Include="xunit.runner.visualstudio" /> | ||
<PackageReference Include="XunitXml.TestLogger" /> | ||
</ItemGroup> | ||
<Import Project="$([MSBuild]::GetPathOfFileAbove('directory.build.targets', '$(MSBuildThisFileDirectory)../'))" /> | ||
</Project> |