Browse Source

Implement ObjectMultiConverters. (#21428)

* Implement object multi converters and tests.

* Rename null check methods

* Remove method AreNotEqual

* Move to ObjectConverters

* Change logic for AreAnyNull

---------

Co-authored-by: Emmanuel Hansen <emmausssss@gmail.com>
pull/21888/head
Theofanis kouniakis 1 month ago
committed by GitHub
parent
commit
b1e68c3e0f
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 50
      src/Avalonia.Base/Data/Converters/ObjectConverters.cs
  2. 71
      tests/Avalonia.Base.UnitTests/Data/ObjectConvertersTests.cs

50
src/Avalonia.Base/Data/Converters/ObjectConverters.cs

@ -1,3 +1,6 @@
using System.Linq;
using System.Collections.Generic;
namespace Avalonia.Data.Converters
{
/// <summary>
@ -28,5 +31,52 @@ namespace Avalonia.Data.Converters
/// </summary>
public static readonly IValueConverter NotEqual =
new FuncValueConverter<object?, object?, bool>((a, b) => !a?.Equals(b) ?? b is not null);
/// <summary>
/// A multi-value converter that returns true if all inputs are null.
/// </summary>
public static readonly IMultiValueConverter AreAllNull =
new FuncMultiValueConverter<object?, bool>(x => x.All(item => item is null));
/// <summary>
/// A multi-value converter that returns true if at least one input is null.
/// </summary>
public static readonly IMultiValueConverter AreAnyNull =
new FuncMultiValueConverter<object?, bool>(x => x.Any(item => item is null));
/// <summary>
/// A multi-value converter that returns true if all inputs are equal to each other.
/// Null values are not considered equal to anything since they don't have Equals method.
/// </summary>
public static readonly IMultiValueConverter AreAllEqual =
new FuncMultiValueConverter<object?, bool>(EqualityFunction);
/// <summary>
/// Helper function for AreAllEqual converter. Returns true if all inputs are equal to each other.
/// </summary>
/// <param name="values">The values to compare.</param>
/// <returns>True if all values are equal, false otherwise.</returns>
private static bool EqualityFunction(IEnumerable<object?> values)
{
using var enumerator = values.GetEnumerator();
//Empty collection is considered equal.
if (!enumerator.MoveNext())
return true;
//Null values are not considered equal to anything since they don't have Equals method.
var first = enumerator.Current;
if (first is null)
return false;
while (enumerator.MoveNext())
{
var item = enumerator.Current;
if (item is null || !item.Equals(first))
return false;
}
return true;
}
}
}

71
tests/Avalonia.Base.UnitTests/Data/ObjectConvertersTests.cs

@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Avalonia.Data.Converters;
using Xunit;
namespace Avalonia.Base.UnitTests.Data
{
public class ObjectConvertersTests
{
[Theory]
[InlineData(null, null, null, true)]
[InlineData(null, null, "value", false)]
[InlineData(null, "value", null, false)]
[InlineData("value", null, null, false)]
[InlineData("value", "value", "value", false)]
public void ObjectConvertersTests_AreAllNull_Works(object? value1, object? value2, object? value3, bool valid)
{
var converter = ObjectConverters.AreAllNull;
var result = converter.Convert([value1, value2, value3], typeof(bool), null, CultureInfo.CurrentCulture);
Assert.Equal(valid, Assert.IsType<bool>(result));
}
[Theory]
[InlineData(null, null, null, true)]
[InlineData(null, null, "value", true)]
[InlineData(null, "value", null, true)]
[InlineData("value", null, null, true)]
[InlineData("value", "value", "value", false)]
public void ObjectConvertersTests_AreAnyNull_Works(object? value1, object? value2, object? value3, bool valid)
{
var converter = ObjectConverters.AreAnyNull;
var result = converter.Convert([value1, value2, value3], typeof(bool), null, CultureInfo.CurrentCulture);
Assert.Equal(valid, Assert.IsType<bool>(result));
}
[Theory]
[InlineData("value", "value", "value", true)]
[InlineData(null, "value", null, false)]
[InlineData("value", null, "value", false)]
[InlineData("value", "value", "value1", false)]
[InlineData("value1", "value", "value1", false)]
[InlineData("value", "value", 1, false)]
public void ObjectConvertersTests_AreEqual_Works(object? value1, object? value2, object? value3, bool valid)
{
var converter = ObjectConverters.AreAllEqual;
var result = converter.Convert([value1, value2, value3], typeof(bool), null, CultureInfo.CurrentCulture);
Assert.Equal(valid, Assert.IsType<bool>(result));
}
[Theory]
[InlineData(true, true, true)]
[InlineData(false, true, false)]
[InlineData(false, false, true)]
public void ObjectConvertersTests_AreEqual_Edge_Works(bool empty, bool unique, bool valid)
{
ICollection<object?> values;
if (empty)
values = Array.Empty<object?>();
else if (unique)
values = ["1", "2"];
else
values = ["1", "1"];
var converter = ObjectConverters.AreAllEqual;
var result = converter.Convert(values.ToList(), typeof(bool), null, CultureInfo.CurrentCulture);
Assert.Equal(valid, Assert.IsType<bool>(result));
}
}
}
Loading…
Cancel
Save