Add more unit tests

This commit is contained in:
Antony Male 2014-05-07 13:20:36 +01:00
parent d648b264d1
commit 43fe090fa9
10 changed files with 510 additions and 15 deletions

View File

@ -46,7 +46,7 @@ end
desc "Generate code coverage reports for CONFIG (or Debug)"
task :cover => [:build, COVERAGE_DIR] do |t|
sh OPENCOVER_CONSOLE, %Q{-register:user -target:"#{NUNIT_CONSOLE}" -filter:+[Stylet]* -targetargs:"#{UNIT_TESTS_DLL} /noshadow" -output:"#{COVERAGE_FILE}"}
sh REPORT_GENERATOR, %Q{"-reports:#{COVERAGE_FILE}" "-targetdir:#{COVERAGE_DIR}"}
sh REPORT_GENERATOR, %Q{-reports:"#{COVERAGE_FILE}" "-targetdir:#{COVERAGE_DIR}"}
rm 'TestResult.xml'
end

View File

@ -55,6 +55,7 @@ namespace Stylet
this.ConfigureResources();
this.Configure();
View.ViewManager = IoC.Get<IViewManager>();
IoC.Get<IWindowManager>().ShowWindow(IoC.Get<TRootViewModel>());
}

View File

@ -12,14 +12,7 @@ namespace Stylet
public class View : DependencyObject
{
private static readonly ContentPropertyAttribute defaultContentProperty = new ContentPropertyAttribute("Content");
private static IViewManager viewManager;
static View()
{
// Don't complain that IoC is not initialized if we're in design mode
if (!Execute.InDesignMode)
viewManager = IoC.Get<IViewManager>();
}
public static IViewManager ViewManager;
public static object GetActionTarget(DependencyObject obj)
{
@ -45,7 +38,7 @@ namespace Stylet
}
public static readonly DependencyProperty ModelProperty =
DependencyProperty.RegisterAttached("Model", typeof(object), typeof(View), new PropertyMetadata(null, (d, e) => viewManager.OnModelChanged(d, e) ));
DependencyProperty.RegisterAttached("Model", typeof(object), typeof(View), new PropertyMetadata(null, (d, e) => ViewManager.OnModelChanged(d, e) ));
public static void SetContentProperty(DependencyObject targetLocation, UIElement view)

View File

@ -63,7 +63,7 @@ namespace Stylet
}
}
public virtual Type LocalViewForModel(Type modelType)
public virtual Type LocateViewForModel(Type modelType)
{
var viewName = Regex.Replace(modelType.FullName, @"ViewModel", "View");
// TODO: This might need some more thinking
@ -77,7 +77,7 @@ namespace Stylet
public virtual UIElement CreateViewForModel(object model)
{
var viewType = this.LocalViewForModel(model.GetType());
var viewType = this.LocateViewForModel(model.GetType());
if (viewType.IsInterface || viewType.IsAbstract || !typeof(UIElement).IsAssignableFrom(viewType))
throw new Exception(String.Format("Found type for view: {0}, but it wasn't a class derived from UIElement", viewType.Name));

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
@ -37,10 +38,11 @@ namespace Stylet
internal void PropertyChangedHandler(object sender, PropertyChangedEventArgs e)
{
TSource source;
if (this.source.TryGetTarget(out source))
var got = this.source.TryGetTarget(out source);
// We should never hit this case. The PropertyChangedeventManager shouldn't call us if the source became null
Debug.Assert(got);
if (got)
this.handler(this.valueSelector(source));
else
this.remover(this);
}
public void Unbind()

View File

@ -0,0 +1,97 @@
using NUnit.Framework;
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 BoolToVisibilityConverterTests
{
private BoolToVisibilityConverter converter;
[SetUp]
public void SetUp()
{
this.converter = new BoolToVisibilityConverter();
}
[Test]
public void InstanceReturnsSingleton()
{
Assert.IsNotNull(BoolToVisibilityConverter.Instance);
Assert.AreEqual(BoolToVisibilityConverter.Instance, BoolToVisibilityConverter.Instance);
}
[Test]
public void ConvertReturnsNullIfValueNotBool()
{
var result = this.converter.Convert(new object(), null, null, null);
Assert.Null(result);
}
[Test]
public void ConvertReturnsVisibleForTrueByDefault()
{
var result = this.converter.Convert(true, null, null, null);
Assert.AreEqual(Visibility.Visible, result);
}
[Test]
public void ConvertReturnsSetTrueVisibility()
{
this.converter.TrueVisibility = Visibility.Hidden;
var result = this.converter.Convert(true, null, null, null);
Assert.AreEqual(Visibility.Hidden, result);
}
[Test]
public void ConvertReturnsCollapsedForFalseByDefault()
{
var result = this.converter.Convert(false, null, null, null);
Assert.AreEqual(Visibility.Collapsed, result);
}
[Test]
public void ConvertReturnsSetFalseVisibility()
{
this.converter.FalseVisibility = Visibility.Visible;
var result = this.converter.Convert(false, null, null, null);
Assert.AreEqual(Visibility.Visible, result);
}
[Test]
public void ConvertBackReturnsTrueIfValueIsTrueVisibility()
{
this.converter.TrueVisibility = Visibility.Hidden;
var result = this.converter.ConvertBack(Visibility.Hidden, null, null, null);
Assert.AreEqual(true, result);
}
[Test]
public void ConvertBackReturnsFalseIfValueIsFalseVisibility()
{
this.converter.FalseVisibility = Visibility.Hidden;
var result = this.converter.ConvertBack(Visibility.Hidden, null, null, null);
Assert.AreEqual(false, result);
}
[Test]
public void ConvertBackReturnsNullIfValueIsNotAVisibility()
{
var result = this.converter.ConvertBack(new object(), null, null, null);
Assert.Null(result);
}
[Test]
public void ConvertBackReturnsNullIfValueIsNotAConfiguredVisibility()
{
var result = this.converter.ConvertBack(Visibility.Hidden, null, null, null);
Assert.Null(result);
}
}
}

View File

@ -0,0 +1,109 @@
using Moq;
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 ScreenExtensionTests
{
private Screen parent;
private Mock<IScreen> child;
[SetUp]
public void SetUp()
{
this.parent = new Screen();
this.child = new Mock<IScreen>();
}
[Test]
public void TryActivateActivatesIActivate()
{
var screen = new Mock<IActivate>();
ScreenExtensions.TryActivate(screen.Object);
screen.Verify(x => x.Activate());
}
[Test]
public void TryActivateDoesNothingToNonIActivate()
{
var screen = new Mock<IDeactivate>(MockBehavior.Strict);
ScreenExtensions.TryActivate(screen.Object);
}
[Test]
public void TryDeactivateDeactivatesIDeactivate()
{
var screen = new Mock<IDeactivate>();
ScreenExtensions.TryDeactivate(screen.Object);
screen.Verify(x => x.Deactivate());
}
[Test]
public void TryDeactivateDoesNothingToNonIDeactivate()
{
var screen = new Mock<IActivate>(MockBehavior.Strict);
ScreenExtensions.TryDeactivate(screen.Object);
}
[Test]
public void TryCloseClosesIClose()
{
var screen = new Mock<IClose>();
ScreenExtensions.TryClose(screen.Object);
screen.Verify(x => x.Close());
}
[Test]
public void TryCloseDoesNothingToNonIClose()
{
var screen = new Mock<IActivate>(MockBehavior.Strict);
ScreenExtensions.TryClose(screen.Object);
}
[Test]
public void ConductWithActivates()
{
this.child.Object.ConductWith(this.parent);
((IActivate)this.parent).Activate();
this.child.Verify(x => x.Activate());
}
[Test]
public void ConductWithDeactivates()
{
// Needs to be active....
((IActivate)this.parent).Activate();
this.child.Object.ConductWith(this.parent);
((IDeactivate)this.parent).Deactivate();
this.child.Verify(x => x.Deactivate());
}
[Test]
public void ConductWithCloses()
{
this.child.Object.ConductWith(this.parent);
((IClose)this.parent).Close();
this.child.Verify(x => x.Close());
}
[Test]
public void ConductWithDoesNotRetain()
{
var child = new Screen();
child.ConductWith(this.parent);
var weakChild = new WeakReference(child);
child = null;
GC.Collect();
Assert.Null(weakChild.Target);
}
}
}

View File

@ -54,6 +54,7 @@
<Compile Include="ActionExtensionTests.cs" />
<Compile Include="AssemblySourceTests.cs" />
<Compile Include="BindableCollectionTests.cs" />
<Compile Include="BoolToVisibilityConverterTests.cs" />
<Compile Include="ConductorAllActiveTests.cs" />
<Compile Include="ConductorNavigatingTests.cs" />
<Compile Include="ConductorOneActiveTests.cs" />
@ -67,6 +68,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PropertyChangedBaseTests.cs" />
<Compile Include="PropertyChangedExtensionsTests.cs" />
<Compile Include="ScreenExtensionTests.cs" />
<Compile Include="ScreenTests.cs" />
<Compile Include="StyletIoC\StyletIoCAutobindingTests.cs" />
<Compile Include="StyletIoC\StyletIoCBindingChecksTests.cs" />
@ -77,6 +79,8 @@
<Compile Include="StyletIoC\StyletIoCGetSingleKeyedTests.cs" />
<Compile Include="StyletIoC\StyletIoCGetSingleTests.cs" />
<Compile Include="StyletIoC\StyletIoCUnboundGenericTests.cs" />
<Compile Include="ViewManagerTests.cs" />
<Compile Include="ViewTests.cs" />
<Compile Include="WindowManagerTests.cs" />
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,219 @@
using Moq;
using NUnit.Framework;
using Stylet;
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
{
public class ViewManagerTestsViewModel
{
}
public class ViewManagerTestsView
{
}
[TestFixture, RequiresSTA]
public class ViewManagerTests
{
private interface I1 { }
private abstract class AC1 { }
private class C1 { }
private class CreatingAndBindingViewManager : ViewManager
{
public UIElement View;
public object RequestedModel;
public override UIElement CreateViewForModel(object model)
{
this.RequestedModel = model;
return this.View;
}
public UIElement BindViewToModelView;
public object BindViewtoModelViewModel;
public override void BindViewToModel(UIElement view, object viewModel)
{
this.BindViewToModelView = view;
this.BindViewtoModelViewModel = viewModel;
}
}
private class LocatingViewManager : ViewManager
{
public Type LocatedViewType;
public override Type LocateViewForModel(Type modelType)
{
return this.LocatedViewType;
}
}
private class TestView : UIElement
{
public bool InitializeComponentCalled;
public void InitializeComponent()
{
this.InitializeComponentCalled = true;
}
}
private ViewManager viewManager;
[SetUp]
public void SetUp()
{
this.viewManager = new ViewManager();
}
[Test]
public void OnModelChangedDoesNothingIfNoChange()
{
var val = new object();
this.viewManager.OnModelChanged(null, new DependencyPropertyChangedEventArgs(View.ModelProperty, val, val));
}
[Test]
public void OnModelChangedSetsNullIfNewValueNull()
{
var target = new ContentControl();
this.viewManager.OnModelChanged(target, new DependencyPropertyChangedEventArgs(View.ModelProperty, 5, null));
Assert.Null(target.Content);
}
[Test]
public void OnModelChangedUsesViewIfAlreadySet()
{
var target = new ContentControl();
var model = new Mock<IScreen>();
var view = new UIElement();
model.Setup(x => x.View).Returns(view);
this.viewManager.OnModelChanged(target, new DependencyPropertyChangedEventArgs(View.ModelProperty, null, model.Object));
Assert.AreEqual(view, target.Content);
}
[Test]
public void OnModelChangedCreatesAndBindsView()
{
var target = new ContentControl();
var model = new object();
var view = new UIElement();
var viewManager = new CreatingAndBindingViewManager();
viewManager.View = view;
viewManager.OnModelChanged(target, new DependencyPropertyChangedEventArgs(View.ModelProperty, null, model));
Assert.AreEqual(viewManager.RequestedModel, model);
Assert.AreEqual(viewManager.BindViewToModelView, view);
Assert.AreEqual(viewManager.BindViewtoModelViewModel, model);
Assert.AreEqual(view, target.Content);
}
[Test]
public void LocateViewforModelThrowsIfViewNotFound()
{
Assert.Throws<Exception>(() => this.viewManager.LocateViewForModel(typeof(C1)));
}
[Test]
public void LocateViewforModelFindsViewForModel()
{
Execute.TestExecuteSynchronously = true;
AssemblySource.Assemblies.Add(Assembly.GetExecutingAssembly());
var viewType = this.viewManager.LocateViewForModel(typeof(ViewManagerTestsViewModel));
Assert.AreEqual(typeof(ViewManagerTestsView), viewType);
}
[Test]
public void CreateViewForModelThrowsIfViewIsNotConcreteUIElement()
{
var viewManager = new LocatingViewManager();
viewManager.LocatedViewType = typeof(I1);
Assert.Throws<Exception>(() => viewManager.CreateViewForModel(new object()));
viewManager.LocatedViewType = typeof(AC1);
Assert.Throws<Exception>(() => viewManager.CreateViewForModel(new object()));
viewManager.LocatedViewType = typeof(C1);
Assert.Throws<Exception>(() => viewManager.CreateViewForModel(new object()));
}
[Test]
public void CreateViewForModelCallsFetchesViewAndCallsInitializeComponent()
{
var view = new TestView();
IoC.GetInstance = (t, k) =>
{
Assert.AreEqual(typeof(TestView), t);
Assert.Null(k);
return view;
};
var viewManager = new LocatingViewManager();
viewManager.LocatedViewType = typeof(TestView);
var returnedView = viewManager.CreateViewForModel(new object());
Assert.True(view.InitializeComponentCalled);
Assert.AreEqual(view, returnedView);
}
[Test]
public void CreateViewForModelDoesNotComplainIfNoInitializeComponentMethod()
{
var view = new UIElement();
IoC.GetInstance = (t, k) =>
{
Assert.AreEqual(typeof(UIElement), t);
Assert.Null(k);
return view;
};
var viewManager = new LocatingViewManager();
viewManager.LocatedViewType = typeof(UIElement);
var returnedView = viewManager.CreateViewForModel(new object());
Assert.AreEqual(view, returnedView);
}
[Test]
public void BindViewToModelSetsActionTarget()
{
var view = new UIElement();
var model = new object();
this.viewManager.BindViewToModel(view, model);
Assert.AreEqual(model, View.GetActionTarget(view));
}
[Test]
public void BindViewToModelSetsDataContext()
{
var view = new FrameworkElement();
var model = new object();
this.viewManager.BindViewToModel(view, model);
Assert.AreEqual(model, view.DataContext);
}
[Test]
public void BindViewToModelAttachesView()
{
var view = new UIElement();
var model = new Mock<IViewAware>();
this.viewManager.BindViewToModel(view, model.Object);
model.Verify(x => x.AttachView(view));
}
}
}

View File

@ -0,0 +1,70 @@
using Moq;
using NUnit.Framework;
using Stylet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace StyletUnitTests
{
[TestFixture, RequiresSTA]
public class ViewTests
{
private Mock<IViewManager> viewManager;
[SetUp]
public void SetUp()
{
this.viewManager = new Mock<IViewManager>();
View.ViewManager = this.viewManager.Object;
}
[Test]
public void ActionTargetStores()
{
var obj = new DependencyObject();
View.SetActionTarget(obj, 5);
Assert.AreEqual(5, View.GetActionTarget(obj));
}
[Test]
public void ModelStores()
{
var obj = new DependencyObject();
View.SetModel(obj, 5);
Assert.AreEqual(5, View.GetModel(obj));
}
[Test]
public void ChangingModelCallsOnModelChanged()
{
var obj = new DependencyObject();
var model = new object();
View.SetModel(obj, null);
DependencyPropertyChangedEventArgs ea = default(DependencyPropertyChangedEventArgs);
this.viewManager.Setup(x => x.OnModelChanged(obj, It.IsAny<DependencyPropertyChangedEventArgs>()))
.Callback<DependencyObject, DependencyPropertyChangedEventArgs>((d, e) => ea = e).Verifiable();
View.SetModel(obj, model);
this.viewManager.Verify();
Assert.Null(ea.OldValue);
Assert.AreEqual(model, ea.NewValue);
Assert.AreEqual(View.ModelProperty, ea.Property);
}
[Test]
public void SetsContentControlContentProperty()
{
var obj = new ContentControl();
var view = new UIElement();
View.SetContentProperty(obj, view);
Assert.AreEqual(obj.Content, view);
}
}
}