public void CreateSingleCrossReferenceFieldMappingTest()
        {
            // Arrange.
            const string ProcessName = "TestProcess";
            var fieldName = ReflectionHelper.GetPropertyName<TestEditable>(x => x.CR);
            const string ReferencedProcessName = "CRProcess";

            var keyMapping = new FieldMappingDefinition
                                 {
                                     FieldName = ReflectionHelper.GetPropertyName<ReferenceEdit>(x => x.Field1),
                                     ValueExpression = context => null,
                                     IsKey = true,
                                 };
            var fieldMapping = new FieldMappingDefinition { FieldName = fieldName, ValueExpression = context => null, IsKey = true, Subfields = { keyMapping } };
            var dtm = new Mock<IDynamicTypeManager>();
            dtm.Setup(x => x.GetEditableRootType(ProcessName)).Returns(typeof(TestEditable));
            dtm.Setup(x => x.GetEditableRootType(ReferencedProcessName)).Returns(typeof(ReferenceEdit));

            var typeConverter = Mock.Create<ITypeConverter>(Behavior.Loose);
            var runtimeDatabase = Mock.Create<IRuntimeDatabase>(Behavior.Loose);
            var factory = new ProcessFieldMappingFactory { DynamicTypeManager = dtm.Object, TypeConverter = typeConverter, RuntimeDatabase = runtimeDatabase };

            // Act.
            var mapping = factory.CreateMapping(ProcessName, fieldMapping);

            // Assert.
            Assert.IsTrue(mapping is SingleCrossReferenceFieldMapping);
       }
        public void CreateComplexValueCalculatorTest()
        {
            // Arrange.
            var typeConverter = Mock.Create<ITypeConverter>(Behavior.Loose);

            var fieldMappingDefinition = new FieldMappingDefinition
                                             {
                                                 FieldName = ReflectionHelper.GetFieldName<Employee>(x => x.FirstName),
                                                 ValueExpression = c => "First Name"
                                             };
            var propertyMappingDefinition = new FieldMappingDefinition
                                                {
                                                    FieldName = ReflectionHelper.GetPropertyName<Employee>(x => x.LastName),
                                                    ValueExpression = c => "Last Name"
                                                };
            var mappingDefinition = new FieldMappingDefinition { FieldName = "TestField", Subfields = { fieldMappingDefinition, propertyMappingDefinition } };

            var factory = new ValueCalculatorFactory(typeConverter);

            // Act.
            var valueCalculator = factory.CreateValueCalculator(typeof(Employee), mappingDefinition);

            // Assert.
            Assert.IsTrue(valueCalculator is ComplexValueCalculator);
        }
        public void CreateSimpleValueCalculatorTest()
        {
            // Arrange.
            var typeConverter = Mock.Create<ITypeConverter>(Behavior.Loose);

            var mappingDefinition = new FieldMappingDefinition { FieldName = "TestField", ValueExpression = c => null };
            var factory = new ValueCalculatorFactory(typeConverter);

            // Act.
            var valueCalculator = factory.CreateValueCalculator(typeof(string), mappingDefinition);

            // Assert.
            Assert.IsTrue(valueCalculator is SimpleValueCalculator);
        }
        public void CreateArrayValueCalculatorTest()
        {
            // Arrange.
            var typeConverter = Mock.Create<ITypeConverter>(Behavior.Loose);

            var elementMappingDefinition = new FieldMappingDefinition { FieldName = Constants.ArrayItemGenericFieldName };
            var mappingDefinition = new FieldMappingDefinition { FieldName = "TestField", Subfields = { elementMappingDefinition } };

            var factory = new ValueCalculatorFactory(typeConverter);

            // Act.
            var valueCalculator = factory.CreateValueCalculator(typeof(string[]), mappingDefinition);

            // Assert.
            Assert.IsTrue(valueCalculator is ArrayValueCalculator);
        }
        /// <summary>
        /// Create a <see cref="IValueCalculator"/> for the specified <see cref="FieldMappingDefinition"/>.
        /// </summary>
        /// <param name="type">
        /// The <see cref="IValueCalculator"/> value type.
        /// </param>
        /// <param name="mappingDefinition">
        /// The mapping definition.
        /// </param>
        /// <returns>
        /// The <see cref="IValueCalculator"/>.
        /// </returns>
        public IValueCalculator CreateValueCalculator(Type type, FieldMappingDefinition mappingDefinition)
        {
            if (type == null)
                throw new ArgumentNullException("type");

            if (mappingDefinition == null)
                throw new ArgumentNullException("mappingDefinition");

            if (type.IsArray)
                return CreateArrayValueCalculator(type, mappingDefinition);

            if (IsSimpleType(type))
                return CreateSimpleValueCalculator(type, mappingDefinition);

            return CreateComplexValueCalculator(type, mappingDefinition);
        }
        /// <summary>
        /// Creates a mapping.
        /// </summary>
        /// <param name="processName">
        /// The process name.
        /// </param>
        /// <param name="mappingDefinition">
        /// The mapping definition.
        /// </param>
        /// <returns>
        /// The <see cref="IProcessFieldMapping"/>.
        /// </returns>
        public IProcessFieldMapping CreateMapping(string processName, FieldMappingDefinition mappingDefinition)
        {
            if (mappingDefinition == null)
                throw new ArgumentNullException("mappingDefinition");

            var editableRootType = DynamicTypeManager.GetEditableRootType(processName);
            var property = editableRootType.GetPropertyByName(mappingDefinition.FieldName);
            if (property == null)
                throw new ArgumentException(
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "Could not find field \"{0}\" in process \"{1}\".",
                        mappingDefinition.FieldName,
                        processName));

            if (property.Name == Constants.CurrentStateColumnName)
                return CreateSimpleFieldMapping(property, mappingDefinition);

            var crAttribute = property.GetCustomAttribute<CrossRefFieldAttribute>();
            if (crAttribute != null)
            {
                return !crAttribute.AllowMultiple
                    ? (IProcessFieldMapping)
                        CreateSingleCrossReferenceFieldMapping(property, mappingDefinition)
                    : CreateMultiCrossReferenceFieldMapping(property, mappingDefinition);
            }

            var fileAttribute = property.GetCustomAttribute<FileProcessAttribute>();
            if (fileAttribute != null)
            {
                return CreateFileFieldMapping(property, mappingDefinition);
            }

            var checklistAttribute = property.GetCustomAttribute<ChecklistFieldAttribute>();
            if (checklistAttribute != null)
            {
                return CreateChecklistFieldMapping(property, mappingDefinition);
            }

            var fieldTypeAttribute = property.GetCustomAttribute<FieldTypeAttribute>();
            if (fieldTypeAttribute != null && fieldTypeAttribute.ColumnType == ColumnTypes.Sample)
            {
                return CreateSampleFieldMapping(property, mappingDefinition);
            }

            return CreateSimpleFieldMapping(property, mappingDefinition);
        }
        public void CreateSimpleFieldMappingTest()
        {
            // Arrange.
            const string ProcessName = "TestProcess";
            var fieldName = ReflectionHelper.GetPropertyName<TestEditable>(x => x.Text);
            var fieldMapping = new FieldMappingDefinition { FieldName = fieldName, IsKey = true, ValueExpression = context => null };

            var dtm = new Mock<IDynamicTypeManager>();
            dtm.Setup(x => x.GetEditableRootType(ProcessName)).Returns(typeof(TestEditable));

            var typeConverter = Mock.Create<ITypeConverter>(Behavior.Loose);
            var factory = new ProcessFieldMappingFactory { DynamicTypeManager = dtm.Object, TypeConverter = typeConverter };

            // Act.
            var mapping = factory.CreateMapping(ProcessName, fieldMapping);

            // Assert.
            Assert.IsTrue(mapping is SimpleFieldMapping);
        }
 private IValueCalculator CreateSimpleValueCalculator(Type type, FieldMappingDefinition mappingDefinition)
 {
     return new SimpleValueCalculator(mappingDefinition.ValueExpression, type, TypeConverter);
 }
        public void CreateSampleFieldMappingTest()
        {
            // Arrange.
            const string ProcessName = "TestProcess";
            var fieldName = ReflectionHelper.GetPropertyName<TestEditable>(x => x.Sample);

            var valueMapping = new FieldMappingDefinition
                                   {
                                       FieldName = ReflectionHelper.GetPropertyName<ISampleEdit>(s => s.SampleNumeric),
                                       ValueExpression = context => null
                                   };

            var fieldMapping = new FieldMappingDefinition { FieldName = fieldName, ValueExpression = context => null, Subfields = { valueMapping } };

            var dtm = Mock.Create<IDynamicTypeManager>(Behavior.Loose);
            Mock.Arrange(() => dtm.GetEditableRootType(ProcessName)).Returns(typeof(TestEditable));

            var typeConverter = Mock.Create<ITypeConverter>(Behavior.Loose);
            var runtimeDatabase = Mock.Create<IRuntimeDatabase>(Behavior.Loose);
            var factory = new ProcessFieldMappingFactory { DynamicTypeManager = dtm, TypeConverter = typeConverter, RuntimeDatabase = runtimeDatabase };

            // Act.
            var mapping = factory.CreateMapping(ProcessName, fieldMapping);

            // Assert.
            Assert.IsTrue(mapping is SampleFieldMapping);
        }
        private IPropertySetter CreatePropertySetter(Type targetType, FieldMappingDefinition mappingDefinition)
        {
            var propertyInfo = targetType.GetProperty(mappingDefinition.FieldName, BindingFlags.Instance | BindingFlags.Public);
            if (propertyInfo != null)
            {
                return new PropertySetter(propertyInfo, CreateValueCalculator(propertyInfo.PropertyType, mappingDefinition));
            }

            var fieldInfo = targetType.GetField(mappingDefinition.FieldName, BindingFlags.Instance | BindingFlags.Public);
            if (fieldInfo != null)
            {
                return new FieldSetter(fieldInfo, CreateValueCalculator(fieldInfo.FieldType, mappingDefinition));
            }

            throw new ArgumentException(
                string.Format(
                    CultureInfo.InvariantCulture,
                    "Could not find the field or property \"{0}\" in type \"{1}\".",
                    mappingDefinition.FieldName,
                    targetType.AssemblyQualifiedName),
                "mappingDefinition");
        }
 private SampleFieldMapping CreateSampleFieldMapping(PropertyInfo property, FieldMappingDefinition mappingDefinition)
 {
     return new SampleFieldMapping(
         property,
         mappingDefinition.ValueExpression,
         mappingDefinition.Subfields.Select(CreateSampleValueMapping));
 }
        private ChecklistFieldMapping CreateChecklistFieldMapping(PropertyInfo property, FieldMappingDefinition mappingDefinition)
        {
            var checklistAttribute = property.GetCustomAttribute<ChecklistFieldAttribute>();
            var childMappings = CreateChildMappings(checklistAttribute.AnswerProcessName, mappingDefinition);

            return new ChecklistFieldMapping(property, mappingDefinition.ValueExpression, childMappings, DynamicTypeManager);
        }
        private FileFieldMapping CreateFileFieldMapping(PropertyInfo property, FieldMappingDefinition mappingDefinition)
        {
            MappingExpression nameExpression = null;
            var nameMappingDefinition = mappingDefinition.Subfields.FirstOrDefault(m => m.FieldName == Constants.ExpressionDesignerFileNameFieldName);
            if (nameMappingDefinition != null)
            {
                nameExpression = nameMappingDefinition.ValueExpression;
            }

            MappingExpression contentExpression = null;
            var contentMappingDefinition = mappingDefinition.Subfields.FirstOrDefault(m => m.FieldName == Constants.ExpressionDesignerFileContentFieldName);
            if (contentMappingDefinition != null)
            {
                contentExpression = contentMappingDefinition.ValueExpression;
            }

            MappingExpression locationExpression = null;
            var locationMappingDefinition = mappingDefinition.Subfields.FirstOrDefault(m => m.FieldName == Constants.ExpressionDesignerFileLocationFieldName);
            if (locationMappingDefinition != null)
            {
                locationExpression = locationMappingDefinition.ValueExpression;
            }

            return new FileFieldMapping(property, nameExpression, contentExpression, locationExpression, TypeConverter, FileManager);
        }
        private MultiCrossReferenceFieldMapping CreateMultiCrossReferenceFieldMapping(PropertyInfo property, FieldMappingDefinition mappingDefinition)
        {
            var crAttribute = property.GetCustomAttribute<CrossRefFieldAttribute>();
            var childMappings = CreateChildMappings(crAttribute.ReferenceTableName, mappingDefinition);

            return new MultiCrossReferenceFieldMapping(
                property,
                mappingDefinition.ValueExpression,
                childMappings,
                DynamicTypeManager,
                RuntimeDatabase);
        }
 private SimpleFieldMapping CreateSimpleFieldMapping(PropertyInfo property, FieldMappingDefinition mappingDefinition)
 {
     return new SimpleFieldMapping(property, mappingDefinition.ValueExpression, mappingDefinition.IsKey, TypeConverter);
 }
 private IValueCalculator CreateComplexValueCalculator(Type type, FieldMappingDefinition mappingDefinition)
 {
     return new ComplexValueCalculator(type, mappingDefinition.Subfields.Select(m => CreatePropertySetter(type, m)));
 }
        private IValueCalculator CreateArrayValueCalculator(Type type, FieldMappingDefinition mappingDefinition)
        {
            var elementType = type.GetElementType();
            IValueCalculator elementCalculator = null;
            var elementMappingDefinition = mappingDefinition.Subfields.FirstOrDefault(m => m.FieldName == Constants.ArrayItemGenericFieldName);
            if (elementMappingDefinition != null)
            {
                elementCalculator = CreateValueCalculator(elementType, elementMappingDefinition);
            }

            return new ArrayValueCalculator(elementType, mappingDefinition.ValueExpression, elementCalculator, TypeConverter);
        }
        private ISampleValueMapping CreateSampleValueMapping(FieldMappingDefinition mappingDefinition)
        {
            var property = typeof(ISampleEdit).GetProperty(mappingDefinition.FieldName);
            if (property == null)
                throw new ArgumentException(
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "Could not find property \"{0}\" in type \"{1}\".",
                        mappingDefinition.FieldName,
                        typeof(ISampleEdit).AssemblyQualifiedName));

            return new SampleValueMapping(property, mappingDefinition.ValueExpression, mappingDefinition.IsKey, TypeConverter);
        }
 private IEnumerable<IProcessFieldMapping> CreateChildMappings(string processName, FieldMappingDefinition mappingDefinition)
 {
     return mappingDefinition.Subfields.Select(subfield => CreateMapping(processName, subfield)).SortByExecutionOrder();
 }
        public void CreateFileFieldMappingTest()
        {
            // Arrange.
            const string ProcessName = "TestProcess";

            var nameMapping = new FieldMappingDefinition
                                  {
                                      FieldName = Constants.ExpressionDesignerFileNameFieldName,
                                      ValueExpression = context => null,
                                      IsKey = false
                                  };
            var contentMapping = new FieldMappingDefinition
                                     {
                                         FieldName = Constants.ExpressionDesignerFileContentFieldName,
                                         ValueExpression = context => null,
                                         IsKey = false
                                     };
            var locationMapping = new FieldMappingDefinition
                                      {
                                          FieldName = Constants.ExpressionDesignerFileLocationFieldName,
                                          ValueExpression = context => null,
                                          IsKey = false
                                      };

            var fileMapping = new FieldMappingDefinition
                                  {
                                      FieldName = ReflectionHelper.GetPropertyName<TestEditable>(x => x.File),
                                      ValueExpression = null,
                                      IsKey = false,
                                      Subfields = { nameMapping, contentMapping, locationMapping }
                                  };

            var dtm = Mock.Create<IDynamicTypeManager>(Behavior.Loose);
            Mock.Arrange(() => dtm.GetEditableRootType(ProcessName)).Returns(typeof(TestEditable));

            var typeConverter = Mock.Create<ITypeConverter>(Behavior.Loose);
            var fileManager = Mock.Create<IFileManager>(Behavior.Loose);
            var factory = new ProcessFieldMappingFactory { DynamicTypeManager = dtm, TypeConverter = typeConverter, FileManager = fileManager };

            // Act.
            var mapping = factory.CreateMapping(ProcessName, fileMapping);

            // Assert.
            Assert.IsTrue(mapping is FileFieldMapping);
        }