public virtual void BindingShouldAddSelfToDataContext()
        {
            IBindingPath path = BindingPath.Create("test");
            var bindingManager = new BindingManager();
            var target = new BindingSourceAccessorMock
            {
                Source = new BindingSourceMock { GetSource = b => new object(), Path = path }
            };
            var source = new BindingSourceAccessorMock();
            DataBinding binding = CreateDataBinding(target, source, bindingManager);

            var dataContext = binding.Context;
            dataContext.Count.ShouldEqual(1);
            dataContext.GetData(BindingConstants.Binding).ShouldEqual(binding);
        }
        public virtual void BindingShouldCorrectInitializeProperties()
        {
            IBindingPath path = BindingPath.Create("test");
            var bindingManager = new BindingManager();
            var target = new BindingSourceAccessorMock
            {
                Source = new BindingSourceMock { GetSource = b => new object(), Path = path }
            };
            var source = new BindingSourceAccessorMock();
            DataBinding binding = CreateDataBinding(target, source, bindingManager);

            binding.TargetAccessor.ShouldEqual(target);
            binding.SourceAccessor.ShouldEqual(source);
            binding.Behaviors.ShouldBeEmpty();
        }
        public void SetValueShouldUpdateIsEnabledPropertyOneTimeModeAfterDispose()
        {
            bool canExecute = false;
            var command = new RelayCommand(o => { }, o => canExecute, this);

            var srcAccessor = new BindingSourceAccessorMock();
            var source = new BindingSourceModel();
            var ctx = new DataContext(BindingBuilderConstants.Behaviors.ToValue(new List<IBindingBehavior> { new OneTimeBindingMode() }));
            var accessor = GetAccessor(source, BindingSourceModel.EventName, ctx, false);
            srcAccessor.GetValue = (info, context, arg3) => command;
            accessor.SetValue(srcAccessor, EmptyContext, true);
            accessor.Dispose();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            source.IsEnabled.ShouldBeFalse();
            canExecute = true;
            command.RaiseCanExecuteChanged();
            source.IsEnabled.ShouldBeTrue();
        }
        public void ExecuteShouldCallCmdExecuteMethodOneTimeModeAfterDispose()
        {
            var parameter = new object();
            bool isInvoked = false;
            var command = new RelayCommand(o =>
            {
                o.ShouldEqual(parameter);
                isInvoked = true;
            });
            var srcAccessor = new BindingSourceAccessorMock();
            var source = new BindingSourceModel();
            var ctx = new DataContext(BindingBuilderConstants.Behaviors.ToValue(new List<IBindingBehavior> { new OneTimeBindingMode() }));
            var accessor = GetAccessor(source, BindingSourceModel.EventName, ctx, false, d => parameter);
            srcAccessor.GetValue = (info, context, arg3) => command;
            accessor.SetValue(srcAccessor, EmptyContext, true);
            accessor.Dispose();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            source.RaiseEvent();
            isInvoked.ShouldBeTrue();

            isInvoked = false;
            source.RaiseEvent();
            isInvoked.ShouldBeTrue();
        }
        public void SetValueShouldUpdateValueInSourceNestedProperty()
        {
            var srcAccessor = new BindingSourceAccessorMock();
            var propertyName = GetMemberPath<BindingSourceModel>(model => model.NestedModel.IntProperty);
            var sourceModel = new BindingSourceModel { NestedModel = new BindingSourceNestedModel() };
            var valueAccessor = GetAccessor(sourceModel, propertyName, EmptyContext, true);

            srcAccessor.GetValue = (info, context, arg3) =>
            {
                context.ShouldEqual(EmptyContext);
                return int.MaxValue;
            };
            valueAccessor.SetValue(srcAccessor, EmptyContext, true);
            sourceModel.NestedModel.IntProperty.ShouldEqual(int.MaxValue);
        }
 public virtual void BindingShouldUpdateTargetWithBindingContext()
 {
     bool isInvoked = false;
     IBindingPath path = BindingPath.Create("test");
     var bindingManager = new BindingManager();
     var target = new BindingSourceAccessorMock
     {
         Source = new BindingSourceMock
         {
             GetSource = b => new object(),
             Path = path
         }
     };
     var source = new BindingSourceAccessorMock
     {
         Source = new BindingSourceMock
         {
             IsValid = b => true
         }
     };
     DataBinding binding = CreateDataBinding(target, source, bindingManager);
     target.SetValue = (func, context, arg3) =>
     {
         context.ShouldEqual(binding.Context);
         arg3.ShouldBeTrue();
         isInvoked = true;
         return true;
     };
     binding.UpdateTarget();
     isInvoked.ShouldBeTrue();
 }
        public virtual void BindingShouldNotAddBehaviorIfAttachReturnsFalse()
        {
            IBindingPath path = BindingPath.Create("test");
            var bindingManager = new BindingManager();
            var target = new BindingSourceAccessorMock
            {
                Source = new BindingSourceMock { GetSource = b => new object(), Path = path }
            };
            var source = new BindingSourceAccessorMock();
            DataBinding binding = CreateDataBinding(target, source, bindingManager);

            var first = new BindingBehaviorMock
            {
                Id = Guid.Empty,
                Attach = binding1 => false
            };
            binding.Behaviors.Add(first);
            binding.Behaviors.Count.ShouldEqual(0);
            binding.Behaviors.Contains(first).ShouldBeFalse();
        }
        public virtual void BindingShouldRaiseEventWhenUpdateSourceFalse()
        {
            bool isInvoked = false;
            IBindingPath path = BindingPath.Create("test");
            var bindingManager = new BindingManager();
            var target = new BindingSourceAccessorMock
            {
                Source = new BindingSourceMock { GetSource = b => new object(), Path = path }
            };
            var source = new BindingSourceAccessorMock();

            DataBinding binding = CreateDataBinding(target, source, bindingManager);
            source.SetValue = (func, context, arg3) => false;
            binding.BindingUpdated += (sender, args) =>
            {
                args.Action.ShouldEqual(BindingAction.UpdateSource);
                args.Result.ShouldBeFalse();
                isInvoked = true;
            };
            binding.UpdateSource();
            isInvoked.ShouldBeTrue();
        }
        public void SetValueShouldAutoConvertValueFalse()
        {
            var srcAccessor = new BindingSourceAccessorMock();
            var sourceModel = new BindingSourceModel();
            string propertyName = GetMemberPath<BindingSourceModel>(model => model.IntProperty);
            var valueAccessor = GetAccessor(sourceModel, propertyName, EmptyContext, true);
            BindingServiceProvider.ValueConverter = null;

            srcAccessor.GetValue = (info, context, arg3) =>
            {
                context.ShouldEqual(EmptyContext);
                return int.MaxValue.ToString();
            };
            ShouldThrow<InvalidCastException>(() => valueAccessor.SetValue(srcAccessor, EmptyContext, true));
        }
        public void SetValueShouldAutoConvertValueTrue()
        {
            var srcAccessor = new BindingSourceAccessorMock();
            var sourceModel = new BindingSourceModel();
            string propertyName = GetMemberPath<BindingSourceModel>(model => model.IntProperty);
            var valueAccessor = GetAccessor(sourceModel, propertyName, EmptyContext, true);

            srcAccessor.GetValue = (info, context, arg3) =>
            {
                context.ShouldEqual(EmptyContext);
                return int.MaxValue.ToString();
            };
            valueAccessor.SetValue(srcAccessor, EmptyContext, true);
            sourceModel.IntProperty.ShouldEqual(int.MaxValue);
        }
 public void SetValueShouldNotThrowExceptionInvalidValueIfFlagFalse()
 {
     var srcAccessor = new BindingSourceAccessorMock();
     srcAccessor.GetValue = (info, context, arg3) => string.Empty;
     var sourceModel = new BindingSourceModel();
     string propertyName = GetMemberPath<BindingSourceModel>(model => model.IntProperty);
     var valueAccessor = GetAccessor(sourceModel, propertyName, EmptyContext, true);
     valueAccessor.SetValue(srcAccessor, EmptyContext, false);
 }
        public void ValueChangedShouldBeRaised()
        {
            int oldValue = 0;
            int value = int.MaxValue;
            bool isInvoked = false;
            var sourceModel = new BindingSourceModel();
            var srcAccessor = new BindingSourceAccessorMock();
            string propertyName = GetMemberPath<BindingSourceModel>(model => model.IntProperty);
            var valueAccessor = GetAccessor(sourceModel, propertyName, EmptyContext, true);
            valueAccessor.ValueChanged += (sender, args) =>
            {
                sender.ShouldEqual(valueAccessor);
                args.OldValue.ShouldEqual(oldValue);
                args.NewValue.ShouldEqual(value);
                isInvoked = true;
            };

            srcAccessor.GetValue = (info, context, arg3) =>
            {
                context.ShouldEqual(EmptyContext);
                return value;
            };
            valueAccessor.SetValue(srcAccessor, EmptyContext, true);
            isInvoked.ShouldBeTrue();
            isInvoked = false;

            oldValue = value;
            value = int.MinValue;
            valueAccessor.SetValue(srcAccessor, EmptyContext, true);
            isInvoked.ShouldBeTrue();
        }
        public void SetValueShouldDoNothingIfNewValueIsBindingUnsetValue()
        {
            var srcAccessor = new BindingSourceAccessorMock();
            var sourceModel = new BindingSourceModel();
            string propertyName = GetMemberPath<BindingSourceModel>(model => model.IntProperty);
            var valueAccessor = GetAccessor(sourceModel, propertyName, EmptyContext, true);

            srcAccessor.GetValue = (info, context, arg3) =>
            {
                context.ShouldEqual(EmptyContext);
                return BindingConstants.UnsetValue;
            };
            valueAccessor.SetValue(srcAccessor, EmptyContext, true);
            sourceModel.IntProperty.ShouldEqual(0);
        }
        public void SetValueShouldNotUpdateValueInSourceIfNestedPropertyNullDoubleIndexer()
        {
            var srcAccessor = new BindingSourceAccessorMock();
            var propertyName = GetMemberPath<BindingSourceModel>(model => model.NestedModel["test", 0]);
            var sourceModel = new BindingSourceModel();
            var valueAccessor = GetAccessor(sourceModel, propertyName, EmptyContext, true);

            srcAccessor.GetValue = (info, context, arg3) =>
            {
                context.ShouldEqual(EmptyContext);
                return propertyName;
            };
            valueAccessor.SetValue(srcAccessor, EmptyContext, true);
            sourceModel.NestedModel.ShouldBeNull();
        }
        public void AccessorShouldUseCommandParameterCanExecuteOneTimeModeAfterDispose()
        {
            bool isInvoked = false;
            var parameter = new object();
            var command = new RelayCommand(o => { }, o =>
            {
                o.ShouldEqual(parameter);
                isInvoked = true;
                return false;
            }, this);
            var srcAccessor = new BindingSourceAccessorMock();
            var source = new BindingSourceModel();
            var ctx = new DataContext(BindingBuilderConstants.Behaviors.ToValue(new List<IBindingBehavior> { new OneTimeBindingMode() }));
            var accessor = GetAccessor(source, BindingSourceModel.EventName, ctx, false, d => parameter);
            srcAccessor.GetValue = (info, context, arg3) => command;

            accessor.SetValue(srcAccessor, EmptyContext, true);
            accessor.Dispose();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            isInvoked.ShouldBeTrue();

            isInvoked = false;
            command.RaiseCanExecuteChanged();
            isInvoked.ShouldBeTrue();
            source.ToString();//TO KEEP ALIVE
        }
        public void AccessorShouldToggleEnabledFalse()
        {
            bool canExecute = false;
            bool isInvoked = false;
            var parameter = new object();
            var command = new RelayCommand(o => { }, o =>
            {
                o.ShouldEqual(parameter);
                isInvoked = true;
                return canExecute;
            }, this);
            bool isEnabled = true;
            IAttachedBindingMemberInfo<object, bool> member =
                AttachedBindingMember.CreateMember<object, bool>(AttachedMemberConstants.Enabled,
                    (info, o) => isEnabled,
                    (info, o, v) => isEnabled = v);
            var memberProvider = new BindingMemberProvider();
            memberProvider.Register(typeof(object), member, false);
            BindingServiceProvider.MemberProvider = memberProvider;

            var srcAccessor = new BindingSourceAccessorMock();
            var source = new BindingSourceModel();
            var accessor = GetAccessor(source, BindingSourceModel.EventName, new DataContext(BindingBuilderConstants.ToggleEnabledState.ToValue(false)), false, d => parameter);
            srcAccessor.GetValue = (info, context, arg3) => command;

            isEnabled.ShouldBeTrue();
            accessor.SetValue(srcAccessor, EmptyContext, true);
            isInvoked.ShouldBeFalse();
            isEnabled.ShouldBeTrue();

            isInvoked = false;
            canExecute = true;
            command.RaiseCanExecuteChanged();
            isInvoked.ShouldBeFalse();
            isEnabled.ShouldBeTrue();
        }
        public void SetValueShouldAutoConvertValueTypeConverterOnProperty()
        {
            var srcAccessor = new BindingSourceAccessorMock();
            var sourceModel = new ConverterTestClass();
            string propertyName = GetMemberPath<ConverterTestClass>(model => model.DoubleProperty);
            var valueAccessor = GetAccessor(sourceModel, propertyName, EmptyContext, true);

            srcAccessor.GetValue = (info, context, arg3) =>
            {
                context.ShouldEqual(EmptyContext);
                return double.MaxValue;
            };
            valueAccessor.SetValue(srcAccessor, EmptyContext, true);
            sourceModel.DoubleProperty.ShouldNotBeNull();
            sourceModel.DoubleProperty.Double.ShouldEqual(double.MaxValue);
        }
        public virtual void BindingShouldNotAddSameBehavior()
        {
            IBindingPath path = BindingPath.Create("test");
            var bindingManager = new BindingManager();
            var target = new BindingSourceAccessorMock
            {
                Source = new BindingSourceMock { GetSource = b => new object(), Path = path }
            };
            var source = new BindingSourceAccessorMock();
            DataBinding binding = CreateDataBinding(target, source, bindingManager);

            var first = new BindingBehaviorMock
            {
                Id = Guid.Empty,
                Attach = binding1 => true
            };
            binding.Behaviors.Add(first);
            ShouldThrow(() => binding.Behaviors.Add(first));
        }
        public void SetValueShouldUpdateIsEnabledProperty()
        {
            bool canExecute = false;
            var command = new RelayCommand(o => { }, o => canExecute, this);

            var srcAccessor = new BindingSourceAccessorMock();
            var source = new BindingSourceModel();
            var accessor = GetAccessor(source, BindingSourceModel.EventName, EmptyContext, false);
            srcAccessor.GetValue = (info, context, arg3) => command;

            accessor.SetValue(srcAccessor, EmptyContext, true);
            source.IsEnabled.ShouldBeFalse();
            canExecute = true;
            command.RaiseCanExecuteChanged();
            source.IsEnabled.ShouldBeTrue();
        }
        public virtual void BindingShouldCallAttachDetachMethodInBehavior()
        {
            IBindingPath path = BindingPath.Create("test");
            var bindingManager = new BindingManager();
            var target = new BindingSourceAccessorMock
            {
                Source = new BindingSourceMock { GetSource = b => new object(), Path = path }
            };
            var source = new BindingSourceAccessorMock();
            DataBinding binding = CreateDataBinding(target, source, bindingManager);

            int countAttach = 0;
            int countDetach = 0;
            var first = new BindingBehaviorMock
            {
                Id = Guid.Empty,
                Attach = binding1 =>
                {
                    countAttach++;
                    return true;
                },
                Detach = binding1 => countDetach++
            };
            binding.Behaviors.Add(first);
            countAttach.ShouldEqual(1);
            countDetach.ShouldEqual(0);

            binding.Behaviors.Remove(first);
            countAttach.ShouldEqual(1);
            countDetach.ShouldEqual(1);
        }
        public void AccessorShouldUseCommandParameterCanExecute()
        {
            bool isInvoked = false;
            var parameter = new object();
            var command = new RelayCommand(o => { }, o =>
            {
                o.ShouldEqual(parameter);
                isInvoked = true;
                return false;
            }, this);
            var srcAccessor = new BindingSourceAccessorMock();
            var source = new BindingSourceModel();
            var accessor = GetAccessor(source, BindingSourceModel.EventName, EmptyContext, false, d => parameter);
            srcAccessor.GetValue = (info, context, arg3) => command;

            accessor.SetValue(srcAccessor, EmptyContext, true);
            isInvoked.ShouldBeTrue();

            isInvoked = false;
            command.RaiseCanExecuteChanged();
            isInvoked.ShouldBeTrue();
        }
        public void AccessorShouldUseOnlyOneCmd()
        {
            bool isEnabled = false;
            var oldCmd = new RelayCommand(o => { }, o => false, this);
            var command = new RelayCommand(o => { }, o => isEnabled, this);
            var srcAccessor = new BindingSourceAccessorMock();
            var source = new BindingSourceModel();
            var accessor = GetAccessor(source, BindingSourceModel.EventName, EmptyContext, false);
            srcAccessor.GetValue = (info, context, arg3) => oldCmd;

            accessor.SetValue(srcAccessor, EmptyContext, true);
            source.IsEnabled.ShouldBeFalse();
            oldCmd.RaiseCanExecuteChanged();
            source.IsEnabled.ShouldBeFalse();

            srcAccessor.GetValue = (info, context, arg3) => command;
            accessor.SetValue(srcAccessor, EmptyContext, true);
            isEnabled = true;
            command.RaiseCanExecuteChanged();
            source.IsEnabled.ShouldEqual(isEnabled);

            oldCmd.RaiseCanExecuteChanged();
            source.IsEnabled.ShouldEqual(isEnabled);

            srcAccessor.GetValue = (info, context, arg3) => null;
            accessor.SetValue(srcAccessor, EmptyContext, true);
            isEnabled = false;
            command.RaiseCanExecuteChanged();
            source.IsEnabled.ShouldBeTrue();
        }
        public void ExecuteShouldCallCmdExecuteMethod()
        {
            var parameter = new object();
            bool isInvoked = false;
            var command = new RelayCommand(o =>
            {
                o.ShouldEqual(parameter);
                isInvoked = true;
            });
            var srcAccessor = new BindingSourceAccessorMock();
            var source = new BindingSourceModel();
            var accessor = GetAccessor(source, BindingSourceModel.EventName, EmptyContext, false, d => parameter);
            srcAccessor.GetValue = (info, context, arg3) => command;
            accessor.SetValue(srcAccessor, EmptyContext, true);
            source.RaiseEvent();
            isInvoked.ShouldBeTrue();

            isInvoked = false;
            source.RaiseEvent();
            isInvoked.ShouldBeTrue();
        }
 public virtual void BindingShouldRaiseExceptionEventWhenUpdateTargetThrowException()
 {
     bool isInvoked = false;
     IBindingPath path = BindingPath.Create("test");
     var bindingManager = new BindingManager();
     var target = new BindingSourceAccessorMock
     {
         Source = new BindingSourceMock { GetSource = b => new object(), Path = path }
     };
     var source = new BindingSourceAccessorMock
     {
         Source = new BindingSourceMock
         {
             GetSource = b => new object(),
             Path = path,
             IsValid = b => true
         }
     };
     DataBinding binding = CreateDataBinding(target, source, bindingManager);
     target.SetValue = (func, context, arg3) => { throw new TestException(); };
     binding.BindingException += (sender, args) =>
     {
         args.Action.ShouldEqual(BindingAction.UpdateTarget);
         args.Exception.InnerException.ShouldBeType<TestException>();
         isInvoked = true;
     };
     binding.UpdateTarget();
     isInvoked.ShouldBeTrue();
 }
        public virtual void BindingShouldThrowExceptionDuplicateIdBehavior()
        {
            IBindingPath path = new BindingPath("test");
            var bindingManager = new BindingManager();
            var target = new BindingSourceAccessorMock
            {
                Source = new ObserverMock { GetActualSource = b => new object(), Path = path }
            };
            var source = new BindingSourceAccessorMock();
            DataBinding binding = CreateDataBinding(target, source, bindingManager);

            var first = new BindingBehaviorMock { Id = Guid.Empty, Attach = binding1 => true };
            var second = new BindingBehaviorMock { Id = Guid.Empty, Attach = binding1 => true };
            binding.Behaviors.Add(first);
            ShouldThrow(() => binding.Behaviors.Add(second));
        }