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 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 ResolverShouldRegisterAndResolveDynamicObjectTarget()
        {
            string name = BindingServiceProvider.ResourceResolver.RootElementResourceName;
            const string firstValue = "1";
            var visualTreeManagerMock = new VisualTreeManagerMock();
            BindingServiceProvider.VisualTreeManager = visualTreeManagerMock;
            var rootMember = AttachedBindingMember.CreateAutoProperty<object, object>("root");
            visualTreeManagerMock.GetRootMember = type => rootMember;
            var target = new object();
            rootMember.SetValue(target, target);

            var dataContext = new DataContext
            {
                {BindingBuilderConstants.Target, target}
            };

            var source = new BindingResourceObject(firstValue);
            var resolver = CreateBindingResourceResolver();

            bool isInvoked = false;
            var value = resolver.ResolveObject(name, dataContext, false);
            value.Value.ShouldEqual(target);
            value.ValueChanged += (sender, args) => isInvoked = true;

            resolver.AddObject(name, source, true);
            value.Value.ShouldEqual(firstValue);
            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 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 ResolverShouldResolveRootMember()
        {
            string name = BindingServiceProvider.ResourceResolver.RootElementResourceName;
            var visualTreeManagerMock = new VisualTreeManagerMock();
            BindingServiceProvider.VisualTreeManager = visualTreeManagerMock;
            var rootMember = AttachedBindingMember.CreateAutoProperty<object, object>(name);
            visualTreeManagerMock.GetRootMember = type => rootMember;
            var target = new object();

            var dataContext = new DataContext
            {
                {BindingBuilderConstants.Target, target}
            };

            var resolver = CreateBindingResourceResolver();
            var value = resolver.ResolveObject(name, dataContext, false);
            value.Value.ShouldBeNull();

            rootMember.SetValue(target, target);
            value.Value.ShouldEqual(target);
        }
        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 ManagerShouldRaiseEventWhenDataContextChangedNotExplicit()
        {
            bool contextChanged = false;
            var context = new object();
            var managerMock = new VisualTreeManagerMock
            {
                FindParent = o => null,
                GetParentMember = type => null
            };

            var manager = CreateContextManager(managerMock);
            var bindingContext = manager.GetBindingContext(context);
            bindingContext.ValueChanged += (sender, args) => contextChanged = true;
            bindingContext.Value = context;
            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 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 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();
        }