diff --git a/.gitignore b/.gitignore index 61069dc..662e4a0 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ mono_crash.* [Rr]eleases/ x64/ x86/ +[Ww][Ii][Nn]32/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ bld/ @@ -61,6 +62,9 @@ project.lock.json project.fragment.lock.json artifacts/ +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + # StyleCop StyleCopReport.xml @@ -350,3 +354,6 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/NetCore.Tests/ButtonExtensionsTests.cs b/NetCore.Tests/ButtonExtensionsTests.cs new file mode 100644 index 0000000..93881b5 --- /dev/null +++ b/NetCore.Tests/ButtonExtensionsTests.cs @@ -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); + }); + } + } +} diff --git a/NetCore.Tests/CommandBindingTests.cs b/NetCore.Tests/CommandBindingTests.cs new file mode 100644 index 0000000..f18fece --- /dev/null +++ b/NetCore.Tests/CommandBindingTests.cs @@ -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 + { + 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 + { + public override void Execute(ViewModel parameter) + { + throw new NotImplementedException(); + } + } + } +} diff --git a/NetCore.Tests/CompositeViewModelCollectionTests.cs b/NetCore.Tests/CompositeViewModelCollectionTests.cs new file mode 100644 index 0000000..6ee8c0f --- /dev/null +++ b/NetCore.Tests/CompositeViewModelCollectionTests.cs @@ -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(() => viewModel.Composition.Add(null!)); + Assert.ThrowsException(() => viewModel.Composition.Contains(null!)); + Assert.ThrowsException(() => viewModel.Composition.IndexOf(null!)); + Assert.ThrowsException(() => viewModel.Composition.Insert(0, null!)); + Assert.ThrowsException(() => 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? Children { get; set; } + + public ObservableViewModelCollection? Dummies { get; set; } + + public CompositeViewModelCollection Composition { get; set; } = new CompositeViewModelCollection(); + + public TestViewModel() + { + Children = new ObservableViewModelCollection(this); + Dummies = new ObservableViewModelCollection(this); + Composition.Add(Children); + Composition.Add(Dummies); + } + } + + class DummyViewModel : ViewModel { } + } +} diff --git a/NetCore.Tests/Converters/AllBoolToVisibilityConverterTests.cs b/NetCore.Tests/Converters/AllBoolToVisibilityConverterTests.cs new file mode 100644 index 0000000..1b32700 --- /dev/null +++ b/NetCore.Tests/Converters/AllBoolToVisibilityConverterTests.cs @@ -0,0 +1,29 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using PresentationBase.Converters; +using System.Windows; + +namespace PresentationBase.Tests.Converters +{ + [TestClass] + public class AllBoolToVisibilityConverterTests + : ConverterTestsBase + { + [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); + } + } +} diff --git a/NetCore.Tests/Converters/BoolToVisibilityConverterTests.cs b/NetCore.Tests/Converters/BoolToVisibilityConverterTests.cs new file mode 100644 index 0000000..475e288 --- /dev/null +++ b/NetCore.Tests/Converters/BoolToVisibilityConverterTests.cs @@ -0,0 +1,60 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using PresentationBase.Converters; +using System.Windows; + +namespace PresentationBase.Tests.Converters +{ + [TestClass] + public class BoolToVisibilityConverterTests + : ConverterTestsBase + { + [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); + } + } +} diff --git a/NetCore.Tests/Converters/ConverterTestsBase.cs b/NetCore.Tests/Converters/ConverterTestsBase.cs new file mode 100644 index 0000000..9e3512d --- /dev/null +++ b/NetCore.Tests/Converters/ConverterTestsBase.cs @@ -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 + 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(false); + Assert.IsNotNull(valueConversionAttr); + + var returnTypeAttr = _converter!.GetType().GetCustomAttribute(false); + Assert.IsNotNull(returnTypeAttr); + Assert.AreEqual(typeof(TConverter), returnTypeAttr!.ReturnType); + } + + public abstract void Convert(); + + public virtual void ConvertBack() { } + } +} diff --git a/NetCore.Tests/NetCore.Tests.csproj b/NetCore.Tests/NetCore.Tests.csproj new file mode 100644 index 0000000..eb6c5ac --- /dev/null +++ b/NetCore.Tests/NetCore.Tests.csproj @@ -0,0 +1,34 @@ + + + + netcoreapp3.1 + PresentationBase.Tests + PresentationBase.Tests + false + + + + + 8.0 + enable + strict + true + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/NetCore.Tests/UiHelperTests.cs b/NetCore.Tests/UiHelperTests.cs new file mode 100644 index 0000000..833bd6c --- /dev/null +++ b/NetCore.Tests/UiHelperTests.cs @@ -0,0 +1,49 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Windows.Controls; + +namespace PresentationBase.Tests +{ + [TestClass] + public class UiHelperTests : WpfTestsBase + { + [TestMethod] + public void TryFindChild() + { + App!.Dispatcher.Invoke(() => + { + var grid = new Grid(); + grid.Children.Add(new Button + { + Name = "ButtonToFind" + }); + grid.Children.Add(new Button + { + Name = "OtherButton" + }); + grid.Children.Add(new TextBox()); + + CreateInvisibleMainWindow(); + App.MainWindow.Content = grid; + App.MainWindow.Show(); + + var foundButton = UiHelper.TryFindChild