public void TestBucketAssignment()
        {
            var s = createSliceDefs() as SliceGroupBucket;

            var p = new Patient();

            p.Telecom.Add(new ContactPoint {
                System = ContactPoint.ContactPointSystem.Phone, Use = ContactPoint.ContactPointUse.Home, Value = "+31-6-39015765"
            });
            p.Telecom.Add(new ContactPoint {
                System = ContactPoint.ContactPointSystem.Email, Use = ContactPoint.ContactPointUse.Work, Value = "*****@*****.**"
            });
            p.Telecom.Add(new ContactPoint {
                System = ContactPoint.ContactPointSystem.Other, Use = ContactPoint.ContactPointUse.Temp, Value = "skype://crap"
            });
            p.Telecom.Add(new ContactPoint {
                System = ContactPoint.ContactPointSystem.Other, Use = ContactPoint.ContactPointUse.Home, Value = "http://nu.nl"
            });
            p.Telecom.Add(new ContactPoint {
                System = ContactPoint.ContactPointSystem.Fax, Use = ContactPoint.ContactPointUse.Work, Value = "+31-20-6707070"
            });
            var pnode = new ScopedNode(p.ToTypedElement());

            var telecoms = pnode.Children("telecom").Cast <ScopedNode>();

            foreach (var telecom in telecoms)
            {
                Assert.True(s.Add(telecom));
            }

            var outcome = s.Validate(_validator, pnode);

            Assert.True(outcome.Success);
            Assert.Equal(0, outcome.Warnings);

            Assert.Equal("+31-6-39015765", s.ChildSlices[0].Members.Single().Children("value").Single().Value);

            var emailBucket = s.ChildSlices[1] as SliceGroupBucket;

            Assert.Equal("*****@*****.**", emailBucket.Members.Single().Children("value").Single().Value);
            Assert.False(emailBucket.ChildSlices[0].Members.Any());
            Assert.Equal("*****@*****.**", emailBucket.ChildSlices[1].Members.Single().Children("value").Single().Value);

            var otherBucket = s.ChildSlices[2] as SliceGroupBucket;

            Assert.Equal("http://nu.nl", otherBucket.ChildSlices[0].Members.Single().Children("value").Single().Value);
            Assert.False(otherBucket.ChildSlices[1].Members.Any());
            Assert.Equal("skype://crap", otherBucket.Members.First().Children("value").Single().Value); // in the open slice - find it on other bucket, not child

            Assert.Equal("+31-20-6707070", s.Members.Last().Children("value").Single().Value);          // in the open-at-end slice
        }
        public void KeepScopes()
        {
            Assert.IsNull(_bundleNode.ParentResource);
            Assert.AreEqual("Bundle", _bundleNode.InstanceType);
            Assert.AreEqual("Bundle", _bundleNode.NearestResourceType);

            var entry = (ScopedNode)_bundleNode.Children("entry").First();

            Assert.IsNotNull(entry);
            Assert.AreEqual("Bundle.entry[0]", entry.Location);
            Assert.AreEqual("Bundle.entry[0]", entry.LocalLocation);
            Assert.AreEqual("Bundle", entry.ParentResource.Location);
            Assert.AreEqual("Bundle", entry.ParentResource.LocalLocation);
            Assert.AreNotEqual("Bundle", entry.InstanceType);
            Assert.IsFalse(entry.AtResource);

            var resource = (ScopedNode)entry.Children("resource").First();

            Assert.IsNotNull(resource);
            Assert.AreEqual("Bundle.entry[0].resource[0]", resource.Location);
            Assert.AreEqual("Bundle.entry[0].resource[0]", resource.LocalLocation);
            Assert.AreEqual("Bundle", resource.ParentResource.Location);
            Assert.AreNotEqual("Bundle", resource.InstanceType);
            Assert.IsTrue(resource.AtResource);

            var active = (ScopedNode)resource.Children("active").First();

            Assert.IsNotNull(active);
            Assert.AreEqual("Bundle.entry[0].resource[0].active[0]", active.Location);
            Assert.AreEqual("Organization", active.NearestResourceType);
            Assert.AreEqual("Organization.active[0]", active.LocalLocation);
            Assert.AreEqual("Bundle.entry[0].resource[0]", active.ParentResource.Location);
            Assert.AreEqual("Bundle", active.ParentResource.ParentResource.Location);
            Assert.AreNotEqual("Bundle", active.InstanceType);
            Assert.IsFalse(active.AtResource);
        }
예제 #3
0
        //   private OperationOutcome validateElement(ElementDefinitionNavigator definition, IElementNavigator instance)

        private OperationOutcome validateElement(ElementDefinitionNavigator definition, ScopedNode instance)
        {
            var outcome = new OperationOutcome();

            Trace(outcome, $"Start validation of ElementDefinition at path '{definition.QualifiedDefinitionPath()}'", Issue.PROCESSING_PROGRESS, instance);

            // If navigator cannot be moved to content, there's really nothing to validate against.
            if (definition.AtRoot && !definition.MoveToFirstChild())
            {
                outcome.AddIssue($"Snapshot component of profile '{definition.StructureDefinition?.Url}' has no content.", Issue.PROFILE_ELEMENTDEF_IS_EMPTY, instance);
                return(outcome);
            }

            // This does not work, since the children might still be empty, we need something better
            //// Any node must either have a value, or children, or both (e.g. extensions on primitives)
            if (instance.Value == null && !instance.Children().Any())
            {
                outcome.AddIssue("Element must not be empty", Issue.CONTENT_ELEMENT_MUST_HAVE_VALUE_OR_CHILDREN, instance);
                return(outcome);
            }

            var elementConstraints = definition.Current;

            if (elementConstraints.IsPrimitiveValueConstraint())
            {
                // The "value" property of a FHIR Primitive is the bottom of our recursion chain, it does not have a nameReference
                // nor a <type>, the only thing left to do to validate the content is to validate the string representation of the
                // primitive against the regex given in the core definition
                outcome.Add(VerifyPrimitiveContents(elementConstraints, instance));
            }
            else
            {
                bool isInlineChildren = !definition.Current.IsRootElement();

                // Now, validate the children
                if (definition.HasChildren)
                {
                    // If we are at the root of an abstract type (e.g. is this instance a Resource)?
                    // or we are at a nested resource, we may expect more children in the instance than
                    // we know about
                    bool allowAdditionalChildren = (isInlineChildren && elementConstraints.IsResourcePlaceholder()) ||
                                                   (!isInlineChildren && definition.StructureDefinition.Abstract == true);

                    // Handle in-lined constraints on children. In a snapshot, these children should be exhaustive,
                    // so there's no point in also validating the <type> or <nameReference>
                    // TODO: Check whether this is even true when the <type> has a profile?
                    // Note: the snapshot is *not* exhaustive if the declared type is a base FHIR type (like Resource),
                    // in which case there may be additional children (verified in the next step)
                    outcome.Add(this.ValidateChildConstraints(definition, instance, allowAdditionalChildren: allowAdditionalChildren));

                    // Special case: if we are located at a nested resource (i.e. contained or Bundle.entry.resource),
                    // we need to validate based on the actual type of the instance
                    if (isInlineChildren && elementConstraints.IsResourcePlaceholder())
                    {
                        outcome.Add(this.ValidateType(elementConstraints, instance));
                    }
                }

                if (!definition.HasChildren)
                {
                    // No inline-children, so validation depends on the presence of a <type> or <nameReference>
                    if (elementConstraints.Type != null || elementConstraints.NameReference != null)
                    {
                        outcome.Add(this.ValidateType(elementConstraints, instance));
                        outcome.Add(ValidateNameReference(elementConstraints, definition, instance));
                    }
                    else
                    {
                        Trace(outcome, "ElementDefinition has no child, nor does it specify a type or nameReference to validate the instance data against", Issue.PROFILE_ELEMENTDEF_CONTAINS_NO_TYPE_OR_NAMEREF, instance);
                    }
                }
            }

            outcome.Add(this.ValidateFixed(elementConstraints, instance));
            outcome.Add(this.ValidatePattern(elementConstraints, instance));
            outcome.Add(this.ValidateMinMaxValue(elementConstraints, instance));
            outcome.Add(ValidateMaxLength(elementConstraints, instance));
            outcome.Add(this.ValidateFp(elementConstraints, instance));
            outcome.Add(this.ValidateBinding(elementConstraints, instance));
            outcome.Add(this.ValidateExtension(elementConstraints, instance, "http://hl7.org/fhir/StructureDefinition/regex"));

            // If the report only has partial information, no use to show the hierarchy, so flatten it.
            if (Settings.Trace == false)
            {
                outcome.Flatten();
            }

            return(outcome);
        }