public void TimeDataTemplate_ShouldCreatesAppropriateType()
        {
            //arrange
            string testNamespace           = "testNamespace";
            string testType                = "testType";
            ITextTemplatingSession session = CreateTemplateSession(testNamespace, testType);

            //act
            string templateOutput = _templateProcessor.ProcessTemplateWithSession(_template, session);

            //assert
            SyntaxTree parsedTemplateOutput = _templateCompiler.ParseTemplateOutput(templateOutput);
            Assembly   compiledAssembly     = _templateCompiler.CompileSyntaxTree(parsedTemplateOutput, DefaultCompilationOptions, DefaultReferences, MethodBase.GetCurrentMethod().Name);

            _templateCompiler.CompilationInfo.Success.Should().BeTrue();

            compiledAssembly.Should().NotBeNull();
            compiledAssembly.DefinedTypes.Should().NotBeNull();
            compiledAssembly.DefinedTypes.Should().HaveCount(1);

            Type resultType = compiledAssembly.DefinedTypes.First();

            resultType.Namespace.Should().Be(testNamespace);
            resultType.Name.Should().Be(testType);
            resultType.IsValueType.Should().BeTrue();

            MethodInfo equalsMethod = resultType.GetMethod("Equals");

            equalsMethod.Should().NotBeNull();
            equalsMethod.ReturnType.Should().Be(typeof(Boolean));
            equalsMethod.IsPublic.Should().BeTrue();
            equalsMethod.IsVirtual.Should().BeTrue();

            IEnumerable <MethodInfo> resultMethodCollection = resultType.GetMethods();

            resultMethodCollection.Should().NotBeNull();

            MethodInfo resultEqualsMethod = resultMethodCollection.FirstOrDefault(member => member.Name == EQUALS_METHOD.Key);

            resultEqualsMethod.Should().NotBeNull();
            resultEqualsMethod.ReturnType.Should().Be(EQUALS_METHOD.Value);

            IEnumerable <PropertyInfo> resultPropertyCollection = resultType.GetProperties();

            resultPropertyCollection.Should().HaveCount(2);

            PropertyInfo resultSecProperty = resultPropertyCollection.SingleOrDefault(property => property.Name == SEC_PROPERTY.Key);

            resultSecProperty.Should().NotBeNull();
            resultSecProperty.PropertyType.Should().Be(SEC_PROPERTY.Value);

            PropertyInfo resultNSecProperty = resultPropertyCollection.SingleOrDefault(property => property.Name == NSEC_PROPERTY.Key);

            resultNSecProperty.Should().NotBeNull();
            resultNSecProperty.PropertyType.Should().Be(NSEC_PROPERTY.Value);
        }
        public void RosMessageTemplate_ShouldCreateAppropriateType()
        {
            //arrange
            Type   rosMessageTypeAttributeType = typeof(RosMessageTypeAttribute);
            string rosbridgeAttributeNamespace = rosMessageTypeAttributeType.Namespace;
            string rosbridgeAttributeType      = rosMessageTypeAttributeType.Name;
            string namespacePrefix             = "testPrefix";
            string testNamespace = "testNamespace";
            string testType      = "testType";
            IEnumerable <string> testDependencies = new string[] { };
            IEnumerable <Tuple <string, string, string> > testConstantFields = new List <Tuple <string, string, string> >()
            {
                Tuple.Create("String", "TestFieldName1", "TestValue")
            };
            IEnumerable <Tuple <string, string, int> > testArrayFields = new List <Tuple <string, string, int> >()
            {
                Tuple.Create("String", "TestFieldName2", 2)
            };
            IDictionary <string, string> testFields = new Dictionary <string, string>()
            {
                { "TestFieldName3", "String" }
            };

            ITextTemplatingSession session = CreateTemplateSession(
                rosbridgeAttributeNamespace,
                rosbridgeAttributeType,
                namespacePrefix,
                testNamespace,
                testType,
                testDependencies,
                testConstantFields,
                testArrayFields,
                testFields);

            //act
            string templateOutput = _templateProcessor.ProcessTemplateWithSession(_template, session);

            //assert
            SyntaxTree parsedTemplateOutput = _templateCompiler.ParseTemplateOutput(templateOutput);
            Assembly   compiledAssembly     = _templateCompiler.CompileSyntaxTree(parsedTemplateOutput, DefaultCompilationOptions, DefaultReferences, MethodBase.GetCurrentMethod().Name);

            _templateCompiler.CompilationInfo.Success.Should().BeTrue();

            compiledAssembly.Should().NotBeNull();
            compiledAssembly.DefinedTypes.Should().NotBeNull();
            compiledAssembly.DefinedTypes.Should().HaveCount(1);

            //type check
            Type resultType = compiledAssembly.DefinedTypes.First();

            resultType.Name.Should().Be(testType);
            resultType.Namespace.Should().Be($"{namespacePrefix}.{testNamespace}");
            resultType.IsValueType.Should().BeFalse();
            resultType.CustomAttributes.Should().Contain(attribute => attribute.AttributeType == rosMessageTypeAttributeType);

            MethodInfo equalsMethod = resultType.GetMethod("Equals");

            equalsMethod.Should().NotBeNull();
            equalsMethod.ReturnType.Should().Be(typeof(Boolean));
            equalsMethod.IsPublic.Should().BeTrue();
            equalsMethod.IsVirtual.Should().BeTrue();

            IEnumerable <FieldInfo> resultConstantFieldCollection = resultType.GetFields().Where(field => field.IsLiteral && !field.IsInitOnly).ToList();

            resultConstantFieldCollection.Should().NotBeNull();
            resultConstantFieldCollection.Should().HaveCount(1);

            Tuple <string, string, string> testConstantField = testConstantFields.First();
            FieldInfo resultConstantField = resultConstantFieldCollection.SingleOrDefault(field => field.Name == testConstantField.Item2);

            resultConstantField.Should().NotBeNull();
            resultConstantField.FieldType.Name.Should().Be(testConstantField.Item1);

            IEnumerable <PropertyInfo> resultPropertyCollection = resultType.GetProperties();

            resultPropertyCollection.Should().NotBeNull();
            resultPropertyCollection.Should().HaveCount(testArrayFields.Count() + testFields.Count);

            Tuple <string, string, int> testArrayField = testArrayFields.First();
            PropertyInfo resultArrayProperty           = resultPropertyCollection.SingleOrDefault(property => property.Name == testArrayField.Item2);

            resultArrayProperty.Should().NotBeNull();
            resultArrayProperty.PropertyType.IsArray.Should().BeTrue();
            resultArrayProperty.PropertyType.GetElementType().Name.Should().Be(testArrayField.Item1);

            KeyValuePair <string, string> testField = testFields.FirstOrDefault();
            PropertyInfo resultFieldProperty        = resultPropertyCollection.SingleOrDefault(property => property.Name == testField.Key);

            resultFieldProperty.Should().NotBeNull();
            resultFieldProperty.PropertyType.Name.Should().Be(testField.Value);

            //instance check
            dynamic instantiatedResultType = Activator.CreateInstance(resultType);

            dynamic resultConstantFieldInstanceValue = resultConstantField.GetValue(instantiatedResultType);

            testConstantField.Item3.Should().Be(resultConstantFieldInstanceValue);

            dynamic resultArrayPropertyInstanceValue = resultArrayProperty.GetValue(instantiatedResultType);

            testArrayField.Item3.Should().Be(resultArrayPropertyInstanceValue.Length);
        }