Skip to content
This repository has been archived by the owner on Apr 2, 2024. It is now read-only.

Commit

Permalink
Added unit tests, split the independent MVVM code into its own packag…
Browse files Browse the repository at this point in the history
…e and some API changes.
  • Loading branch information
sungaila committed May 20, 2020
1 parent 99f057b commit 7e6a1d2
Show file tree
Hide file tree
Showing 46 changed files with 671 additions and 1,362 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ mono_crash.*
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
Expand Down Expand Up @@ -61,6 +62,9 @@ project.lock.json
project.fragment.lock.json
artifacts/

# ASP.NET Scaffolding
ScaffoldingReadMe.txt

# StyleCop
StyleCopReport.xml

Expand Down Expand Up @@ -350,3 +354,6 @@ MigrationBackup/

# Ionide (cross platform F# VS Code tools) working folder
.ionide/

# Fody - auto-generated XML schema
FodyWeavers.xsd
33 changes: 33 additions & 0 deletions NetCore.Tests/ButtonExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PresentationBase.Extensions;
using System.Windows;
using System.Windows.Controls;

namespace PresentationBase.Tests
{
[TestClass]
public class ButtonExtensionsTests : WpfTestsBase
{
[TestMethod]
public void CommandExecute()
{
App!.Dispatcher.Invoke(() =>
{
App.ShutdownMode = ShutdownMode.OnExplicitShutdown;

var button = new Button();
ButtonExtensions.SetDialogResult(button, true);

CreateInvisibleMainWindow();
App.MainWindow.Content = button;

Assert.IsTrue(App.MainWindow.DialogResult != true);
App.MainWindow.Loaded += (s, e) =>
{
button.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
};
Assert.IsTrue(App.MainWindow.ShowDialog() == true);
});
}
}
}
87 changes: 87 additions & 0 deletions NetCore.Tests/CommandBindingTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Windows.Controls;
using System.Windows.Data;

namespace PresentationBase.Tests
{
[TestClass]
public class CommandBindingTests : WpfTestsBase
{
[TestMethod]
public void CommandExecute()
{
App!.Dispatcher.Invoke(() =>
{
var viewModel = new TestViewModel();
var button = new Button
{
DataContext = viewModel
};

CreateInvisibleMainWindow();
App.MainWindow.Content = button;
App.MainWindow.Show();

Assert.IsTrue(button.IsEnabled);

BindingOperations.SetBinding(button, Button.CommandParameterProperty, new Binding());
BindingOperations.SetBinding(button, Button.CommandProperty, new CommandBinding(typeof(TestCommand)));
Assert.IsNotNull(button.CommandParameter);
Assert.IsNotNull(button.Command);
Assert.IsInstanceOfType(button.Command, typeof(TestCommand));

Assert.IsFalse(button.IsEnabled);
Assert.IsTrue(((TestCommand)button.Command).CanExecuteCalled);
((TestCommand)button.Command).CanExecuteCalled = false;

viewModel.Name = "Adam Jensen";
Assert.IsTrue(button.IsEnabled);
Assert.IsTrue(((TestCommand)button.Command).CanExecuteCalled);

button.Command.Execute(button.CommandParameter);
Assert.IsTrue(((TestCommand)button.Command).ExecuteCalled);

BindingOperations.SetBinding(button, Button.CommandProperty, new CommandBinding(typeof(DummyCommand)));
Assert.IsNull(button.Command);
});
}

class TestViewModel : ViewModel
{
private string? _name;

public string? Name
{
get => _name;
set => SetProperty(ref _name, value);
}
}

class TestCommand : ViewModelCommand<TestViewModel>
{
public bool CanExecuteCalled { get; set; }

public bool ExecuteCalled { get; set; }

public override void Execute(TestViewModel parameter)
{
ExecuteCalled = true;
}

public override bool CanExecute(TestViewModel parameter)
{
CanExecuteCalled = true;
return base.CanExecute(parameter) && parameter.Name != null;
}
}

class DummyCommand : ViewModelCommand<ViewModel>
{
public override void Execute(ViewModel parameter)
{
throw new NotImplementedException();
}
}
}
}
76 changes: 76 additions & 0 deletions NetCore.Tests/CompositeViewModelCollectionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;

namespace PresentationBase.Tests
{
[TestClass]
public class CompositeViewModelCollectionTests
{
[TestMethod]
public void Exceptions()
{
var viewModel = new TestViewModel();

Assert.ThrowsException<ArgumentNullException>(() => viewModel.Composition.Add(null!));
Assert.ThrowsException<ArgumentNullException>(() => viewModel.Composition.Contains(null!));
Assert.ThrowsException<ArgumentNullException>(() => viewModel.Composition.IndexOf(null!));
Assert.ThrowsException<ArgumentNullException>(() => viewModel.Composition.Insert(0, null!));
Assert.ThrowsException<ArgumentNullException>(() => viewModel.Composition.Remove(null!));
}

[TestMethod]
public void CollectionManipulation()
{
var viewModel = new TestViewModel();
Assert.IsNotNull(viewModel.Composition);
Assert.AreEqual(2, viewModel.Composition.Count);
Assert.AreSame(viewModel.Children, viewModel.Composition[0]);
Assert.AreSame(viewModel.Dummies, viewModel.Composition[1]);

foreach (var collection in viewModel.Composition)
{
Assert.IsNotNull(collection);
Assert.AreEqual(0, collection.Count());
}

viewModel.Children!.AddRange(new[] { new TestViewModel(), new TestViewModel(), new TestViewModel() });
Assert.AreEqual(2, viewModel.Composition.Count);
Assert.AreEqual(3, viewModel.Composition[0].Count());
viewModel.Children.Clear();
Assert.AreEqual(0, viewModel.Composition[0].Count());

viewModel.Dummies!.AddRange(new[] { new DummyViewModel() });
Assert.AreEqual(2, viewModel.Composition.Count);
Assert.AreEqual(1, viewModel.Composition[1].Count());
viewModel.Dummies.Clear();
Assert.AreEqual(0, viewModel.Composition[1].Count());

viewModel.Composition.Remove(viewModel.Children);
Assert.AreEqual(1, viewModel.Composition.Count);
Assert.AreSame(viewModel.Dummies, viewModel.Composition[0]);

viewModel.Composition.Clear();
Assert.AreEqual(0, viewModel.Composition.Count);
}

class TestViewModel : ViewModel
{
public ObservableViewModelCollection<TestViewModel>? Children { get; set; }

public ObservableViewModelCollection<DummyViewModel>? Dummies { get; set; }

public CompositeViewModelCollection<ViewModel> Composition { get; set; } = new CompositeViewModelCollection<ViewModel>();

public TestViewModel()
{
Children = new ObservableViewModelCollection<TestViewModel>(this);
Dummies = new ObservableViewModelCollection<DummyViewModel>(this);
Composition.Add(Children);
Composition.Add(Dummies);
}
}

class DummyViewModel : ViewModel { }
}
}
29 changes: 29 additions & 0 deletions NetCore.Tests/Converters/AllBoolToVisibilityConverterTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PresentationBase.Converters;
using System.Windows;

namespace PresentationBase.Tests.Converters
{
[TestClass]
public class AllBoolToVisibilityConverterTests
: ConverterTestsBase<AllBoolToVisibilityConverter>
{
[TestMethod]
public override void Convert()
{
var result1 = _converter!.Convert(new object[] { true, true }, null, null, null);
Assert.IsNotNull(result1);
Assert.IsInstanceOfType(result1, typeof(Visibility));
Assert.AreEqual(Visibility.Visible, result1);

var result2 = _converter!.Convert(new object[] { true, false }, null, null, null);
Assert.IsNotNull(result2);
Assert.IsInstanceOfType(result2, typeof(Visibility));
Assert.AreEqual(Visibility.Collapsed, result2);

var result3 = _converter!.Convert(null, null, null, null);
Assert.IsNotNull(result3);
Assert.AreEqual(DependencyProperty.UnsetValue, result3);
}
}
}
60 changes: 60 additions & 0 deletions NetCore.Tests/Converters/BoolToVisibilityConverterTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PresentationBase.Converters;
using System.Windows;

namespace PresentationBase.Tests.Converters
{
[TestClass]
public class BoolToVisibilityConverterTests
: ConverterTestsBase<BoolToVisibilityConverter>
{
[TestMethod]
public override void Convert()
{
var result1 = _converter!.Convert(true, null, null, null);
Assert.IsNotNull(result1);
Assert.IsInstanceOfType(result1, typeof(Visibility));
Assert.AreEqual(Visibility.Visible, result1);

var result2 = _converter!.Convert(false, null, null, null);
Assert.IsNotNull(result2);
Assert.IsInstanceOfType(result2, typeof(Visibility));
Assert.AreEqual(Visibility.Collapsed, result2);

var result3 = _converter!.Convert(null, null, null, null);
Assert.IsNotNull(result3);
Assert.AreEqual(DependencyProperty.UnsetValue, result3);

var result4 = _converter!.Convert("Trash", null, null, null);
Assert.IsNotNull(result4);
Assert.AreEqual(DependencyProperty.UnsetValue, result4);
}

[TestMethod]
public override void ConvertBack()
{
var result1 = _converter!.ConvertBack(Visibility.Visible, null, null, null);
Assert.IsNotNull(result1);
Assert.IsInstanceOfType(result1, typeof(bool));
Assert.AreEqual(true, result1);

var result2 = _converter!.ConvertBack(Visibility.Collapsed, null, null, null);
Assert.IsNotNull(result2);
Assert.IsInstanceOfType(result2, typeof(bool));
Assert.AreEqual(false, result2);

var result3 = _converter!.ConvertBack(Visibility.Hidden, null, null, null);
Assert.IsNotNull(result3);
Assert.IsInstanceOfType(result3, typeof(bool));
Assert.AreEqual(false, result3);

var result4 = _converter!.ConvertBack(null, null, null, null);
Assert.IsNotNull(result4);
Assert.AreEqual(DependencyProperty.UnsetValue, result4);

var result5 = _converter!.ConvertBack("Trash", null, null, null);
Assert.IsNotNull(result5);
Assert.AreEqual(DependencyProperty.UnsetValue, result5);
}
}
}
43 changes: 43 additions & 0 deletions NetCore.Tests/Converters/ConverterTestsBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PresentationBase.Converters;
using System.Reflection;
using System.Windows.Data;
using System.Windows.Markup;

namespace PresentationBase.Tests.Converters
{
public abstract class ConverterTestsBase<TConverter>
where TConverter : class, IConverter, new()
{
protected TConverter? _converter = null;

[TestInitialize]
public void Initialize()
{
_converter = new TConverter();
}

[TestMethod]
public void ProvideValue()
{
var result = _converter!.ProvideValue(null!);
Assert.IsNotNull(result);
Assert.IsInstanceOfType(result, typeof(TConverter));
}

[TestMethod]
public void Attributes()
{
var valueConversionAttr = _converter!.GetType().GetCustomAttribute<ValueConversionAttribute>(false);
Assert.IsNotNull(valueConversionAttr);

var returnTypeAttr = _converter!.GetType().GetCustomAttribute<MarkupExtensionReturnTypeAttribute>(false);
Assert.IsNotNull(returnTypeAttr);
Assert.AreEqual(typeof(TConverter), returnTypeAttr!.ReturnType);
}

public abstract void Convert();

public virtual void ConvertBack() { }
}
}
34 changes: 34 additions & 0 deletions NetCore.Tests/NetCore.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- Assembly -->
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>PresentationBase.Tests</AssemblyName>
<RootNamespace>PresentationBase.Tests</RootNamespace>
<IsPackable>false</IsPackable>
</PropertyGroup>

<!-- C# compiler -->
<PropertyGroup>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
<Features>strict</Features>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

<!-- Project references -->
<ItemGroup>
<ProjectReference Include="..\NetCore\NetCore.csproj" />
</ItemGroup>

<!-- NuGet Icon -->
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
<PackageReference Include="coverlet.collector" Version="1.2.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

</Project>
Loading

0 comments on commit 7e6a1d2

Please sign in to comment.