public void BuilderShouldUseGetErrorsMethod4()
        {
            var builder = new BindingBuilder();
            var sourceModel = new BindingSourceModel();
            builder.Bind(sourceModel, "empty").To(sourceModel, () => model => BindingSyntaxEx.GetErrors("1", "2").Concat(BindingSyntaxEx.GetErrors(model.ObjectProperty)));


            var sources = builder.GetData(BindingBuilderConstants.Sources).Select(func => func(builder)).ToArray();
            sources[0].GetSource(true).ShouldEqual(sourceModel);
            sources[1].GetSource(true).ShouldEqual(sourceModel);
            if (sources[0].Path.IsEmpty)
                sources[1].Path.Path.ShouldEqual(GetMemberPath(sourceModel, model => model.ObjectProperty));
            else
                sources[0].Path.Path.ShouldEqual(GetMemberPath(sourceModel, model => model.ObjectProperty));

            var behaviors = builder.GetOrAddBehaviors().OfType<NotifyDataErrorsAggregatorBehavior>().ToArray();
            builder.AddOrUpdate(BindingConstants.Binding, new DataBindingMock { Behaviors = behaviors });
            var behavior = behaviors.Single(b => !b.ErrorPaths.IsNullOrEmpty());
            behavior.ErrorPaths.SequenceEqual(new[] { "1", "2" }).ShouldBeTrue();

            behaviors.ForEach(aggregatorBehavior => aggregatorBehavior.Errors = new[] { "1" });
            var expression = builder.GetData(BindingBuilderConstants.MultiExpression);
            var errors = (IEnumerable<object>)expression(builder, new object[] { sourceModel, sourceModel });
            errors.SequenceEqual(behaviors[0].Errors.Concat(behaviors[1].Errors)).ShouldBeTrue();
        }
        public void BuilderShouldUseGetErrorsMethodForParameter2()
        {
            var builder = new BindingBuilder();
            var sourceModel = new BindingSourceModel();
            builder.Bind(sourceModel, "empty").To(sourceModel, () => model => model.IntProperty)
                .WithCommandParameter(() => model => BindingSyntaxEx.GetErrors("1", "2"));

            var behavior = builder.GetOrAddBehaviors().OfType<NotifyDataErrorsAggregatorBehavior>().Single();
            behavior.ErrorPaths.SequenceEqual(new[] { "1", "2" }).ShouldBeTrue();
            builder.AddOrUpdate(BindingConstants.Binding, new DataBindingMock { Behaviors = new[] { behavior } });

            var expression = builder.GetData(BindingBuilderConstants.CommandParameter);
            behavior.Errors = new List<object> { "test" };
            expression(builder).ShouldEqual(behavior.Errors);
        }
        public void BuilderShouldUseGetErrorsMethod3()
        {
            var builder = new BindingBuilder();
            var sourceModel = new BindingSourceModel();
            builder.Bind(sourceModel, "empty").To(sourceModel, () => model => BindingSyntaxEx.GetErrors("1", "2", model.ObjectProperty));

            var source = builder.GetData(BindingBuilderConstants.Sources).Single().Invoke(builder);
            source.Path.Path.ShouldEqual(GetMemberPath(sourceModel, model => model.ObjectProperty));
            source.GetSource(true).ShouldEqual(sourceModel);

            var behavior = builder.GetOrAddBehaviors().OfType<NotifyDataErrorsAggregatorBehavior>().Single();
            behavior.ErrorPaths.SequenceEqual(new[] { "1", "2" }).ShouldBeTrue();
            builder.AddOrUpdate(BindingConstants.Binding, new DataBindingMock { Behaviors = new[] { behavior } });

            var expression = builder.GetData(BindingBuilderConstants.MultiExpression);
            behavior.Errors = new List<object> { "test" };
            expression(builder, new object[] { sourceModel }).ShouldEqual(behavior.Errors);
        }
        public void BuilderShouldUseGetErrorsMethod1()
        {
            var builder = new BindingBuilder();
            var sourceModel = new BindingSourceModel();
            builder.Bind(sourceModel, "empty").To(sourceModel, () => (model, ctx) => ctx.GetErrors());

            var source = builder.GetData(BindingBuilderConstants.Sources).Single().Invoke(builder);
            source.Path.IsEmpty.ShouldBeTrue();
            source.GetActualSource(true).ShouldEqual(sourceModel);

            var behavior = builder.GetOrAddBehaviors().OfType<NotifyDataErrorsAggregatorBehavior>().Single();
            behavior.ErrorPaths.IsNullOrEmpty().ShouldBeTrue();
            builder.AddOrUpdate(BindingConstants.Binding, new DataBindingMock { Behaviors = new[] { behavior } });

            var expression = builder.GetData(BindingBuilderConstants.MultiExpression);
            behavior.Errors = new List<object> { "test" };
            expression(builder, new object[] { sourceModel }).ShouldEqual(behavior.Errors);
        }
        public void BuilderShouldUseGetErrorsMethodForParameter1()
        {
            for (int i = 0; i < 4; i++)
            {
                var builder = new BindingBuilder();
                var sourceModel = new BindingSourceModel();
                builder.Bind(sourceModel, "empty").To(sourceModel, () => (model, ctx) => model.IntProperty)
                    .WithCommandParameter(() => (model, ctx) => ctx.GetErrors());

                var behavior = builder.GetOrAddBehaviors().OfType<NotifyDataErrorsAggregatorBehavior>().Single();
                behavior.ErrorPaths.IsNullOrEmpty().ShouldBeTrue();
                builder.AddOrUpdate(BindingConstants.Binding, new DataBindingMock { Behaviors = new[] { behavior } });

                var expression = builder.GetData(BindingBuilderConstants.CommandParameter);
                behavior.Errors = new List<object> { "test" };
                expression(builder).ShouldEqual(behavior.Errors);
            }
        }
        public void ParserShouldParseMultiExpressionWithOneTimeScope()
        {
            const string targetPath = "Text";
            const string sourcePath1 = "SourceText1";
            const string sourcePath2 = "SourceText2";
            const string sourcePath3 = "SourceText3";
            const string methodName = "TestMethod";
            const string binding = "Text $OneTime($TestMethod(SourceText1, SourceText2).IntProperty) + SourceText3";

            const int firstValue = -1;
            var ctx = new DataContext();
            var bindingMock = new DataBindingMock { GetContext = () => ctx };
            int executionCount = 0;
            var target = new object();
            var args = new object[] { "tset", 1, 3 };
            var sourceModel = new BindingSourceModel { IntProperty = firstValue };

            var provider = new BindingProvider();
            var resolver = new BindingResourceResolver();
            BindingServiceProvider.ResourceResolver = resolver;
            var method = new BindingResourceMethod((list, objects, c) =>
            {
                ++executionCount;
                objects[0].ShouldEqual(args[0]);
                objects[1].ShouldEqual(args[1]);
                return sourceModel;
            }, typeof(BindingSourceModel));
            resolver.AddMethod(methodName, method, true);
            IBindingParser bindingParser = CreateBindingParser(bindingProvider: provider);


            var context = new BindingBuilder(bindingParser.Parse(target, binding, null, null).Single());
            context.AddOrUpdate(BindingConstants.Binding, bindingMock);
            IBindingPath path = context.GetData(BindingBuilderConstants.TargetPath);
            path.Path.ShouldEqual(targetPath);

            var expression = context.GetData(BindingBuilderConstants.MultiExpression);
            expression(context, args).ShouldEqual(firstValue + 3);
            sourceModel.IntProperty = int.MinValue;
            args[2] = 5;
            expression(context, args).ShouldEqual(firstValue + 5);
            args[2] = 6;
            expression(context, args).ShouldEqual(firstValue + 6);

            executionCount.ShouldEqual(1);

            var sources = context.GetData(BindingBuilderConstants.Sources);
            BindingSourceShouldBeValidDataContext(target, sources[0].Invoke(context), sourcePath1);
            BindingSourceShouldBeValidDataContext(target, sources[1].Invoke(context), sourcePath2);
            BindingSourceShouldBeValidDataContext(target, sources[2].Invoke(context), sourcePath3);
        }
        public void BuilderShouldUseExpressionWithOneTimeScope()
        {
            const string key = "key";
            var builder = new BindingBuilder();
            var sourceModel = new BindingSourceModel();
            const int firstValue = -1;
            int executionCount = 0;
            var dataContext = new DataContext();
            var bindingMock = new DataBindingMock { GetContext = () => dataContext };
            var result = new BindingSourceModel { IntProperty = firstValue };
            BindingServiceProvider.ResourceResolver.AddMethod<string, object, BindingSourceModel>(key, (s1, s2, context) =>
            {
                ++executionCount;
                s1.ShouldEqual(key);
                s2.ShouldEqual(builder);
                context.ShouldEqual(builder);
                return result;
            });
            builder.Bind(sourceModel, "empty").To<BindingSourceModel>(() => (model, ctx) => ctx.OneTime(ctx.ResourceMethod<BindingSourceModel>(key, key, builder).IntProperty) + 3);
            builder.AddOrUpdate(BindingConstants.Binding, bindingMock);

            var sources = builder.GetData(BindingBuilderConstants.Sources);
            sources.Count.ShouldEqual(1);
            sources[0].Invoke(builder).Path.Path.ShouldEqual(string.Empty);
            var expression = builder.GetData(BindingBuilderConstants.MultiExpression);
            expression(builder, Empty.Array<object>()).ShouldEqual(firstValue + 3);
            sourceModel.IntProperty = int.MinValue;
            expression(builder, Empty.Array<object>()).ShouldEqual(firstValue + 3);
            executionCount.ShouldEqual(1);
        }
 public void BuilderShouldUseBinding()
 {
     var builder = new BindingBuilder();
     var dataContext = new DataContext();
     var bindingMock = new DataBindingMock { GetContext = () => dataContext };
     builder.Bind(new object(), "empty").To<BindingSourceModel>(() => (model, ctx) => ctx.Binding());
     
     builder.AddOrUpdate(BindingConstants.Binding, bindingMock);
     var expression = builder.GetData(BindingBuilderConstants.MultiExpression);
     expression(builder, Empty.Array<object>()).ShouldEqual(bindingMock);
 }