public async Task GivenConfigurationSetAndFhirResources_WhenTransform_CdmFolderShouldBeGenerated()
        {
            string cdmFolder = Guid.NewGuid().ToString("N");
            BaseMappingDefinitionLoader            loader          = new LocalMappingDefinitionLoader("TestResource\\testSchema");
            IEnumerable <TabularMappingDefinition> tabularMappings = loader.Load();
            CdmCorpusDefinition defination = CdmSchemaGenerator.InitLocalcdmCorpusDefinition(cdmFolder);

            CdmSchemaGenerator cdmSchemaGenerator = new CdmSchemaGenerator(defination);
            await cdmSchemaGenerator.InitializeCdmFolderAsync(tabularMappings);

            ISource source = new LocalNdjsonSource(Path.Combine("TestResource", "FhirResource"));
            ISink   sink   = new LocalCsvSink(cdmFolder)
            {
                CsvFilePath = (string tableName) =>
                {
                    return($"data/Local{tableName}/{tableName}-partition-data.csv");
                }
            };
            var transformer = new BasicFhirElementTabularTransformer();

            FhirElementTabularTransformer.IdGenerator = () =>
            {
                return("0000");
            };
            TransformationExecutor executor = new TransformationExecutor(source, sink, tabularMappings, transformer);

            await executor.ExecuteAsync();

            // Whether generated CDM schema
            Assert.IsTrue(File.Exists(Path.Combine(cdmFolder, "default.manifest.cdm.json")));
            Assert.IsTrue(File.Exists(Path.Combine(cdmFolder, "LocalPatient.cdm.json")));
            Assert.IsTrue(File.Exists(Path.Combine(cdmFolder, "LocalPatientName.cdm.json")));

            // If generated flatten data
            Assert.IsTrue(Directory.Exists(Path.Combine(cdmFolder, "data", "LocalPatient")));
            Assert.IsTrue(Directory.Exists(Path.Combine(cdmFolder, "data", "LocalPatientName")));

            // If generated data are same with ground truth
            string[] tableNames =
            {
                "Patient",
                "AllergyIntolerance",
                "CarePlan",
                "Encounter",
                "Location",
                "Observation",

                "PatientName",
                "PatientFlattenJson",
                "EncounterClass",
                "CarePlanPeriod"
            };

            foreach (var tableName in tableNames)
            {
                var sourceFilePath = Path.Combine("TestResource", "TestOutput", $"Local{tableName}", $"{tableName}-partition-data.csv");
                var targetFilePath = Path.Combine(@$ "{cdmFolder}", "data", $"Local{tableName}", $"{tableName}-partition-data.csv");
                Assert.IsTrue(CheckSameContent(sourceFilePath, targetFilePath), $"{sourceFilePath} and {targetFilePath} are different.");
            }
        }
示例#2
0
        public void GivenAFhirResourceAndColumnDefinition_WhenToTabularSource_ValuesAndTypesShouldBeReturn()
        {
            BasicFhirElementTabularTransformer t = new BasicFhirElementTabularTransformer();
            Patient patient = new Patient()
            {
                Gender = AdministrativeGender.Male
            };

            patient.Address.Add(new Address()
            {
                City = "Shanghai"
            });

            ElementNode node = ElementNode.FromElement(patient.ToTypedElement());
            TabularMappingDefinition defination = new TabularMappingDefinition("Test");

            defination.Root.Children["address"] = new DefinitionNode(new ColumnDefinition("column1", "string"));
            defination.Root.Children["address"].Children["city"] = new DefinitionNode(new ColumnDefinition("column2", "string"));
            Dictionary <string, (object, object)> result = t.ToTabular(node, defination);

            Assert.AreEqual("{\"city\":\"Shanghai\"}", result["column1"].Item1);
            Assert.AreEqual("string", result["column1"].Item2);
            Assert.AreEqual("Shanghai", result["column2"].Item1);
            Assert.AreEqual("string", result["column2"].Item2);
        }
        public void GivenStringRelated_AfterTransforming_CorrectDateTimeInstanceShouldBeReturned()
        {
            List <(ElementNode node, (object expectedValue, object expectedType))> examples = new List <(ElementNode node, (object expectedValue, object expectedType))>()
            {
                (node : ElementNode.FromElement(new FhirString("").ToTypedElement()),
                 (new string(""), "string")),
                (node : ElementNode.FromElement(new FhirString("A sequence of Unicode characters").ToTypedElement()),
                 (new string("A sequence of Unicode characters"), "string")),
                (node : ElementNode.FromElement(new Canonical("A URI that refers to a resource by its canonical URL").ToTypedElement()),
                 (new string("A URI that refers to a resource by its canonical URL"), "canonical")),
                (node : ElementNode.FromElement(new Code("A date, or partial date as used in human communication").ToTypedElement()),
                 (new string("A date, or partial date as used in human communication"), "code")),
                (node : ElementNode.FromElement(new Id("Any combination of upper- or lower-case ASCII letters").ToTypedElement()),
                 (new string("Any combination of upper- or lower-case ASCII letters"), "id")),
                (node : ElementNode.FromElement(new Markdown("A FHIR string that may contain markdown").ToTypedElement()),
                 (new string("A FHIR string that may contain markdown"), "markdown")),
                (node : ElementNode.FromElement(new Oid("urn:oid:1.2.3.4.5").ToTypedElement()),
                 (new string("urn:oid:1.2.3.4.5"), "oid")),
                (node : ElementNode.FromElement(new Uuid("urn:uuid:c757873d-ec9a-4326-a141-556f43239520").ToTypedElement()),
                 (new string("urn:uuid:c757873d-ec9a-4326-a141-556f43239520"), "uuid")),
                (node : ElementNode.FromElement(new FhirUri("https://www.hl7.org/fhir").ToTypedElement()),
                 (new string("https://www.hl7.org/fhir"), "uri")),
                (node : ElementNode.FromElement(new FhirUrl("https://www.hl7.org/fhir").ToTypedElement()),
                 (new string("https://www.hl7.org/fhir"), "url"))
            };

            FhirElementTabularTransformer transformer = new BasicFhirElementTabularTransformer();

            foreach (var example in examples)
            {
                var transformResult = transformer.ConvertElementNode(example.node, example.Item2.expectedType.ToString());
                Assert.AreEqual(transformResult, example.Item2);
            }
        }
示例#4
0
        public void GivenColumnDefinitionWithFhirExpressionInChildren_WhenToTabularSource_EvaluatedValueShourlBeReturn()
        {
            BasicFhirElementTabularTransformer t = new BasicFhirElementTabularTransformer();
            Patient patient = new Patient()
            {
                Gender = AdministrativeGender.Male
            };

            patient.Address.Add(new Address()
            {
                City = "Shanghai"
            });
            patient.Address.Add(new Address()
            {
                City = "Beijing"
            });

            ElementNode node = ElementNode.FromElement(patient.ToTypedElement());
            TabularMappingDefinition defination = new TabularMappingDefinition("Test");

            defination.Root.Children[""] = new DefinitionNode(new ColumnDefinition("column1", "string", "address.last()", null),
                                                              new ColumnDefinition("column2", "string", "address.first().city", null));
            Dictionary <string, (object, object)> result = t.ToTabular(node, defination);

            Assert.AreEqual("{\"city\":\"Beijing\"}", result["column1"].Item1);
            Assert.AreEqual("Shanghai", result["column2"].Item1);
        }
        public void GivenAFhirDateTimeNode_AfterTransforming_CorrectDateTimeInstanceShouldBeReturned()
        {
            List <(ElementNode node, (object expectedValue, object expectedType))> examples = new List <(ElementNode node, (object expectedValue, object expectedType))>()
            {
                (node : ElementNode.FromElement(new FhirDateTime("2015").ToTypedElement()), (new DateTime(2015, 1, 1), "dateTime")),
                (node : ElementNode.FromElement(new FhirDateTime("2015-05").ToTypedElement()), (new DateTime(2015, 5, 1), "dateTime")),
                (node : ElementNode.FromElement(new FhirDateTime("2015-05-04").ToTypedElement()), (new DateTime(2015, 5, 4), "dateTime")),
                (node : ElementNode.FromElement(new FhirDateTime("2016-05-04T12:00:00").ToTypedElement()), (new DateTime(2016, 5, 4, 12, 0, 0), "dateTime")),
                (node : ElementNode.FromElement(new FhirDateTime("2016-05-04T12:00:00+00:00").ToTypedElement()), (new DateTime(2016, 5, 4, 12, 0, 0), "dateTime")),
                (node : ElementNode.FromElement(new FhirDateTime("2016-05-04T12:00:00Z").ToTypedElement()), (new DateTime(2016, 5, 4, 12, 0, 0), "dateTime")),
                (node : ElementNode.FromElement(new FhirDateTime("2015-02-07T13:28:17").ToTypedElement()), (new DateTime(2015, 2, 7, 13, 28, 17), "dateTime")),
                (node : ElementNode.FromElement(new FhirDateTime("2015-02-07T13:28:17.159").ToTypedElement()), (new DateTime(2015, 2, 7, 13, 28, 17, 159), "dateTime")),
                (node : ElementNode.FromElement(new FhirDateTime("2015-02-07T19:28:17-07:00").ToTypedElement()), (new DateTime(2015, 2, 8, 2, 28, 17), "dateTime")),
                (node : ElementNode.FromElement(new FhirDateTime("2015-02-07T13:28:17.159-05:00").ToTypedElement()), (new DateTime(2015, 2, 7, 18, 28, 17, 159), "dateTime")),
                (node : ElementNode.FromElement(new FhirDateTime("2015-02-07T13:28:17Z").ToTypedElement()), (new DateTime(2015, 2, 7, 13, 28, 17), "dateTime")),
                (node : ElementNode.FromElement(new FhirDateTime("2015-02-07T13:28:17.159Z").ToTypedElement()), (new DateTime(2015, 2, 7, 13, 28, 17, 159), "dateTime")),
                (node : null, (null, "dateTime"))
            };
            FhirElementTabularTransformer transformer = new BasicFhirElementTabularTransformer();

            foreach (var example in examples)
            {
                var transformResult = transformer.ConvertElementNode(example.node, FhirTypeNames.DateTime);
                Assert.AreEqual(transformResult, example.Item2);
            }
        }
示例#6
0
        static async Task Main(string[] args)
        {
            TransformationLogging.LoggerFactory = LoggerFactory.Create(builder => {
                builder.AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("Microsoft.Health.Fhir.Transformation", LogLevel.Information)
                .AddConsole();
            });

            ILogger logger = TransformationLogging.CreateLogger <Program>();

            var rootCommand = new RootCommand()
            {
                new Option <string>("--config"),
                new Option <string>("--input"),
                new Option <string>("--output"),
                new Option <int>("--maxDepth", getDefaultValue: () => 3),
            };

            rootCommand.Handler = CommandHandler.Create(
                new Func <string, string, string, int, Task>(async(config, input, output, maxDepth) =>
            {
                LocalMappingDefinitionLoader configLoader = new LocalMappingDefinitionLoader(config, maxDepth);
                TabularMappingDefinition[] mappings       = configLoader.Load();
                FhirElementTabularTransformer transformer = new BasicFhirElementTabularTransformer();

                logger.LogInformation("Start to generate CDM schema.");
                CdmCorpusDefinition defination        = CdmSchemaGenerator.InitLocalcdmCorpusDefinition(output);
                CdmSchemaGenerator cdmSchemaGenerator = new CdmSchemaGenerator(defination);
                cdmSchemaGenerator.InitializeCdmFolderAsync(mappings).Wait();
                logger.LogInformation("Generate CDM schema completed.");

                string operationId = Guid.NewGuid().ToString("N");
                ISource source     = new LocalNdjsonSource(input);
                ISink sink         = new LocalCsvSink(output)
                {
                    CsvFilePath = (string tableName) =>
                    {
                        return($"data/Local{tableName}/partition-data-{operationId}.csv");
                    }
                };

                logger.LogInformation("Start to transform data.");
                IProgress <(int, int)> progressHandler = new Progress <(int, int)>(progress =>
                {
                    if (progress.Item1 % 100 == 0 || progress.Item2 % 100 == 0)
                    {
                        logger.LogInformation($"({progress.Item1} loaded, {progress.Item2} transformed) to CDM folder. {DateTime.UtcNow.ToLongTimeString()}");
                    }
                });

                TransformationExecutor executor = new TransformationExecutor(source, sink, mappings, transformer);
                await executor.ExecuteAsync(progressHandler);
                logger.LogInformation("Complete to transform data.");
            }));

            await rootCommand.InvokeAsync(args);
        }
        public void GivenANodeWithInvalidValue_AfterTransforming_CorrectDateTimeInstanceShouldBeReturned()
        {
            FhirElementTabularTransformer transformer = new BasicFhirElementTabularTransformer();
            ElementNode node = ElementNode.FromElement(new Date("").ToTypedElement());

            Assert.AreEqual(transformer.ConvertElementNode(node, FhirTypeNames.Date),
                            (null, "date"));

            node.Value = null;
            Assert.AreEqual(transformer.ConvertElementNode(node, FhirTypeNames.Date),
                            (null, "date"));

            node.Value = "123";
            Assert.AreEqual(transformer.ConvertElementNode(node, FhirTypeNames.Date),
                            (null, "date"));
        }
        public void GivenAFhirDateNode_AfterTransforming_CorrectDateTimeInstanceShouldBeReturned()
        {
            List <(ElementNode node, (object expectedValue, object expectedType))> examples = new List <(ElementNode node, (object expectedValue, object expectedType))>()
            {
                (node : ElementNode.FromElement(new Date("2015").ToTypedElement()), (new DateTime(2015, 1, 1), "date")),
                (node : ElementNode.FromElement(new Date("2015-05").ToTypedElement()), (new DateTime(2015, 5, 1), "date")),
                (node : ElementNode.FromElement(new Date("2015-05-04").ToTypedElement()), (new DateTime(2015, 5, 4), "date")),
                (node : null, (null, "date"))
            };
            FhirElementTabularTransformer transformer = new BasicFhirElementTabularTransformer();

            foreach (var example in examples)
            {
                var transformResult = transformer.ConvertElementNode(example.node, FhirTypeNames.Date);
                Assert.AreEqual(transformResult, example.Item2);
            }
        }
        public void GivenAFhirDecimalNode_AfterTransforming_CorrectDateTimeInstanceShouldBeReturned()
        {
            List <(ElementNode node, (object expectedValue, object expectedType))> examples = new List <(ElementNode node, (object expectedValue, object expectedType))>()
            {
                (node : ElementNode.FromElement(new FhirDecimal((decimal)1).ToTypedElement()), ((float)(1), "decimal")),
                (node : ElementNode.FromElement(new FhirDecimal((decimal)1.1).ToTypedElement()), ((float)(1.1), "decimal")),
                (node : ElementNode.FromElement(new FhirDecimal((decimal)1.1e5).ToTypedElement()), ((float)110000, "decimal")),
                (node : null, (null, "decimal"))
            };

            FhirElementTabularTransformer transformer = new BasicFhirElementTabularTransformer();

            foreach (var example in examples)
            {
                var transformResult = transformer.ConvertElementNode(example.node, FhirTypeNames.Decimal);
                Assert.AreEqual(transformResult, example.Item2);
            }
        }
        public void GivenAFhirUnsignedIntNode_AfterTransforming_CorrectDateTimeInstanceShouldBeReturned()
        {
            List <(ElementNode node, (object expectedValue, object expectedType))> examples = new List <(ElementNode node, (object expectedValue, object expectedType))>()
            {
                (node : ElementNode.FromElement(new UnsignedInt(int.MaxValue).ToTypedElement()), (int.MaxValue, "unsignedInt")),
                (node : ElementNode.FromElement(new UnsignedInt(0).ToTypedElement()), ((int)(0), "unsignedInt")),
                (node : ElementNode.FromElement(new UnsignedInt(-1).ToTypedElement()), ((int)(-1), "unsignedInt")),
                (node : null, (null, "unsignedInt"))
            };

            FhirElementTabularTransformer transformer = new BasicFhirElementTabularTransformer();

            foreach (var example in examples)
            {
                var transformResult = transformer.ConvertElementNode(example.node, FhirTypeNames.UnsignedInt);
                Assert.AreEqual(transformResult, example.Item2);
            }
        }
        public void GivenAFhirTimeNode_AfterTransforming_CorrectDateTimeInstanceShouldBeReturned()
        {
            List <(ElementNode node, (object expectedValue, object expectedType))> examples = new List <(ElementNode node, (object expectedValue, object expectedType))>()
            {
                (node : ElementNode.FromElement(new Time("01:00:00").ToTypedElement()), (new DateTime(0001, 1, 1, 1, 0, 0), "time")),
                (node : ElementNode.FromElement(new Time("12:00:00").ToTypedElement()), (new DateTime(0001, 1, 1, 12, 0, 0), "time")),
                (node : ElementNode.FromElement(new Time("00:00:00").ToTypedElement()), (new DateTime(0001, 1, 1, 0, 0, 0), "time")),
                (node : ElementNode.FromElement(new Time("05:01:00.159").ToTypedElement()), (new DateTime(0001, 1, 1, 5, 1, 0, 159), "time")),
                (node : null, (null, "time"))
            };
            FhirElementTabularTransformer transformer = new BasicFhirElementTabularTransformer();

            foreach (var example in examples)
            {
                var transformResult = transformer.ConvertElementNode(example.node, FhirTypeNames.Time);
                Assert.AreEqual(transformResult, example.Item2);
            }
        }
        public void GivenAFhirBase64BinaryNode_AfterTransforming_CorrectDateTimeInstanceShouldBeReturned()
        {
            List <(ElementNode node, (object expectedValue, object expectedType))> examples = new List <(ElementNode node, (object expectedValue, object expectedType))>()
            {
                (node : ElementNode.FromElement(new Base64Binary(Encoding.ASCII.GetBytes("A stream of bytes, base64 encoded")).ToTypedElement()),
                 (new string("A stream of bytes, base64 encoded"), "base64Binary")),
                (node : ElementNode.FromElement(new Base64Binary(Encoding.ASCII.GetBytes("")).ToTypedElement()), (new string(""), "base64Binary")),
                (node : null, (null, "base64Binary"))
            };

            FhirElementTabularTransformer transformer = new BasicFhirElementTabularTransformer();

            foreach (var example in examples)
            {
                string expectedString = example.Item2.expectedValue == null? null
                                        :Convert.ToBase64String(Encoding.ASCII.GetBytes(example.Item2.expectedValue.ToString()));
                var transformResult = transformer.ConvertElementNode(example.node, FhirTypeNames.Base64Binary);
                Assert.AreEqual(transformResult, (expectedString, example.Item2.expectedType));
            }
        }
示例#13
0
        public void GivenColumnDefinitionWithFhirExpressionInRoot_WhenToTabularSource_EvaluatedValueShourlBeReturn()
        {
            BasicFhirElementTabularTransformer t = new BasicFhirElementTabularTransformer();
            Patient patient = new Patient()
            {
                Gender = AdministrativeGender.Male
            };

            patient.Id        = "TestId";
            patient.BirthDate = "1974-12-25";

            ElementNode node = ElementNode.FromElement(patient.ToTypedElement());
            TabularMappingDefinition defination = new TabularMappingDefinition("Test");

            defination.Root.Children[""] = new DefinitionNode(new ColumnDefinition("column1", "string", "id", null),
                                                              new ColumnDefinition("column2", "string", "birthDate", null));
            Dictionary <string, (object, object)> result = t.ToTabular(node, defination);

            Assert.AreEqual("TestId", result["column1"].Item1);
            Assert.AreEqual("1974-12-25", result["column2"].Item1);
        }
        public void GivenAFhirInstantNode_AfterTransforming_CorrectDateTimeInstanceShouldBeReturned()
        {
            List <(ElementNode node, (object expectedValue, object expectedType))> examples = new List <(ElementNode node, (object expectedValue, object expectedType))>()
            {
                (node : ElementNode.FromElement(new Instant(DateTimeOffset.Parse("2015-05-04Z")).ToTypedElement()), (new DateTime(2015, 5, 4), "instant")),
                (node : ElementNode.FromElement(new Instant(DateTimeOffset.Parse("2015-02-07T13:28:17Z")).ToTypedElement()), (new DateTime(2015, 2, 7, 13, 28, 17), "instant")),
                (node : ElementNode.FromElement(new Instant(DateTimeOffset.Parse("2015-02-07T13:28:17.159Z")).ToTypedElement()), (new DateTime(2015, 2, 7, 13, 28, 17, 159), "instant")),
                (node : ElementNode.FromElement(new Instant(DateTimeOffset.Parse("2015-02-07T13:28:17-05:00")).ToTypedElement()), (new DateTime(2015, 2, 7, 18, 28, 17), "instant")),
                (node : ElementNode.FromElement(new Instant(DateTimeOffset.Parse("2015-02-07T13:28:17.159-05:00")).ToTypedElement()), (new DateTime(2015, 2, 7, 18, 28, 17, 159), "instant")),
                (node : ElementNode.FromElement(new Instant(DateTimeOffset.Parse("2015-02-07T13:28:17Z")).ToTypedElement()), (new DateTime(2015, 2, 7, 13, 28, 17), "instant")),
                (node : ElementNode.FromElement(new Instant(DateTimeOffset.Parse("2015-02-07T13:28:17.159Z")).ToTypedElement()), (new DateTime(2015, 2, 7, 13, 28, 17, 159), "instant")),
                (node : null, (null, "instant"))
            };
            FhirElementTabularTransformer transformer = new BasicFhirElementTabularTransformer();

            foreach (var example in examples)
            {
                var transformResult = transformer.ConvertElementNode(example.node, FhirTypeNames.Instant);
                Assert.AreEqual(transformResult, example.Item2);
            }
        }
示例#15
0
        public void GivenUnrollPathConfiguration_WhenToTabularSource_MultipleItemsShouldBeReturn()
        {
            BasicFhirElementTabularTransformer t = new BasicFhirElementTabularTransformer();
            Patient patient = new Patient()
            {
                Gender = AdministrativeGender.Male
            };

            patient.Address.Add(new Address()
            {
                City = "Shanghai"
            });
            patient.Address.Add(new Address()
            {
                City = "Beijing"
            });
            patient.BirthDate = "1974-12-25";
            patient.Id        = "Test1";
            patient.Telecom.Add(new ContactPoint()
            {
                Rank = 1
            });

            TabularMappingDefinition defination = new TabularMappingDefinition("Test");

            defination.Unrollpath            = "Patient.address";
            defination.Root.Children["city"] = new DefinitionNode(new ColumnDefinition("column1", "string"));
            IEnumerable <Dictionary <string, (object, object)> > results = t.ToTabular(patient, defination);

            Assert.AreEqual(2, results.Count());

            foreach (var result in results)
            {
                Assert.AreEqual("Test1", result[ReservedColumnName.ResourceId].Item1);
                Assert.IsTrue(result.ContainsKey(ReservedColumnName.FhirPath));
                Assert.IsTrue(result.ContainsKey("column1"));
                Assert.IsTrue(!string.IsNullOrEmpty(result["column1"].Item1?.ToString()));
            }
        }
示例#16
0
        public void GivenConfigurationWithInvalidPath_WhenToTabularSource_NullValueShouldBeReturn()
        {
            BasicFhirElementTabularTransformer t = new BasicFhirElementTabularTransformer();
            Patient patient = new Patient()
            {
                Gender = AdministrativeGender.Male
            };

            patient.Address.Add(new Address()
            {
                City = "Shanghai"
            });
            ElementNode node = ElementNode.FromElement(patient.ToTypedElement());

            TabularMappingDefinition defination = new TabularMappingDefinition("Test");

            defination.Root.Children["invalid"] = new DefinitionNode();
            defination.Root.Children["invalid"].Children["invalid"] = new DefinitionNode(new ColumnDefinition("column1", "string"));
            Dictionary <string, (object, object)> result = t.ToTabular(node, defination);

            Assert.IsNull(result["column1"].Item1);
            Assert.AreEqual("string", result["column1"].Item2);
        }
示例#17
0
        public void GivenColumnDefinitionWithDifferentTypes_WhenToTabularSource_ValueCanBeConvertedShouldBeReturn()
        {
            BasicFhirElementTabularTransformer t = new BasicFhirElementTabularTransformer();
            Patient patient = new Patient()
            {
                Gender = AdministrativeGender.Male
            };

            patient.Address.Add(new Address()
            {
                City = "Shanghai"
            });
            patient.BirthDate = "1974-12-25";
            patient.Telecom.Add(new ContactPoint()
            {
                Rank = 1
            });
            ElementNode node = ElementNode.FromElement(patient.ToTypedElement());

            TabularMappingDefinition defination = new TabularMappingDefinition("Test");

            defination.Root.Children["address"] = new DefinitionNode();
            defination.Root.Children["address"].Children["city"] = new DefinitionNode(new ColumnDefinition("column1", "string"));
            defination.Root.Children["birthDate"] = new DefinitionNode(new ColumnDefinition("column2", "date"));
            defination.Root.Children["telecom"]   = new DefinitionNode();
            defination.Root.Children["telecom"].Children["rank"] = new DefinitionNode(new ColumnDefinition("column3", "integer"));
            Dictionary <string, (object, object)> result = t.ToTabular(node, defination);

            Assert.AreEqual("Shanghai", result["column1"].Item1);
            Assert.AreEqual("string", result["column1"].Item2);

            Assert.AreEqual(DateTime.Parse("1974-12-25"), result["column2"].Item1);
            Assert.AreEqual("date", result["column2"].Item2);

            Assert.AreEqual(1, result["column3"].Item1);
            Assert.AreEqual("integer", result["column3"].Item2);
        }
        public void GivenAFhirArrayNodeThatHasParent_AfterTransformingUsingAsJson_CorrectStringInstanceShouldBeReturned()
        {
            FhirElementTabularTransformer transformer = new BasicFhirElementTabularTransformer();

            Patient patient = new Patient()
            {
                Gender = AdministrativeGender.Male
            };

            patient.Name.Add(new HumanName()
            {
                Use = HumanName.NameUse.Official, Family = "Chalmers", Given = new List <string>()
                {
                    "Peter", "James"
                }
            });
            patient.Name.Add(new HumanName()
            {
                Use = HumanName.NameUse.Usual, Given = new List <string>()
                {
                    "Jim"
                }
            });
            patient.Name.Add(new HumanName()
            {
                Use = HumanName.NameUse.Maiden, Family = "Windsor", Given = new List <string>()
                {
                    "Peter"
                }
            });
            ElementNode node = ElementNode.FromElement(patient.ToTypedElement());

            var expected = ("[{\"use\":\"official\",\"family\":\"Chalmers\",\"given\":[\"Peter\",\"James\"]},{\"use\":\"usual\",\"given\":[\"Jim\"]},{\"use\":\"maiden\",\"family\":\"Windsor\",\"given\":[\"Peter\"]}]"
                            , "array");

            Assert.AreEqual(transformer.ConvertElementNode(node["name"].FirstOrDefault(), FhirTypeNames.Array), expected);
        }