Add tests for CommandAction and EventAction

This commit is contained in:
Antony Male 2014-05-09 13:59:38 +01:00
parent e38ebee6d1
commit a96ec2a6e4
5 changed files with 348 additions and 4 deletions

View File

@ -81,7 +81,7 @@ namespace Stylet.Xaml
{
// If it's Enable or Disable we don't do anything - CanExecute will handle this
if (this.targetNullBehaviour == ActionUnavailableBehaviour.Throw)
throw new Exception(String.Format("Method {0} has a target set which is null", this.MethodName));
throw new ArgumentException(String.Format("Method {0} has a target set which is null", this.MethodName));
}
else
{
@ -144,8 +144,8 @@ namespace Stylet.Xaml
// It's enabled only if both the targetNull and actionNonExistent tests pass
// Throw is handled when the target is set
if (this.target == null && this.targetNullBehaviour == ActionUnavailableBehaviour.Disable)
return false;
if (this.target == null)
return this.targetNullBehaviour != ActionUnavailableBehaviour.Disable;
// Throw is handled when the target is set
if (this.targetMethodInfo == null)

View File

@ -58,6 +58,8 @@ namespace Stylet.Xaml
this.nullTargetBehaviour = nullTargetBehaviour;
this.actionNonExistentBehaviour = actionNonExistentBehaviour;
this.UpdateMethod();
// Observe the View.ActionTarget for changes, and re-bind the guard property and MethodInfo if it changes
DependencyPropertyDescriptor.FromProperty(View.ActionTargetProperty, typeof(View)).AddValueChanged(this.subject, (o, e) => this.UpdateMethod());
}
@ -70,7 +72,7 @@ namespace Stylet.Xaml
if (newTarget == null)
{
if (this.nullTargetBehaviour == ActionUnavailableBehaviour.Throw)
throw new Exception(String.Format("Method {0} has a target set which is null", this.methodName));
throw new ArgumentException(String.Format("Method {0} has a target set which is null", this.methodName));
}
else
{

View File

@ -0,0 +1,205 @@
using NUnit.Framework;
using Stylet;
using Stylet.Xaml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace StyletUnitTests
{
[TestFixture]
public class CommandActionTests
{
private class Target : PropertyChangedBase
{
public bool DoSomethingCalled;
public void DoSomething()
{
this.DoSomethingCalled = true;
}
private bool _canDoSomethingWithGuard;
public bool CanDoSomethingWithGuard
{
get { return this._canDoSomethingWithGuard; }
set { SetAndNotify(ref this._canDoSomethingWithGuard, value); }
}
public void DoSomethingWithGuard()
{
}
public object DoSomethingArgument;
public void DoSomethingWithArgument(object arg)
{
this.DoSomethingArgument = arg;
}
public void DoSomethingWithManyArguments(object arg1, object arg2)
{
}
}
private class Target2
{
}
private DependencyObject subject;
private Target target;
[TestFixtureSetUp]
public void TestFixtureSetUp()
{
Execute.TestExecuteSynchronously = true;
}
[SetUp]
public void SetUp()
{
this.target = new Target();
this.subject = new DependencyObject();
View.SetActionTarget(this.subject, this.target);
}
[Test]
public void ThrowsIfTargetNullBehaviourIsThrowAndTargetBecomesNull()
{
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Disable);
Assert.Throws<ArgumentException>(() => View.SetActionTarget(this.subject, null));
}
[Test]
public void DisablesIfTargetNullBehaviourIsDisableAndTargetIsNull()
{
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Disable, ActionUnavailableBehaviour.Disable);
View.SetActionTarget(this.subject, null);
Assert.False(cmd.CanExecute(null));
}
[Test]
public void EnablesIfTargetNullBehaviourIsEnableAndTargetIsNull()
{
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Disable);
View.SetActionTarget(this.subject, null);
Assert.True(cmd.CanExecute(null));
}
[Test]
public void ThrowsIfActionNonExistentBehaviourIsThrowAndActionIsNonExistent()
{
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
Assert.Throws<ArgumentException>(() => View.SetActionTarget(this.subject, new Target2()));
}
[Test]
public void DisablesIfActionNonExistentBehaviourIsThrowAndActionIsNonExistent()
{
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Disable);
View.SetActionTarget(this.subject, new Target2());
Assert.False(cmd.CanExecute(null));
}
[Test]
public void EnablesIfActionNonExistentBehaviourIsThrowAndActionIsNonExistent()
{
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Enable);
View.SetActionTarget(this.subject, new Target2());
Assert.True(cmd.CanExecute(null));
}
[Test]
public void EnablesIfTargetAndActionExistAndNoGuardMethod()
{
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
Assert.True(cmd.CanExecute(null));
}
[Test]
public void EnablesIfTargetAndActionExistAndGuardMethodReturnsTrue()
{
this.target.CanDoSomethingWithGuard = true;
var cmd = new CommandAction(this.subject, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
Assert.True(cmd.CanExecute(null));
}
[Test]
public void DisablesIfTargetAndActionExistAndGuardMethodReturnsFalse()
{
this.target.CanDoSomethingWithGuard = false;
var cmd = new CommandAction(this.subject, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
Assert.False(cmd.CanExecute(null));
}
[Test]
public void ChangesEnabledStateWhenGuardChanges()
{
this.target.CanDoSomethingWithGuard = false;
var cmd = new CommandAction(this.subject, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
Assert.False(cmd.CanExecute(null));
this.target.CanDoSomethingWithGuard = true;
Assert.True(cmd.CanExecute(null));
}
[Test]
public void RaisesEventWhenGuardValueChanges()
{
this.target.CanDoSomethingWithGuard = false;
var cmd = new CommandAction(this.subject, "DoSomethingWithGuard", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Throw);
bool eventRaised = false;
cmd.CanExecuteChanged += (o, e) => eventRaised = true;
this.target.CanDoSomethingWithGuard = true;
Assert.True(eventRaised);
}
[Test]
public void RaisesEventWhenTargetChanges()
{
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Disable, ActionUnavailableBehaviour.Disable);
bool eventRaised = false;
cmd.CanExecuteChanged += (o, e) => eventRaised = true;
View.SetActionTarget(this.subject, null);
Assert.True(eventRaised);
}
[Test]
public void ExecuteDoesNothingIfTargetIsNull()
{
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
View.SetActionTarget(this.subject, null);
Assert.DoesNotThrow(() => cmd.Execute(null));
}
[Test]
public void ExecuteDoesNothingIfActionIsNull()
{
var cmd = new CommandAction(this.subject, "DoesNotExist", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
View.SetActionTarget(this.subject, null);
Assert.DoesNotThrow(() => cmd.Execute(null));
}
[Test]
public void ExecuteCallsMethod()
{
var cmd = new CommandAction(this.subject, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
cmd.Execute(null);
Assert.True(this.target.DoSomethingCalled);
}
[Test]
public void ExecutePassesArgumentIfGiven()
{
var cmd = new CommandAction(this.subject, "DoSomethingWithArgument", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
var arg = "hello";
cmd.Execute(arg);
Assert.AreEqual("hello", this.target.DoSomethingArgument);
}
[Test]
public void ThrowsIfMethodHasMoreThanOneParameter()
{
Assert.Throws<ArgumentException>(() => new CommandAction(this.subject, "DoSomethingWithManyArguments", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable));
}
}
}

View File

@ -0,0 +1,135 @@
using NUnit.Framework;
using Stylet;
using Stylet.Xaml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace StyletUnitTests
{
[TestFixture, RequiresSTA]
public class EventActionTests
{
private class Target
{
public bool DoSomethingCalled;
public void DoSomething()
{
this.DoSomethingCalled = true;
}
public void DoSomethingWithTooManyArgs(object arg1, object arg2)
{
}
public void DoSomethingWithBadArgument(string arg)
{
}
public RoutedEventArgs EventArgs;
public void DoSomethingWithEventArgs(RoutedEventArgs ea)
{
this.EventArgs = ea;
}
}
private class Target2
{
}
private DependencyObject subject;
private Target target;
private EventInfo eventInfo;
[TestFixtureSetUp]
public void TestFixtureSetUp()
{
Execute.TestExecuteSynchronously = true;
}
[SetUp]
public void SetUp()
{
this.target = new Target();
this.subject = new Button();
this.eventInfo = typeof(Button).GetEvent("Click");
View.SetActionTarget(this.subject, this.target);
}
[Test]
public void ThrowsIfNullTargetBehaviourIsDisable()
{
Assert.Throws<ArgumentException>(() => new EventAction(this.subject, this.eventInfo, "DoSomething", ActionUnavailableBehaviour.Disable, ActionUnavailableBehaviour.Enable));
}
[Test]
public void ThrowsIfNonExistentActionBehaviourIsDisable()
{
Assert.Throws<ArgumentException>(() => new EventAction(this.subject, this.eventInfo, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Disable));
}
[Test]
public void ThrowsIfTargetNullBehaviourIsThrowAndTargetBecomesNull()
{
var cmd = new EventAction(this.subject, this.eventInfo, "DoSomething", ActionUnavailableBehaviour.Throw, ActionUnavailableBehaviour.Enable);
Assert.Throws<ArgumentException>(() => View.SetActionTarget(this.subject, null));
}
[Test]
public void ThrowsIfActionNonExistentBehaviourIsThrowAndActionIsNonExistent()
{
var cmd = new EventAction(this.subject, this.eventInfo, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Throw);
Assert.Throws<ArgumentException>(() => View.SetActionTarget(this.subject, new Target2()));
}
[Test]
public void ThrowsIfMethodHasTooManyArguments()
{
Assert.Throws<ArgumentException>(() => new EventAction(this.subject, this.eventInfo, "DoSomethingWithTooManyArgs", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable));
}
[Test]
public void ThrowsIfMethodHasBadParameter()
{
Assert.Throws<ArgumentException>(() => new EventAction(this.subject, this.eventInfo, "DoSomethingWithBadArgument", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable));
}
[Test]
public void InvokingCommandDoesNothingIfTargetIsNull()
{
var cmd = new EventAction(this.subject, this.eventInfo, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
View.SetActionTarget(this.subject, null);
cmd.GetDelegate().DynamicInvoke(null, null);
}
[Test]
public void InvokingCommandDoesNothingIfActionIsNonExistent()
{
var cmd = new EventAction(this.subject, this.eventInfo, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
View.SetActionTarget(this.subject, new Target2());
cmd.GetDelegate().DynamicInvoke(null, null);
}
[Test]
public void InvokingCommandCallsMethod()
{
var cmd = new EventAction(this.subject, this.eventInfo, "DoSomething", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
cmd.GetDelegate().DynamicInvoke(null, null);
Assert.True(this.target.DoSomethingCalled);
}
[Test]
public void InvokingCommandCallsMethodWithEventArgs()
{
var cmd = new EventAction(this.subject, this.eventInfo, "DoSomethingWithEventArgs", ActionUnavailableBehaviour.Enable, ActionUnavailableBehaviour.Enable);
var arg = new RoutedEventArgs();
cmd.GetDelegate().DynamicInvoke(null, arg);
Assert.AreEqual(arg, this.target.EventArgs);
}
}
}

View File

@ -55,11 +55,13 @@
<Compile Include="AssemblySourceTests.cs" />
<Compile Include="BindableCollectionTests.cs" />
<Compile Include="BoolToVisibilityConverterTests.cs" />
<Compile Include="CommandActionTests.cs" />
<Compile Include="ConductorAllActiveTests.cs" />
<Compile Include="ConductorNavigatingTests.cs" />
<Compile Include="ConductorOneActiveTests.cs" />
<Compile Include="ConductorTests.cs" />
<Compile Include="DebugConverterTests.cs" />
<Compile Include="EventActionTests.cs" />
<Compile Include="EventAggregatorTests.cs" />
<Compile Include="ExecuteTests.cs" />
<Compile Include="ExpressionExtensionsTests.cs" />