From da4be92fa05afd423fe1ed9f22e63fecb76eefc7 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Tue, 3 Dec 2024 17:02:35 +0000 Subject: [PATCH] BoolConverters.Not should support ConvertBack (#17658) * BoolConverters.Not should support ConvertBack * Add previously missing BoolConvertersTests and StringConvertersTests * Fix "false & true" test case --- .../Data/Converters/BoolConverters.cs | 26 +++++++++- .../Data/BoolConvertersTests.cs | 51 +++++++++++++++++++ .../Data/StringConvertersTests.cs | 31 +++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 tests/Avalonia.Base.UnitTests/Data/BoolConvertersTests.cs create mode 100644 tests/Avalonia.Base.UnitTests/Data/StringConvertersTests.cs diff --git a/src/Avalonia.Base/Data/Converters/BoolConverters.cs b/src/Avalonia.Base/Data/Converters/BoolConverters.cs index 3985c5e32f..d8c880cca9 100644 --- a/src/Avalonia.Base/Data/Converters/BoolConverters.cs +++ b/src/Avalonia.Base/Data/Converters/BoolConverters.cs @@ -1,3 +1,6 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.Globalization; using System.Linq; namespace Avalonia.Data.Converters @@ -23,6 +26,27 @@ namespace Avalonia.Data.Converters /// A value converter that returns true when input is false and false when input is true. /// public static readonly IValueConverter Not = - new FuncValueConverter(x => !x); + new NotConverter(); + + private class NotConverter : IValueConverter + { + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value is bool val) + { + return !val; + } + return AvaloniaProperty.UnsetValue; + } + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value is bool val) + { + return !val; + } + return AvaloniaProperty.UnsetValue; + } + } } } diff --git a/tests/Avalonia.Base.UnitTests/Data/BoolConvertersTests.cs b/tests/Avalonia.Base.UnitTests/Data/BoolConvertersTests.cs new file mode 100644 index 0000000000..b2da02554a --- /dev/null +++ b/tests/Avalonia.Base.UnitTests/Data/BoolConvertersTests.cs @@ -0,0 +1,51 @@ +using System.Globalization; +using Avalonia.Data.Converters; +using Xunit; + +namespace Avalonia.Base.UnitTests.Data; + +public class BoolConvertersTests +{ + [Fact] + public void BoolConverters_Not_Works_TwoWay() + { + var converter = BoolConverters.Not; + var result = converter.Convert(true, typeof(bool), null, CultureInfo.CurrentCulture); + Assert.False(Assert.IsType(result)); + + result = converter.ConvertBack(false, typeof(bool), null, CultureInfo.CurrentCulture); + Assert.True(Assert.IsType(result)); + } + + [Fact] + public void BoolConverters_Not_Returns_Unset_On_Invalid_Input() + { + var converter = BoolConverters.Not; + var result = converter.Convert(1234, typeof(bool), null, CultureInfo.CurrentCulture); + Assert.Equal(AvaloniaProperty.UnsetValue, result); + } + + [Theory] + [InlineData(false, false, false)] + [InlineData(false, true, false)] + [InlineData(true, false, false)] + [InlineData(true, true, true)] + public void BoolConverters_And_Works(bool a, bool b, bool y) + { + var converter = BoolConverters.And; + var result = converter.Convert([a, b], typeof(bool), null, CultureInfo.CurrentCulture); + Assert.Equal(y, Assert.IsType(result)); + } + + [Theory] + [InlineData(false, false, false)] + [InlineData(false, true, true)] + [InlineData(true, false, true)] + [InlineData(true, true, true)] + public void BoolConverters_Or_Works(bool a, bool b, bool y) + { + var converter = BoolConverters.Or; + var result = converter.Convert([a, b], typeof(bool), null, CultureInfo.CurrentCulture); + Assert.Equal(y, Assert.IsType(result)); + } +} diff --git a/tests/Avalonia.Base.UnitTests/Data/StringConvertersTests.cs b/tests/Avalonia.Base.UnitTests/Data/StringConvertersTests.cs new file mode 100644 index 0000000000..b9ae0ac750 --- /dev/null +++ b/tests/Avalonia.Base.UnitTests/Data/StringConvertersTests.cs @@ -0,0 +1,31 @@ +using System.Globalization; +using Avalonia.Data.Converters; +using Xunit; + +namespace Avalonia.Base.UnitTests.Data; + +public class StringConvertersTests +{ + [Theory] + [InlineData("hello", false)] + [InlineData("", true)] + [InlineData(null, true)] + public void StringConverters_IsNullOrEmpty_Works(string input, bool expected) + { + var converter = StringConverters.IsNullOrEmpty; + var result = converter.Convert(input, typeof(bool), null, CultureInfo.CurrentCulture); + Assert.Equal(expected, Assert.IsType(result)); + } + + [Theory] + [InlineData("hello", true)] + [InlineData("", false)] + [InlineData(null, false)] + public void StringConverters_IsNotNullOrEmpty_Works(string input, bool expected) + { + var converter = StringConverters.IsNotNullOrEmpty; + var result = converter.Convert(input, typeof(bool), null, CultureInfo.CurrentCulture); + Assert.Equal(expected, Assert.IsType(result)); + } + +}