public void GenerateSchematronAssertion_NestedElement_WithAttribute_NULLFlavor_ConformanceSHALL_CardinalityOneToOne()
        {
            var idElement           = new DocumentTemplateElement("id");
            var nullFlavorAttribute = new DocumentTemplateElementAttribute("nullFlavor", "NI");

            idElement.AddAttribute(nullFlavorAttribute);
            var cdaDocumentTemplate = new DocumentTemplate("urn:hl7-org:v3");

            cdaDocumentTemplate.AddElement(new DocumentTemplateElement("component")
                                           .AddElement(new DocumentTemplateElement("section")
                                                       .AddElement(new DocumentTemplateElement("entry")
                                                                   .AddElement(new DocumentTemplateElement("organizer")
                                                                               .AddElement(new DocumentTemplateElement("performer")
                                                                                           .AddElement(new DocumentTemplateElement("assignedEntity")
                                                                                                       .AddElement(idElement)))))));
            var builder = new AssertionLineBuilder(this.tdb, nullFlavorAttribute, this.igType, this.igTypeSchema);

            builder.ConformsTo(ConformanceParser.Parse("SHALL")).WithCardinality(CardinalityParser.Parse("1..1")).WithinContext("cda:");
            var assertion         = builder.ToString();
            var expectedAssertion = @"cda:id[@nullFlavor='NI']";

            Assert.IsTrue(assertion == expectedAssertion,
                          "Assertion string was not correct. Expected '{0}', Actual '{1}'.", expectedAssertion, assertion);
            var contextBuilder  = new ContextBuilder(idElement.ParentElement, "cda");
            var context         = contextBuilder.GetRelativeContextString();
            var expectedContext = "cda:assignedEntity";

            Assert.IsTrue(context == expectedContext, "Context is not correct. Expected '{0}', Actual '{1}'", expectedContext, context);
        }
Пример #2
0
        public void GenerateSchematronAssertion_Attribute_Value_DataType_ConformanceSHALL_CardinalityOneToOne()
        {
            var attr = new DocumentTemplateElementAttribute("code", "57024-2")
            {
                DataType = "CE"
            };
            //create schematron assertion line builder, build one at a time (regular interface, see above for fluent interface)
            var builder = new AssertionLineBuilder(attr, templateIdentifierXpath, templateVersionIdentifierXpath);
            //define cardinality
            var cardinality = CardinalityParser.Parse("1..1");

            //add cardinality for the element
            builder.WithCardinality(cardinality);
            //define conformance
            var conformance = ConformanceParser.Parse("SHALL");

            //add conformance for the element
            builder.ConformsTo(conformance);
            //generate string
            string assertion = builder.ToString();
            //did we generate the correct string?
            string expected = @"count(self::node()[@code='57024-2'])=1";

            Assert.IsTrue(assertion == expected, "Assertion string was not correct. Expected '{0}', Actual '{1}'.", expected, assertion);
        }
Пример #3
0
        private AssertionLineBuilder CreateAssertionLineBuilderForAttribute(DocumentTemplateElement aParentElement, DocumentTemplateElementAttribute aAttribute, ref string aParentContext, ref IConstraint aConstraint)
        {
            AssertionLineBuilder asb = null;

            if ((aParentElement != null) && (aConstraint.Parent.IsBranch))
            {
                asb         = CreateAssertionLineBuilderForElement(aParentElement, aConstraint.Parent, ref aParentContext);
                aConstraint = aConstraint.Parent;
            }
            else
            {
                asb = new AssertionLineBuilder(this.tdb, aAttribute, this.igType, this.igTypeSchema);

                if (aConstraint.Parent != null)
                {
                    Cardinality cardinality = CardinalityParser.Parse(aConstraint.Parent.Cardinality);
                    if (cardinality.Left == 0)
                    {
                        asb.HasOptionalParentContext();
                    }
                }
            }

            return(asb);
        }
        public void GenerateSchematronAssertion_Attribute_TwoAttributes_No_Element_ConformanceSHALL_CardinalityOneToOne()
        {
            var attr = new DocumentTemplateElementAttribute("code");

            attr.SingleValue = "OBS";
            attr.DataType    = "CD";
            //create schematron assertion line builder, build one at a time (regular interface, see above for fluent interface)
            var builder = new AssertionLineBuilder(this.tdb, attr, this.igType, this.igTypeSchema);
            //define cardinality
            var cardinality = CardinalityParser.Parse("1..1");

            //add cardinality for the element
            builder.WithCardinality(cardinality);
            //define conformance
            var conformance = ConformanceParser.Parse("SHALL");

            //add conformance for the element
            builder.ConformsTo(conformance);
            //generate string
            string assertion = builder.ToString();
            //did we generate the correct string?
            string expected = @"count(self::node()[@code='OBS'])=1";

            Assert.IsTrue(assertion == expected, "Assertion string was not correct. Expected '{0}', Actual '{1}'.", expected, assertion);
        }
Пример #5
0
        public ConstraintParser(IObjectRepository tdb,
                                IConstraint constraint,
                                ImplementationGuideType igType,
                                SimpleSchema igTypeSchema,
                                IEnumerable <Template> allTemplates,
                                string valueSetFile = "voc.xml",
                                VocabularyOutputType vocabularyOutputType = VocabularyOutputType.Default)
        {
            this.tdb          = tdb;
            this.constraint   = constraint;
            this.valueSetFile = valueSetFile;
            this.igType       = igType;
            this.igTypeSchema = igTypeSchema;
            this.allTemplates = allTemplates;
            this.igTypePlugin = igType.GetPlugin();

            if (!string.IsNullOrEmpty(this.constraint.Cardinality))
            {
                this.constraintCardinalityType = CardinalityParser.Parse(this.constraint.Cardinality);
            }

            if (!string.IsNullOrEmpty(this.constraint.Conformance))
            {
                this.constraintConformanceType = ConformanceParser.Parse(this.constraint.Conformance);
            }

            this.prefix = igType.SchemaPrefix;

            this.vocabularyOutputType = vocabularyOutputType;
        }
        public void GenerateSchematronAssertion_Element_With_Value_And_AttributeOverride_ConformanceSHALL_CardinalityOneToOne()
        {
            //create cda doc
            var cdaDocumentTemplate = new DocumentTemplate("urn:hl7-org:v3");
            //create code element
            var element = new DocumentTemplateElement("statusCode", "Test");

            element.ElementToAttributeOverrideMapping.Add("statusCode", "code");
            element.ElementToAttributeOverrideMapping.Add("code", "code");
            //add element to doc
            cdaDocumentTemplate.AddElement(element);
            //create schematron assertion line builder
            var builder = new AssertionLineBuilder(this.tdb, element, this.igType, this.igTypeSchema);
            //define cardinality and conformance
            var cardinality = CardinalityParser.Parse("1..1");
            var conformance = ConformanceParser.Parse("SHALL");

            //add element (context comes from doc), conformance, cardinality through fluent interface
            builder.ConformsTo(conformance).WithCardinality(cardinality);
            //generate string
            string assertion = builder.ToString();

            //did we generate the correct string?
            Assert.IsTrue(assertion == @"count(cda:statusCode[@code='Test'])=1", "The generated assertion was not correct. Expected 'count(cda:statusCode[@code='Test'])=1', Actual '{0}'.", assertion);
        }
        public void GenerateSchematronAssertion_NestedElement_WithAttribute_ConformanceSHALL_CardinalityOneToOne()
        {
            var addrElement = new DocumentTemplateElement("addr");
            var useAttr     = new DocumentTemplateElementAttribute("use", "HP");

            addrElement.AddAttribute(useAttr);
            var element             = new DocumentTemplateElement("state");
            var cdaDocumentTemplate = new DocumentTemplate("urn:hl7-org:v3")
                                      .AddElement(new DocumentTemplateElement("recordTarget")
                                                  .AddElement(new DocumentTemplateElement("patientRole")
                                                              .AddElement(addrElement)
                                                              .AddElement(element)));
            //need to have cardinality on both parent and child elements?
            //how do we tell it to generate cda: on context as in below?
            var cardinality       = CardinalityParser.Parse("1..1");
            var builder           = new AssertionLineBuilder(this.tdb, element, this.igType, this.igTypeSchema).WithCardinality(cardinality).ConformsTo(Conformance.SHALL).WithinContext(@"cda:");
            var assertion         = builder.ToString();
            var expectedAssertion = @"count(cda:state)=1";

            Assert.IsTrue(assertion == expectedAssertion,
                          "Assertion string was not correct. Expected '{0}', Actual '{1}'.", expectedAssertion, assertion);
            var contextBuilder  = new ContextBuilder(useAttr, "cda");
            var context         = contextBuilder.GetRelativeContextString();
            var expectedContext = "cda:addr[@use='HP']";

            Assert.IsTrue(context == expectedContext, "Context is not correct. Expected '{0}', Actual '{1}'", expectedContext, context);
        }
        public void GenerateSchematronAssertion_NestedElement_ConformanceSHALL_CardinalityOneToOne()
        {
            var doc = new DocumentTemplate("cda");

            doc.AddElement(new DocumentTemplateElement("observation"));
            doc.ChildElements[0].AddElement(new DocumentTemplateElement("templateId"));
            doc.ChildElements[0].ChildElements[0].AddAttribute(new DocumentTemplateElementAttribute("root", "2.16.840.1.113883.10.20.22.4.48"));
            doc.ChildElements[0].AddElement(new DocumentTemplateElement("effectiveTime"));
            doc.ChildElements[0].ChildElements[1].AddElement(new DocumentTemplateElement("high"));

            var contextBuilder          = new ContextBuilder(doc.ChildElements[0].ChildElements[0].Attributes[0], "cda"); //observation/templateid[@root]
            var relativeContext         = contextBuilder.GetRelativeContextString();
            var fqContext               = contextBuilder.GetFullyQualifiedContextString();
            var expectedRelativeContext = "cda:templateId[@root='2.16.840.1.113883.10.20.22.4.48']";
            var expectedFqContext       = "cda:observation[templateId/@root='2.16.840.1.113883.10.20.22.4.48']";

            Assert.IsTrue(relativeContext == expectedRelativeContext, "Relative context was not correct. Expected '{0}', Actual '{1}'", expectedRelativeContext, relativeContext);
            Assert.IsTrue(fqContext == expectedFqContext, "Fully Qualified context was not correct. Expected '{0}', Actual '{1}'", expectedFqContext, fqContext);
            var childAssertionBuilder = new AssertionLineBuilder(this.tdb, doc.ChildElements[0].ChildElements[1].ChildElements[0], this.igType, this.igTypeSchema);  //high

            childAssertionBuilder.WithCardinality(CardinalityParser.Parse("1..1")).ConformsTo(Conformance.SHALL).WithinContext("cda:");
            var assertionBuilder = new AssertionLineBuilder(this.tdb, doc.ChildElements[0].ChildElements[1], this.igType, this.igTypeSchema);  //effectiveTime
            var assertion        = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..1")).WithinContext("cda:").ConformsTo(Conformance.SHALL).WithChildElementBuilder(childAssertionBuilder).ToString();
            var expected         = "count(cda:effectiveTime[count(cda:high)=1])=1";

            Assert.IsTrue(assertion == expected, "Assertion string was not correct. Expected '{0}', Actual '{1}'", expected, assertion);
        }
        public void TestOneToFive()
        {
            var c = CardinalityParser.Parse("1..5");

            Assert.IsNotNull(c, "No cardinality instance returned");
            Assert.IsTrue(c.Left == 1, "Left side is not correct. Expected 1, Actual {0}", c.Left);
            Assert.IsTrue(c.Right == 5, "Right side is not correct. Expected 5, Actual {1}", c.Right);
        }
        public void TestZeroToNine()
        {
            var c = CardinalityParser.Parse("0..9");

            Assert.IsNotNull(c, "No cardinality instance returned");
            Assert.IsTrue(c.Left == 0, "Left side is not correct. Expected 0, Actual {0}", c.Left);
            Assert.IsTrue(c.Right == 9, "Right side is not correct. Expected 9, Actual {1}", c.Right);
        }
        public void TestManyToMany()
        {
            var c = CardinalityParser.Parse("*..*");

            Assert.IsNotNull(c, "No cardinality instance returned");
            Assert.IsTrue(c.Left == Cardinality.MANY, "Left side is not correct. Expected MANY (*) or {0}, Actual {1}", Cardinality.MANY, c.Left);
            Assert.IsTrue(c.Right == Cardinality.MANY, "Right side is not correct. Expected MANY (*) or {0}, Actual {1}", Cardinality.MANY, c.Right);
        }
        public void TestZeroToZero()
        {
            var c = CardinalityParser.Parse("0..0");

            Assert.IsNotNull(c, "No cardinality instance returned");
            Assert.IsTrue(c.Left == 0, "Left side is not correct. Expected 0, Actual {0}", c.Left);
            Assert.IsTrue(c.Right == 0, "Right side is not correct. Expected 0, Actual {1}", c.Right);
            Assert.IsTrue(c.IsZeroToZero(), "Expected IsZeroToZero() to return true instead it returned false");
        }
        public void TestOneToOne()
        {
            var c = CardinalityParser.Parse("1..1");

            Assert.IsNotNull(c, "No cardinality instance returned");
            Assert.IsTrue(c.Left == 1, "Left side is not correct. Expected 1, Actual {0}", c.Left);
            Assert.IsTrue(c.Right == 1, "Right side is not correct. Expected 1, Actual {1}", c.Right);
            Assert.IsTrue(c.IsOneToOne(), "Expected IsOneToOne() to return true instead it returned false");
        }
Пример #14
0
 static public void AddCardinality(IConstraint aTemplateConstraint, AssertionLineBuilder aAssertionLineBuilder)
 {
     // Determine if we have a cardinality
     if (!string.IsNullOrEmpty(aTemplateConstraint.Cardinality))
     {
         aAssertionLineBuilder.WithCardinality(
             CardinalityParser.Parse(aTemplateConstraint.Cardinality));
     }
 }
        public void TestZeroToMany()
        {
            var c = CardinalityParser.Parse("0..*");

            Assert.IsNotNull(c, "No cardinality instance returned");
            Assert.IsTrue(c.Left == 0, "Left side is not correct. Expected 0, Actual {0}", c.Left);
            Assert.IsTrue(c.Right == Cardinality.MANY, "Right side is not correct. Expected MANY (*) or {0}, Actual {1}", Cardinality.MANY, c.Right);
            Assert.IsTrue(c.IsZeroToMany(), "Expected IsZeroToMany() to return true instead it returned false");
            Assert.IsFalse(c.IsOneToMany(), "Expected IsOneToMany() to return false instead it returned true");
        }
 public void TestInvalidRight()
 {
     try
     {
         var c = CardinalityParser.Parse("1..a");
         Assert.IsTrue(false, "Expected an error to be thrown before this code executed.");
     }
     catch (ArgumentException)
     {
     }
 }
 public void TestCompletelyInvalid()
 {
     try
     {
         var c = CardinalityParser.Parse("adfads");
         Assert.IsTrue(false, "Expected an error to be thrown before this code executed.");
     }
     catch (ArgumentException)
     {
     }
 }
        public void GenerateSchematronAssertion_Element_ConformanceSHALL_CardinalityOneToMany()
        {
            var doc = new DocumentTemplate("cda");

            doc.AddElement(new DocumentTemplateElement("observation"));
            doc.ChildElements[0].AddElement(new DocumentTemplateElement("id"));

            var contextBuilder   = new ContextBuilder(doc.ChildElements[0].ChildElements[0], "cda");
            var assertionBuilder = new AssertionLineBuilder(this.tdb, doc.ChildElements[0].ChildElements[0], this.igType, this.igTypeSchema);              //"id"
            var assertion        = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..*")).WithinContext("cda:").ConformsTo(Conformance.SHALL).ToString();
            var expected         = "count(cda:id) > 0";

            Assert.IsTrue(assertion == expected, "Assertion string was not correct. Expected '{0}', Actual '{1}'", expected, assertion);
        }
        public void GenerateSchematronAssertion_Element_WithSiblingAttributes_ConformanceSHALL_CardinalityOneToOne()
        {
            var doc = new DocumentTemplate("cda");

            doc.AddElement(new DocumentTemplateElement("observation"));
            doc.ChildElements[0].AddAttribute(new DocumentTemplateElementAttribute("classCode", "OBS"));
            doc.ChildElements[0].AddAttribute(new DocumentTemplateElementAttribute("moodCode", "EVN"));

            var contextBuilder   = new ContextBuilder(doc.ChildElements[0], "cda");
            var assertionBuilder = new AssertionLineBuilder(this.tdb, doc.ChildElements[0].Attributes[0], this.igType, this.igTypeSchema);              //"EVN/@moodCode"
            var assertion        = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..1")).ConformsTo(Conformance.SHALL).ToString();
            var expected         = "cda:observation[@classCode='OBS']";

            Assert.IsTrue(assertion == expected, "Assertion string was not correct. Expected '{0}', Actual '{1}'", expected, assertion);
        }
Пример #20
0
        private void DecorateParentOptionality(AssertionLineBuilder aAssertionLineBuilder, IConstraint aConstraint)
        {
            Cardinality cardinality = CardinalityParser.Parse(aConstraint.Cardinality);

            if (aConstraint.Parent != null)
            {
                var current = aConstraint.Parent;
                while (current != null)
                {
                    cardinality = CardinalityParser.Parse(current.Cardinality);

                    if (cardinality.Left == 0)
                    {
                        aAssertionLineBuilder.HasOptionalParentContext();
                        break;
                    }

                    current = current.Parent;
                }
            }
        }
Пример #21
0
        public void GenerateSchematronAssertion_Element_With_Value_ConformanceSHALL_CardinalityOneToOne()
        {
            //create cda doc
            var cdaDocumentTemplate = new DocumentTemplate("urn:hl7-org:v3");
            //create code element
            var element = new DocumentTemplateElement("code", "Test");

            //add element to doc
            cdaDocumentTemplate.AddElement(element);
            //create schematron assertion line builder
            var builder = new AssertionLineBuilder(element, templateIdentifierXpath, templateVersionIdentifierXpath, "cda");
            //define cardinality and conformance
            var cardinality = CardinalityParser.Parse("1..1");
            var conformance = ConformanceParser.Parse("SHALL");

            //add element (context comes from doc), conformance, cardinality through fluent interface
            builder.ConformsTo(conformance).WithCardinality(cardinality);
            //generate string
            string assertion = builder.ToString();

            //did we generate the correct string?
            Assert.IsTrue(assertion == @"count(cda:code[translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')='test'])=1", "The generated assertion was not correct. Expected 'count(cda:code[text()='Test'])=1', Actual '{0}'.", assertion);
        }
        public void GenerateSchematronAssertion_Element_ValueSet_SVS_ConformanceSHALL_CardinalityOneToOne()
        {
            var element = new DocumentTemplateElement("administrativeGenderCode");
            //create schematron assertion line builder, build one at a time (regular interface, see above for fluent interface)
            var builder = new AssertionLineBuilder(this.tdb, element, this.igType, this.igTypeSchema);
            //define cardinality
            var cardinality = CardinalityParser.Parse("1..1");

            //add cardinality for the element
            builder.WithCardinality(cardinality);
            //define conformance
            var conformance = ConformanceParser.Parse("SHALL");

            //add conformance for the element
            builder.ConformsTo(conformance);
            builder.WithinValueSet("4.3.2.1", VocabularyOutputType.SVS_SingleValueSet);
            //generate string
            string assertion = builder.ToString();
            //did we generate the correct string?
            string expected = @"count(cda:administrativeGenderCode[@code=document('4.3.2.1.xml')/svs:RetrieveValueSetResponse/svs:ValueSet[@id='4.3.2.1']/svs:ConceptList/svs:Concept/@code])=1";

            Assert.IsTrue(assertion == expected, "Assertion string was not correct. Expected '{0}', Actual '{1}'.", expected, assertion);
        }
        public void GenerateSchematronAssertion_NamespaceEMA_Element_Template_ConformanceSHALL_CardinalityOneToOne()
        {
            //create cda doc
            var cdaDocumentTemplate = new DocumentTemplate("urn:hl7-org:v3");
            //create code element
            var element = new DocumentTemplateElement("encounter");

            //add element to doc
            cdaDocumentTemplate.AddElement(element);
            //create schematron assertion line builder
            var builder = new AssertionLineBuilder(this.tdb, element, this.igType, this.igTypeSchema, "ema");
            //define cardinality and conformance
            var cardinality = CardinalityParser.Parse("1..1");
            var conformance = ConformanceParser.Parse("SHALL");

            //add element (context comes from doc), conformance, cardinality through fluent interface
            builder.ConformsTo(conformance).WithCardinality(cardinality).ContainsTemplate("urn:oid:4.3.2.1", "Section");
            //generate string
            string assertion = builder.ToString();
            string expected  = @"count(ema:encounter[ema:templateId[@root='4.3.2.1']])=1";

            //did we generate the correct string?
            Assert.IsTrue(assertion == expected, "The generated assertion was not correct. Expected '{0}', Actual '{1}'.", expected, assertion);
        }
        public void GenerateSchematronAssertion_Attribute_Valueset_ConformanceMAYNOT_CardinalityOneToOne()
        {
            var attr = new DocumentTemplateElementAttribute("moodCode", "EVN");
            //create schematron assertion line builder, build one at a time (regular interface, see above for fluent interface)
            var builder = new AssertionLineBuilder(this.tdb, attr, this.igType, this.igTypeSchema);
            //define cardinality
            var cardinality = CardinalityParser.Parse("1..1");

            //add cardinality for the element
            builder.WithCardinality(cardinality);
            //define conformance
            var conformance = Conformance.MAY_NOT;

            //add conformance for the element
            builder.ConformsTo(conformance);
            //add valueset
            builder.WithinValueSet("2.16.840.1.113883.1.11.20.2");
            //generate string
            string assertion = builder.ToString();
            //did we generate the correct string?
            string expected = "not(@moodCode='EVN' and @moodCode=document('the_voc.xml')/voc:systems/voc:system[@valueSetOid='2.16.840.1.113883.1.11.20.2']/voc:code/@value)";

            Assert.IsTrue(assertion == expected, "Assertion string was not correct. Expected empty string, Actual '{1}'.", expected, assertion);
        }
Пример #25
0
        public ConstraintParser(IObjectRepository tdb, IConstraint constraint, ImplementationGuideType igType, string valueSetFile = "voc.xml", VocabularyOutputType vocabularyOutputType = VocabularyOutputType.Default)
        {
            this.tdb          = tdb;
            this.constraint   = constraint;
            this.valueSetFile = valueSetFile;
            this.igTypePlugin = igType.GetPlugin();

            if (this.constraint.ValueSetId != null)
            {
                this.constraintValueSet = this.tdb.ValueSets.Single(y => y.Id == constraint.ValueSetId);
            }

            if (this.constraint.ValueCodeSystemId != null)
            {
                this.constraintCodeSystem = this.tdb.CodeSystems.Single(y => y.Id == constraint.ValueCodeSystemId);
            }

            if (!string.IsNullOrEmpty(this.constraint.Cardinality))
            {
                this.constraintCardinalityType = CardinalityParser.Parse(this.constraint.Cardinality);
            }

            if (!string.IsNullOrEmpty(this.constraint.Conformance))
            {
                this.constraintConformanceType = ConformanceParser.Parse(this.constraint.Conformance);
            }

            if (this.constraint.ContainedTemplateId != null)
            {
                this.containedTemplate = this.tdb.Templates.Single(y => y.Id == this.constraint.ContainedTemplateId.Value);
            }

            this.prefix = igType.SchemaPrefix;

            this.vocabularyOutputType = vocabularyOutputType;
        }
        public void GenerateSchematronAssertion_Element_ConformanceSHALL_CardinalityZeroToMany()
        {
            //create cda doc
            var cdaDocumentTemplate = new DocumentTemplate("urn:hl7-org:v3");
            //create code element
            var element = new DocumentTemplateElement("code");

            //add element to doc
            cdaDocumentTemplate.AddElement(element);
            //create schematron assertion line builder
            var builder = new AssertionLineBuilder(this.tdb, element, this.igType, this.igTypeSchema);
            //define cardinality and conformance
            var cardinality = CardinalityParser.Parse("0..*");
            var conformance = ConformanceParser.Parse("SHALL");

            //add element (context comes from doc), conformance, cardinality through fluent interface
            builder.ConformsTo(conformance).WithCardinality(cardinality);
            //generate string
            string assertion = builder.ToString();
            string expected  = "not(cda:code) or cda:code";

            //did we generate the correct string?
            Assert.IsTrue(assertion == expected, "The generated assertion was not correct. Expected '{0}', Actual '{1}'.", expected, assertion);
        }
Пример #27
0
        public void BuildAdvanceDirectiveObservationDocument_1stLevelOnly()
        {
            var sectionCount = 1;
            var phase        = new Phase();

            phase.ID = "error";
            var document = new SchematronDocument();

            document.Phases.Add(phase);


            var doc = new DocumentTemplate("cda");

            doc.AddElement(new DocumentTemplateElement("observation"));
            doc.ChildElements[0].AddAttribute(new DocumentTemplateElementAttribute("classCode", "OBS"));
            doc.ChildElements[0].AddAttribute(new DocumentTemplateElementAttribute("moodCode", "EVN"));
            doc.AddElement(new DocumentTemplateElement("templateId"));
            doc.ChildElements[1].AddAttribute(new DocumentTemplateElementAttribute("root", "2.16.840.1.113883.10.20.22.4.48"));
            doc.AddElement(new DocumentTemplateElement("id"));
            doc.AddElement(new DocumentTemplateElement("code"));
            doc.ChildElements[doc.ChildElements.Count - 1].AddAttribute(new DocumentTemplateElementAttribute("xsi-type", "CE", "2.16.840.1.113883.1.11.20.2"));
            doc.AddElement(new DocumentTemplateElement("statusCode"));
            doc.ChildElements[doc.ChildElements.Count - 1].AddAttribute(new DocumentTemplateElementAttribute("code", "completed", "2.16.840.1.113883.5.14"));
            var participantElement = new DocumentTemplateElement("participant");

            doc.ChildElements[0].AddElement(participantElement);
            participantElement.AddAttribute(new DocumentTemplateElementAttribute("typeCode", "VRF"));
            var templateIdElement = new DocumentTemplateElement("templateId");

            templateIdElement.AddAttribute(new DocumentTemplateElementAttribute("root", "2.16.840.1.113883.10.20.1.58"));
            participantElement.AddElement(templateIdElement);
            var timeElement = new DocumentTemplateElement("time");

            timeElement.AddAttribute(new DocumentTemplateElementAttribute("xsi:type", "TS"));
            participantElement.AddElement(timeElement);
            var participantRoleElement = new DocumentTemplateElement("participantRole");

            participantElement.AddElement(participantRoleElement);


            var contextBuilder = new ContextBuilder(doc.ChildElements[0], "cda");
            var rule           = new Rule();

            rule.Context = contextBuilder.GetFullyQualifiedContextString();

            var assertionBuilder = new AssertionLineBuilder(doc.ChildElements[0].Attributes[0], templateIdentifierXpath, templateVersionIdentifierXpath);  //"OBS"

            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "SHALL contain 1..1 @classCode='OBS' Observation (CodeSystem: HL7ActClass 2.16.840.1.113883.5.6) (CONF:8648).",
                Test             = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..1")).WithinContext(contextBuilder.GetRelativeContextString()).ConformsTo(Conformance.SHALL).ToString()
            });

            assertionBuilder = new AssertionLineBuilder(doc.ChildElements[0].Attributes[1], templateIdentifierXpath, templateVersionIdentifierXpath);  //"EVN"
            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "SHALL contain 1..1 @moodCode='EVN' Event (CodeSystem: ActMood 2.16.840.1.113883.5.1001) (CONF:8649).",
                Test             = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..1")).WithinContext(contextBuilder.GetRelativeContextString()).ConformsTo(Conformance.SHALL).ToString()
            });
            var pattern = new Pattern();

            pattern.ID   = sectionCount.ToString();
            pattern.Name = string.Format("pattern-{0}-errors", pattern.ID);
            pattern.Rules.Add(rule);
            phase.ActivePatterns.Add(pattern);

            rule             = new Rule();
            contextBuilder   = new ContextBuilder(doc.ChildElements[1], "cda");
            rule.Context     = contextBuilder.GetFullyQualifiedContextString();
            assertionBuilder = new AssertionLineBuilder(doc.ChildElements[1], templateIdentifierXpath, templateVersionIdentifierXpath);  //"templateId[@rootCode]"
            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "SHALL contain 1..1 @root='2.16.840.1.113883.10.20.22.4.48' (CONF:10485).",
                Test             = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..1")).WithinContext(contextBuilder.GetRelativeContextString()).ConformsTo(Conformance.SHALL).ToString()
            });

            sectionCount++;
            pattern      = new Pattern();
            pattern.ID   = sectionCount.ToString();
            pattern.Name = string.Format("pattern-{0}-errors", pattern.ID);
            pattern.Rules.Add(rule);
            phase.ActivePatterns.Add(pattern);

            rule             = new Rule();
            contextBuilder   = new ContextBuilder(doc.ChildElements[2], "cda");
            rule.Context     = contextBuilder.GetFullyQualifiedContextString();
            assertionBuilder = new AssertionLineBuilder(doc.ChildElements[2], templateIdentifierXpath, templateVersionIdentifierXpath);  //"1..* id"
            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "SHALL contain 1..* id (CONF:8654)",
                Test             = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..*")).WithinContext(contextBuilder.GetRelativeContextString()).ConformsTo(Conformance.SHALL).ToString()
            });

            sectionCount++;
            pattern      = new Pattern();
            pattern.ID   = sectionCount.ToString();
            pattern.Name = string.Format("pattern-{0}-errors", pattern.ID);
            pattern.Rules.Add(rule);
            phase.ActivePatterns.Add(pattern);

            rule             = new Rule();
            contextBuilder   = new ContextBuilder(doc.ChildElements[3], "cda");
            rule.Context     = contextBuilder.GetFullyQualifiedContextString();
            assertionBuilder = new AssertionLineBuilder(doc.ChildElements[3], templateIdentifierXpath, templateVersionIdentifierXpath);  //"1..1 code @xsi:type='CE' valueset = 2.16.840.1.113883.1.11.20.2"
            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "SHALL contain 1..1 code with @xsi:type='CE', where the @code SHOULD be selected from ValueSet AdvanceDirectiveTypeCode 2.16.840.1.113883.1.11.20.2 STATIC 2006-10-17 (CONF:8651).",
                Test             = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..1")).WithinContext(contextBuilder.GetRelativeContextString()).ConformsTo(Conformance.SHALL).ToString()
            });

            sectionCount++;
            pattern      = new Pattern();
            pattern.ID   = sectionCount.ToString();
            pattern.Name = string.Format("pattern-{0}-errors", pattern.ID);
            pattern.Rules.Add(rule);
            phase.ActivePatterns.Add(pattern);

            rule             = new Rule();
            contextBuilder   = new ContextBuilder(doc.ChildElements[3], "cda");
            rule.Context     = contextBuilder.GetFullyQualifiedContextString();
            assertionBuilder = new AssertionLineBuilder(doc.ChildElements[3], templateIdentifierXpath, templateVersionIdentifierXpath);  //"1..1 statusCode @code='completed' valueset = 2.16.840.1.113883.1.11.20.2"
            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "SHALL contain 1..1 code with @xsi:type='CE', where the @code SHOULD be selected from ValueSet AdvanceDirectiveTypeCode 2.16.840.1.113883.1.11.20.2 STATIC 2006-10-17 (CONF:8651).",
                Test             = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..1")).WithinContext(contextBuilder.GetRelativeContextString()).ConformsTo(Conformance.SHALL).ToString()
            });

            sectionCount++;
            pattern      = new Pattern();
            pattern.ID   = sectionCount.ToString();
            pattern.Name = string.Format("pattern-{0}-errors", pattern.ID);
            pattern.Rules.Add(rule);
            phase.ActivePatterns.Add(pattern);

            rule           = new Rule();
            contextBuilder = new ContextBuilder(doc.ChildElements[1].Attributes[0], "cda");
            rule.Context   = contextBuilder.GetFullyQualifiedContextString();
            var childtemplateIdElementAssertionBuilder = new AssertionLineBuilder(templateIdElement.Attributes[0], templateIdentifierXpath, templateVersionIdentifierXpath)  //templateId/@root
                                                         .WithCardinality(CardinalityParser.Parse("1..1"))
                                                         .ConformsTo(Conformance.SHALL)
                                                         .WithinContext("cda:");
            var childParticipantElementAssertionBuilder = new AssertionLineBuilder(participantRoleElement, templateIdentifierXpath, templateVersionIdentifierXpath)
                                                          .WithCardinality(CardinalityParser.Parse("1..*"))
                                                          .ConformsTo(Conformance.SHALL)
                                                          .WithinContext("cda:");
            var childTimeElementAssertionBuilder = new AssertionLineBuilder(timeElement, templateIdentifierXpath, templateVersionIdentifierXpath)
                                                   .WithCardinality(CardinalityParser.Parse("0..1"))
                                                   .ConformsTo(Conformance.SHOULD)
                                                   .WithinContext("cda:");

            assertionBuilder = new AssertionLineBuilder(participantElement, templateIdentifierXpath, templateVersionIdentifierXpath);  //participant
            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "should contain 1..* participant (CONF:8662), participant should contain 0..1 time (CONF:8665), the data type of Observation/participant/time in a verification SHALL be TS (time stamp) (CONF:8666), participant shall contain 1..1 participantRole (CONF:8825), participant shall contain 1..1 @typeCode=VRF 'Verifier' (CodeSystem: 2.16.840.1.113883.5.90) (CONF:8663), participant shall contain 1..1 templateId (CONF:8664), templateId shall contain 1..1 @root=2.16.840.1.113883.10.20.1.58 (CONF:10486)",
                Test             = assertionBuilder
                                   .WithCardinality(CardinalityParser.Parse("1..*"))
                                   .WithinContext("cda:")
                                   .ConformsTo(Conformance.SHALL)
                                   .WithChildElementBuilder(childTimeElementAssertionBuilder)
                                   .WithChildElementBuilder(childParticipantElementAssertionBuilder)
                                   .WithChildElementBuilder(childtemplateIdElementAssertionBuilder)
                                   .ToString()
            });

            sectionCount++;
            pattern      = new Pattern();
            pattern.ID   = sectionCount.ToString();
            pattern.Name = string.Format("pattern-{0}-errors", pattern.ID);
            pattern.Rules.Add(rule);
            phase.ActivePatterns.Add(pattern);

            var    builder         = new SchematronDocumentSerializer();
            string serializedModel = builder.SerializeDocument(document);

            Assert.IsFalse(string.IsNullOrEmpty(serializedModel), "No string returned from serialize document");

            string[] lModelLines = serializedModel.Split('\n');
            Assert.IsNotNull(lModelLines, "The generated string was not split on lines");
            Assert.IsTrue(lModelLines.Length > 1, "The generated string was not split on lines");
        }
        public void GenerateSchematronAssertion_MultipleNestedElement_ConformanceSHALL_AND_SHOULD_CardinalityOneToOne_AND_ZeroToOne_For_Advance_Directive_Number9Constraint()
        {
            var doc = new DocumentTemplate("cda");

            doc.AddElement(new DocumentTemplateElement("observation"));
            var participantElement = new DocumentTemplateElement("participant");

            participantElement.AddAttribute(new DocumentTemplateElementAttribute("typeCode", "CST"));
            var participantRoleElement = new DocumentTemplateElement("participantRole");

            participantRoleElement.AddAttribute(new DocumentTemplateElementAttribute("classCode", "AGNT"));
            participantElement.AddElement(participantRoleElement);
            var addrElement = new DocumentTemplateElement("addr");

            participantRoleElement.AddElement(addrElement);
            var telecomElement = new DocumentTemplateElement("telecom");

            participantRoleElement.AddElement(telecomElement);
            var playingEntityElement = new DocumentTemplateElement("playingEntity");

            participantRoleElement.AddElement(playingEntityElement);
            var nameElement = new DocumentTemplateElement("name");

            playingEntityElement.AddElement(nameElement);


            var participantRoleChildAssertionBuilder = new AssertionLineBuilder(this.tdb, participantRoleElement, this.igType, this.igTypeSchema)
                                                       .WithinContext("cda:")
                                                       .WithCardinality(CardinalityParser.Parse("1..1"))
                                                       .ConformsTo(Conformance.SHALL);
            var addrChildAssertionBuilder = new AssertionLineBuilder(this.tdb, addrElement, this.igType, this.igTypeSchema)
                                            .WithinContext("cda:")
                                            .WithCardinality(CardinalityParser.Parse("0..1"))
                                            .ConformsTo(Conformance.SHALL);
            var telecomChildAssertionBuilder = new AssertionLineBuilder(this.tdb, telecomElement, this.igType, this.igTypeSchema)
                                               .WithinContext("cda:")
                                               .WithCardinality(CardinalityParser.Parse("0..1"))
                                               .ConformsTo(Conformance.SHALL);
            var nameChildAssertionBuilder = new AssertionLineBuilder(this.tdb, nameElement, this.igType, this.igTypeSchema)
                                            .WithinContext("cda:")
                                            .WithCardinality(CardinalityParser.Parse("1..1"))
                                            .ConformsTo(Conformance.SHALL);
            var playingEntityChildAssertionBuilder = new AssertionLineBuilder(this.tdb, playingEntityElement, this.igType, this.igTypeSchema)
                                                     .WithinContext("cda:")
                                                     .WithCardinality(CardinalityParser.Parse("1..1"))
                                                     .WithChildElementBuilder(nameChildAssertionBuilder)                                                                 //nested child assertion builder
                                                     .ConformsTo(Conformance.SHALL);

            var assertionBuilder = new AssertionLineBuilder(this.tdb, participantElement, this.igType, this.igTypeSchema);  //participant
            var assertion        = assertionBuilder
                                   .WithCardinality(CardinalityParser.Parse("1..1"))
                                   .WithinContext("cda:")
                                   .ConformsTo(Conformance.SHALL)
                                   .WithChildElementBuilder(participantRoleChildAssertionBuilder)
                                   .WithChildElementBuilder(addrChildAssertionBuilder)
                                   .WithChildElementBuilder(telecomChildAssertionBuilder)
                                   .WithChildElementBuilder(playingEntityChildAssertionBuilder)
                                   .ToString();
            var expected = "count(cda:participant[@typeCode='CST'][count(cda:participantRole[@classCode='AGNT'])=1][count(cda:addr) < 2][count(cda:telecom) < 2][count(cda:playingEntity[count(cda:name)=1])=1])=1";

            Assert.IsTrue(assertion == expected, "Assertion string was not correct. Expected '{0}', Actual '{1}'", expected, assertion);
        }