diff --git a/MessageCommunicator.TestGui.Tests/MessageCommunicator.TestGui.Tests.csproj b/MessageCommunicator.TestGui.Tests/MessageCommunicator.TestGui.Tests.csproj new file mode 100644 index 0000000..2ef1354 --- /dev/null +++ b/MessageCommunicator.TestGui.Tests/MessageCommunicator.TestGui.Tests.csproj @@ -0,0 +1,23 @@ + + + + netcoreapp3.1 + 8.0 + enable + false + + + + + + + + + + + + + + + + diff --git a/MessageCommunicator.TestGui.Tests/ViewServiceContainerTests.cs b/MessageCommunicator.TestGui.Tests/ViewServiceContainerTests.cs new file mode 100644 index 0000000..0da22e1 --- /dev/null +++ b/MessageCommunicator.TestGui.Tests/ViewServiceContainerTests.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reactive.Disposables; +using System.Text; +using Avalonia.Controls; +using FakeItEasy; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace MessageCommunicator.TestGui.Tests +{ + [TestClass] + public class ViewServiceContainerTests + { + [TestMethod] + public void Check_EmptyObject() + { + var fakeOwner = A.Fake(); + var viewServiceContainer = new ViewServiceContainer(fakeOwner); + + Assert.IsFalse(viewServiceContainer.IsObserving); + } + + [TestMethod] + public void Check_RegisterNullViewModel() + { + var fakeOwner = A.Fake(); + var viewServiceContainer = new ViewServiceContainer(fakeOwner); + + var compositeDisposable = new CompositeDisposable(); + viewServiceContainer.StartObserving(compositeDisposable, null); + + Assert.IsTrue(compositeDisposable.Count == 1); + Assert.IsTrue(viewServiceContainer.IsObserving); + } + + [TestMethod] + public void Check_RegisterNullViewModel_WithDeregister() + { + var fakeOwner = A.Fake(); + var viewServiceContainer = new ViewServiceContainer(fakeOwner); + + var compositeDisposable = new CompositeDisposable(); + viewServiceContainer.StartObserving(compositeDisposable, null); + + compositeDisposable.Dispose(); + + Assert.IsTrue(compositeDisposable.Count == 0); + Assert.IsFalse(viewServiceContainer.IsObserving); + } + + [TestMethod] + public void Check_RegisterNullViewModel_WithViewService() + { + var fakeOwner = A.Fake(); + var viewServiceContainer = new ViewServiceContainer(fakeOwner); + var fakeViewService1 = A.Fake(); + var fakeViewService2 = A.Fake(); + + viewServiceContainer.ViewServices.Add(fakeViewService1); + + var compositeDisposable = new CompositeDisposable(); + viewServiceContainer.StartObserving(compositeDisposable, null); + + viewServiceContainer.ViewServices.Add(fakeViewService2); + + Assert.IsTrue(compositeDisposable.Count == 1); + Assert.IsTrue(viewServiceContainer.IsObserving); + Assert.IsTrue(Fake.GetCalls(fakeViewService1).Any(actCall => actCall.Method.Name == $"add_{nameof(IViewService.ViewServiceRequest)}")); + Assert.IsTrue(Fake.GetCalls(fakeViewService2).Any(actCall => actCall.Method.Name == $"add_{nameof(IViewService.ViewServiceRequest)}")); + } + + [TestMethod] + public void Check_RegisterNullViewModel__WithDeregister_WithViewService() + { + var fakeOwner = A.Fake(); + var viewServiceContainer = new ViewServiceContainer(fakeOwner); + var fakeViewService1 = A.Fake(); + var fakeViewService2 = A.Fake(); + + viewServiceContainer.ViewServices.Add(fakeViewService1); + + var compositeDisposable = new CompositeDisposable(); + viewServiceContainer.StartObserving(compositeDisposable, null); + + viewServiceContainer.ViewServices.Add(fakeViewService2); + + compositeDisposable.Dispose(); + + Assert.IsTrue(compositeDisposable.Count == 0); + Assert.IsFalse(viewServiceContainer.IsObserving); + Assert.IsTrue(Fake.GetCalls(fakeViewService1).Any(actCall => actCall.Method.Name == $"add_{nameof(IViewService.ViewServiceRequest)}")); + Assert.IsTrue(Fake.GetCalls(fakeViewService1).Any(actCall => actCall.Method.Name == $"remove_{nameof(IViewService.ViewServiceRequest)}")); + Assert.IsTrue(Fake.GetCalls(fakeViewService2).Any(actCall => actCall.Method.Name == $"add_{nameof(IViewService.ViewServiceRequest)}")); + Assert.IsTrue(Fake.GetCalls(fakeViewService2).Any(actCall => actCall.Method.Name == $"remove_{nameof(IViewService.ViewServiceRequest)}")); + } + } +} diff --git a/MessageCommunicator.TestGui/_Util/_View/ViewServiceContainer.cs b/MessageCommunicator.TestGui/_Util/_View/ViewServiceContainer.cs index 3c2adae..33fc1e8 100644 --- a/MessageCommunicator.TestGui/_Util/_View/ViewServiceContainer.cs +++ b/MessageCommunicator.TestGui/_Util/_View/ViewServiceContainer.cs @@ -27,14 +27,16 @@ public ViewServiceContainer(IControl owner) public void StartObserving(CompositeDisposable disposables, OwnViewModelBase? viewModel) { - if (viewModel == null) { return; } if (_observerDisposable != null) { throw new InvalidOperationException("This instance is already registered on the view!"); } _observedViewModel = viewModel; - _observedViewModel.ViewServiceRequest += this.OnViewServiceRequest; + if (_observedViewModel != null) + { + _observedViewModel.ViewServiceRequest += this.OnViewServiceRequest; + } _observerDisposable = new ObserverStopAdapter(this); disposables.Add(_observerDisposable); @@ -61,7 +63,7 @@ private void StopObserving() } } - private object? FindViewService(Type viewServiceType) + public object? FindViewService(Type viewServiceType) { var actParent = (IControl?)this.Owner; object? result = null; @@ -89,17 +91,23 @@ private void OnViewServices_CollectionChanged(object sender, NotifyCollectionCha { if (_observerDisposable == null) { return; } - foreach (IViewService? actNewItem in e.NewItems) + if (e.NewItems != null) { - if(actNewItem == null){ continue; } + foreach (IViewService? actNewItem in e.NewItems) + { + if(actNewItem == null){ continue; } - actNewItem.ViewServiceRequest += this.OnViewServiceRequest; + actNewItem.ViewServiceRequest += this.OnViewServiceRequest; + } } - foreach (IViewService? actOldItem in e.OldItems) + if (e.OldItems != null) { - if(actOldItem == null){ continue; } + foreach (IViewService? actOldItem in e.OldItems) + { + if(actOldItem == null){ continue; } - actOldItem.ViewServiceRequest -= this.OnViewServiceRequest; + actOldItem.ViewServiceRequest -= this.OnViewServiceRequest; + } } } diff --git a/MessageCommunicator.sln b/MessageCommunicator.sln index bf7f4ce..9e73dae 100644 --- a/MessageCommunicator.sln +++ b/MessageCommunicator.sln @@ -43,6 +43,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Nuget", "Nuget", "{C55F0A61 _Misc\Nuget\MessageCommunicator_128.png = _Misc\Nuget\MessageCommunicator_128.png EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessageCommunicator.TestGui.Tests", "MessageCommunicator.TestGui.Tests\MessageCommunicator.TestGui.Tests.csproj", "{890F521E-B731-44C1-9C73-D2E45B5FC2E7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -65,6 +67,10 @@ Global {7B36AA01-E6A4-49BD-9063-DA56DD25DBAD}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B36AA01-E6A4-49BD-9063-DA56DD25DBAD}.Release|Any CPU.ActiveCfg = Release|Any CPU {7B36AA01-E6A4-49BD-9063-DA56DD25DBAD}.Release|Any CPU.Build.0 = Release|Any CPU + {890F521E-B731-44C1-9C73-D2E45B5FC2E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {890F521E-B731-44C1-9C73-D2E45B5FC2E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {890F521E-B731-44C1-9C73-D2E45B5FC2E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {890F521E-B731-44C1-9C73-D2E45B5FC2E7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE