Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swap to using IValueConverter for the EventToCommandBehavior #665

Merged
merged 3 commits into from
Oct 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Reflection;
using CommunityToolkit.Maui.Behaviors;
using CommunityToolkit.Maui.Converters;
using CommunityToolkit.Maui.UnitTests.Mocks;
using Xunit;

namespace CommunityToolkit.Maui.UnitTests.Behaviors;
Expand Down Expand Up @@ -43,7 +44,7 @@ public void NoExceptionIfAttachedToPage()
[Fact]
public void NoExceptionWhenTheEventArgsAreNotNull()
{
var vm = new ViewModelCoffe();
var vm = new ViewModelCoffee();
var behavior = new EventToCommandBehavior<Coffee>
{
EventName = nameof(ListView.ItemTapped),
Expand All @@ -65,7 +66,7 @@ public void NoExceptionWhenTheEventArgsAreNotNull()
[Fact]
public void NoExceptionWhenTheEventArgsAreNotNull_InheritedType()
{
var vm = new ViewModelCoffe();
var vm = new ViewModelCoffee();
var behavior = new EventToCommandBehavior<Coffee>
{
EventName = nameof(ListView.ItemTapped),
Expand All @@ -87,7 +88,7 @@ public void NoExceptionWhenTheEventArgsAreNotNull_InheritedType()
[Fact]
public void ParameterOfTypeInt()
{
var vm = new ViewModelCoffe();
var vm = new ViewModelCoffee();
var behavior = new EventToCommandBehavior<int>
{
EventName = nameof(ListView.ItemTapped),
Expand All @@ -103,7 +104,7 @@ public void ParameterOfTypeInt()
[Fact]
public void NoExceptionWhenTheSelectedItemIsNull()
{
var vm = new ViewModelCoffe();
var vm = new ViewModelCoffee();
var behavior = new EventToCommandBehavior<Coffee>
{
EventName = nameof(ListView.ItemTapped),
Expand All @@ -120,6 +121,27 @@ public void NoExceptionWhenTheSelectedItemIsNull()
Assert.Null(vm.CoffeeName);
}

[Fact]
public void HappilyUsesIValueConverterImplementation()
{
var vm = new ViewModelCoffee();
var convertedValue = default(object);
var cappuccino = new Coffee();

var behavior = new EventToCommandBehavior<Coffee>
{
EventName = nameof(ListView.ItemTapped),
EventArgsConverter = new MockValueConverter((value) => cappuccino),
Command = new Command((parameter) => convertedValue = parameter)
};

var nullArgs = new object?[] { null, null };

TriggerEventToCommandBehavior(behavior, nullArgs);

Assert.Equal(cappuccino, convertedValue);
}

static void TriggerEventToCommandBehavior<T>(EventToCommandBehavior<T> eventToCommand, object?[] args)
{
var method = eventToCommand.GetType().GetMethod("OnTriggerHandled", BindingFlags.Instance | BindingFlags.NonPublic);
Expand All @@ -141,13 +163,13 @@ public class Coffee
public string Image { get; set; } = string.Empty;
}

public class ViewModelCoffe
public class ViewModelCoffee
{
public Command<Coffee> SelectedCommand { get; set; }

public string? CoffeeName { get; set; }

public ViewModelCoffe()
public ViewModelCoffee()
{
SelectedCommand = new Command<Coffee>(Selected);
}
Expand Down
23 changes: 23 additions & 0 deletions src/CommunityToolkit.Maui.UnitTests/Mocks/MockValueConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Globalization;

namespace CommunityToolkit.Maui.UnitTests.Mocks;

class MockValueConverter : IValueConverter
{
readonly Func<object, object> returnValue;

public MockValueConverter(Func<object, object> returnValue)
{
this.returnValue = returnValue;
}

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return returnValue.Invoke(value);
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return returnValue.Invoke(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class EventToCommandBehavior : BaseBehavior<VisualElement>
/// Backing BindableProperty for the <see cref="EventArgs"/> property.
/// </summary>
public static readonly BindableProperty EventArgsConverterProperty =
BindableProperty.Create(nameof(EventArgsConverter), typeof(ICommunityToolkitValueConverter), typeof(EventToCommandBehavior));
BindableProperty.Create(nameof(EventArgsConverter), typeof(IValueConverter), typeof(EventToCommandBehavior));

readonly MethodInfo eventHandlerMethodInfo = typeof(EventToCommandBehavior).GetTypeInfo()?.GetDeclaredMethod(nameof(OnTriggerHandled)) ?? throw new InvalidOperationException($"Cannot find method {nameof(OnTriggerHandled)}");

Expand Down Expand Up @@ -69,9 +69,9 @@ public class EventToCommandBehavior : BaseBehavior<VisualElement>
/// <summary>
/// An optional <see cref="ICommunityToolkitValueConverter"/> that can be used to convert <see cref="EventArgs"/> values, associated with the event configured with <see cref="EventName"/>, to values passed into the <see cref="Command"/>. This is a bindable property.
/// </summary>
public ICommunityToolkitValueConverter? EventArgsConverter
public IValueConverter? EventArgsConverter
{
get => (ICommunityToolkitValueConverter?)GetValue(EventArgsConverterProperty);
get => (IValueConverter?)GetValue(EventArgsConverterProperty);
set => SetValue(EventArgsConverterProperty, value);
}

Expand Down