Add more conductor tests, and tests for Execute, PropertyChangedBase

This commit is contained in:
Antony Male 2014-03-25 13:20:31 +00:00
parent fc156247b0
commit 31c9844c47
7 changed files with 343 additions and 2 deletions

View File

@ -142,6 +142,8 @@ namespace Stylet
{
foreach (var item in this.items.OfType<IDeactivate>())
item.Deactivate(true);
this.items.Clear();
}
else
{

View File

@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace Stylet
{
public class PropertyChangedBase : INotifyPropertyChanged, INotifyPropertyChangedDispatcher
public abstract class PropertyChangedBase : INotifyPropertyChanged, INotifyPropertyChangedDispatcher
{
private Action<Action> _propertyChangedDispatcher = Execute.DefaultPropertyChangedDispatcher;
/// <summary>

View File

@ -86,7 +86,7 @@ namespace Stylet
void IDeactivate.Deactivate(bool close)
{
if (!this.IsActive)
if (!this.IsActive && !close)
return;
this.IsActive = false;

View File

@ -90,5 +90,126 @@ namespace StyletUnitTests
Assert.AreEqual(screen2.Object, this.conductor.ActiveItem);
Assert.AreEqual(new[] { screen1.Object, screen2.Object }, this.conductor.Items);
}
[Test]
public void ActivateItemDoesNotActivateIfConductorIsNotActive()
{
var screen = new Mock<IScreen>();
this.conductor.ActivateItem(screen.Object);
screen.Verify(x => x.Activate(), Times.Never);
}
[Test]
public void ActivateItemDoesActiveIfConductorIsActive()
{
var screen = new Mock<IScreen>();
((IActivate)this.conductor).Activate();
this.conductor.ActivateItem(screen.Object);
screen.Verify(x => x.Activate());
}
[Test]
public void DeactiveDeactivatesItems()
{
var screen = new Mock<IScreen>();
((IActivate)this.conductor).Activate();
this.conductor.ActivateItem(screen.Object);
((IDeactivate)this.conductor).Deactivate(false);
screen.Verify(x => x.Deactivate(false));
}
[Test]
public void ClosingClosesAllItems()
{
var screen = new Mock<IScreen>();
((IActivate)this.conductor).Activate();
this.conductor.ActivateItem(screen.Object);
((IDeactivate)this.conductor).Deactivate(true);
screen.Verify(x => x.Deactivate(true));
Assert.AreEqual(0, this.conductor.Items.Count);
}
[Test]
public void ConductorCanCloseIfAllItemsCanClose()
{
var screen1 = new Mock<IScreen>();
var screen2 = new Mock<IScreen>();
screen1.Setup(x => x.CanCloseAsync()).Returns(Task.FromResult(true));
screen2.Setup(x => x.CanCloseAsync()).Returns(Task.FromResult(true));
this.conductor.Items.AddRange(new[] { screen1.Object, screen2.Object });
Assert.IsTrue(this.conductor.CanCloseAsync().Result);
}
[Test]
public void ConductorCanNotCloseIfAnyItemCanNotClose()
{
var screen1 = new Mock<IScreen>();
var screen2 = new Mock<IScreen>();
screen1.Setup(x => x.CanCloseAsync()).Returns(Task.FromResult(true));
screen2.Setup(x => x.CanCloseAsync()).Returns(Task.FromResult(false));
this.conductor.Items.AddRange(new[] { screen1.Object, screen2.Object });
Assert.IsFalse(this.conductor.CanCloseAsync().Result);
}
[Test]
public void AddingItemSetsParent()
{
var screen = new Mock<IScreen>();
this.conductor.Items.Add(screen.Object);
screen.VerifySet(x => x.Parent = this.conductor);
}
[Test]
public void RemovingItemRemovesParent()
{
var screen = new Mock<IScreen>();
this.conductor.Items.Add(screen.Object);
this.conductor.Items.Remove(screen.Object);
screen.VerifySet(x => x.Parent = null);
}
[Test]
public void AddingItemTwiceDoesNotResultInDuplicates()
{
var screen = new Mock<IScreen>();
this.conductor.ActivateItem(screen.Object);
this.conductor.ActivateItem(screen.Object);
Assert.AreEqual(1, this.conductor.Items.Count);
}
[Test]
public void DeactivateItemDeactivatesItemButDoesNotRemoveFromItems()
{
var screen = new Mock<IScreen>();
this.conductor.ActivateItem(screen.Object);
this.conductor.DeactivateItem(screen.Object, false);
screen.Verify(x => x.Deactivate(false));
Assert.That(this.conductor.Items, Is.EquivalentTo(new[] { screen.Object }));
}
[Test]
public void CloseItemDoesNothingIfItemCanNotClose()
{
var screen = new Mock<IScreen>();
this.conductor.ActivateItem(screen.Object);
this.conductor.DeactivateItem(screen.Object, true);
screen.Verify(x => x.Deactivate(true), Times.Never);
Assert.That(this.conductor.Items, Is.EquivalentTo(new[] { screen.Object }));
}
[Test]
public void CloseItemDeactivatesItemAndRemovesFromItemsIfItemCanClose()
{
var screen = new Mock<IScreen>();
screen.Setup(x => x.CanCloseAsync()).Returns(Task.FromResult(true));
this.conductor.ActivateItem(screen.Object);
this.conductor.DeactivateItem(screen.Object, true);
screen.Verify(x => x.Deactivate(true));
Assert.AreEqual(0, this.conductor.Items.Count);
}
}
}

View File

@ -0,0 +1,87 @@
using Moq;
using NUnit.Framework;
using Stylet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StyletUnitTests
{
[TestFixture]
public class ExecuteTests
{
[Test]
public void OnUIThreadExecutesSynchronouslyIfNoSynchronizationContext()
{
Execute.SynchronizationContext = null;
bool blockWasRun = false;
Execute.OnUIThread(() => blockWasRun = true);
Assert.IsTrue(blockWasRun);
}
[Test]
public void OnUIThreadExecutesAsynchronouslyIfSynchronizationContextIsNotNull()
{
var sync = new Mock<SynchronizationContext>();
Execute.SynchronizationContext = sync.Object;
SendOrPostCallback passedAction = null;
sync.Setup(x => x.Post(It.IsAny<SendOrPostCallback>(), null)).Callback((SendOrPostCallback a, object o) => passedAction = a);
bool actionCalled = false;
Execute.OnUIThread(() => actionCalled = true);
Assert.IsFalse(actionCalled);
passedAction(null);
Assert.IsTrue(actionCalled);
}
[Test]
public async Task OnUIThreadAsyncExecutesSynchronouslyIfNoSynchronizationContext()
{
Execute.SynchronizationContext = null;
bool blockWasRun = false;
await Execute.OnUIThreadAsync(() => blockWasRun = true);
Assert.IsTrue(blockWasRun);
}
[Test]
public void OnUIThreadAsyncExecutesAsynchronouslyIfSynchronizationContextIsNotNull()
{
var sync = new Mock<SynchronizationContext>();
Execute.SynchronizationContext = sync.Object;
SendOrPostCallback passedAction = null;
sync.Setup(x => x.Post(It.IsAny<SendOrPostCallback>(), null)).Callback((SendOrPostCallback a, object o) => passedAction = a);
bool actionCalled = false;
var task = Execute.OnUIThreadAsync(() => actionCalled = true);
Assert.IsFalse(task.IsCompleted);
Assert.IsFalse(actionCalled);
passedAction(null);
Assert.IsTrue(actionCalled);
Assert.IsTrue(task.IsCompleted);
}
[Test]
public void OnUIThreadAsyncPropagatesException()
{
var sync = new Mock<SynchronizationContext>();
Execute.SynchronizationContext = sync.Object;
SendOrPostCallback passedAction = null;
sync.Setup(x => x.Post(It.IsAny<SendOrPostCallback>(), null)).Callback((SendOrPostCallback a, object o) => passedAction = a);
var ex = new Exception("test");
var task = Execute.OnUIThreadAsync(() => { throw ex; });
passedAction(null);
Assert.IsTrue(task.IsFaulted);
Assert.AreEqual(ex, task.Exception.InnerExceptions[0]);
}
}
}

View File

@ -0,0 +1,129 @@
using NUnit.Framework;
using Stylet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StyletUnitTests
{
[TestFixture]
public class PropertyChangedBaseTests
{
class PropertyChanged : PropertyChangedBase
{
public int IntProperty { get; set; }
public string StringProperty
{
set { this.NotifyOfPropertyChange(); }
}
private double _doubleProperty;
public double DoubleProperty
{
get { return this._doubleProperty; }
set { SetAndNotify(ref this._doubleProperty, value); }
}
public void RaiseIntPropertyChangedWithExpression()
{
this.NotifyOfPropertyChange(() => this.IntProperty);
}
public void RaiseIntPropertyChangedWithString()
{
this.NotifyOfPropertyChange("IntProperty");
}
}
[Test]
public void RefreshRaisesPropertyChangedWithEmptyString()
{
var pc = new PropertyChanged();
string changedProperty = null;
pc.PropertyChanged += (o, e) => changedProperty = e.PropertyName;
pc.Refresh();
Assert.AreEqual(String.Empty, changedProperty);
}
[Test]
public void NotifyOfPropertyChangedWithExpressionRaises()
{
var pc = new PropertyChanged();
string changedProperty = null;
pc.PropertyChanged += (o, e) => changedProperty = e.PropertyName;
pc.RaiseIntPropertyChangedWithExpression();
Assert.AreEqual("IntProperty", changedProperty);
}
[Test]
public void NotifyOfPropertyChangedWithStringRaises()
{
var pc = new PropertyChanged();
string changedProperty = null;
pc.PropertyChanged += (o, e) => changedProperty = e.PropertyName;
pc.RaiseIntPropertyChangedWithString();
Assert.AreEqual("IntProperty", changedProperty);
}
[Test]
public void NotifyOfPropertyChangedWithCallerMemberName()
{
var pc = new PropertyChanged();
string changedProperty = null;
pc.PropertyChanged += (o, e) => changedProperty = e.PropertyName;
pc.StringProperty = "hello";
Assert.AreEqual("StringProperty", changedProperty);
}
[Test]
public void UsesDispatcher()
{
var pc = new PropertyChanged();
string changedProperty = null;
pc.PropertyChanged += (o, e) => changedProperty = e.PropertyName;
Action action = null;
pc.PropertyChangedDispatcher = a => action = a;
pc.RaiseIntPropertyChangedWithExpression();
Assert.IsNull(changedProperty);
Assert.IsNotNull(action);
action();
Assert.AreEqual("IntProperty", changedProperty);
}
[Test]
public void UsesExecutesDispatcherByDefault()
{
Action action = null;
var oldDispatcher = Execute.DefaultPropertyChangedDispatcher;
Execute.DefaultPropertyChangedDispatcher = a => action = a;
var pc = new PropertyChanged();
string changedProperty = null;
pc.PropertyChanged += (o, e) => changedProperty = e.PropertyName;
pc.RaiseIntPropertyChangedWithExpression();
Assert.IsNull(changedProperty);
Assert.IsNotNull(action);
action();
Assert.AreEqual("IntProperty", changedProperty);
Execute.DefaultPropertyChangedDispatcher = oldDispatcher;
}
[Test]
public void SetAndNotifyWorks()
{
var pc = new PropertyChanged();
string changedProperty = null;
pc.PropertyChanged += (o, e) => changedProperty = e.PropertyName;
pc.DoubleProperty = 5;
Assert.AreEqual("DoubleProperty", changedProperty);
Assert.AreEqual(5, pc.DoubleProperty);
}
}
}

View File

@ -57,7 +57,9 @@
<Compile Include="ConductorOneActiveTests.cs" />
<Compile Include="ConductorTests.cs" />
<Compile Include="EventAggregatorTests.cs" />
<Compile Include="ExecuteTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PropertyChangedBaseTests.cs" />
<Compile Include="PropertyChangedExtensionsTests.cs" />
<Compile Include="StyletIoC\StyletIoCAutobindingTests.cs" />
<Compile Include="StyletIoC\StyletIoCBindingChecksTests.cs" />