public void Should_Track_NonIntegerIndexer()
        {
            var data = new { Foo = new NonIntegerIndexer() };

            data.Foo["foo"] = "bar";
            data.Foo["baz"] = "qux";

            var target = ExpressionObserverBuilder.Build(data, "Foo[foo]");
            var result = new List <object>();

            using (var sub = target.Subscribe(x => result.Add(x)))
            {
                data.Foo["foo"] = "bar2";
            }

            // Forces WeakEvent compact
            Dispatcher.UIThread.RunJobs();

            var expected = new[] { "bar", "bar2" };

            Assert.Equal(expected, result);
            Assert.Equal(0, data.Foo.PropertyChangedSubscriptionCount);

            GC.KeepAlive(data);
        }
Esempio n. 2
0
        public void Should_Update_Value_After_Root_Changes_With_ComplexPath()
        {
            var root    = new { DataContext = new { Foo = new { Value = "Foo" } } };
            var subject = new Subject <object>();
            var obs     = ExpressionObserverBuilder.Build(subject, "DataContext.Foo.Value");

            var values = new List <object>();

            obs.Subscribe(v => values.Add(v));

            subject.OnNext(root);
            subject.OnNext(null);
            subject.OnNext(root);

            Assert.Equal("Foo", values[0]);

            Assert.IsType <BindingNotification>(values[1]);
            var bn = values[1] as BindingNotification;

            Assert.Equal(AvaloniaProperty.UnsetValue, bn.Value);
            Assert.Equal(BindingErrorType.Error, bn.ErrorType);

            Assert.Equal(3, values.Count);
            Assert.Equal("Foo", values[2]);
        }
Esempio n. 3
0
        public void Should_Have_Null_ResultType_For_Broken_Chain()
        {
            var data   = new { Foo = new { Bar = 1 } };
            var target = ExpressionObserverBuilder.Build(data, "Foo.Bar.Baz");

            Assert.Null(target.ResultType);

            GC.KeepAlive(data);
        }
Esempio n. 4
0
        private ExpressionObserver CreateSourceObserver(
            object source,
            string path,
            bool enableDataValidation)
        {
            Contract.Requires <ArgumentNullException>(source != null);

            return(ExpressionObserverBuilder.Build(source, path, enableDataValidation, typeResolver: TypeResolver));
        }
        public async Task Should_Get_UnsetValue_For_Object_Without_Indexer()
        {
            var data   = new { Foo = 5 };
            var target = ExpressionObserverBuilder.Build(data, "Foo[noindexer]");
            var result = await target.Take(1);

            Assert.Equal(AvaloniaProperty.UnsetValue, result);

            GC.KeepAlive(data);
        }
Esempio n. 6
0
        public async Task Should_Negate_True_String()
        {
            var data   = new { Foo = "True" };
            var target = ExpressionObserverBuilder.Build(data, "!Foo");
            var result = await target.Take(1);

            Assert.False((bool)result);

            GC.KeepAlive(data);
        }
        public async Task Should_Get_UnsetValue_For_Invalid_Array_Index()
        {
            var data   = new { Foo = new[] { "foo", "bar" } };
            var target = ExpressionObserverBuilder.Build(data, "Foo[invalid]");
            var result = await target.Take(1);

            Assert.Equal(AvaloniaProperty.UnsetValue, result);

            GC.KeepAlive(data);
        }
Esempio n. 8
0
        public async Task Should_Get_Attached_Property_Value()
        {
            var data   = new Class1();
            var target = ExpressionObserverBuilder.Build(data, "(Owner.Foo)", typeResolver: _typeResolver);
            var result = await target.Take(1);

            Assert.Equal("foo", result);

            Assert.Null(((IAvaloniaObjectDebug)data).GetPropertyChangedSubscribers());
        }
Esempio n. 9
0
        public InstancedBinding ItemsSelector(object item)
        {
            if (ItemsSource != null)
            {
                var obs = ExpressionObserverBuilder.Build(item, ItemsSource.Path);
                return(InstancedBinding.OneWay(obs, BindingPriority.Style));
            }

            return(null);
        }
        public async Task Should_Get_Array_Value()
        {
            var data   = new { Foo = new[] { "foo", "bar" } };
            var target = ExpressionObserverBuilder.Build(data, "Foo[1]");
            var result = await target.Take(1);

            Assert.Equal("bar", result);

            GC.KeepAlive(data);
        }
        public async Task Indexer_Only_Binding_Works()
        {
            var data = new[] { 1, 2, 3 };

            var target = ExpressionObserverBuilder.Build(data, "[1]");

            var value = await target.Take(1);

            Assert.Equal(data[1], value);
        }
        public async Task Array_With_Wrong_Dimensions_Should_Return_UnsetValue()
        {
            var data   = new { Foo = new[] { "foo", "bar" } };
            var target = ExpressionObserverBuilder.Build(data, "Foo[1,2]");
            var result = await target.Take(1);

            Assert.Equal(AvaloniaProperty.UnsetValue, result);

            GC.KeepAlive(data);
        }
        public async Task Should_Get_AvaloniaProperty_By_Name()
        {
            var data   = new Class1();
            var target = ExpressionObserverBuilder.Build(data, "Foo");
            var result = await target.Take(1);

            Assert.Equal("foo", result);

            Assert.Null(((IAvaloniaObjectDebug)data).GetPropertyChangedSubscribers());
        }
Esempio n. 14
0
        public async Task Should_Get_Method_WithCorrectDelegateType(string methodName, Type expectedType)
        {
            var data     = new TestObject();
            var observer = ExpressionObserverBuilder.Build(data, methodName);
            var result   = await observer.Take(1);

            Assert.IsType(expectedType, result);

            GC.KeepAlive(data);
        }
Esempio n. 15
0
        public async Task Should_Get_Method()
        {
            var data     = new TestObject();
            var observer = ExpressionObserverBuilder.Build(data, nameof(TestObject.MethodWithoutReturn));
            var result   = await observer.Take(1);

            Assert.NotNull(result);

            GC.KeepAlive(data);
        }
Esempio n. 16
0
        public async Task Should_Negate_BindingNotification_Value()
        {
            var data   = new { Foo = true };
            var target = ExpressionObserverBuilder.Build(data, "!Foo", enableDataValidation: true);
            var result = await target.Take(1);

            Assert.Equal(new BindingNotification(false), result);

            GC.KeepAlive(data);
        }
Esempio n. 17
0
        public void SetValue_Should_Return_False_For_Invalid_Value()
        {
            var data   = new { Foo = "foo" };
            var target = ExpressionObserverBuilder.Build(data, "!Foo");

            target.Subscribe(_ => { });

            Assert.False(target.SetValue("bar"));

            GC.KeepAlive(data);
        }
        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 target = ExpressionObserverBuilder.Build(data, "Foo[1.0]");
            var result = await target.Take(1);

            Assert.Equal("bar", result);

            GC.KeepAlive(data);
        }
Esempio n. 19
0
        public async Task Can_Call_Method_Returned_From_Observer()
        {
            var data     = new TestObject();
            var observer = ExpressionObserverBuilder.Build(data, nameof(TestObject.MethodWithReturnAndParameters));
            var result   = await observer.Take(1);

            var callback = (Func <int, int>)result;

            Assert.Equal(1, callback(1));

            GC.KeepAlive(data);
        }
        public async Task List_Out_Of_Bounds_Should_Return_UnsetValue()
        {
            var data = new { Foo = new List <string> {
                                 "foo", "bar"
                             } };
            var target = ExpressionObserverBuilder.Build(data, "Foo[2]");
            var result = await target.Take(1);

            Assert.Equal(AvaloniaProperty.UnsetValue, result);

            GC.KeepAlive(data);
        }
Esempio n. 21
0
        public async Task Should_Get_Attached_Property_Value_With_Namespace()
        {
            var data   = new Class1();
            var target = ExpressionObserverBuilder.Build(
                data,
                "(NS:Owner.Foo)",
                typeResolver: (ns, name) => ns == "NS" && name == "Owner" ? typeof(Owner) : null);
            var result = await target.Take(1);

            Assert.Equal("foo", result);
            Assert.Null(((IAvaloniaObjectDebug)data).GetPropertyChangedSubscribers());
        }
        public async Task Should_Get_MultiDimensional_Array_Value()
        {
            var data = new { Foo = new[, ] {
                                 { "foo", "bar" }, { "baz", "qux" }
                             } };
            var target = ExpressionObserverBuilder.Build(data, "Foo[1, 1]");
            var result = await target.Take(1);

            Assert.Equal("qux", result);

            GC.KeepAlive(data);
        }
        public async Task Should_Return_Error_Notification_If_Too_Many_Parameters(string methodName)
        {
            var data     = new TestObject();
            var observer = ExpressionObserverBuilder.Build(data, methodName);
            var result   = await observer.Take(1);

            Assert.IsType <BindingNotification>(result);

            Assert.Equal(BindingErrorType.Error, ((BindingNotification)result).ErrorType);

            GC.KeepAlive(data);
        }
Esempio n. 24
0
        public object Select(object o)
        {
            if (string.IsNullOrEmpty(MemberName))
            {
                return(o);
            }

            var    expression = ExpressionObserverBuilder.Build(o, MemberName);
            object result     = AvaloniaProperty.UnsetValue;

            expression.Subscribe(x => result = x);
            return((result == AvaloniaProperty.UnsetValue || result is BindingNotification) ? null : result);
        }
Esempio n. 25
0
        public async Task Should_Pass_Through_BindingNotification_Error()
        {
            var data   = new { };
            var target = ExpressionObserverBuilder.Build(data, "!Foo", enableDataValidation: true);
            var result = await target.Take(1);

            Assert.Equal(
                new BindingNotification(
                    new MissingMemberException("Could not find a matching property accessor for 'Foo' on '{ }'"),
                    BindingErrorType.Error),
                result);

            GC.KeepAlive(data);
        }
        public void Should_SetArrayIndex()
        {
            var data   = new { Foo = new[] { "foo", "bar" } };
            var target = ExpressionObserverBuilder.Build(data, "Foo[1]");

            using (target.Subscribe(_ => { }))
            {
                Assert.True(target.SetValue("baz"));
            }

            Assert.Equal("baz", data.Foo[1]);

            GC.KeepAlive(data);
        }
Esempio n. 27
0
        public async Task Should_Return_BindingNotification_For_Value_Not_Convertible_To_Boolean()
        {
            var data   = new { Foo = new object() };
            var target = ExpressionObserverBuilder.Build(data, "!Foo");
            var result = await target.Take(1);

            Assert.Equal(
                new BindingNotification(
                    new InvalidCastException($"Unable to convert 'System.Object' to bool."),
                    BindingErrorType.Error),
                result);

            GC.KeepAlive(data);
        }
Esempio n. 28
0
        public async Task Should_Return_BindingNotification_Error_For_Broken_Chain()
        {
            var data   = new { Foo = new { Bar = 1 } };
            var target = ExpressionObserverBuilder.Build(data, "Foo.Bar.Baz");
            var result = await target.Take(1);

            Assert.IsType <BindingNotification>(result);

            Assert.Equal(
                new BindingNotification(
                    new MissingMemberException("Could not find a matching property accessor for 'Baz' on '1'"), BindingErrorType.Error),
                result);

            GC.KeepAlive(data);
        }
        public InstancedBinding ItemsSelector(object item)
        {
            if (ItemsSource != null)
            {
                var obs = ItemsSource switch
                {
                    Binding reflection => ExpressionObserverBuilder.Build(item, reflection.Path),
                    CompiledBindingExtension compiled => new ExpressionObserver(item, compiled.Path.BuildExpression(false)),
                    _ => throw new InvalidOperationException("TreeDataTemplate currently only supports Binding and CompiledBindingExtension!")
                };

                return(InstancedBinding.OneWay(obs, BindingPriority.Style));
            }

            return(null);
        }
Esempio n. 30
0
        public void Should_Track_Simple_Attached_Value()
        {
            var data   = new Class1();
            var target = ExpressionObserverBuilder.Build(data, "(Owner.Foo)", typeResolver: _typeResolver);
            var result = new List <object>();

            var sub = target.Subscribe(x => result.Add(x));

            data.SetValue(Owner.FooProperty, "bar");

            Assert.Equal(new[] { "foo", "bar" }, result);

            sub.Dispose();

            Assert.Null(((IAvaloniaObjectDebug)data).GetPropertyChangedSubscribers());
        }