Browse Source

Merge branch 'fixes/1035-reenable-skipped-tests' into fixes/1029-fix-tooltip-crash

pull/1031/head
Steven Kirk 9 years ago
parent
commit
ee40eee9e9
  1. 2
      src/Markup/Avalonia.Markup.Xaml/Data/MultiBinding.cs
  2. 4
      src/Markup/Avalonia.Markup/Data/BindingExpression.cs
  3. 2
      tests/Avalonia.Base.UnitTests/Properties/AssemblyInfo.cs
  4. 3
      tests/Avalonia.Markup.UnitTests/ControlLocatorTests.cs
  5. 70
      tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs
  6. 5
      tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_AttachedProperty.cs
  7. 3
      tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_AvaloniaProperty.cs
  8. 9
      tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_DataValidation.cs
  9. 67
      tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs
  10. 5
      tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Lifetime.cs
  11. 31
      tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Negation.cs
  12. 12
      tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Observable.cs
  13. 78
      tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs
  14. 12
      tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Task.cs
  15. 2
      tests/Avalonia.Markup.UnitTests/Data/Plugins/ExceptionValidationPluginTests.cs
  16. 3
      tests/Avalonia.Markup.Xaml.UnitTests/Data/MultiBindingTests.cs
  17. 3
      tests/Avalonia.Styling.UnitTests/SelectorTests_Child.cs
  18. 12
      tests/Avalonia.UnitTests/InvariantCultureFixture.cs

2
src/Markup/Avalonia.Markup.Xaml/Data/MultiBinding.cs

@ -102,7 +102,7 @@ namespace Avalonia.Markup.Xaml.Data
private object ConvertValue(IList<object> values, Type targetType) private object ConvertValue(IList<object> 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) if (converted == AvaloniaProperty.UnsetValue && FallbackValue != null)
{ {

4
src/Markup/Avalonia.Markup/Data/BindingExpression.cs

@ -122,7 +122,7 @@ namespace Avalonia.Markup.Data
value, value,
type, type,
ConverterParameter, ConverterParameter,
CultureInfo.CurrentUICulture); CultureInfo.CurrentCulture);
if (converted == AvaloniaProperty.UnsetValue) if (converted == AvaloniaProperty.UnsetValue)
{ {
@ -186,7 +186,7 @@ namespace Avalonia.Markup.Data
value, value,
_targetType, _targetType,
ConverterParameter, ConverterParameter,
CultureInfo.CurrentUICulture); CultureInfo.CurrentCulture);
notification = converted as BindingNotification; notification = converted as BindingNotification;

2
tests/Avalonia.Base.UnitTests/Properties/AssemblyInfo.cs

@ -7,4 +7,4 @@ using Xunit;
[assembly: AssemblyTitle("Avalonia.UnitTests")] [assembly: AssemblyTitle("Avalonia.UnitTests")]
// Don't run tests in parallel. // Don't run tests in parallel.
[assembly: CollectionBehavior(MaxParallelThreads = 1)] [assembly: CollectionBehavior(DisableTestParallelization = true)]

3
tests/Avalonia.Markup.UnitTests/ControlLocatorTests.cs

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Threading.Tasks;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.UnitTests; using Avalonia.UnitTests;
using Xunit; using Xunit;
@ -13,7 +14,7 @@ namespace Avalonia.Markup.UnitTests
public class ControlLocatorTests public class ControlLocatorTests
{ {
[Fact] [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 target;
TextBlock relativeTo; TextBlock relativeTo;

70
tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Markup.Data; using Avalonia.Markup.Data;
using Avalonia.UnitTests; using Avalonia.UnitTests;
@ -17,13 +18,15 @@ namespace Avalonia.Markup.UnitTests.Data
public class BindingExpressionTests : IClassFixture<InvariantCultureFixture> public class BindingExpressionTests : IClassFixture<InvariantCultureFixture>
{ {
[Fact] [Fact]
public async void Should_Get_Simple_Property_Value() public async Task Should_Get_Simple_Property_Value()
{ {
var data = new Class1 { StringValue = "foo" }; var data = new Class1 { StringValue = "foo" };
var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(string)); var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(string));
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal("foo", result); Assert.Equal("foo", result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -35,6 +38,8 @@ namespace Avalonia.Markup.UnitTests.Data
target.OnNext("bar"); target.OnNext("bar");
Assert.Equal("bar", data.StringValue); Assert.Equal("bar", data.StringValue);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -46,36 +51,44 @@ namespace Avalonia.Markup.UnitTests.Data
target.OnNext("bar"); target.OnNext("bar");
Assert.Equal("bar", data.Foo[0]); Assert.Equal("bar", data.Foo[0]);
GC.KeepAlive(data);
} }
[Fact] [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 data = new Class1 { StringValue = "5.6" };
var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(double)); var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(double));
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(5.6, result); Assert.Equal(5.6, result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new Class1 { StringValue = "foo" };
var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(double)); var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(double));
var result = await target.Take(1); var result = await target.Take(1);
Assert.IsType<BindingNotification>(result); Assert.IsType<BindingNotification>(result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new Class1 { StringValue = null };
var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(double)); var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(double));
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(AvaloniaProperty.UnsetValue, result); Assert.Equal(AvaloniaProperty.UnsetValue, result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -87,16 +100,20 @@ namespace Avalonia.Markup.UnitTests.Data
target.OnNext(6.7); target.OnNext(6.7);
Assert.Equal((6.7).ToString(), data.StringValue); Assert.Equal((6.7).ToString(), data.StringValue);
GC.KeepAlive(data);
} }
[Fact] [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 data = new Class1 { DoubleValue = 5.6 };
var target = new BindingExpression(new ExpressionObserver(data, "DoubleValue"), typeof(string)); var target = new BindingExpression(new ExpressionObserver(data, "DoubleValue"), typeof(string));
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal((5.6).ToString(), result); Assert.Equal((5.6).ToString(), result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -108,10 +125,12 @@ namespace Avalonia.Markup.UnitTests.Data
target.OnNext("6.7"); target.OnNext("6.7");
Assert.Equal(6.7, data.DoubleValue); Assert.Equal(6.7, data.DoubleValue);
GC.KeepAlive(data);
} }
[Fact] [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 data = new Class1 { StringValue = "foo" };
var target = new BindingExpression( var target = new BindingExpression(
@ -127,10 +146,12 @@ namespace Avalonia.Markup.UnitTests.Data
BindingErrorType.Error, BindingErrorType.Error,
42), 42),
result); result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new Class1 { StringValue = "foo" };
var target = new BindingExpression( var target = new BindingExpression(
@ -146,10 +167,12 @@ namespace Avalonia.Markup.UnitTests.Data
BindingErrorType.Error, BindingErrorType.Error,
42), 42),
result); result);
GC.KeepAlive(data);
} }
[Fact(Skip="Result is not always AggregateException.")] [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 data = new Class1 { StringValue = "foo" };
var target = new BindingExpression( var target = new BindingExpression(
@ -166,10 +189,12 @@ namespace Avalonia.Markup.UnitTests.Data
new InvalidCastException("Could not convert FallbackValue 'bar' to 'System.Int32'")), new InvalidCastException("Could not convert FallbackValue 'bar' to 'System.Int32'")),
BindingErrorType.Error), BindingErrorType.Error),
result); result);
GC.KeepAlive(data);
} }
[Fact(Skip="Result is not always AggregateException.")] [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 data = new Class1 { StringValue = "foo" };
var target = new BindingExpression( var target = new BindingExpression(
@ -186,6 +211,8 @@ namespace Avalonia.Markup.UnitTests.Data
new InvalidCastException("Could not convert FallbackValue 'bar' to 'System.Int32'")), new InvalidCastException("Could not convert FallbackValue 'bar' to 'System.Int32'")),
BindingErrorType.Error), BindingErrorType.Error),
result); result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -197,6 +224,8 @@ namespace Avalonia.Markup.UnitTests.Data
target.OnNext("foo"); target.OnNext("foo");
Assert.Equal(5.6, data.DoubleValue); Assert.Equal(5.6, data.DoubleValue);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -212,6 +241,8 @@ namespace Avalonia.Markup.UnitTests.Data
target.OnNext("foo"); target.OnNext("foo");
Assert.Equal(9.8, data.DoubleValue); Assert.Equal(9.8, data.DoubleValue);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -223,6 +254,8 @@ namespace Avalonia.Markup.UnitTests.Data
target.OnNext(null); target.OnNext(null);
Assert.Equal(0, data.DoubleValue); Assert.Equal(0, data.DoubleValue);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -234,13 +267,16 @@ namespace Avalonia.Markup.UnitTests.Data
target.OnNext(AvaloniaProperty.UnsetValue); target.OnNext(AvaloniaProperty.UnsetValue);
Assert.Equal(0, data.DoubleValue); Assert.Equal(0, data.DoubleValue);
GC.KeepAlive(data);
} }
[Fact(Skip="Moq.MockException")] [Fact]
public void Should_Pass_ConverterParameter_To_Convert() public void Should_Pass_ConverterParameter_To_Convert()
{ {
var data = new Class1 { DoubleValue = 5.6 }; var data = new Class1 { DoubleValue = 5.6 };
var converter = new Mock<IValueConverter>(); var converter = new Mock<IValueConverter>();
var target = new BindingExpression( var target = new BindingExpression(
new ExpressionObserver(data, "DoubleValue"), new ExpressionObserver(data, "DoubleValue"),
typeof(string), typeof(string),
@ -249,10 +285,12 @@ namespace Avalonia.Markup.UnitTests.Data
target.Subscribe(_ => { }); 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));
GC.KeepAlive(data);
} }
[Fact(Skip="Moq.MockException")] [Fact]
public void Should_Pass_ConverterParameter_To_ConvertBack() public void Should_Pass_ConverterParameter_To_ConvertBack()
{ {
var data = new Class1 { DoubleValue = 5.6 }; var data = new Class1 { DoubleValue = 5.6 };
@ -265,10 +303,12 @@ namespace Avalonia.Markup.UnitTests.Data
target.OnNext("bar"); 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));
GC.KeepAlive(data);
} }
[Fact(Skip="Moq.MockException")] [Fact]
public void Should_Handle_DataValidation() public void Should_Handle_DataValidation()
{ {
var data = new Class1 { DoubleValue = 5.6 }; var data = new Class1 { DoubleValue = 5.6 };
@ -292,6 +332,8 @@ namespace Avalonia.Markup.UnitTests.Data
BindingErrorType.Error) BindingErrorType.Error)
}, },
result); result);
GC.KeepAlive(data);
} }
private class Class1 : NotifyingBase private class Class1 : NotifyingBase

5
tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_AttachedProperty.cs

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Threading.Tasks;
using Avalonia.Diagnostics; using Avalonia.Diagnostics;
using Avalonia.Markup.Data; using Avalonia.Markup.Data;
using Xunit; using Xunit;
@ -18,7 +19,7 @@ namespace Avalonia.Markup.UnitTests.Data
} }
[Fact] [Fact]
public async void Should_Get_Attached_Property_Value() public async Task Should_Get_Attached_Property_Value()
{ {
var data = new Class1(); var data = new Class1();
var target = new ExpressionObserver(data, "(Owner.Foo)"); var target = new ExpressionObserver(data, "(Owner.Foo)");
@ -30,7 +31,7 @@ namespace Avalonia.Markup.UnitTests.Data
} }
[Fact] [Fact]
public async void Should_Get_Chained_Attached_Property_Value() public async Task Should_Get_Chained_Attached_Property_Value()
{ {
var data = new Class1 var data = new Class1
{ {

3
tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_AvaloniaProperty.cs

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Threading.Tasks;
using Avalonia.Diagnostics; using Avalonia.Diagnostics;
using Avalonia.Markup.Data; using Avalonia.Markup.Data;
using Xunit; using Xunit;
@ -18,7 +19,7 @@ namespace Avalonia.Markup.UnitTests.Data
} }
[Fact] [Fact]
public async void Should_Get_Simple_Property_Value() public async Task Should_Get_Simple_Property_Value()
{ {
var data = new Class1(); var data = new Class1();
var target = new ExpressionObserver(data, "Foo"); var target = new ExpressionObserver(data, "Foo");

9
tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_DataValidation.cs

@ -28,6 +28,8 @@ namespace Avalonia.Markup.UnitTests.Data
observer.SetValue(-5); observer.SetValue(-5);
Assert.False(validationMessageFound); Assert.False(validationMessageFound);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -43,6 +45,8 @@ namespace Avalonia.Markup.UnitTests.Data
observer.SetValue(-5); observer.SetValue(-5);
Assert.True(validationMessageFound); Assert.True(validationMessageFound);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -102,6 +106,8 @@ namespace Avalonia.Markup.UnitTests.Data
new BindingNotification(new Exception("Must be positive"), BindingErrorType.DataValidationError, 5), new BindingNotification(new Exception("Must be positive"), BindingErrorType.DataValidationError, 5),
new BindingNotification(5), new BindingNotification(5),
}, result); }, result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -147,6 +153,9 @@ namespace Avalonia.Markup.UnitTests.Data
BindingErrorType.Error, BindingErrorType.Error,
AvaloniaProperty.UnsetValue), AvaloniaProperty.UnsetValue),
}, result); }, result);
GC.KeepAlive(container);
GC.KeepAlive(inner);
} }
public class ExceptionTest : NotifyingBase public class ExceptionTest : NotifyingBase

67
tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Indexer.cs

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Threading.Tasks;
using Avalonia.Collections; using Avalonia.Collections;
using Avalonia.Diagnostics; using Avalonia.Diagnostics;
using Avalonia.Markup.Data; using Avalonia.Markup.Data;
@ -16,113 +17,135 @@ namespace Avalonia.Markup.UnitTests.Data
public class ExpressionObserverTests_Indexer public class ExpressionObserverTests_Indexer
{ {
[Fact] [Fact]
public async void Should_Get_Array_Value() public async Task Should_Get_Array_Value()
{ {
var data = new { Foo = new [] { "foo", "bar" } }; var data = new { Foo = new [] { "foo", "bar" } };
var target = new ExpressionObserver(data, "Foo[1]"); var target = new ExpressionObserver(data, "Foo[1]");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal("bar", result); Assert.Equal("bar", result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new { Foo = new[] { "foo", "bar" } };
var target = new ExpressionObserver(data, "Foo[invalid]"); var target = new ExpressionObserver(data, "Foo[invalid]");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(AvaloniaProperty.UnsetValue, result); Assert.Equal(AvaloniaProperty.UnsetValue, result);
GC.KeepAlive(data);
} }
[Fact] [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<int, string> { { 1, "foo" } } }; var data = new { Foo = new Dictionary<int, string> { { 1, "foo" } } };
var target = new ExpressionObserver(data, "Foo[invalid]"); var target = new ExpressionObserver(data, "Foo[invalid]");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(AvaloniaProperty.UnsetValue, result); Assert.Equal(AvaloniaProperty.UnsetValue, result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new { Foo = 5 };
var target = new ExpressionObserver(data, "Foo[noindexer]"); var target = new ExpressionObserver(data, "Foo[noindexer]");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(AvaloniaProperty.UnsetValue, result); Assert.Equal(AvaloniaProperty.UnsetValue, result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new { Foo = new[,] { { "foo", "bar" }, { "baz", "qux" } } };
var target = new ExpressionObserver(data, "Foo[1, 1]"); var target = new ExpressionObserver(data, "Foo[1, 1]");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal("qux", result); Assert.Equal("qux", result);
GC.KeepAlive(data);
} }
[Fact] [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<string, string> { { "foo", "bar" }, { "baz", "qux" } } }; var data = new { Foo = new Dictionary<string, string> { { "foo", "bar" }, { "baz", "qux" } } };
var target = new ExpressionObserver(data, "Foo[foo]"); var target = new ExpressionObserver(data, "Foo[foo]");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal("bar", result); Assert.Equal("bar", result);
GC.KeepAlive(data);
} }
[Fact] [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<double, string> { { 1.0, "bar" }, { 2.0, "qux" } } }; var data = new { Foo = new Dictionary<double, string> { { 1.0, "bar" }, { 2.0, "qux" } } };
var target = new ExpressionObserver(data, "Foo[1.0]"); var target = new ExpressionObserver(data, "Foo[1.0]");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal("bar", result); Assert.Equal("bar", result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new { Foo = new[] { "foo", "bar" } };
var target = new ExpressionObserver(data, "Foo[2]"); var target = new ExpressionObserver(data, "Foo[2]");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(AvaloniaProperty.UnsetValue, result); Assert.Equal(AvaloniaProperty.UnsetValue, result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new { Foo = new[] { "foo", "bar" } };
var target = new ExpressionObserver(data, "Foo[1,2]"); var target = new ExpressionObserver(data, "Foo[1,2]");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(AvaloniaProperty.UnsetValue, result); Assert.Equal(AvaloniaProperty.UnsetValue, result);
GC.KeepAlive(data);
} }
[Fact] [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<string> { "foo", "bar" } }; var data = new { Foo = new List<string> { "foo", "bar" } };
var target = new ExpressionObserver(data, "Foo[2]"); var target = new ExpressionObserver(data, "Foo[2]");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(AvaloniaProperty.UnsetValue, result); Assert.Equal(AvaloniaProperty.UnsetValue, result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
public async void Should_Get_List_Value() public async Task Should_Get_List_Value()
{ {
var data = new { Foo = new List<string> { "foo", "bar" } }; var data = new { Foo = new List<string> { "foo", "bar" } };
var target = new ExpressionObserver(data, "Foo[1]"); var target = new ExpressionObserver(data, "Foo[1]");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal("bar", result); Assert.Equal("bar", result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -139,6 +162,8 @@ namespace Avalonia.Markup.UnitTests.Data
Assert.Equal(new[] { AvaloniaProperty.UnsetValue, "baz" }, result); Assert.Equal(new[] { AvaloniaProperty.UnsetValue, "baz" }, result);
Assert.Null(((INotifyCollectionChangedDebug)data.Foo).GetCollectionChangedSubscribers()); Assert.Null(((INotifyCollectionChangedDebug)data.Foo).GetCollectionChangedSubscribers());
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -155,6 +180,8 @@ namespace Avalonia.Markup.UnitTests.Data
Assert.Equal(new[] { "foo", "bar" }, result); Assert.Equal(new[] { "foo", "bar" }, result);
Assert.Null(((INotifyCollectionChangedDebug)data.Foo).GetCollectionChangedSubscribers()); Assert.Null(((INotifyCollectionChangedDebug)data.Foo).GetCollectionChangedSubscribers());
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -171,6 +198,8 @@ namespace Avalonia.Markup.UnitTests.Data
Assert.Equal(new[] { "bar", "baz" }, result); Assert.Equal(new[] { "bar", "baz" }, result);
Assert.Null(((INotifyCollectionChangedDebug)data.Foo).GetCollectionChangedSubscribers()); Assert.Null(((INotifyCollectionChangedDebug)data.Foo).GetCollectionChangedSubscribers());
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -187,6 +216,9 @@ namespace Avalonia.Markup.UnitTests.Data
data.Foo.Move(0, 1); data.Foo.Move(0, 1);
Assert.Equal(new[] { "bar", "foo" }, result); Assert.Equal(new[] { "bar", "foo" }, result);
GC.KeepAlive(sub);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -200,6 +232,9 @@ namespace Avalonia.Markup.UnitTests.Data
data.Foo.Clear(); data.Foo.Clear();
Assert.Equal(new[] { "bar", AvaloniaProperty.UnsetValue }, result); Assert.Equal(new[] { "bar", AvaloniaProperty.UnsetValue }, result);
GC.KeepAlive(sub);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -220,6 +255,8 @@ namespace Avalonia.Markup.UnitTests.Data
var expected = new[] { "bar", "bar2" }; var expected = new[] { "bar", "bar2" };
Assert.Equal(expected, result); Assert.Equal(expected, result);
Assert.Equal(0, data.Foo.PropertyChangedSubscriptionCount); Assert.Equal(0, data.Foo.PropertyChangedSubscriptionCount);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -234,6 +271,8 @@ namespace Avalonia.Markup.UnitTests.Data
} }
Assert.Equal("baz", data.Foo[1]); Assert.Equal("baz", data.Foo[1]);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -254,6 +293,8 @@ namespace Avalonia.Markup.UnitTests.Data
} }
Assert.Equal(4, data.Foo["foo"]); Assert.Equal(4, data.Foo["foo"]);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -274,6 +315,8 @@ namespace Avalonia.Markup.UnitTests.Data
} }
Assert.Equal(4, data.Foo["bar"]); Assert.Equal(4, data.Foo["bar"]);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -291,6 +334,8 @@ namespace Avalonia.Markup.UnitTests.Data
} }
Assert.Equal("bar2", data.Foo["foo"]); Assert.Equal("bar2", data.Foo["foo"]);
GC.KeepAlive(data);
} }
private class NonIntegerIndexer : NotifyingBase private class NonIntegerIndexer : NotifyingBase

5
tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Lifetime.cs

@ -90,7 +90,8 @@ namespace Avalonia.Markup.UnitTests.Data
{ {
var scheduler = new TestScheduler(); var scheduler = new TestScheduler();
var update = scheduler.CreateColdObservable<Unit>(); var update = scheduler.CreateColdObservable<Unit>();
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<object>(); var result = new List<object>();
using (target.Subscribe(x => result.Add(x))) using (target.Subscribe(x => result.Add(x)))
@ -101,6 +102,8 @@ namespace Avalonia.Markup.UnitTests.Data
Assert.Equal(new[] { "foo" }, result); Assert.Equal(new[] { "foo" }, result);
Assert.All(update.Subscriptions, x => Assert.NotEqual(Subscription.Infinite, x.Unsubscribe)); Assert.All(update.Subscriptions, x => Assert.NotEqual(Subscription.Infinite, x.Unsubscribe));
GC.KeepAlive(data);
} }
private Recorded<Notification<object>> OnNext(long time, object value) private Recorded<Notification<object>> OnNext(long time, object value)

31
tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Negation.cs

@ -3,6 +3,7 @@
using System; using System;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Threading.Tasks;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Markup.Data; using Avalonia.Markup.Data;
using Xunit; using Xunit;
@ -12,57 +13,67 @@ namespace Avalonia.Markup.UnitTests.Data
public class ExpressionObserverTests_Negation public class ExpressionObserverTests_Negation
{ {
[Fact] [Fact]
public async void Should_Negate_Boolean_Value() public async Task Should_Negate_Boolean_Value()
{ {
var data = new { Foo = true }; var data = new { Foo = true };
var target = new ExpressionObserver(data, "!Foo"); var target = new ExpressionObserver(data, "!Foo");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(false, result); Assert.Equal(false, result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
public async void Should_Negate_0() public async Task Should_Negate_0()
{ {
var data = new { Foo = 0 }; var data = new { Foo = 0 };
var target = new ExpressionObserver(data, "!Foo"); var target = new ExpressionObserver(data, "!Foo");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(true, result); Assert.Equal(true, result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
public async void Should_Negate_1() public async Task Should_Negate_1()
{ {
var data = new { Foo = 1 }; var data = new { Foo = 1 };
var target = new ExpressionObserver(data, "!Foo"); var target = new ExpressionObserver(data, "!Foo");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(false, result); Assert.Equal(false, result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
public async void Should_Negate_False_String() public async Task Should_Negate_False_String()
{ {
var data = new { Foo = "false" }; var data = new { Foo = "false" };
var target = new ExpressionObserver(data, "!Foo"); var target = new ExpressionObserver(data, "!Foo");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(true, result); Assert.Equal(true, result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
public async void Should_Negate_True_String() public async Task Should_Negate_True_String()
{ {
var data = new { Foo = "True" }; var data = new { Foo = "True" };
var target = new ExpressionObserver(data, "!Foo"); var target = new ExpressionObserver(data, "!Foo");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(false, result); Assert.Equal(false, result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new { Foo = "foo" };
var target = new ExpressionObserver(data, "!Foo"); var target = new ExpressionObserver(data, "!Foo");
@ -73,10 +84,12 @@ namespace Avalonia.Markup.UnitTests.Data
new InvalidCastException($"Unable to convert 'foo' to bool."), new InvalidCastException($"Unable to convert 'foo' to bool."),
BindingErrorType.Error), BindingErrorType.Error),
result); result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new { Foo = new object() };
var target = new ExpressionObserver(data, "!Foo"); var target = new ExpressionObserver(data, "!Foo");
@ -87,6 +100,8 @@ namespace Avalonia.Markup.UnitTests.Data
new InvalidCastException($"Unable to convert 'System.Object' to bool."), new InvalidCastException($"Unable to convert 'System.Object' to bool."),
BindingErrorType.Error), BindingErrorType.Error),
result); result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -96,6 +111,8 @@ namespace Avalonia.Markup.UnitTests.Data
var target = new ExpressionObserver(data, "!Foo"); var target = new ExpressionObserver(data, "!Foo");
Assert.False(target.SetValue("bar")); Assert.False(target.SetValue("bar"));
GC.KeepAlive(data);
} }
} }
} }

12
tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Observable.cs

@ -29,6 +29,8 @@ namespace Avalonia.Markup.UnitTests.Data
sync.ExecutePostedCallbacks(); sync.ExecutePostedCallbacks();
Assert.Equal(new[] { source }, result); Assert.Equal(new[] { source }, result);
GC.KeepAlive(data);
} }
} }
@ -47,6 +49,8 @@ namespace Avalonia.Markup.UnitTests.Data
sync.ExecutePostedCallbacks(); sync.ExecutePostedCallbacks();
Assert.Equal(new[] { "foo", "bar" }, result); Assert.Equal(new[] { "foo", "bar" }, result);
GC.KeepAlive(data);
} }
} }
@ -67,6 +71,8 @@ namespace Avalonia.Markup.UnitTests.Data
sub.Dispose(); sub.Dispose();
Assert.Equal(0, data.PropertyChangedSubscriptionCount); 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 // 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. // it's hard to know what to do here so for the moment the value is returned.
Assert.Equal(new[] { "foo", "bar" }, result); Assert.Equal(new[] { "foo", "bar" }, result);
GC.KeepAlive(data);
} }
} }
@ -107,6 +115,8 @@ namespace Avalonia.Markup.UnitTests.Data
sub.Dispose(); sub.Dispose();
Assert.Equal(0, data.PropertyChangedSubscriptionCount); Assert.Equal(0, data.PropertyChangedSubscriptionCount);
GC.KeepAlive(data);
} }
} }
@ -132,6 +142,8 @@ namespace Avalonia.Markup.UnitTests.Data
result); result);
sub.Dispose(); sub.Dispose();
GC.KeepAlive(data);
} }
} }

78
tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs

@ -11,19 +11,22 @@ using Avalonia.Data;
using Avalonia.Markup.Data; using Avalonia.Markup.Data;
using Avalonia.UnitTests; using Avalonia.UnitTests;
using Xunit; using Xunit;
using System.Threading.Tasks;
namespace Avalonia.Markup.UnitTests.Data namespace Avalonia.Markup.UnitTests.Data
{ {
public class ExpressionObserverTests_Property public class ExpressionObserverTests_Property
{ {
[Fact] [Fact]
public async void Should_Get_Simple_Property_Value() public async Task Should_Get_Simple_Property_Value()
{ {
var data = new { Foo = "foo" }; var data = new { Foo = "foo" };
var target = new ExpressionObserver(data, "Foo"); var target = new ExpressionObserver(data, "Foo");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal("foo", result); Assert.Equal("foo", result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -35,76 +38,92 @@ namespace Avalonia.Markup.UnitTests.Data
target.Subscribe(_ => { }); target.Subscribe(_ => { });
Assert.Equal(typeof(string), target.ResultType); Assert.Equal(typeof(string), target.ResultType);
GC.KeepAlive(data);
} }
[Fact] [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 data = new { Foo = (string)null };
var target = new ExpressionObserver(data, "Foo"); var target = new ExpressionObserver(data, "Foo");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Null(result); Assert.Null(result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new Class3 { Foo = "foo" };
var target = new ExpressionObserver(data, "Foo"); var target = new ExpressionObserver(data, "Foo");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal("foo", result); Assert.Equal("foo", result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new Class3 { Foo = "foo" };
var target = new ExpressionObserver(default(object), "Foo"); var target = new ExpressionObserver(default(object), "Foo");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(AvaloniaProperty.UnsetValue, result); Assert.Equal(AvaloniaProperty.UnsetValue, result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new Class3 { Foo = "foo" };
var target = new ExpressionObserver(AvaloniaProperty.UnsetValue, "Foo"); var target = new ExpressionObserver(AvaloniaProperty.UnsetValue, "Foo");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(AvaloniaProperty.UnsetValue, result); Assert.Equal(AvaloniaProperty.UnsetValue, result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new Class3 { Foo = "foo" };
var target = new ExpressionObserver(Observable.Return(default(object)), "Foo"); var target = new ExpressionObserver(Observable.Return(default(object)), "Foo");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(AvaloniaProperty.UnsetValue, result); Assert.Equal(AvaloniaProperty.UnsetValue, result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new Class3 { Foo = "foo" };
var target = new ExpressionObserver(Observable.Return(AvaloniaProperty.UnsetValue), "Foo"); var target = new ExpressionObserver(Observable.Return(AvaloniaProperty.UnsetValue), "Foo");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal(AvaloniaProperty.UnsetValue, result); Assert.Equal(AvaloniaProperty.UnsetValue, result);
GC.KeepAlive(data);
} }
[Fact] [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 data = new { Foo = new { Bar = new { Baz = "baz" } } };
var target = new ExpressionObserver(data, "Foo.Bar.Baz"); var target = new ExpressionObserver(data, "Foo.Bar.Baz");
var result = await target.Take(1); var result = await target.Take(1);
Assert.Equal("baz", result); Assert.Equal("baz", result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -116,10 +135,12 @@ namespace Avalonia.Markup.UnitTests.Data
target.Subscribe(_ => { }); target.Subscribe(_ => { });
Assert.Equal(typeof(string), target.ResultType); Assert.Equal(typeof(string), target.ResultType);
GC.KeepAlive(data);
} }
[Fact] [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 data = new { Foo = new { Bar = 1 } };
var target = new ExpressionObserver(data, "Foo.Bar.Baz"); var target = new ExpressionObserver(data, "Foo.Bar.Baz");
@ -131,6 +152,8 @@ namespace Avalonia.Markup.UnitTests.Data
new BindingNotification( new BindingNotification(
new MissingMemberException("Could not find CLR property 'Baz' on '1'"), BindingErrorType.Error), new MissingMemberException("Could not find CLR property 'Baz' on '1'"), BindingErrorType.Error),
result); result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -151,6 +174,8 @@ namespace Avalonia.Markup.UnitTests.Data
AvaloniaProperty.UnsetValue), AvaloniaProperty.UnsetValue),
}, },
result); result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -160,6 +185,8 @@ namespace Avalonia.Markup.UnitTests.Data
var target = new ExpressionObserver(data, "Foo.Bar.Baz"); var target = new ExpressionObserver(data, "Foo.Bar.Baz");
Assert.Null(target.ResultType); Assert.Null(target.ResultType);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -177,6 +204,8 @@ namespace Avalonia.Markup.UnitTests.Data
sub.Dispose(); sub.Dispose();
Assert.Equal(0, data.PropertyChangedSubscriptionCount); Assert.Equal(0, data.PropertyChangedSubscriptionCount);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -205,6 +234,8 @@ namespace Avalonia.Markup.UnitTests.Data
sub.Dispose(); sub.Dispose();
Assert.Equal(0, data.PropertyChangedSubscriptionCount); Assert.Equal(0, data.PropertyChangedSubscriptionCount);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -224,6 +255,8 @@ namespace Avalonia.Markup.UnitTests.Data
Assert.Equal(0, data.PropertyChangedSubscriptionCount); Assert.Equal(0, data.PropertyChangedSubscriptionCount);
Assert.Equal(0, data.Next.PropertyChangedSubscriptionCount); Assert.Equal(0, data.Next.PropertyChangedSubscriptionCount);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -245,6 +278,8 @@ namespace Avalonia.Markup.UnitTests.Data
Assert.Equal(0, data.PropertyChangedSubscriptionCount); Assert.Equal(0, data.PropertyChangedSubscriptionCount);
Assert.Equal(0, data.Next.PropertyChangedSubscriptionCount); Assert.Equal(0, data.Next.PropertyChangedSubscriptionCount);
Assert.Equal(0, old.PropertyChangedSubscriptionCount); Assert.Equal(0, old.PropertyChangedSubscriptionCount);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -286,6 +321,8 @@ namespace Avalonia.Markup.UnitTests.Data
Assert.Equal(0, data.PropertyChangedSubscriptionCount); Assert.Equal(0, data.PropertyChangedSubscriptionCount);
Assert.Equal(0, data.Next.PropertyChangedSubscriptionCount); Assert.Equal(0, data.Next.PropertyChangedSubscriptionCount);
Assert.Equal(0, old.PropertyChangedSubscriptionCount); Assert.Equal(0, old.PropertyChangedSubscriptionCount);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -318,6 +355,8 @@ namespace Avalonia.Markup.UnitTests.Data
Assert.Equal(0, data.Next.PropertyChangedSubscriptionCount); Assert.Equal(0, data.Next.PropertyChangedSubscriptionCount);
Assert.Equal(0, breaking.PropertyChangedSubscriptionCount); Assert.Equal(0, breaking.PropertyChangedSubscriptionCount);
Assert.Equal(0, old.PropertyChangedSubscriptionCount); Assert.Equal(0, old.PropertyChangedSubscriptionCount);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -334,6 +373,8 @@ namespace Avalonia.Markup.UnitTests.Data
update.OnNext(Unit.Default); update.OnNext(Unit.Default);
Assert.Equal(new[] { "foo", "bar" }, result); Assert.Equal(new[] { "foo", "bar" }, result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -374,6 +415,8 @@ namespace Avalonia.Markup.UnitTests.Data
Assert.Equal(new[] { "foo", "bar" }, result1); Assert.Equal(new[] { "foo", "bar" }, result1);
Assert.Equal(new[] { "foo", "bar" }, result2); Assert.Equal(new[] { "foo", "bar" }, result2);
Assert.Equal(new[] { "bar" }, result3); Assert.Equal(new[] { "bar" }, result3);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -391,6 +434,8 @@ namespace Avalonia.Markup.UnitTests.Data
sub2.Dispose(); sub2.Dispose();
Assert.Equal(0, data.PropertyChangedSubscriptionCount); Assert.Equal(0, data.PropertyChangedSubscriptionCount);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -405,6 +450,8 @@ namespace Avalonia.Markup.UnitTests.Data
} }
Assert.Equal("bar", data.Foo); Assert.Equal("bar", data.Foo);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -419,6 +466,8 @@ namespace Avalonia.Markup.UnitTests.Data
} }
Assert.Equal("baz", ((Class2)data.Next).Bar); Assert.Equal("baz", ((Class2)data.Next).Bar);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -431,6 +480,8 @@ namespace Avalonia.Markup.UnitTests.Data
{ {
Assert.False(target.SetValue("baz")); Assert.False(target.SetValue("baz"));
} }
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -444,6 +495,8 @@ namespace Avalonia.Markup.UnitTests.Data
target.SetValue("bar"); target.SetValue("bar");
Assert.Equal(new[] { null, "bar" }, result); Assert.Equal(new[] { null, "bar" }, result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -457,6 +510,8 @@ namespace Avalonia.Markup.UnitTests.Data
target.SetValue("bar"); target.SetValue("bar");
Assert.Equal(new[] { null, "bar" }, result); Assert.Equal(new[] { null, "bar" }, result);
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -469,6 +524,8 @@ namespace Avalonia.Markup.UnitTests.Data
{ {
Assert.False(target.SetValue("baz")); Assert.False(target.SetValue("baz"));
} }
GC.KeepAlive(data);
} }
[Fact] [Fact]
@ -498,6 +555,9 @@ namespace Avalonia.Markup.UnitTests.Data
Assert.Equal(0, first.PropertyChangedSubscriptionCount); Assert.Equal(0, first.PropertyChangedSubscriptionCount);
Assert.Equal(0, second.PropertyChangedSubscriptionCount); Assert.Equal(0, second.PropertyChangedSubscriptionCount);
GC.KeepAlive(first);
GC.KeepAlive(second);
} }
[Fact] [Fact]

12
tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Task.cs

@ -30,6 +30,8 @@ namespace Avalonia.Markup.UnitTests.Data
Assert.Equal(1, result.Count); Assert.Equal(1, result.Count);
Assert.IsType<Task<string>>(result[0]); Assert.IsType<Task<string>>(result[0]);
GC.KeepAlive(data);
} }
} }
@ -45,6 +47,8 @@ namespace Avalonia.Markup.UnitTests.Data
var sub = target.Subscribe(x => result.Add(x)); var sub = target.Subscribe(x => result.Add(x));
Assert.Equal(new[] { "foo" }, result); Assert.Equal(new[] { "foo" }, result);
GC.KeepAlive(data);
} }
} }
@ -63,6 +67,8 @@ namespace Avalonia.Markup.UnitTests.Data
sync.ExecutePostedCallbacks(); sync.ExecutePostedCallbacks();
Assert.Equal(new[] { "foo" }, result); Assert.Equal(new[] { "foo" }, result);
GC.KeepAlive(data);
} }
} }
@ -88,6 +94,8 @@ namespace Avalonia.Markup.UnitTests.Data
BindingErrorType.Error) BindingErrorType.Error)
}, },
result); result);
GC.KeepAlive(data);
} }
} }
@ -110,6 +118,8 @@ namespace Avalonia.Markup.UnitTests.Data
BindingErrorType.Error) BindingErrorType.Error)
}, },
result); 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 // 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. // hard to know what to do here so for the moment the value is returned.
Assert.Equal(new [] { "foo" }, result); Assert.Equal(new [] { "foo" }, result);
GC.KeepAlive(data);
} }
} }

2
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(new ArgumentOutOfRangeException("value"), BindingErrorType.DataValidationError),
new BindingNotification(6), new BindingNotification(6),
}, result); }, result);
GC.KeepAlive(data);
} }
public class Data : NotifyingBase public class Data : NotifyingBase

3
tests/Avalonia.Markup.Xaml.UnitTests/Data/MultiBindingTests.cs

@ -10,13 +10,14 @@ using Moq;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml.Data; using Avalonia.Markup.Xaml.Data;
using Xunit; using Xunit;
using System.Threading.Tasks;
namespace Avalonia.Markup.Xaml.UnitTests.Data namespace Avalonia.Markup.Xaml.UnitTests.Data
{ {
public class MultiBindingTests public class MultiBindingTests
{ {
[Fact] [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 source = new { A = 1, B = 2, C = 3 };
var binding = new MultiBinding var binding = new MultiBinding

3
tests/Avalonia.Styling.UnitTests/SelectorTests_Child.cs

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Threading.Tasks;
using Avalonia.Collections; using Avalonia.Collections;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Data; using Avalonia.Data;
@ -45,7 +46,7 @@ namespace Avalonia.Styling.UnitTests
} }
[Fact] [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 parent = new TestLogical1();
var child = new TestLogical2(); var child = new TestLogical2();

12
tests/Avalonia.UnitTests/InvariantCultureFixture.cs

@ -21,20 +21,20 @@ namespace Avalonia.UnitTests
public InvariantCultureFixture() public InvariantCultureFixture()
{ {
#if NET461 #if NET461
_restore = Thread.CurrentThread.CurrentUICulture; _restore = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
#else #else
_restore = CultureInfo.CurrentUICulture; _restore = CultureInfo.CurrentCulture;
CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture = CultureInfo.InvariantCulture; CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
#endif #endif
} }
public void Dispose() public void Dispose()
{ {
#if NET461 #if NET461
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = _restore; Thread.CurrentThread.CurrentCulture = _restore;
#else #else
CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture = _restore; CultureInfo.CurrentCulture = _restore;
#endif #endif
} }
} }

Loading…
Cancel
Save