From 4d30de7c09b3b39efaf7a2c622a84bb4df56af89 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 5 Jun 2017 20:30:07 +0200 Subject: [PATCH 1/7] Only click when pointer is over the button. Previously a button click was carried out when `:pointerover` was set, but because the button captures mouse input on mouse down, this is always true while the mouse is held. Check that the pointer was released within the bounds of the control. Fixes #938 --- src/Avalonia.Controls/Button.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/Button.cs b/src/Avalonia.Controls/Button.cs index 7ed1c7fd8c..2b3bbc8ad2 100644 --- a/src/Avalonia.Controls/Button.cs +++ b/src/Avalonia.Controls/Button.cs @@ -234,7 +234,7 @@ namespace Avalonia.Controls PseudoClasses.Remove(":pressed"); e.Handled = true; - if (ClickMode == ClickMode.Release && Classes.Contains(":pointerover")) + if (ClickMode == ClickMode.Release && new Rect(Bounds.Size).Contains(e.GetPosition(this))) { RaiseClickEvent(); } From 11586a4d4c0a490330cf09c924328f279ecf31e3 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sun, 25 Jun 2017 12:49:30 +0200 Subject: [PATCH 2/7] Don't have async void tests. That's bad. Also un-skip binding expression tests. --- .../ControlLocatorTests.cs | 3 +- .../Data/BindingExpressionTests.cs | 28 ++++++++++--------- ...xpressionObserverTests_AttachedProperty.cs | 5 ++-- ...xpressionObserverTests_AvaloniaProperty.cs | 3 +- .../Data/ExpressionObserverTests_Indexer.cs | 23 +++++++-------- .../Data/ExpressionObserverTests_Negation.cs | 15 +++++----- .../Data/ExpressionObserverTests_Property.cs | 19 +++++++------ .../Data/MultiBindingTests.cs | 3 +- .../SelectorTests_Child.cs | 3 +- 9 files changed, 56 insertions(+), 46 deletions(-) diff --git a/tests/Avalonia.Markup.UnitTests/ControlLocatorTests.cs b/tests/Avalonia.Markup.UnitTests/ControlLocatorTests.cs index b9e1cb353a..a5414f1e8c 100644 --- a/tests/Avalonia.Markup.UnitTests/ControlLocatorTests.cs +++ b/tests/Avalonia.Markup.UnitTests/ControlLocatorTests.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Reactive.Linq; +using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.UnitTests; using Xunit; @@ -13,7 +14,7 @@ namespace Avalonia.Markup.UnitTests public class ControlLocatorTests { [Fact] - public async void Track_By_Name_Should_Find_Control_Added_Earlier() + public async Task Track_By_Name_Should_Find_Control_Added_Earlier() { TextBlock target; TextBlock relativeTo; diff --git a/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs b/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs index 49d3817347..c6b1fb7b0f 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Globalization; using System.Reactive.Linq; using System.Threading; +using System.Threading.Tasks; using Avalonia.Data; using Avalonia.Markup.Data; using Avalonia.UnitTests; @@ -17,7 +18,7 @@ namespace Avalonia.Markup.UnitTests.Data public class BindingExpressionTests : IClassFixture { [Fact] - public async void Should_Get_Simple_Property_Value() + public async Task Should_Get_Simple_Property_Value() { var data = new Class1 { StringValue = "foo" }; var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(string)); @@ -49,7 +50,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Convert_Get_String_To_Double() + public async Task Should_Convert_Get_String_To_Double() { var data = new Class1 { StringValue = "5.6" }; var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(double)); @@ -59,7 +60,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Getting_Invalid_Double_String_Should_Return_BindingError() + public async Task Getting_Invalid_Double_String_Should_Return_BindingError() { var data = new Class1 { StringValue = "foo" }; var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(double)); @@ -69,7 +70,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Coerce_Get_Null_Double_String_To_UnsetValue() + public async Task Should_Coerce_Get_Null_Double_String_To_UnsetValue() { var data = new Class1 { StringValue = null }; var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(double)); @@ -90,7 +91,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Convert_Get_Double_To_String() + public async Task Should_Convert_Get_Double_To_String() { var data = new Class1 { DoubleValue = 5.6 }; var target = new BindingExpression(new ExpressionObserver(data, "DoubleValue"), typeof(string)); @@ -111,7 +112,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Return_BindingNotification_With_FallbackValue_For_NonConvertibe_Target_Value() + public async Task Should_Return_BindingNotification_With_FallbackValue_For_NonConvertibe_Target_Value() { var data = new Class1 { StringValue = "foo" }; var target = new BindingExpression( @@ -130,7 +131,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Return_BindingNotification_With_FallbackValue_For_NonConvertibe_Target_Value_With_Data_Validation() + public async Task Should_Return_BindingNotification_With_FallbackValue_For_NonConvertibe_Target_Value_With_Data_Validation() { var data = new Class1 { StringValue = "foo" }; var target = new BindingExpression( @@ -149,7 +150,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact(Skip="Result is not always AggregateException.")] - public async void Should_Return_BindingNotification_For_Invalid_FallbackValue() + public async Task Should_Return_BindingNotification_For_Invalid_FallbackValue() { var data = new Class1 { StringValue = "foo" }; var target = new BindingExpression( @@ -169,7 +170,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact(Skip="Result is not always AggregateException.")] - public async void Should_Return_BindingNotification_For_Invalid_FallbackValue_With_Data_Validation() + public async Task Should_Return_BindingNotification_For_Invalid_FallbackValue_With_Data_Validation() { var data = new Class1 { StringValue = "foo" }; var target = new BindingExpression( @@ -236,11 +237,12 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal(0, data.DoubleValue); } - [Fact(Skip="Moq.MockException")] + [Fact] public void Should_Pass_ConverterParameter_To_Convert() { var data = new Class1 { DoubleValue = 5.6 }; var converter = new Mock(); + var target = new BindingExpression( new ExpressionObserver(data, "DoubleValue"), typeof(string), @@ -249,10 +251,10 @@ namespace Avalonia.Markup.UnitTests.Data target.Subscribe(_ => { }); - converter.Verify(x => x.Convert(5.6, typeof(string), "foo", CultureInfo.InvariantCulture)); + converter.Verify(x => x.Convert(5.6, typeof(string), "foo", CultureInfo.CurrentCulture)); } - [Fact(Skip="Moq.MockException")] + [Fact] public void Should_Pass_ConverterParameter_To_ConvertBack() { var data = new Class1 { DoubleValue = 5.6 }; @@ -265,7 +267,7 @@ namespace Avalonia.Markup.UnitTests.Data target.OnNext("bar"); - converter.Verify(x => x.ConvertBack("bar", typeof(double), "foo", CultureInfo.InvariantCulture)); + converter.Verify(x => x.ConvertBack("bar", typeof(double), "foo", CultureInfo.CurrentCulture)); } [Fact(Skip="Moq.MockException")] diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_AttachedProperty.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_AttachedProperty.cs index 349a09da2c..a8069cb75c 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_AttachedProperty.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_AttachedProperty.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Reactive.Linq; +using System.Threading.Tasks; using Avalonia.Diagnostics; using Avalonia.Markup.Data; using Xunit; @@ -18,7 +19,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Get_Attached_Property_Value() + public async Task Should_Get_Attached_Property_Value() { var data = new Class1(); var target = new ExpressionObserver(data, "(Owner.Foo)"); @@ -30,7 +31,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Get_Chained_Attached_Property_Value() + public async Task Should_Get_Chained_Attached_Property_Value() { var data = new Class1 { diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_AvaloniaProperty.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_AvaloniaProperty.cs index ece9437308..cd691daaf9 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_AvaloniaProperty.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_AvaloniaProperty.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Reactive.Linq; +using System.Threading.Tasks; using Avalonia.Diagnostics; using Avalonia.Markup.Data; using Xunit; @@ -18,7 +19,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Get_Simple_Property_Value() + public async Task Should_Get_Simple_Property_Value() { var data = new Class1(); var target = new ExpressionObserver(data, "Foo"); diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs index 9cc843381c..135ec0f4db 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Reactive.Linq; +using System.Threading.Tasks; using Avalonia.Collections; using Avalonia.Diagnostics; using Avalonia.Markup.Data; @@ -16,7 +17,7 @@ namespace Avalonia.Markup.UnitTests.Data public class ExpressionObserverTests_Indexer { [Fact] - public async void Should_Get_Array_Value() + public async Task Should_Get_Array_Value() { var data = new { Foo = new [] { "foo", "bar" } }; var target = new ExpressionObserver(data, "Foo[1]"); @@ -26,7 +27,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Get_UnsetValue_For_Invalid_Array_Index() + public async Task Should_Get_UnsetValue_For_Invalid_Array_Index() { var data = new { Foo = new[] { "foo", "bar" } }; var target = new ExpressionObserver(data, "Foo[invalid]"); @@ -36,7 +37,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Get_UnsetValue_For_Invalid_Dictionary_Index() + public async Task Should_Get_UnsetValue_For_Invalid_Dictionary_Index() { var data = new { Foo = new Dictionary { { 1, "foo" } } }; var target = new ExpressionObserver(data, "Foo[invalid]"); @@ -46,7 +47,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Get_UnsetValue_For_Object_Without_Indexer() + public async Task Should_Get_UnsetValue_For_Object_Without_Indexer() { var data = new { Foo = 5 }; var target = new ExpressionObserver(data, "Foo[noindexer]"); @@ -56,7 +57,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Get_MultiDimensional_Array_Value() + public async Task Should_Get_MultiDimensional_Array_Value() { var data = new { Foo = new[,] { { "foo", "bar" }, { "baz", "qux" } } }; var target = new ExpressionObserver(data, "Foo[1, 1]"); @@ -66,7 +67,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Get_Value_For_String_Indexer() + public async Task Should_Get_Value_For_String_Indexer() { var data = new { Foo = new Dictionary { { "foo", "bar" }, { "baz", "qux" } } }; var target = new ExpressionObserver(data, "Foo[foo]"); @@ -76,7 +77,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Get_Value_For_Non_String_Indexer() + public async Task Should_Get_Value_For_Non_String_Indexer() { var data = new { Foo = new Dictionary { { 1.0, "bar" }, { 2.0, "qux" } } }; var target = new ExpressionObserver(data, "Foo[1.0]"); @@ -86,7 +87,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Array_Out_Of_Bounds_Should_Return_UnsetValue() + public async Task Array_Out_Of_Bounds_Should_Return_UnsetValue() { var data = new { Foo = new[] { "foo", "bar" } }; var target = new ExpressionObserver(data, "Foo[2]"); @@ -96,7 +97,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Array_With_Wrong_Dimensions_Should_Return_UnsetValue() + public async Task Array_With_Wrong_Dimensions_Should_Return_UnsetValue() { var data = new { Foo = new[] { "foo", "bar" } }; var target = new ExpressionObserver(data, "Foo[1,2]"); @@ -106,7 +107,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void List_Out_Of_Bounds_Should_Return_UnsetValue() + public async Task List_Out_Of_Bounds_Should_Return_UnsetValue() { var data = new { Foo = new List { "foo", "bar" } }; var target = new ExpressionObserver(data, "Foo[2]"); @@ -116,7 +117,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Get_List_Value() + public async Task Should_Get_List_Value() { var data = new { Foo = new List { "foo", "bar" } }; var target = new ExpressionObserver(data, "Foo[1]"); diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Negation.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Negation.cs index 6bee0d10f4..a9e8c6ddde 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Negation.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Negation.cs @@ -3,6 +3,7 @@ using System; using System.Reactive.Linq; +using System.Threading.Tasks; using Avalonia.Data; using Avalonia.Markup.Data; using Xunit; @@ -12,7 +13,7 @@ namespace Avalonia.Markup.UnitTests.Data public class ExpressionObserverTests_Negation { [Fact] - public async void Should_Negate_Boolean_Value() + public async Task Should_Negate_Boolean_Value() { var data = new { Foo = true }; var target = new ExpressionObserver(data, "!Foo"); @@ -22,7 +23,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Negate_0() + public async Task Should_Negate_0() { var data = new { Foo = 0 }; var target = new ExpressionObserver(data, "!Foo"); @@ -32,7 +33,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Negate_1() + public async Task Should_Negate_1() { var data = new { Foo = 1 }; var target = new ExpressionObserver(data, "!Foo"); @@ -42,7 +43,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Negate_False_String() + public async Task Should_Negate_False_String() { var data = new { Foo = "false" }; var target = new ExpressionObserver(data, "!Foo"); @@ -52,7 +53,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Negate_True_String() + public async Task Should_Negate_True_String() { var data = new { Foo = "True" }; var target = new ExpressionObserver(data, "!Foo"); @@ -62,7 +63,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Return_BindingNotification_For_String_Not_Convertible_To_Boolean() + public async Task Should_Return_BindingNotification_For_String_Not_Convertible_To_Boolean() { var data = new { Foo = "foo" }; var target = new ExpressionObserver(data, "!Foo"); @@ -76,7 +77,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Return_BindingNotification_For_Value_Not_Convertible_To_Boolean() + public async Task Should_Return_BindingNotification_For_Value_Not_Convertible_To_Boolean() { var data = new { Foo = new object() }; var target = new ExpressionObserver(data, "!Foo"); diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs index bdcd39d997..de33c959b4 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs @@ -11,13 +11,14 @@ using Avalonia.Data; using Avalonia.Markup.Data; using Avalonia.UnitTests; using Xunit; +using System.Threading.Tasks; namespace Avalonia.Markup.UnitTests.Data { public class ExpressionObserverTests_Property { [Fact] - public async void Should_Get_Simple_Property_Value() + public async Task Should_Get_Simple_Property_Value() { var data = new { Foo = "foo" }; var target = new ExpressionObserver(data, "Foo"); @@ -38,7 +39,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Get_Simple_Property_Value_Null() + public async Task Should_Get_Simple_Property_Value_Null() { var data = new { Foo = (string)null }; var target = new ExpressionObserver(data, "Foo"); @@ -48,7 +49,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Get_Simple_Property_From_Base_Class() + public async Task Should_Get_Simple_Property_From_Base_Class() { var data = new Class3 { Foo = "foo" }; var target = new ExpressionObserver(data, "Foo"); @@ -58,7 +59,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Return_UnsetValue_For_Root_Null() + public async Task Should_Return_UnsetValue_For_Root_Null() { var data = new Class3 { Foo = "foo" }; var target = new ExpressionObserver(default(object), "Foo"); @@ -68,7 +69,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Return_UnsetValue_For_Root_UnsetValue() + public async Task Should_Return_UnsetValue_For_Root_UnsetValue() { var data = new Class3 { Foo = "foo" }; var target = new ExpressionObserver(AvaloniaProperty.UnsetValue, "Foo"); @@ -78,7 +79,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Return_UnsetValue_For_Observable_Root_Null() + public async Task Should_Return_UnsetValue_For_Observable_Root_Null() { var data = new Class3 { Foo = "foo" }; var target = new ExpressionObserver(Observable.Return(default(object)), "Foo"); @@ -88,7 +89,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Return_UnsetValue_For_Observable_Root_UnsetValue() + public async Task Should_Return_UnsetValue_For_Observable_Root_UnsetValue() { var data = new Class3 { Foo = "foo" }; var target = new ExpressionObserver(Observable.Return(AvaloniaProperty.UnsetValue), "Foo"); @@ -98,7 +99,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Get_Simple_Property_Chain() + public async Task Should_Get_Simple_Property_Chain() { var data = new { Foo = new { Bar = new { Baz = "baz" } } }; var target = new ExpressionObserver(data, "Foo.Bar.Baz"); @@ -119,7 +120,7 @@ namespace Avalonia.Markup.UnitTests.Data } [Fact] - public async void Should_Return_BindingNotification_Error_For_Broken_Chain() + public async Task Should_Return_BindingNotification_Error_For_Broken_Chain() { var data = new { Foo = new { Bar = 1 } }; var target = new ExpressionObserver(data, "Foo.Bar.Baz"); diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Data/MultiBindingTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Data/MultiBindingTests.cs index 5d67151992..874dc18552 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Data/MultiBindingTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Data/MultiBindingTests.cs @@ -10,13 +10,14 @@ using Moq; using Avalonia.Controls; using Avalonia.Markup.Xaml.Data; using Xunit; +using System.Threading.Tasks; namespace Avalonia.Markup.Xaml.UnitTests.Data { public class MultiBindingTests { [Fact] - public async void OneWay_Binding_Should_Be_Set_Up() + public async Task OneWay_Binding_Should_Be_Set_Up() { var source = new { A = 1, B = 2, C = 3 }; var binding = new MultiBinding diff --git a/tests/Avalonia.Styling.UnitTests/SelectorTests_Child.cs b/tests/Avalonia.Styling.UnitTests/SelectorTests_Child.cs index d97cc74c95..560dd523b7 100644 --- a/tests/Avalonia.Styling.UnitTests/SelectorTests_Child.cs +++ b/tests/Avalonia.Styling.UnitTests/SelectorTests_Child.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Reactive; using System.Reactive.Linq; +using System.Threading.Tasks; using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Data; @@ -45,7 +46,7 @@ namespace Avalonia.Styling.UnitTests } [Fact] - public async void Child_Matches_Control_When_It_Is_Child_OfType_And_Class() + public async Task Child_Matches_Control_When_It_Is_Child_OfType_And_Class() { var parent = new TestLogical1(); var child = new TestLogical2(); From 78bb593f97f63668b258d560ea02b77243ba3ede Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sun, 25 Jun 2017 13:52:41 +0200 Subject: [PATCH 3/7] Use CurrentCulture instead of CurrentUICulture. Use `CurrentCulture` instead of `CurrentUICulture` in converters etc. `CurrentUICulture` should be used for translations, `CurrentCulture` should be used for things like numbers, dates etc. --- src/Markup/Avalonia.Markup.Xaml/Data/MultiBinding.cs | 2 +- src/Markup/Avalonia.Markup/Data/BindingExpression.cs | 4 ++-- tests/Avalonia.UnitTests/InvariantCultureFixture.cs | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Markup/Avalonia.Markup.Xaml/Data/MultiBinding.cs b/src/Markup/Avalonia.Markup.Xaml/Data/MultiBinding.cs index 69190be220..621e06efba 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Data/MultiBinding.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Data/MultiBinding.cs @@ -102,7 +102,7 @@ namespace Avalonia.Markup.Xaml.Data private object ConvertValue(IList values, Type targetType) { - var converted = Converter.Convert(values, targetType, null, CultureInfo.CurrentUICulture); + var converted = Converter.Convert(values, targetType, null, CultureInfo.CurrentCulture); if (converted == AvaloniaProperty.UnsetValue && FallbackValue != null) { diff --git a/src/Markup/Avalonia.Markup/Data/BindingExpression.cs b/src/Markup/Avalonia.Markup/Data/BindingExpression.cs index 0f4c091bff..5b9959e42e 100644 --- a/src/Markup/Avalonia.Markup/Data/BindingExpression.cs +++ b/src/Markup/Avalonia.Markup/Data/BindingExpression.cs @@ -122,7 +122,7 @@ namespace Avalonia.Markup.Data value, type, ConverterParameter, - CultureInfo.CurrentUICulture); + CultureInfo.CurrentCulture); if (converted == AvaloniaProperty.UnsetValue) { @@ -186,7 +186,7 @@ namespace Avalonia.Markup.Data value, _targetType, ConverterParameter, - CultureInfo.CurrentUICulture); + CultureInfo.CurrentCulture); notification = converted as BindingNotification; diff --git a/tests/Avalonia.UnitTests/InvariantCultureFixture.cs b/tests/Avalonia.UnitTests/InvariantCultureFixture.cs index 685142ad02..b00b16e2bb 100644 --- a/tests/Avalonia.UnitTests/InvariantCultureFixture.cs +++ b/tests/Avalonia.UnitTests/InvariantCultureFixture.cs @@ -21,20 +21,20 @@ namespace Avalonia.UnitTests public InvariantCultureFixture() { #if NET461 - _restore = Thread.CurrentThread.CurrentUICulture; - Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; + _restore = Thread.CurrentThread.CurrentCulture; + Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; #else - _restore = CultureInfo.CurrentUICulture; - CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture = CultureInfo.InvariantCulture; + _restore = CultureInfo.CurrentCulture; + CultureInfo.CurrentCulture = CultureInfo.InvariantCulture; #endif } public void Dispose() { #if NET461 - Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = _restore; + Thread.CurrentThread.CurrentCulture = _restore; #else - CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture = _restore; + CultureInfo.CurrentCulture = _restore; #endif } } From 7baa7dc0ddeef1c375da56134fd537988c0cf37f Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sun, 25 Jun 2017 14:54:17 +0200 Subject: [PATCH 4/7] Added GC.KeepAlive to tests. Lots of `Avalonia.Markup.UnitTests` were failing intermittently. This is because in release mode, in a method like this: ``` [Fact] public void SetValue_Should_Return_False_For_Missing_Object() { var data = new Class1(); var target = new ExpressionObserver(data, "Next.Bar"); using (target.Subscribe(_ => { })) { Assert.False(target.SetValue("baz")); } } ``` `data` can get GC'ed at any point after creating target. Added `GC.KeepAlive()` calls to prevent this. Fixes #1035 Fixes #1036 Fixes #1037 --- .../Data/BindingExpressionTests.cs | 40 +++++++++++++ .../ExpressionObserverTests_DataValidation.cs | 9 +++ .../Data/ExpressionObserverTests_Indexer.cs | 44 ++++++++++++++ .../ExpressionObserverTests_Observable.cs | 12 ++++ .../Data/ExpressionObserverTests_Property.cs | 59 +++++++++++++++++++ .../Data/ExpressionObserverTests_Task.cs | 12 ++++ 6 files changed, 176 insertions(+) diff --git a/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs b/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs index c6b1fb7b0f..282b216769 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs @@ -25,6 +25,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal("foo", result); + + GC.KeepAlive(data); } [Fact] @@ -36,6 +38,8 @@ namespace Avalonia.Markup.UnitTests.Data target.OnNext("bar"); Assert.Equal("bar", data.StringValue); + + GC.KeepAlive(data); } [Fact] @@ -47,6 +51,8 @@ namespace Avalonia.Markup.UnitTests.Data target.OnNext("bar"); Assert.Equal("bar", data.Foo[0]); + + GC.KeepAlive(data); } [Fact] @@ -57,6 +63,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(5.6, result); + + GC.KeepAlive(data); } [Fact] @@ -67,6 +75,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.IsType(result); + + GC.KeepAlive(data); } [Fact] @@ -77,6 +87,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(AvaloniaProperty.UnsetValue, result); + + GC.KeepAlive(data); } [Fact] @@ -88,6 +100,8 @@ namespace Avalonia.Markup.UnitTests.Data target.OnNext(6.7); Assert.Equal((6.7).ToString(), data.StringValue); + + GC.KeepAlive(data); } [Fact] @@ -98,6 +112,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal((5.6).ToString(), result); + + GC.KeepAlive(data); } [Fact] @@ -109,6 +125,8 @@ namespace Avalonia.Markup.UnitTests.Data target.OnNext("6.7"); Assert.Equal(6.7, data.DoubleValue); + + GC.KeepAlive(data); } [Fact] @@ -128,6 +146,8 @@ namespace Avalonia.Markup.UnitTests.Data BindingErrorType.Error, 42), result); + + GC.KeepAlive(data); } [Fact] @@ -147,6 +167,8 @@ namespace Avalonia.Markup.UnitTests.Data BindingErrorType.Error, 42), result); + + GC.KeepAlive(data); } [Fact(Skip="Result is not always AggregateException.")] @@ -167,6 +189,8 @@ namespace Avalonia.Markup.UnitTests.Data new InvalidCastException("Could not convert FallbackValue 'bar' to 'System.Int32'")), BindingErrorType.Error), result); + + GC.KeepAlive(data); } [Fact(Skip="Result is not always AggregateException.")] @@ -187,6 +211,8 @@ namespace Avalonia.Markup.UnitTests.Data new InvalidCastException("Could not convert FallbackValue 'bar' to 'System.Int32'")), BindingErrorType.Error), result); + + GC.KeepAlive(data); } [Fact] @@ -198,6 +224,8 @@ namespace Avalonia.Markup.UnitTests.Data target.OnNext("foo"); Assert.Equal(5.6, data.DoubleValue); + + GC.KeepAlive(data); } [Fact] @@ -213,6 +241,8 @@ namespace Avalonia.Markup.UnitTests.Data target.OnNext("foo"); Assert.Equal(9.8, data.DoubleValue); + + GC.KeepAlive(data); } [Fact] @@ -224,6 +254,8 @@ namespace Avalonia.Markup.UnitTests.Data target.OnNext(null); Assert.Equal(0, data.DoubleValue); + + GC.KeepAlive(data); } [Fact] @@ -235,6 +267,8 @@ namespace Avalonia.Markup.UnitTests.Data target.OnNext(AvaloniaProperty.UnsetValue); Assert.Equal(0, data.DoubleValue); + + GC.KeepAlive(data); } [Fact] @@ -252,6 +286,8 @@ namespace Avalonia.Markup.UnitTests.Data target.Subscribe(_ => { }); converter.Verify(x => x.Convert(5.6, typeof(string), "foo", CultureInfo.CurrentCulture)); + + GC.KeepAlive(data); } [Fact] @@ -268,6 +304,8 @@ namespace Avalonia.Markup.UnitTests.Data target.OnNext("bar"); converter.Verify(x => x.ConvertBack("bar", typeof(double), "foo", CultureInfo.CurrentCulture)); + + GC.KeepAlive(data); } [Fact(Skip="Moq.MockException")] @@ -294,6 +332,8 @@ namespace Avalonia.Markup.UnitTests.Data BindingErrorType.Error) }, result); + + GC.KeepAlive(data); } private class Class1 : NotifyingBase diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_DataValidation.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_DataValidation.cs index 3b5ca26db1..125bd84f3d 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_DataValidation.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_DataValidation.cs @@ -28,6 +28,8 @@ namespace Avalonia.Markup.UnitTests.Data observer.SetValue(-5); Assert.False(validationMessageFound); + + GC.KeepAlive(data); } [Fact] @@ -43,6 +45,8 @@ namespace Avalonia.Markup.UnitTests.Data observer.SetValue(-5); Assert.True(validationMessageFound); + + GC.KeepAlive(data); } [Fact] @@ -102,6 +106,8 @@ namespace Avalonia.Markup.UnitTests.Data new BindingNotification(new Exception("Must be positive"), BindingErrorType.DataValidationError, 5), new BindingNotification(5), }, result); + + GC.KeepAlive(data); } [Fact] @@ -147,6 +153,9 @@ namespace Avalonia.Markup.UnitTests.Data BindingErrorType.Error, AvaloniaProperty.UnsetValue), }, result); + + GC.KeepAlive(container); + GC.KeepAlive(inner); } public class ExceptionTest : NotifyingBase diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs index 135ec0f4db..a68213baee 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs @@ -24,6 +24,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal("bar", result); + + GC.KeepAlive(data); } [Fact] @@ -34,6 +36,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(AvaloniaProperty.UnsetValue, result); + + GC.KeepAlive(data); } [Fact] @@ -44,6 +48,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(AvaloniaProperty.UnsetValue, result); + + GC.KeepAlive(data); } [Fact] @@ -54,6 +60,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(AvaloniaProperty.UnsetValue, result); + + GC.KeepAlive(data); } [Fact] @@ -64,6 +72,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal("qux", result); + + GC.KeepAlive(data); } [Fact] @@ -74,6 +84,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal("bar", result); + + GC.KeepAlive(data); } [Fact] @@ -84,6 +96,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal("bar", result); + + GC.KeepAlive(data); } [Fact] @@ -94,6 +108,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(AvaloniaProperty.UnsetValue, result); + + GC.KeepAlive(data); } [Fact] @@ -104,6 +120,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(AvaloniaProperty.UnsetValue, result); + + GC.KeepAlive(data); } [Fact] @@ -114,6 +132,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(AvaloniaProperty.UnsetValue, result); + + GC.KeepAlive(data); } [Fact] @@ -124,6 +144,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal("bar", result); + + GC.KeepAlive(data); } [Fact] @@ -140,6 +162,8 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal(new[] { AvaloniaProperty.UnsetValue, "baz" }, result); Assert.Null(((INotifyCollectionChangedDebug)data.Foo).GetCollectionChangedSubscribers()); + + GC.KeepAlive(data); } [Fact] @@ -156,6 +180,8 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal(new[] { "foo", "bar" }, result); Assert.Null(((INotifyCollectionChangedDebug)data.Foo).GetCollectionChangedSubscribers()); + + GC.KeepAlive(data); } [Fact] @@ -172,6 +198,8 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal(new[] { "bar", "baz" }, result); Assert.Null(((INotifyCollectionChangedDebug)data.Foo).GetCollectionChangedSubscribers()); + + GC.KeepAlive(data); } [Fact] @@ -188,6 +216,9 @@ namespace Avalonia.Markup.UnitTests.Data data.Foo.Move(0, 1); Assert.Equal(new[] { "bar", "foo" }, result); + + GC.KeepAlive(sub); + GC.KeepAlive(data); } [Fact] @@ -201,6 +232,9 @@ namespace Avalonia.Markup.UnitTests.Data data.Foo.Clear(); Assert.Equal(new[] { "bar", AvaloniaProperty.UnsetValue }, result); + + GC.KeepAlive(sub); + GC.KeepAlive(data); } [Fact] @@ -221,6 +255,8 @@ namespace Avalonia.Markup.UnitTests.Data var expected = new[] { "bar", "bar2" }; Assert.Equal(expected, result); Assert.Equal(0, data.Foo.PropertyChangedSubscriptionCount); + + GC.KeepAlive(data); } [Fact] @@ -235,6 +271,8 @@ namespace Avalonia.Markup.UnitTests.Data } Assert.Equal("baz", data.Foo[1]); + + GC.KeepAlive(data); } [Fact] @@ -255,6 +293,8 @@ namespace Avalonia.Markup.UnitTests.Data } Assert.Equal(4, data.Foo["foo"]); + + GC.KeepAlive(data); } [Fact] @@ -275,6 +315,8 @@ namespace Avalonia.Markup.UnitTests.Data } Assert.Equal(4, data.Foo["bar"]); + + GC.KeepAlive(data); } [Fact] @@ -292,6 +334,8 @@ namespace Avalonia.Markup.UnitTests.Data } Assert.Equal("bar2", data.Foo["foo"]); + + GC.KeepAlive(data); } private class NonIntegerIndexer : NotifyingBase diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Observable.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Observable.cs index 640d82fa19..62d5c28f49 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Observable.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Observable.cs @@ -29,6 +29,8 @@ namespace Avalonia.Markup.UnitTests.Data sync.ExecutePostedCallbacks(); Assert.Equal(new[] { source }, result); + + GC.KeepAlive(data); } } @@ -47,6 +49,8 @@ namespace Avalonia.Markup.UnitTests.Data sync.ExecutePostedCallbacks(); Assert.Equal(new[] { "foo", "bar" }, result); + + GC.KeepAlive(data); } } @@ -67,6 +71,8 @@ namespace Avalonia.Markup.UnitTests.Data sub.Dispose(); Assert.Equal(0, data.PropertyChangedSubscriptionCount); + + GC.KeepAlive(data); } } @@ -87,6 +93,8 @@ namespace Avalonia.Markup.UnitTests.Data // What does it mean to have data validation on an observable? Without a use-case // it's hard to know what to do here so for the moment the value is returned. Assert.Equal(new[] { "foo", "bar" }, result); + + GC.KeepAlive(data); } } @@ -107,6 +115,8 @@ namespace Avalonia.Markup.UnitTests.Data sub.Dispose(); Assert.Equal(0, data.PropertyChangedSubscriptionCount); + + GC.KeepAlive(data); } } @@ -132,6 +142,8 @@ namespace Avalonia.Markup.UnitTests.Data result); sub.Dispose(); + + GC.KeepAlive(data); } } diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs index de33c959b4..4cb2061c9e 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs @@ -25,6 +25,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal("foo", result); + + GC.KeepAlive(data); } [Fact] @@ -36,6 +38,8 @@ namespace Avalonia.Markup.UnitTests.Data target.Subscribe(_ => { }); Assert.Equal(typeof(string), target.ResultType); + + GC.KeepAlive(data); } [Fact] @@ -46,6 +50,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Null(result); + + GC.KeepAlive(data); } [Fact] @@ -56,6 +62,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal("foo", result); + + GC.KeepAlive(data); } [Fact] @@ -66,6 +74,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(AvaloniaProperty.UnsetValue, result); + + GC.KeepAlive(data); } [Fact] @@ -76,6 +86,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(AvaloniaProperty.UnsetValue, result); + + GC.KeepAlive(data); } [Fact] @@ -86,6 +98,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(AvaloniaProperty.UnsetValue, result); + + GC.KeepAlive(data); } [Fact] @@ -96,6 +110,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(AvaloniaProperty.UnsetValue, result); + + GC.KeepAlive(data); } [Fact] @@ -106,6 +122,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal("baz", result); + + GC.KeepAlive(data); } [Fact] @@ -117,6 +135,8 @@ namespace Avalonia.Markup.UnitTests.Data target.Subscribe(_ => { }); Assert.Equal(typeof(string), target.ResultType); + + GC.KeepAlive(data); } [Fact] @@ -132,6 +152,8 @@ namespace Avalonia.Markup.UnitTests.Data new BindingNotification( new MissingMemberException("Could not find CLR property 'Baz' on '1'"), BindingErrorType.Error), result); + + GC.KeepAlive(data); } [Fact] @@ -152,6 +174,8 @@ namespace Avalonia.Markup.UnitTests.Data AvaloniaProperty.UnsetValue), }, result); + + GC.KeepAlive(data); } [Fact] @@ -161,6 +185,8 @@ namespace Avalonia.Markup.UnitTests.Data var target = new ExpressionObserver(data, "Foo.Bar.Baz"); Assert.Null(target.ResultType); + + GC.KeepAlive(data); } [Fact] @@ -178,6 +204,8 @@ namespace Avalonia.Markup.UnitTests.Data sub.Dispose(); Assert.Equal(0, data.PropertyChangedSubscriptionCount); + + GC.KeepAlive(data); } [Fact] @@ -206,6 +234,8 @@ namespace Avalonia.Markup.UnitTests.Data sub.Dispose(); Assert.Equal(0, data.PropertyChangedSubscriptionCount); + + GC.KeepAlive(data); } [Fact] @@ -225,6 +255,8 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal(0, data.PropertyChangedSubscriptionCount); Assert.Equal(0, data.Next.PropertyChangedSubscriptionCount); + + GC.KeepAlive(data); } [Fact] @@ -246,6 +278,8 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal(0, data.PropertyChangedSubscriptionCount); Assert.Equal(0, data.Next.PropertyChangedSubscriptionCount); Assert.Equal(0, old.PropertyChangedSubscriptionCount); + + GC.KeepAlive(data); } [Fact] @@ -287,6 +321,8 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal(0, data.PropertyChangedSubscriptionCount); Assert.Equal(0, data.Next.PropertyChangedSubscriptionCount); Assert.Equal(0, old.PropertyChangedSubscriptionCount); + + GC.KeepAlive(data); } [Fact] @@ -319,6 +355,8 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal(0, data.Next.PropertyChangedSubscriptionCount); Assert.Equal(0, breaking.PropertyChangedSubscriptionCount); Assert.Equal(0, old.PropertyChangedSubscriptionCount); + + GC.KeepAlive(data); } [Fact] @@ -335,6 +373,8 @@ namespace Avalonia.Markup.UnitTests.Data update.OnNext(Unit.Default); Assert.Equal(new[] { "foo", "bar" }, result); + + GC.KeepAlive(data); } [Fact] @@ -375,6 +415,8 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal(new[] { "foo", "bar" }, result1); Assert.Equal(new[] { "foo", "bar" }, result2); Assert.Equal(new[] { "bar" }, result3); + + GC.KeepAlive(data); } [Fact] @@ -392,6 +434,8 @@ namespace Avalonia.Markup.UnitTests.Data sub2.Dispose(); Assert.Equal(0, data.PropertyChangedSubscriptionCount); + + GC.KeepAlive(data); } [Fact] @@ -406,6 +450,8 @@ namespace Avalonia.Markup.UnitTests.Data } Assert.Equal("bar", data.Foo); + + GC.KeepAlive(data); } [Fact] @@ -420,6 +466,8 @@ namespace Avalonia.Markup.UnitTests.Data } Assert.Equal("baz", ((Class2)data.Next).Bar); + + GC.KeepAlive(data); } [Fact] @@ -432,6 +480,8 @@ namespace Avalonia.Markup.UnitTests.Data { Assert.False(target.SetValue("baz")); } + + GC.KeepAlive(data); } [Fact] @@ -445,6 +495,8 @@ namespace Avalonia.Markup.UnitTests.Data target.SetValue("bar"); Assert.Equal(new[] { null, "bar" }, result); + + GC.KeepAlive(data); } [Fact] @@ -458,6 +510,8 @@ namespace Avalonia.Markup.UnitTests.Data target.SetValue("bar"); Assert.Equal(new[] { null, "bar" }, result); + + GC.KeepAlive(data); } [Fact] @@ -470,6 +524,8 @@ namespace Avalonia.Markup.UnitTests.Data { Assert.False(target.SetValue("baz")); } + + GC.KeepAlive(data); } [Fact] @@ -499,6 +555,9 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal(0, first.PropertyChangedSubscriptionCount); Assert.Equal(0, second.PropertyChangedSubscriptionCount); + + GC.KeepAlive(first); + GC.KeepAlive(second); } [Fact] diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Task.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Task.cs index 61e6dcb833..c251f4398a 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Task.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Task.cs @@ -30,6 +30,8 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal(1, result.Count); Assert.IsType>(result[0]); + + GC.KeepAlive(data); } } @@ -45,6 +47,8 @@ namespace Avalonia.Markup.UnitTests.Data var sub = target.Subscribe(x => result.Add(x)); Assert.Equal(new[] { "foo" }, result); + + GC.KeepAlive(data); } } @@ -63,6 +67,8 @@ namespace Avalonia.Markup.UnitTests.Data sync.ExecutePostedCallbacks(); Assert.Equal(new[] { "foo" }, result); + + GC.KeepAlive(data); } } @@ -88,6 +94,8 @@ namespace Avalonia.Markup.UnitTests.Data BindingErrorType.Error) }, result); + + GC.KeepAlive(data); } } @@ -110,6 +118,8 @@ namespace Avalonia.Markup.UnitTests.Data BindingErrorType.Error) }, result); + + GC.KeepAlive(data); } } @@ -130,6 +140,8 @@ namespace Avalonia.Markup.UnitTests.Data // What does it mean to have data validation on a Task? Without a use-case it's // hard to know what to do here so for the moment the value is returned. Assert.Equal(new [] { "foo" }, result); + + GC.KeepAlive(data); } } From 3b3fbdbbd645fca18df1994e490c7e6284c531e7 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sun, 25 Jun 2017 14:54:54 +0200 Subject: [PATCH 5/7] Use `DisableTestParallelization` Instead of `MaxParallelThreads = 1` - that's how we do it in other assemblies. --- tests/Avalonia.Base.UnitTests/Properties/AssemblyInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Avalonia.Base.UnitTests/Properties/AssemblyInfo.cs b/tests/Avalonia.Base.UnitTests/Properties/AssemblyInfo.cs index 562de2dc06..4b93ea8400 100644 --- a/tests/Avalonia.Base.UnitTests/Properties/AssemblyInfo.cs +++ b/tests/Avalonia.Base.UnitTests/Properties/AssemblyInfo.cs @@ -7,4 +7,4 @@ using Xunit; [assembly: AssemblyTitle("Avalonia.UnitTests")] // Don't run tests in parallel. -[assembly: CollectionBehavior(MaxParallelThreads = 1)] +[assembly: CollectionBehavior(DisableTestParallelization = true)] From ef1039b865dc5b67e34e972eae73dce96f97255e Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sun, 25 Jun 2017 15:04:58 +0200 Subject: [PATCH 6/7] Unskip another test. --- tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs b/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs index 282b216769..370e3b51e6 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs @@ -308,7 +308,7 @@ namespace Avalonia.Markup.UnitTests.Data GC.KeepAlive(data); } - [Fact(Skip="Moq.MockException")] + [Fact] public void Should_Handle_DataValidation() { var data = new Class1 { DoubleValue = 5.6 }; From 129378cad1ed0da543c80e41b0d7b833a5474544 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sun, 25 Jun 2017 15:19:26 +0200 Subject: [PATCH 7/7] Added more GC.KeepAlive statements. --- .../Data/ExpressionObserverTests_Lifetime.cs | 5 ++++- .../Data/ExpressionObserverTests_Negation.cs | 16 ++++++++++++++++ .../Plugins/ExceptionValidationPluginTests.cs | 2 ++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Lifetime.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Lifetime.cs index 2a2bf06bf1..04a8e30d16 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Lifetime.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Lifetime.cs @@ -90,7 +90,8 @@ namespace Avalonia.Markup.UnitTests.Data { var scheduler = new TestScheduler(); var update = scheduler.CreateColdObservable(); - var target = new ExpressionObserver(() => new { Foo = "foo" }, "Foo", update); + var data = new { Foo = "foo" }; + var target = new ExpressionObserver(() => data, "Foo", update); var result = new List(); using (target.Subscribe(x => result.Add(x))) @@ -101,6 +102,8 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal(new[] { "foo" }, result); Assert.All(update.Subscriptions, x => Assert.NotEqual(Subscription.Infinite, x.Unsubscribe)); + + GC.KeepAlive(data); } private Recorded> OnNext(long time, object value) diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Negation.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Negation.cs index a9e8c6ddde..d8dc2de847 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Negation.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Negation.cs @@ -20,6 +20,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(false, result); + + GC.KeepAlive(data); } [Fact] @@ -30,6 +32,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(true, result); + + GC.KeepAlive(data); } [Fact] @@ -40,6 +44,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(false, result); + + GC.KeepAlive(data); } [Fact] @@ -50,6 +56,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(true, result); + + GC.KeepAlive(data); } [Fact] @@ -60,6 +68,8 @@ namespace Avalonia.Markup.UnitTests.Data var result = await target.Take(1); Assert.Equal(false, result); + + GC.KeepAlive(data); } [Fact] @@ -74,6 +84,8 @@ namespace Avalonia.Markup.UnitTests.Data new InvalidCastException($"Unable to convert 'foo' to bool."), BindingErrorType.Error), result); + + GC.KeepAlive(data); } [Fact] @@ -88,6 +100,8 @@ namespace Avalonia.Markup.UnitTests.Data new InvalidCastException($"Unable to convert 'System.Object' to bool."), BindingErrorType.Error), result); + + GC.KeepAlive(data); } [Fact] @@ -97,6 +111,8 @@ namespace Avalonia.Markup.UnitTests.Data var target = new ExpressionObserver(data, "!Foo"); Assert.False(target.SetValue("bar")); + + GC.KeepAlive(data); } } } diff --git a/tests/Avalonia.Markup.UnitTests/Data/Plugins/ExceptionValidationPluginTests.cs b/tests/Avalonia.Markup.UnitTests/Data/Plugins/ExceptionValidationPluginTests.cs index 4a34791008..eb529a3b13 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/Plugins/ExceptionValidationPluginTests.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/Plugins/ExceptionValidationPluginTests.cs @@ -35,6 +35,8 @@ namespace Avalonia.Markup.UnitTests.Data.Plugins new BindingNotification(new ArgumentOutOfRangeException("value"), BindingErrorType.DataValidationError), new BindingNotification(6), }, result); + + GC.KeepAlive(data); } public class Data : NotifyingBase