public void GetValueShouldReturnActualValueDoubleSource()
        {
            const string value = "100";
            bool isInvoked = false;
            var memberMock = new BindingMemberInfoMock();
            var sourceModel = new BindingSourceModel();
            string propertyName1 = GetMemberPath<BindingSourceModel>(model => model.IntProperty);
            string propertyName2 = GetMemberPath<BindingSourceModel>(model => model["test"]);
            var valueAccessor = new MultiBindingSourceAccessor(new[]
            {
                CreateSource(sourceModel, propertyName1),
                CreateSource(sourceModel, propertyName2),
            },
                (context, list) =>
                {
                    list.Count.ShouldEqual(2);
                    isInvoked = true;
                    context.ShouldEqual(EmptyContext);
                    list[0].ShouldEqual(sourceModel.IntProperty);
                    list[1].ShouldEqual(sourceModel["test"]);
                    return value;
                }, EmptyContext);
            valueAccessor.GetValue(memberMock, EmptyContext, true).ShouldEqual(value);
            isInvoked.ShouldBeTrue();

            isInvoked = false;
            sourceModel["test"] = propertyName1;
            sourceModel.IntProperty = int.MaxValue;
            valueAccessor.GetValue(memberMock, EmptyContext, true).ShouldEqual(value);
            isInvoked.ShouldBeTrue();
        }
 public void GetValueShouldThrowExceptionInvalidValueIfFlagTrue()
 {
     var memberMock = new BindingMemberInfoMock();
     var sourceModel = new BindingSourceModel();
     const string propertyName = "invalid";
     var valueAccessor = new MultiBindingSourceAccessor(new[] { CreateSource(sourceModel, propertyName) },
         (context, list) => null, EmptyContext);
     ShouldThrow(() => valueAccessor.GetValue(memberMock, EmptyContext, true));
 }
        public void GetValueShouldReturnActualValue()
        {
            bool isInvoked = false;
            var memberMock = new BindingMemberInfoMock();
            var sourceModel = new BindingSourceModel();
            string propertyName = GetMemberPath<BindingSourceModel>(model => model.IntProperty);
            var valueAccessor = new MultiBindingSourceAccessor(new[] { CreateSource(sourceModel, propertyName) },
                (context, list) =>
                {
                    isInvoked = true;
                    context.ShouldEqual(EmptyContext);
                    list.Single().ShouldEqual(sourceModel.IntProperty);
                    return sourceModel.IntProperty;
                }, EmptyContext);
            valueAccessor.GetValue(memberMock, EmptyContext, true).ShouldEqual(sourceModel.IntProperty);
            isInvoked.ShouldBeTrue();

            isInvoked = false;
            sourceModel.IntProperty = int.MaxValue;
            valueAccessor.GetValue(memberMock, EmptyContext, true).ShouldEqual(sourceModel.IntProperty);
            isInvoked.ShouldBeTrue();
        }
        public void BuilderShouldUseElementSourceForParameter2()
        {
            const string name = "name";
            var builder = new BindingBuilder();
            var targetObj = new BindingSourceModel { ObjectProperty = "test" };
            var relativeObj = new BindingSourceModel();
            bool isInvoked = false;
            IEventListener eventListener = null;
            var memberMock = new BindingMemberInfoMock
            {
                TryObserveMember = (o, listener) =>
                {
                    eventListener = listener;
                    return null;
                }
            };

            var treeManagerMock = new VisualTreeManagerMock
            {
                FindByName = (o, s) =>
                {
                    o.ShouldEqual(targetObj);
                    s.ShouldEqual(name);
                    isInvoked = true;
                    return relativeObj;
                },
                GetRootMember = type => memberMock
            };
            BindingServiceProvider.VisualTreeManager = treeManagerMock;

            builder.Bind(targetObj, "empty").To<BindingSourceModel>(() => model => model.IntProperty)
                .WithCommandParameter(() => model => BindingSyntaxEx.Element<BindingSourceModel>(name).ObjectProperty);

            builder.GetData(BindingBuilderConstants.CommandParameter).Invoke(builder).ShouldEqual(relativeObj.ObjectProperty);
            isInvoked.ShouldBeTrue();

            isInvoked = false;
            eventListener.ShouldNotBeNull();
            eventListener.Handle(this, EventArgs.Empty);
            isInvoked.ShouldBeTrue();
        }
        public void BuilderShouldUseRelativeSourceForParameter2()
        {
            const uint level = 10u;
            var builder = new BindingBuilder();
            var targetObj = new BindingSourceModel { ObjectProperty = "test" };
            var relativeObj = new BindingSourceModel();
            bool isInvoked = false;
            IEventListener eventListener = null;
            var memberMock = new BindingMemberInfoMock
            {
                TryObserveMember = (o, listener) =>
                {
                    eventListener = listener;
                    return null;
                }
            };

            var treeManagerMock = new VisualTreeManagerMock
            {
                FindRelativeSource = (o, s, arg3) =>
                {
                    o.ShouldEqual(targetObj);
                    s.ShouldEqual(typeof(BindingSourceModel).AssemblyQualifiedName);
                    arg3.ShouldEqual(level);
                    isInvoked = true;
                    return relativeObj;
                },
                GetRootMember = type => memberMock
            };
            BindingServiceProvider.VisualTreeManager = treeManagerMock;

            builder.Bind(targetObj, "empty").To<BindingSourceModel>(() => model => model.IntProperty)
                .WithCommandParameter(() => model => BindingSyntaxEx.Relative<BindingSourceModel>(level).ObjectProperty);

            var func = builder.GetData(BindingBuilderConstants.CommandParameter);
            func(builder).ShouldEqual(relativeObj.ObjectProperty);
            isInvoked.ShouldBeTrue();

            isInvoked = false;
            eventListener.ShouldNotBeNull();
            eventListener.Handle(this, EventArgs.Empty);
            isInvoked.ShouldBeTrue();
        }
 public void GetEventValueShouldAlwaysReturnBindingMemberValue()
 {
     var memberMock = new BindingMemberInfoMock();
     var source = new BindingSourceModel();
     var accessor = GetAccessor(source, BindingSourceModel.EventName, EmptyContext, true);
     var memberValue = (BindingActionValue)accessor.GetValue(memberMock, EmptyContext, true);
     memberValue.MemberSource.Target.ShouldEqual(source);
     memberValue.Member.MemberType.ShouldEqual(BindingMemberType.Event);
 }
        public void ManagerShouldUseParentBindingContextIfItHasNotExplicit()
        {
            bool isFindParentInvoked = false;
            bool isObserveParentInvoked = false;
            var context = new object();

            var memberMock = new BindingMemberInfoMock
            {
                TryObserveMember = (o, listener) =>
                {
                    o.ShouldEqual(context);
                    isObserveParentInvoked = true;
                    return null;
                }
            };
            var managerMock = new VisualTreeManagerMock
            {
                FindParent = o =>
                {
                    o.ShouldEqual(context);
                    isFindParentInvoked = true;
                    return null;
                },
                GetParentMember = type =>
                {
                    type.ShouldEqual(context.GetType());
                    return memberMock;
                }
            };

            var manager = CreateContextManager(managerMock);
            var bindingContext = manager.GetBindingContext(context);
            isFindParentInvoked.ShouldBeTrue();
            isObserveParentInvoked.ShouldBeTrue();
            bindingContext.Value.ShouldBeNull();
        }
        public void GetValueShouldReturnValueUsingFallbackValueSourceDoubleSource()
        {
            const int fallback = 0;
            var memberMock = new BindingMemberInfoMock();
            var sourceModel = new BindingSourceModel { ObjectProperty = BindingConstants.UnsetValue };
            var dataContext = new DataContext
            {
                {BindingBuilderConstants.Fallback, d => fallback},
            };

            string propertyName = GetMemberPath<BindingSourceModel>(model => model.ObjectProperty);
            var valueAccessor = new MultiBindingSourceAccessor(new[]
            {
                CreateSource(sourceModel, propertyName),
                CreateSource(sourceModel, GetMemberPath(sourceModel, model => model.IntProperty)),
            }, (context, list) => list[0], dataContext);
            valueAccessor.GetValue(memberMock, EmptyContext, true).ShouldEqual(fallback);
        }
 public void GetValueShouldNotThrowExceptionInvalidValueIfFlagFalse()
 {
     var memberMock = new BindingMemberInfoMock();
     var sourceModel = new BindingSourceModel();
     const string propertyName = "invalid";
     var valueAccessor = GetAccessor(sourceModel, propertyName, EmptyContext, true);
     valueAccessor.GetValue(memberMock, EmptyContext, false).ShouldEqual(null);
 }
 public void GetValueShouldReturnActualValueForNestedPropertyDoubleIndexer()
 {
     var memberMock = new BindingMemberInfoMock();
     var propertyName = GetMemberPath<BindingSourceModel>(model => model.NestedModel["test", 0]);
     var sourceModel = new BindingSourceModel { NestedModel = new BindingSourceNestedModel() };
     var valueAccessor = GetAccessor(sourceModel, propertyName, EmptyContext, true);
     valueAccessor.GetValue(memberMock, EmptyContext, true).ShouldEqual(sourceModel.NestedModel["test", 0]);
     sourceModel.NestedModel["test", 0] = propertyName;
     valueAccessor.GetValue(memberMock, EmptyContext, true).ShouldEqual(sourceModel.NestedModel["test", 0]);
 }
        public void GetValueShouldReturnDefaultValueIfNestedPropertyNullDoubleIndexer()
        {
            var memberMock = new BindingMemberInfoMock();
            var propertyName = GetMemberPath<BindingSourceModel>(model => model.NestedModel["test", 0]);
            var sourceModel = new BindingSourceModel();
            var valueAccessor = GetAccessor(sourceModel, propertyName, EmptyContext, true);
            valueAccessor.GetValue(memberMock, EmptyContext, true).ShouldEqual(null);

            memberMock.Type = typeof(int);
            valueAccessor.GetValue(memberMock, EmptyContext, true).ShouldEqual(0);
        }
 public void GetValueShouldReturnActualValueIndexer2()
 {
     var memberMock = new BindingMemberInfoMock();
     var sourceModel = new BindingSourceModel();
     string propertyName = GetMemberPath<BindingSourceModel>(model => model[int.MaxValue]);
     var valueAccessor = GetAccessor(sourceModel, propertyName, EmptyContext, true);
     valueAccessor.GetValue(memberMock, EmptyContext, true).ShouldEqual(int.MaxValue);
 }
        public void ParserShouldParseElementSourceExpression3()
        {
            bool isInvoked = false;
            const string targetPath = "Text";
            const string sourcePath = "StringProperty";
            const string sourceName = "type";
            const string binding = "Text $Element(type).StringProperty";

            var target = new BindingSourceModel();
            var relativeObj = new BindingSourceModel();
            IEventListener eventListener = null;
            var memberMock = new BindingMemberInfoMock
            {
                TryObserveMember = (o, listener) =>
                {
                    eventListener = listener;
                    return null;
                }
            };
            var providerMock = new ObserverProviderMock
            {
                Observe = (o, p, arg3) => new MultiPathObserver(o, p, arg3)
            };
            var treeManagerMock = new VisualTreeManagerMock
            {
                FindByName = (o, s) =>
                {
                    o.ShouldEqual(target);
                    s.ShouldEqual(sourceName);
                    isInvoked = true;
                    return relativeObj;
                },
                GetRootMember = type => memberMock
            };

            IBindingParser bindingParser = CreateBindingParser(treeManagerMock, null, providerMock);
            var context = new BindingBuilder(bindingParser.Parse(binding, EmptyContext, target, null).Single());
            IBindingPath path = context.GetData(BindingBuilderConstants.TargetPath);
            path.Path.ShouldEqual(targetPath);

            var sources = context.GetData(BindingBuilderConstants.Sources);
            IBindingSource source = sources.Single().Invoke(context);
            source.Path.Path.ShouldContain(sourcePath);
            isInvoked.ShouldBeTrue();

            isInvoked = false;
            eventListener.ShouldNotBeNull();
            eventListener.Handle(this, EventArgs.Empty);
            isInvoked.ShouldBeTrue();
        }
        public void ManagerShouldRaiseEventWhenParentChanged()
        {
            bool contextChanged = false;
            var context = new object();
            IEventListener eventListener = null;
            var memberMock = new BindingMemberInfoMock
            {
                TryObserveMember = (o, listener) =>
                {
                    eventListener = listener;
                    return null;
                }
            };
            var managerMock = new VisualTreeManagerMock
            {
                FindParent = o => null,
                GetParentMember = type =>
                {
                    type.ShouldEqual(context.GetType());
                    return memberMock;
                }
            };

            var manager = CreateContextManager(managerMock);
            var bindingContext = manager.GetBindingContext(context);
            bindingContext.ValueChanged += (sender, args) => contextChanged = true;
            eventListener.ShouldNotBeNull();
            eventListener.Handle(this, EventArgs.Empty);
            contextChanged.ShouldBeTrue();
        }
        public void ManagerShouldNotUpdateContextWhenParentChangedIfHasValue()
        {
            bool isFindParentInvoked = false;
            var context = new object();
            IEventListener eventListener = null;
            var memberMock = new BindingMemberInfoMock
            {
                TryObserveMember = (o, listener) =>
                {
                    eventListener = listener;
                    return null;
                }
            };
            var managerMock = new VisualTreeManagerMock
            {
                FindParent = o =>
                {
                    o.ShouldEqual(context);
                    isFindParentInvoked = true;
                    return null;
                },
                GetParentMember = type =>
                {
                    type.ShouldEqual(context.GetType());
                    return memberMock;
                }
            };

            var manager = CreateContextManager(managerMock);
            var bindingContext = manager.GetBindingContext(context);
            isFindParentInvoked.ShouldBeTrue();
            bindingContext.Value.ShouldBeNull();

            isFindParentInvoked = false;
            bindingContext.Value = context;
            eventListener.ShouldNotBeNull();
            eventListener.Handle(this, EventArgs.Empty);
            isFindParentInvoked.ShouldBeFalse();
        }
        public void BuilderShouldUseElementSource2()
        {
            const string name = "name";
            var builder = new BindingBuilder();
            var targetObj = new BindingSourceModel { ObjectProperty = "test" };
            var relativeObj = new BindingSourceModel();
            bool isInvoked = false;
            IEventListener eventListener = null;
            var memberMock = new BindingMemberInfoMock
            {
                TryObserveMember = (o, listener) =>
                {
                    eventListener = listener;
                    return null;
                }
            };

            var treeManagerMock = new VisualTreeManagerMock
            {
                FindByName = (o, s) =>
                {
                    o.ShouldEqual(targetObj);
                    s.ShouldEqual(name);
                    isInvoked = true;
                    return relativeObj;
                },
                GetRootMember = type => memberMock
            };
            BindingServiceProvider.VisualTreeManager = treeManagerMock;

            builder.Bind(targetObj, "empty").To<BindingSourceModel>(() => model => BindingSyntaxEx.Element<BindingSourceModel>(name).ObjectProperty);
            var source = builder.GetData(BindingBuilderConstants.Sources).Single().Invoke(builder);
            builder.GetData(BindingBuilderConstants.MultiExpression).ShouldBeNull();
            source.Path.Path.ShouldEqual(GetMemberPath(targetObj, model => model.ObjectProperty));
            source.GetSource(true).ShouldEqual(relativeObj);
            var pathMembers = source.GetPathMembers(true);
            pathMembers.LastMember.GetValue(pathMembers.PenultimateValue, null).ShouldEqual(relativeObj.ObjectProperty);
            isInvoked.ShouldBeTrue();

            isInvoked = false;
            eventListener.ShouldNotBeNull();
            eventListener.Handle(this, EventArgs.Empty);
            isInvoked.ShouldBeTrue();
        }
        public void GetValueShouldReturnValueUsingConverterSourceDoubleSource()
        {
            bool converterInvoked = false;
            var memberMock = new BindingMemberInfoMock
            {
                Type = typeof(int)
            };
            CultureInfo culture = CultureInfo.InvariantCulture;
            var parameter = new object();
            var sourceModel = new BindingSourceModel();
            var converterMock = new ValueConverterCoreMock
            {
                Convert = (o, type, arg3, arg4) =>
                {
                    converterInvoked = true;
                    o.ShouldEqual(sourceModel.IntProperty.ToString() + sourceModel.ObjectProperty);
                    type.ShouldEqual(typeof(int));
                    arg3.ShouldEqual(parameter);
                    arg4.ShouldEqual(culture);
                    return int.MaxValue;
                }
            };
            var dataContext = new DataContext
            {
                {BindingBuilderConstants.Converter, d => converterMock},
                {BindingBuilderConstants.ConverterCulture, d => culture},
                {BindingBuilderConstants.ConverterParameter, d => parameter}
            };

            string propertyName = GetMemberPath<BindingSourceModel>(model => model.IntProperty);
            var valueAccessor = new MultiBindingSourceAccessor(new[]
            {
                CreateSource(sourceModel, propertyName),
                CreateSource(sourceModel, GetMemberPath(sourceModel, model => model.ObjectProperty)),
            },
                (context, list) => list[0].ToString() + list[1], dataContext);
            valueAccessor.GetValue(memberMock, EmptyContext, true).ShouldEqual(int.MaxValue);
            converterInvoked.ShouldBeTrue();
        }
        public void GetValueShouldReturnValueUsingConverterTarget()
        {
            bool converterInvoked = false;
            var memberMock = new BindingMemberInfoMock
            {
                Type = typeof(int)
            };
            CultureInfo culture = CultureInfo.InvariantCulture;
            var parameter = new object();
            var sourceModel = new BindingSourceModel();
            var converterMock = new ValueConverterCoreMock
            {
                ConvertBack = (o, type, arg3, arg4) =>
                {
                    converterInvoked = true;
                    o.ShouldEqual(sourceModel.IntProperty);
                    type.ShouldEqual(typeof(int));
                    arg3.ShouldEqual(parameter);
                    arg4.ShouldEqual(culture);
                    return int.MaxValue;
                }
            };
            var dataContext = new DataContext
            {
                {BindingBuilderConstants.Converter, d => converterMock},
                {BindingBuilderConstants.ConverterCulture, d => culture},
                {BindingBuilderConstants.ConverterParameter, d => parameter}
            };

            string propertyName = GetMemberPath<BindingSourceModel>(model => model.IntProperty);
            var valueAccessor = GetAccessor(sourceModel, propertyName, dataContext, false);
            valueAccessor.GetValue(memberMock, EmptyContext, true).ShouldEqual(int.MaxValue);
            converterInvoked.ShouldBeTrue();
        }
        public void GetValueShouldReturnValueUsingTargetNullValueSource()
        {
            const int targetNullValue = 0;
            var memberMock = new BindingMemberInfoMock();
            var sourceModel = new BindingSourceModel { ObjectProperty = null };
            var dataContext = new DataContext
            {
                {BindingBuilderConstants.TargetNullValue, targetNullValue},
            };

            string propertyName = GetMemberPath<BindingSourceModel>(model => model.ObjectProperty);
            var valueAccessor = new MultiBindingSourceAccessor(new[] { CreateSource(sourceModel, propertyName) },
               (context, list) => list.Single(), dataContext);
            valueAccessor.GetValue(memberMock, dataContext, true).ShouldEqual(targetNullValue);
        }
        public void GetValueShouldReturnValueUsingTargetNullValueTarget()
        {
            const int targetNullValue = 0;
            var memberMock = new BindingMemberInfoMock();
            var sourceModel = new BindingSourceModel { IntProperty = targetNullValue };
            var dataContext = new DataContext
            {
                {BindingBuilderConstants.TargetNullValue, targetNullValue},
            };

            string propertyName = GetMemberPath<BindingSourceModel>(model => model.IntProperty);
            var valueAccessor = GetAccessor(sourceModel, propertyName, dataContext, false);
            valueAccessor.GetValue(memberMock, dataContext, true).ShouldBeNull();
        }
        public void GetValueShouldReturnValueUsingFallbackValueSource()
        {
            const int fallback = 0;
            var memberMock = new BindingMemberInfoMock();
            var sourceModel = new BindingSourceModel { ObjectProperty = BindingConstants.UnsetValue };
            var dataContext = new DataContext
            {
                {BindingBuilderConstants.Fallback, d => fallback},
            };

            string propertyName = GetMemberPath<BindingSourceModel>(model => model.ObjectProperty);
            var valueAccessor = GetAccessor(sourceModel, propertyName, dataContext, true);
            valueAccessor.GetValue(memberMock, dataContext, true).ShouldEqual(fallback);
        }
        public void ValueChangingShouldCanBeCanceled()
        {
            const int oldValue = 0;
            const int value = int.MaxValue;
            bool isInvoked = false;
            var srcAccessor = new BindingSourceAccessorMock();
            var memberMock = new BindingMemberInfoMock();
            var sourceModel = new BindingSourceModel();
            string propertyName = GetMemberPath<BindingSourceModel>(model => model.IntProperty);
            var valueAccessor = GetAccessor(sourceModel, propertyName, EmptyContext, true);
            valueAccessor.ValueChanging += (sender, args) =>
            {
                sender.ShouldEqual(valueAccessor);
                args.OldValue.ShouldEqual(oldValue);
                args.NewValue.ShouldEqual(value);
                args.Cancel = true;
                isInvoked = true;
            };

            srcAccessor.GetValue = (info, context, arg3) =>
            {
                context.ShouldEqual(EmptyContext);
                return value;
            };
            valueAccessor.SetValue(srcAccessor, EmptyContext, true);
            isInvoked.ShouldBeTrue();
            valueAccessor.GetValue(memberMock, EmptyContext, true).ShouldEqual(oldValue);
        }
 public void GetEventValueShouldAlwaysReturnBindingMemberValue()
 {
     var memberMock = new BindingMemberInfoMock { MemberType = BindingMemberType.Event };
     var source = new BindingSourceModel();
     var accessor = new MultiBindingSourceAccessor(new[] { CreateSource(source, BindingSourceModel.EventName) },
             (context, list) => memberMock, EmptyContext);
     var memberValue = (BindingActionValue)accessor.GetValue(memberMock, EmptyContext, true);
     memberValue.GetValue(new object[] { null, null }).ShouldEqual(memberMock);
 }
        public void BuilderShouldUseRelativeSource1()
        {
            var builder = new BindingBuilder();
            var targetObj = new BindingSourceModel { ObjectProperty = "test" };
            var relativeObj = new BindingSourceModel();
            bool isInvoked = false;
            IEventListener eventListener = null;
            var memberMock = new BindingMemberInfoMock
            {
                TryObserveMember = (o, listener) =>
                {
                    eventListener = listener;
                    return null;
                }
            };

            var treeManagerMock = new VisualTreeManagerMock
            {
                FindRelativeSource = (o, s, arg3) =>
                {
                    o.ShouldEqual(targetObj);
                    s.ShouldEqual(typeof(BindingSourceModel).AssemblyQualifiedName);
                    arg3.ShouldEqual(1u);
                    isInvoked = true;
                    return relativeObj;
                },
                GetRootMember = type => memberMock
            };
            BindingServiceProvider.VisualTreeManager = treeManagerMock;

            builder.Bind(targetObj, "empty").To<BindingSourceModel>(() => (model, ctx) => ctx.Relative<BindingSourceModel>());
            var source = builder.GetData(BindingBuilderConstants.Sources).Single().Invoke(builder);
            builder.GetData(BindingBuilderConstants.MultiExpression).ShouldBeNull();
            source.Path.Path.IsEmpty().ShouldBeTrue();
            source.GetActualSource(true).ShouldEqual(relativeObj);
            var pathMembers = source.GetPathMembers(true);
            pathMembers.LastMember.GetValue(pathMembers.PenultimateValue, null).ShouldEqual(relativeObj);
            isInvoked.ShouldBeTrue();

            isInvoked = false;
            eventListener.ShouldNotBeNull();
            eventListener.Handle(this, EventArgs.Empty);
            isInvoked.ShouldBeTrue();
        }