Fixing issue where a cast exception in the Converter could cause the app to crash.
Added unit tests for the Binding converters.
This commit is contained in:
Родитель
67f716044a
Коммит
211c05a45d
|
@ -1114,13 +1114,36 @@ namespace GalaSoft.MvvmLight.Helpers
|
|||
}
|
||||
|
||||
var sourceValue = (TSource)_sourceProperty.GetValue(_propertySource.Target, null);
|
||||
return _converter.Convert(sourceValue);
|
||||
|
||||
try
|
||||
{
|
||||
return _converter.Convert(sourceValue);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (!Equals(FallbackValue, default(TSource)))
|
||||
{
|
||||
return _converter.Convert(FallbackValue);
|
||||
}
|
||||
|
||||
var targetValue = (TTarget)_targetProperty.GetValue(_propertyTarget.Target, null);
|
||||
return targetValue;
|
||||
}
|
||||
}
|
||||
|
||||
private TSource GetTargetValue()
|
||||
{
|
||||
var targetValue = (TTarget)_targetProperty.GetValue(_propertyTarget.Target, null);
|
||||
return _converter.ConvertBack(targetValue);
|
||||
|
||||
try
|
||||
{
|
||||
return _converter.ConvertBack(targetValue);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
var sourceValue = (TSource)_sourceProperty.GetValue(_propertySource.Target, null);
|
||||
return sourceValue;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleSourceEvent<TEventArgs>(object sender, TEventArgs args)
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using GalaSoft.MvvmLight.Helpers;
|
||||
using GalaSoft.MvvmLight.Test.Controls;
|
||||
using GalaSoft.MvvmLight.Test.ViewModel;
|
||||
using NUnit.Framework;
|
||||
|
||||
#if ANDROID
|
||||
using Android.App;
|
||||
using Android.Widget;
|
||||
#elif __IOS__
|
||||
using UIKit;
|
||||
#endif
|
||||
|
||||
namespace GalaSoft.MvvmLight.Test.Binding
|
||||
{
|
||||
[TestFixture]
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
public class ConverterTest
|
||||
{
|
||||
public TestViewModel Vm
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
#if ANDROID
|
||||
public EditText Text
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
#elif __IOS__
|
||||
public UITextViewEx Text
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
#endif
|
||||
|
||||
[Test]
|
||||
public void BindingConverter_ConvertDateTimeToText_NoError()
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
Vm = new TestViewModel
|
||||
{
|
||||
Date = now
|
||||
};
|
||||
|
||||
#if ANDROID
|
||||
Text = new EditText(Application.Context);
|
||||
#elif __IOS__
|
||||
Text = new UITextViewEx();
|
||||
#endif
|
||||
|
||||
this.SetBinding(
|
||||
() => Vm.Date,
|
||||
() => Text.Text)
|
||||
.ConvertSourceToTarget(d => d.Date.ToShortDateString());
|
||||
|
||||
Assert.AreEqual(now, Vm.Date);
|
||||
Assert.AreEqual(now.ToShortDateString(), Text.Text);
|
||||
|
||||
Vm.Date += TimeSpan.FromDays(3);
|
||||
|
||||
Assert.AreEqual((now + TimeSpan.FromDays(3)).ToShortDateString(), Text.Text);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BindingConverter_ConvertDateTimeTwoWayToText_NoError()
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
Vm = new TestViewModel
|
||||
{
|
||||
Date = now
|
||||
};
|
||||
|
||||
#if ANDROID
|
||||
Text = new EditText(Application.Context);
|
||||
#elif __IOS__
|
||||
Text = new UITextViewEx();
|
||||
#endif
|
||||
|
||||
this.SetBinding(
|
||||
() => Vm.Date,
|
||||
() => Text.Text,
|
||||
BindingMode.TwoWay)
|
||||
.ConvertSourceToTarget(d => d.Date.ToShortDateString())
|
||||
.ConvertTargetToSource(d => DateTime.ParseExact(d, "dd/MM/yyyy", CultureInfo.InvariantCulture));
|
||||
|
||||
Assert.AreEqual(now, Vm.Date);
|
||||
Assert.AreEqual(now.ToShortDateString(), Text.Text);
|
||||
Vm.Date += TimeSpan.FromDays(3);
|
||||
Assert.AreEqual((now + TimeSpan.FromDays(3)).ToShortDateString(), Text.Text);
|
||||
|
||||
var newDateString = "13/04/1971";
|
||||
var newDate = new DateTime(1971, 4, 13);
|
||||
Text.Text = newDateString;
|
||||
|
||||
Assert.AreEqual(newDateString, Text.Text);
|
||||
Assert.AreEqual(newDate, Vm.Date);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BindingConverter_ConvertInvalidDateConversion_NoError()
|
||||
{
|
||||
var vmSource = new TestViewModel
|
||||
{
|
||||
Model = new TestModel
|
||||
{
|
||||
MyProperty = "13/04/1971"
|
||||
}
|
||||
};
|
||||
|
||||
var vmTarget = new TestViewModel();
|
||||
|
||||
var binding = new Binding<string, DateTime>(
|
||||
vmSource,
|
||||
() => vmSource.Model.MyProperty,
|
||||
vmTarget,
|
||||
() => vmTarget.Date)
|
||||
.ConvertSourceToTarget(d => DateTime.ParseExact(d, "dd/MM/yyyy", CultureInfo.InvariantCulture));
|
||||
|
||||
var referenceDate = new DateTime(1971, 4, 13);
|
||||
Assert.AreEqual(referenceDate, vmTarget.Date);
|
||||
|
||||
var newDateString = "13/04/197"; // Invalid date string
|
||||
vmSource.Model.MyProperty = newDateString;
|
||||
|
||||
Assert.AreEqual(referenceDate, vmTarget.Date);
|
||||
|
||||
newDateString = "13/04/1972"; // Valid date string
|
||||
vmSource.Model.MyProperty = newDateString;
|
||||
|
||||
referenceDate = new DateTime(1972, 4, 13);
|
||||
Assert.AreEqual(referenceDate, vmTarget.Date);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BindingConverter_ConvertBackInvalidDateConversion_NoError()
|
||||
{
|
||||
var date = DateTime.Now;
|
||||
|
||||
Vm = new TestViewModel
|
||||
{
|
||||
Date = date
|
||||
};
|
||||
|
||||
#if ANDROID
|
||||
Text = new EditText(Application.Context);
|
||||
#elif __IOS__
|
||||
Text = new UITextViewEx();
|
||||
#endif
|
||||
|
||||
this.SetBinding(
|
||||
() => Vm.Date,
|
||||
() => Text.Text,
|
||||
BindingMode.TwoWay)
|
||||
.ConvertSourceToTarget(d => d.Date.ToShortDateString())
|
||||
.ConvertTargetToSource(d => DateTime.ParseExact(d, "dd/MM/yyyy", CultureInfo.InvariantCulture));
|
||||
|
||||
Assert.AreEqual(date, Vm.Date);
|
||||
Assert.AreEqual(date.ToShortDateString(), Text.Text);
|
||||
|
||||
date += TimeSpan.FromDays(3);
|
||||
|
||||
Vm.Date = date;
|
||||
Assert.AreEqual(date.ToShortDateString(), Text.Text);
|
||||
|
||||
var newDateString = "13/04/197"; // Invalid date string
|
||||
Text.Text = newDateString;
|
||||
|
||||
Assert.AreEqual(newDateString, Text.Text);
|
||||
Assert.AreEqual(date, Vm.Date);
|
||||
|
||||
newDateString = "13/04/1971"; // Valid date string
|
||||
Text.Text = newDateString;
|
||||
|
||||
Assert.AreEqual(newDateString, Text.Text);
|
||||
Assert.AreEqual(new DateTime(1971, 4, 13), Vm.Date);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BindingConverter_ConvertInvalidDateConversionWithExplicitExceptionHandling_NoError()
|
||||
{
|
||||
var vmSource = new TestViewModel
|
||||
{
|
||||
Model = new TestModel
|
||||
{
|
||||
MyProperty = "13/04/1971"
|
||||
}
|
||||
};
|
||||
|
||||
var vmTarget = new TestViewModel();
|
||||
|
||||
var binding = new Binding<string, DateTime>(
|
||||
vmSource,
|
||||
() => vmSource.Model.MyProperty,
|
||||
vmTarget,
|
||||
() => vmTarget.Date)
|
||||
.ConvertSourceToTarget(
|
||||
d =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return DateTime.ParseExact(d, "dd/MM/yyyy", CultureInfo.InvariantCulture);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
});
|
||||
|
||||
var referenceDate = new DateTime(1971, 4, 13);
|
||||
Assert.AreEqual(referenceDate, vmTarget.Date);
|
||||
|
||||
var newDateString = "13/04/197"; // Invalid date string
|
||||
vmSource.Model.MyProperty = newDateString;
|
||||
|
||||
Assert.AreEqual(DateTime.MinValue, vmTarget.Date);
|
||||
|
||||
newDateString = "13/04/1972"; // Valid date string
|
||||
vmSource.Model.MyProperty = newDateString;
|
||||
|
||||
referenceDate = new DateTime(1972, 4, 13);
|
||||
Assert.AreEqual(referenceDate, vmTarget.Date);
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче