diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj
index bc52e31d2c..63f500270d 100644
--- a/src/Avalonia.Base/Avalonia.Base.csproj
+++ b/src/Avalonia.Base/Avalonia.Base.csproj
@@ -44,7 +44,7 @@
Properties\SharedAssemblyInfo.cs
-
+
diff --git a/src/Avalonia.Base/Data/BindingChainNullException.cs b/src/Avalonia.Base/Data/BindingChainException.cs
similarity index 52%
rename from src/Avalonia.Base/Data/BindingChainNullException.cs
rename to src/Avalonia.Base/Data/BindingChainException.cs
index 0e50a36d8a..97b0d3ba8b 100644
--- a/src/Avalonia.Base/Data/BindingChainNullException.cs
+++ b/src/Avalonia.Base/Data/BindingChainException.cs
@@ -10,36 +10,39 @@ namespace Avalonia.Data
/// requested binding expression could not be evaluated because of a null in one of the links
/// of the binding chain.
///
- public class BindingChainNullException : Exception
+ public class BindingChainException : Exception
{
private string _message;
///
- /// Initalizes a new instance of the class.
+ /// Initalizes a new instance of the class.
///
- public BindingChainNullException()
+ public BindingChainException()
{
}
///
- /// Initalizes a new instance of the class.
+ /// Initalizes a new instance of the class.
///
- public BindingChainNullException(string message)
+ /// The error message.
+ public BindingChainException(string message)
{
_message = message;
}
///
- /// Initalizes a new instance of the class.
+ /// Initalizes a new instance of the class.
///
+ /// The error message.
/// The expression.
- ///
- /// The point in the expression at which the null was encountered.
+ ///
+ /// The point in the expression at which the error was encountered.
///
- public BindingChainNullException(string expression, string expressionNullPoint)
+ public BindingChainException(string message, string expression, string errorPoint)
{
+ _message = message;
Expression = expression;
- ExpressionNullPoint = expressionNullPoint;
+ ExpressionErrorPoint = errorPoint;
}
///
@@ -48,37 +51,27 @@ namespace Avalonia.Data
public string Expression { get; protected set; }
///
- /// Gets the point in the expression at which the null was encountered.
+ /// Gets the point in the expression at which the error occured.
///
- public string ExpressionNullPoint { get; protected set; }
+ public string ExpressionErrorPoint { get; protected set; }
///
public override string Message
{
get
{
- if (_message == null)
+ if (Expression != null && ExpressionErrorPoint != null)
{
- _message = BuildMessage();
+ return $"{_message} in expression '{Expression}' at '{ExpressionErrorPoint}'.";
+ }
+ else if (ExpressionErrorPoint != null)
+ {
+ return $"{_message} in expression '{ExpressionErrorPoint}'.";
+ }
+ else
+ {
+ return $"{_message} in expression.";
}
-
- return _message;
- }
- }
-
- private string BuildMessage()
- {
- if (Expression != null && ExpressionNullPoint != null)
- {
- return $"'{ExpressionNullPoint}' is null in expression '{Expression}'.";
- }
- else if (ExpressionNullPoint != null)
- {
- return $"'{ExpressionNullPoint}' is null in expression.";
- }
- else
- {
- return "Null encountered in binding expression.";
}
}
}
diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs
index ed92899cc6..bc8da38724 100644
--- a/src/Avalonia.Controls/TextBox.cs
+++ b/src/Avalonia.Controls/TextBox.cs
@@ -547,7 +547,7 @@ namespace Avalonia.Controls
var exceptions = aggregate == null ?
(IEnumerable)new[] { exception } :
aggregate.InnerExceptions;
- var filtered = exceptions.Where(x => !(x is BindingChainNullException)).ToList();
+ var filtered = exceptions.Where(x => !(x is BindingChainException)).ToList();
if (filtered.Count > 0)
{
diff --git a/src/Markup/Avalonia.Markup.Xaml/OmniXAML b/src/Markup/Avalonia.Markup.Xaml/OmniXAML
index b122549406..544af79d21 160000
--- a/src/Markup/Avalonia.Markup.Xaml/OmniXAML
+++ b/src/Markup/Avalonia.Markup.Xaml/OmniXAML
@@ -1 +1 @@
-Subproject commit b122549406107170bbe6e67c0d6a1a4252beef77
+Subproject commit 544af79d218127b4174da4be19896c5ca78eaa5d
diff --git a/src/Markup/Avalonia.Markup/Avalonia.Markup.csproj b/src/Markup/Avalonia.Markup/Avalonia.Markup.csproj
index 88c4a6ab18..1c3f453280 100644
--- a/src/Markup/Avalonia.Markup/Avalonia.Markup.csproj
+++ b/src/Markup/Avalonia.Markup/Avalonia.Markup.csproj
@@ -42,7 +42,8 @@
Properties\SharedAssemblyInfo.cs
-
+
+
@@ -63,9 +64,9 @@
-
-
-
+
+
+
diff --git a/src/Markup/Avalonia.Markup/Data/ExpressionNode.cs b/src/Markup/Avalonia.Markup/Data/ExpressionNode.cs
index b0957c7187..93f20e4c77 100644
--- a/src/Markup/Avalonia.Markup/Data/ExpressionNode.cs
+++ b/src/Markup/Avalonia.Markup/Data/ExpressionNode.cs
@@ -17,7 +17,6 @@ namespace Avalonia.Markup.Data
private WeakReference _target = UnsetReference;
private IDisposable _valueSubscription;
private IObserver _observer;
- private IDisposable _valuePluginSubscription;
public abstract string Description { get; }
public ExpressionNode Next { get; set; }
@@ -37,7 +36,6 @@ namespace Avalonia.Markup.Data
{
_valueSubscription?.Dispose();
_valueSubscription = null;
- _valuePluginSubscription?.Dispose();
_target = value;
if (running)
@@ -63,8 +61,6 @@ namespace Avalonia.Markup.Data
{
_valueSubscription?.Dispose();
_valueSubscription = null;
- _valuePluginSubscription?.Dispose();
- _valuePluginSubscription = null;
nextSubscription?.Dispose();
_observer = null;
});
@@ -92,7 +88,7 @@ namespace Avalonia.Markup.Data
protected virtual void NextValueChanged(object value)
{
- var bindingBroken = BindingNotification.ExtractError(value) as MarkupBindingChainNullException;
+ var bindingBroken = BindingNotification.ExtractError(value) as MarkupBindingChainException;
bindingBroken?.AddNode(Description);
_observer.OnNext(value);
}
@@ -115,25 +111,22 @@ namespace Avalonia.Markup.Data
source = StartListeningCore(_target);
}
- return source.Subscribe(TargetValueChanged);
+ return source.Subscribe(ValueChanged);
}
- private void TargetValueChanged(object value)
+ private void ValueChanged(object value)
{
var notification = value as BindingNotification;
if (notification == null)
{
- if (!HandleSpecialValue(value))
+ if (Next != null)
{
- if (Next != null)
- {
- Next.Target = new WeakReference(value);
- }
- else
- {
- _observer.OnNext(value);
- }
+ Next.Target = new WeakReference(value);
+ }
+ else
+ {
+ _observer.OnNext(value);
}
}
else
@@ -144,44 +137,22 @@ namespace Avalonia.Markup.Data
}
else if (notification.HasValue)
{
- if (!HandleSpecialValue(notification.Value))
+ if (Next != null)
{
- if (Next != null)
- {
- Next.Target = new WeakReference(notification.Value);
- }
- else
- {
- _observer.OnNext(value);
- }
+ Next.Target = new WeakReference(notification.Value);
}
- }
- }
- }
-
- private bool HandleSpecialValue(object value)
- {
- if (_valuePluginSubscription == null)
- {
- var reference = new WeakReference(value);
-
- foreach (var plugin in ExpressionObserver.ValueHandlers)
- {
- if (plugin.Match(reference))
+ else
{
- _valuePluginSubscription = plugin.Start(reference)?.Subscribe(TargetValueChanged);
- return true;
+ _observer.OnNext(value);
}
}
}
-
- return false;
}
private BindingNotification TargetNullNotification()
{
return new BindingNotification(
- new MarkupBindingChainNullException(),
+ new MarkupBindingChainException("Null value"),
BindingErrorType.Error,
AvaloniaProperty.UnsetValue);
}
diff --git a/src/Markup/Avalonia.Markup/Data/ExpressionObserver.cs b/src/Markup/Avalonia.Markup/Data/ExpressionObserver.cs
index 819949b7b9..37226ee74b 100644
--- a/src/Markup/Avalonia.Markup/Data/ExpressionObserver.cs
+++ b/src/Markup/Avalonia.Markup/Data/ExpressionObserver.cs
@@ -41,14 +41,14 @@ namespace Avalonia.Markup.Data
};
///
- /// An ordered collection of value handlers that can be used to customize the handling
- /// of certain values.
+ /// An ordered collection of stream plugins that can be used to customize the behavior
+ /// of the '^' stream binding operator.
///
- public static readonly IList ValueHandlers =
- new List
+ public static readonly IList StreamHandlers =
+ new List
{
- new TaskValuePlugin(),
- new ObservableValuePlugin(),
+ new TaskStreamPlugin(),
+ new ObservableStreamPlugin(),
};
private static readonly object UninitializedValue = new object();
@@ -235,7 +235,7 @@ namespace Avalonia.Markup.Data
}
else
{
- var broken = BindingNotification.ExtractError(o) as MarkupBindingChainNullException;
+ var broken = BindingNotification.ExtractError(o) as MarkupBindingChainException;
if (broken != null)
{
diff --git a/src/Markup/Avalonia.Markup/Data/MarkupBindingChainException.cs b/src/Markup/Avalonia.Markup/Data/MarkupBindingChainException.cs
new file mode 100644
index 0000000000..dab5756976
--- /dev/null
+++ b/src/Markup/Avalonia.Markup/Data/MarkupBindingChainException.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Avalonia.Data;
+
+namespace Avalonia.Markup.Data
+{
+ internal class MarkupBindingChainException : BindingChainException
+ {
+ private IList _nodes = new List();
+
+ public MarkupBindingChainException(string message)
+ : base(message)
+ {
+ }
+
+ public MarkupBindingChainException(string message, string node)
+ : base(message)
+ {
+ AddNode(node);
+ }
+
+ public MarkupBindingChainException(string message, string expression, string expressionNullPoint)
+ : base(message, expression, expressionNullPoint)
+ {
+ _nodes = null;
+ }
+
+ public bool HasNodes => _nodes.Count > 0;
+ public void AddNode(string node) => _nodes.Add(node);
+
+ public void Commit(string expression)
+ {
+ Expression = expression;
+ ExpressionErrorPoint = string.Join(".", _nodes.Reverse())
+ .Replace(".!", "!")
+ .Replace(".[", "[")
+ .Replace(".^", "^");
+ _nodes = null;
+ }
+ }
+}
diff --git a/src/Markup/Avalonia.Markup/Data/MarkupBindingChainNullException.cs b/src/Markup/Avalonia.Markup/Data/MarkupBindingChainNullException.cs
deleted file mode 100644
index a549d6ebb6..0000000000
--- a/src/Markup/Avalonia.Markup/Data/MarkupBindingChainNullException.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using Avalonia.Data;
-
-namespace Avalonia.Markup.Data
-{
- internal class MarkupBindingChainNullException : BindingChainNullException
- {
- private IList _nodes = new List();
-
- public MarkupBindingChainNullException()
- {
- }
-
- public MarkupBindingChainNullException(string expression, string expressionNullPoint)
- : base(expression, expressionNullPoint)
- {
- _nodes = null;
- }
-
- public bool HasNodes => _nodes.Count > 0;
- public void AddNode(string node) => _nodes.Add(node);
-
- public void Commit(string expression)
- {
- Expression = expression;
- ExpressionNullPoint = string.Join(".", _nodes.Reverse())
- .Replace(".!", "!")
- .Replace(".[", "[");
- _nodes = null;
- }
- }
-}
diff --git a/src/Markup/Avalonia.Markup/Data/Parsers/ExpressionParser.cs b/src/Markup/Avalonia.Markup/Data/Parsers/ExpressionParser.cs
index 6f9f2925bc..93ddf77376 100644
--- a/src/Markup/Avalonia.Markup/Data/Parsers/ExpressionParser.cs
+++ b/src/Markup/Avalonia.Markup/Data/Parsers/ExpressionParser.cs
@@ -87,6 +87,11 @@ namespace Avalonia.Markup.Data.Parsers
{
return State.BeforeMember;
}
+ else if (ParseStreamOperator(r))
+ {
+ nodes.Add(new StreamNode());
+ return State.AfterMember;
+ }
else
{
var args = ArgumentListParser.Parse(r, '[', ']');
@@ -161,6 +166,11 @@ namespace Avalonia.Markup.Data.Parsers
return !r.End && r.TakeIf('(');
}
+ private static bool ParseStreamOperator(Reader r)
+ {
+ return !r.End && r.TakeIf('^');
+ }
+
private enum State
{
Start,
diff --git a/src/Markup/Avalonia.Markup/Data/Plugins/IValuePlugin.cs b/src/Markup/Avalonia.Markup/Data/Plugins/IStreamPlugin.cs
similarity index 89%
rename from src/Markup/Avalonia.Markup/Data/Plugins/IValuePlugin.cs
rename to src/Markup/Avalonia.Markup/Data/Plugins/IStreamPlugin.cs
index fb285c6d73..efb2e2d93a 100644
--- a/src/Markup/Avalonia.Markup/Data/Plugins/IValuePlugin.cs
+++ b/src/Markup/Avalonia.Markup/Data/Plugins/IStreamPlugin.cs
@@ -6,9 +6,9 @@ using System;
namespace Avalonia.Markup.Data.Plugins
{
///
- /// Defines how values are observed by an .
+ /// Defines a plugin that handles the '^' stream binding operator.
///
- public interface IValuePlugin
+ public interface IStreamPlugin
{
///
/// Checks whether this plugin handles the specified value.
diff --git a/src/Markup/Avalonia.Markup/Data/Plugins/ObservableValuePlugin.cs b/src/Markup/Avalonia.Markup/Data/Plugins/ObservableStreamPlugin.cs
similarity index 62%
rename from src/Markup/Avalonia.Markup/Data/Plugins/ObservableValuePlugin.cs
rename to src/Markup/Avalonia.Markup/Data/Plugins/ObservableStreamPlugin.cs
index a406fc55b9..a1da42d28f 100644
--- a/src/Markup/Avalonia.Markup/Data/Plugins/ObservableValuePlugin.cs
+++ b/src/Markup/Avalonia.Markup/Data/Plugins/ObservableStreamPlugin.cs
@@ -2,32 +2,20 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
-using System.Reactive.Linq;
-using System.Reactive.Subjects;
-using System.Reflection;
-using System.Threading.Tasks;
-using System.Windows.Input;
-using Avalonia.Data;
namespace Avalonia.Markup.Data.Plugins
{
///
- /// Handles binding to s in an .
+ /// Handles binding to s for the '^' stream binding operator.
///
- public class ObservableValuePlugin : IValuePlugin
+ public class ObservableStreamPlugin : IStreamPlugin
{
///
/// Checks whether this plugin handles the specified value.
///
/// A weak reference to the value.
/// True if the plugin can handle the value; otherwise false.
- public virtual bool Match(WeakReference reference)
- {
- var target = reference.Target;
-
- // ReactiveCommand is an IObservable but we want to bind to it, not its value.
- return target is IObservable && !(target is ICommand);
- }
+ public virtual bool Match(WeakReference reference) => reference.Target is IObservable;
///
/// Starts producing output based on the specified value.
diff --git a/src/Markup/Avalonia.Markup/Data/Plugins/TaskValuePlugin.cs b/src/Markup/Avalonia.Markup/Data/Plugins/TaskStreamPlugin.cs
similarity index 95%
rename from src/Markup/Avalonia.Markup/Data/Plugins/TaskValuePlugin.cs
rename to src/Markup/Avalonia.Markup/Data/Plugins/TaskStreamPlugin.cs
index b6fda67503..d2c8c1b064 100644
--- a/src/Markup/Avalonia.Markup/Data/Plugins/TaskValuePlugin.cs
+++ b/src/Markup/Avalonia.Markup/Data/Plugins/TaskStreamPlugin.cs
@@ -12,9 +12,9 @@ using Avalonia.Data;
namespace Avalonia.Markup.Data.Plugins
{
///
- /// Handles binding to s in an .
+ /// Handles binding to s for the '^' stream binding operator.
///
- public class TaskValuePlugin : IValuePlugin
+ public class TaskStreamPlugin : IStreamPlugin
{
///
/// Checks whether this plugin handles the specified value.
diff --git a/src/Markup/Avalonia.Markup/Data/StreamNode.cs b/src/Markup/Avalonia.Markup/Data/StreamNode.cs
new file mode 100644
index 0000000000..ebcbfc9598
--- /dev/null
+++ b/src/Markup/Avalonia.Markup/Data/StreamNode.cs
@@ -0,0 +1,31 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using System;
+using System.Globalization;
+using Avalonia.Data;
+using System.Reactive.Linq;
+
+namespace Avalonia.Markup.Data
+{
+ internal class StreamNode : ExpressionNode
+ {
+ public override string Description => "^";
+
+ protected override IObservable StartListeningCore(WeakReference reference)
+ {
+ foreach (var plugin in ExpressionObserver.StreamHandlers)
+ {
+ if (plugin.Match(reference))
+ {
+ return plugin.Start(reference);
+ }
+ }
+
+ // TODO: Improve error.
+ return Observable.Return(new BindingNotification(
+ new MarkupBindingChainException("Stream operator applied to unsupported type", Description),
+ BindingErrorType.Error));
+ }
+ }
+}
diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_DataValidation.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_DataValidation.cs
index 546cfe015f..3b5ca26db1 100644
--- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_DataValidation.cs
+++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_DataValidation.cs
@@ -143,7 +143,7 @@ namespace Avalonia.Markup.UnitTests.Data
Assert.Equal(new[]
{
new BindingNotification(
- new MarkupBindingChainNullException("Inner.MustBePositive", "Inner"),
+ new MarkupBindingChainException("Null value", "Inner.MustBePositive", "Inner"),
BindingErrorType.Error,
AvaloniaProperty.UnsetValue),
}, result);
diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Observable.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Observable.cs
index 3263aaace2..640d82fa19 100644
--- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Observable.cs
+++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Observable.cs
@@ -15,7 +15,7 @@ namespace Avalonia.Markup.UnitTests.Data
public class ExpressionObserverTests_Observable
{
[Fact]
- public void Should_Get_Simple_Observable_Value()
+ public void Should_Not_Get_Observable_Value_Without_Modifier_Char()
{
using (var sync = UnitTestSynchronizationContext.Begin())
{
@@ -28,6 +28,24 @@ namespace Avalonia.Markup.UnitTests.Data
source.OnNext("bar");
sync.ExecutePostedCallbacks();
+ Assert.Equal(new[] { source }, result);
+ }
+ }
+
+ [Fact]
+ public void Should_Get_Simple_Observable_Value()
+ {
+ using (var sync = UnitTestSynchronizationContext.Begin())
+ {
+ var source = new BehaviorSubject("foo");
+ var data = new { Foo = source };
+ var target = new ExpressionObserver(data, "Foo^");
+ var result = new List();
+
+ var sub = target.Subscribe(x => result.Add(x));
+ source.OnNext("bar");
+ sync.ExecutePostedCallbacks();
+
Assert.Equal(new[] { "foo", "bar" }, result);
}
}
@@ -38,7 +56,7 @@ namespace Avalonia.Markup.UnitTests.Data
using (var sync = UnitTestSynchronizationContext.Begin())
{
var data = new Class1();
- var target = new ExpressionObserver(data, "Next.Foo");
+ var target = new ExpressionObserver(data, "Next^.Foo");
var result = new List();
var sub = target.Subscribe(x => result.Add(x));
@@ -59,7 +77,7 @@ namespace Avalonia.Markup.UnitTests.Data
{
var source = new BehaviorSubject("foo");
var data = new { Foo = source };
- var target = new ExpressionObserver(data, "Foo", true);
+ var target = new ExpressionObserver(data, "Foo^", true);
var result = new List();
var sub = target.Subscribe(x => result.Add(x));
@@ -78,7 +96,7 @@ namespace Avalonia.Markup.UnitTests.Data
using (var sync = UnitTestSynchronizationContext.Begin())
{
var data = new Class1();
- var target = new ExpressionObserver(data, "Next.Foo", true);
+ var target = new ExpressionObserver(data, "Next^.Foo", true);
var result = new List();
var sub = target.Subscribe(x => result.Add(x));
@@ -92,6 +110,31 @@ namespace Avalonia.Markup.UnitTests.Data
}
}
+ [Fact]
+ public void Should_Return_BindingNotification_If_Stream_Operator_Applied_To_Not_Supported_Type()
+ {
+ using (var sync = UnitTestSynchronizationContext.Begin())
+ {
+ var data = new Class2("foo");
+ var target = new ExpressionObserver(data, "Foo^", true);
+ var result = new List();
+
+ var sub = target.Subscribe(x => result.Add(x));
+ sync.ExecutePostedCallbacks();
+
+ Assert.Equal(
+ new[]
+ {
+ new BindingNotification(
+ new MarkupBindingChainException("Stream operator applied to unsupported type", "Foo^", "Foo^"),
+ BindingErrorType.Error)
+ },
+ result);
+
+ sub.Dispose();
+ }
+ }
+
private class Class1 : NotifyingBase
{
public Subject Next { get; } = new Subject();
diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs
index aa9ee7d58b..bdcd39d997 100644
--- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs
+++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Property.cs
@@ -146,7 +146,7 @@ namespace Avalonia.Markup.UnitTests.Data
new[]
{
new BindingNotification(
- new MarkupBindingChainNullException("Foo.Bar.Baz", "Foo"),
+ new MarkupBindingChainException("Null value", "Foo.Bar.Baz", "Foo"),
BindingErrorType.Error,
AvaloniaProperty.UnsetValue),
},
@@ -274,7 +274,7 @@ namespace Avalonia.Markup.UnitTests.Data
{
"bar",
new BindingNotification(
- new MarkupBindingChainNullException("Next.Next.Bar", "Next.Next"),
+ new MarkupBindingChainException("Null value", "Next.Next.Bar", "Next.Next"),
BindingErrorType.Error,
AvaloniaProperty.UnsetValue),
"bar"
diff --git a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Task.cs b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Task.cs
index 3dcd8a4fbc..61e6dcb833 100644
--- a/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Task.cs
+++ b/tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Task.cs
@@ -15,7 +15,7 @@ namespace Avalonia.Markup.UnitTests.Data
public class ExpressionObserverTests_Task
{
[Fact]
- public void Should_Get_Simple_Task_Value()
+ public void Should_Not_Get_Task_Result_Without_Modifier_Char()
{
using (var sync = UnitTestSynchronizationContext.Begin())
{
@@ -28,7 +28,8 @@ namespace Avalonia.Markup.UnitTests.Data
tcs.SetResult("foo");
sync.ExecutePostedCallbacks();
- Assert.Equal(new[] { "foo" }, result);
+ Assert.Equal(1, result.Count);
+ Assert.IsType>(result[0]);
}
}
@@ -38,7 +39,7 @@ namespace Avalonia.Markup.UnitTests.Data
using (var sync = UnitTestSynchronizationContext.Begin())
{
var data = new { Foo = Task.FromResult("foo") };
- var target = new ExpressionObserver(data, "Foo");
+ var target = new ExpressionObserver(data, "Foo^");
var result = new List();
var sub = target.Subscribe(x => result.Add(x));
@@ -54,7 +55,7 @@ namespace Avalonia.Markup.UnitTests.Data
{
var tcs = new TaskCompletionSource();
var data = new Class1(tcs.Task);
- var target = new ExpressionObserver(data, "Next.Foo");
+ var target = new ExpressionObserver(data, "Next^.Foo");
var result = new List();
var sub = target.Subscribe(x => result.Add(x));
@@ -72,7 +73,7 @@ namespace Avalonia.Markup.UnitTests.Data
{
var tcs = new TaskCompletionSource();
var data = new { Foo = tcs.Task };
- var target = new ExpressionObserver(data, "Foo");
+ var target = new ExpressionObserver(data, "Foo^");
var result = new List();
var sub = target.Subscribe(x => result.Add(x));
@@ -96,7 +97,7 @@ namespace Avalonia.Markup.UnitTests.Data
using (var sync = UnitTestSynchronizationContext.Begin())
{
var data = new { Foo = TaskFromException(new NotSupportedException()) };
- var target = new ExpressionObserver(data, "Foo");
+ var target = new ExpressionObserver(data, "Foo^");
var result = new List();
var sub = target.Subscribe(x => result.Add(x));
@@ -119,7 +120,7 @@ namespace Avalonia.Markup.UnitTests.Data
{
var tcs = new TaskCompletionSource();
var data = new { Foo = tcs.Task };
- var target = new ExpressionObserver(data, "Foo", true);
+ var target = new ExpressionObserver(data, "Foo^", true);
var result = new List();
var sub = target.Subscribe(x => result.Add(x));