diff --git a/.gitignore b/.gitignore
index dfcfd56f..4255ff93 100644
--- a/.gitignore
+++ b/.gitignore
@@ -348,3 +348,4 @@ MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
+/.idea/.idea.Firely.Validator.API/.idea/workspace.xml
diff --git a/.idea/.idea.Firely.Validator.API/.idea/inspectionProfiles/Project_Default.xml b/.idea/.idea.Firely.Validator.API/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 00000000..7c041470
--- /dev/null
+++ b/.idea/.idea.Firely.Validator.API/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.Firely.Validator.API/.idea/workspace.xml b/.idea/.idea.Firely.Validator.API/.idea/workspace.xml
deleted file mode 100644
index d3144c80..00000000
--- a/.idea/.idea.Firely.Validator.API/.idea/workspace.xml
+++ /dev/null
@@ -1,253 +0,0 @@
-
-
-
- test/Benchmarks/Benchmarks.csproj
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {
- "associatedIndex": 8
-}
-
-
-
-
-
-
-
-
-
- {
- "keyToString": {
- ".NET Project.Benchmarks.executor": "Run",
- "2dfc1c9d-cb76-452c-8172-af0ab4eaf4dd.executor": "Debug",
- "ASKED_ADD_EXTERNAL_FILES": "true",
- "ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
- "RunOnceActivity.OpenProjectViewOnStart": "true",
- "RunOnceActivity.ShowReadmeOnStart": "true",
- "SHARE_PROJECT_CONFIGURATION_FILES": "true",
- "git-widget-placeholder": "develop",
- "ignore.virus.scanning.warn.message": "true",
- "node.js.detected.package.eslint": "true",
- "node.js.detected.package.tslint": "true",
- "node.js.selected.package.eslint": "(autodetect)",
- "node.js.selected.package.tslint": "(autodetect)",
- "nodejs_package_manager_path": "npm",
- "settings.editor.selected.configurable": "com.github.copilot.settings.ApplicationConfigurable",
- "vue.rearranger.settings.migration": "true"
- },
- "keyToStringList": {
- "rider.external.source.directories": [
- "C:\\Users\\ewout\\AppData\\Roaming\\JetBrains\\Rider2023.3\\resharper-host\\DecompilerCache",
- "C:\\Users\\ewout\\AppData\\Roaming\\JetBrains\\Rider2023.3\\resharper-host\\SourcesCache",
- "C:\\Users\\ewout\\AppData\\Local\\Symbols\\src"
- ]
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1705581290711
-
-
- 1705581290711
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- file://$PROJECT_DIR$/test/Firely.Fhir.Validation.Compilation.Tests.Shared/ValidationIntegrationTests.cs
- 67
-
-
-
-
-
-
-
-
-
-
-
- file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/fb2a285657b34c4aa83f5bbf6f19147e21400/a2/5a684b5c/CanonicalIndexer.cs
- 154
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/firely-validator-api-tests.props b/firely-validator-api-tests.props
index c14e448a..1ad20286 100644
--- a/firely-validator-api-tests.props
+++ b/firely-validator-api-tests.props
@@ -4,14 +4,11 @@
true
net8.0
false
-
- 1591
enable
- 5.5.1
- 5.1.0
+ 5.5.2-20240131.10
diff --git a/firely-validator-api.props b/firely-validator-api.props
index f4f16001..a7aa7f13 100644
--- a/firely-validator-api.props
+++ b/firely-validator-api.props
@@ -27,7 +27,7 @@
- 5.5.1
+ 5.5.2-20240131.10
diff --git a/src/Firely.Fhir.Validation.Compilation.Shared/SchemaBuilder.cs b/src/Firely.Fhir.Validation.Compilation.Shared/SchemaBuilder.cs
index 79eca15f..2e837848 100644
--- a/src/Firely.Fhir.Validation.Compilation.Shared/SchemaBuilder.cs
+++ b/src/Firely.Fhir.Validation.Compilation.Shared/SchemaBuilder.cs
@@ -7,6 +7,7 @@
*/
using Hl7.Fhir.Model;
+using Hl7.Fhir.Serialization;
using Hl7.Fhir.Specification.Navigation;
using Hl7.Fhir.Specification.Source;
using Hl7.Fhir.Support;
@@ -14,6 +15,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.IO;
using System.Linq;
using static Hl7.Fhir.Model.ElementDefinition;
@@ -53,10 +55,6 @@ public SchemaBuilder(IAsyncResourceResolver source, IEnumerable?
///
public IEnumerable Build(ElementDefinitionNavigator nav, ElementConversionMode? conversionMode = ElementConversionMode.Full)
{
- //Enable this when you need a snapshot of a test SD written out in your %TEMP%/testprofiles dir.
- //string p = Path.Combine(Path.GetTempPath(), "testprofiles", (nav.StructureDefinition.Id ?? nav.StructureDefinition.Name) + ".xml");
- //File.WriteAllText(p, nav.StructureDefinition.ToXml());
-
if (!nav.MoveToFirstChild()) return new[] { new ElementSchema(nav.StructureDefinition.Url) };
var subschemaCollector = new SubschemaCollector(nav);
@@ -405,7 +403,10 @@ private static IAssertion createDefaultSlice(SlicingComponent slicing) =>
private IAssertion buildDiscriminatorCondition(SlicingComponent slicing, ElementDefinitionNavigator slice)
{
- IEnumerable sliceAssertions = slicing.Discriminator.Select(d => DiscriminatorFactory.Build(slice, d, Source));
+ var sliceAssertions = slicing.Discriminator
+ .Select(d => DiscriminatorFactory.Build(slice, d, Source))
+ .ToArray();
+
if (sliceAssertions.All(sa => sa is null))
{
var paths = string.Join(',', slicing.Discriminator.Select(d => d.Path));
diff --git a/src/Firely.Fhir.Validation.Compilation.Shared/SchemaBuilders/TypeReferenceBuilder.cs b/src/Firely.Fhir.Validation.Compilation.Shared/SchemaBuilders/TypeReferenceBuilder.cs
index 19438c65..52adab46 100644
--- a/src/Firely.Fhir.Validation.Compilation.Shared/SchemaBuilders/TypeReferenceBuilder.cs
+++ b/src/Firely.Fhir.Validation.Compilation.Shared/SchemaBuilders/TypeReferenceBuilder.cs
@@ -72,9 +72,9 @@ public IEnumerable Build(ElementDefinitionNavigator nav, ElementConv
#endif
if ((!nav.HasChildren || hasProfileDetails) && def.Type.Count > 0)
{
- var typeAssertions = ConvertTypeReferences(def.Type);
- if (typeAssertions is not null)
- yield return typeAssertions;
+ var typeAssertion = ConvertTypeReferences(def.Type);
+ if (typeAssertion is not null)
+ yield return typeAssertion;
}
}
@@ -135,7 +135,7 @@ public IEnumerable Build(ElementDefinitionNavigator nav, ElementConv
? new AllValidator(profileAssertions, validateReferenceAssertion)
: validateReferenceAssertion;
}
- else if (!(code is "Reference" or "canonical" or "CodeableReference") && typeRef.TargetProfile.Any())
+ else if (!ReferencedInstanceValidator.IsReferenceType(code) && typeRef.TargetProfile.Any())
{
throw new IncorrectElementDefinitionException($"Encountered targetProfiles {string.Join(",", typeRef.TargetProfile)} on an element that is not " +
$"a reference type (canonical or Reference) but a {code}.");
diff --git a/src/Firely.Fhir.Validation.Compilation/Firely.Fhir.Validation.Compilation.csproj b/src/Firely.Fhir.Validation.Compilation/Firely.Fhir.Validation.Compilation.csproj
index c1245491..d953f3cf 100644
--- a/src/Firely.Fhir.Validation.Compilation/Firely.Fhir.Validation.Compilation.csproj
+++ b/src/Firely.Fhir.Validation.Compilation/Firely.Fhir.Validation.Compilation.csproj
@@ -1,4 +1,4 @@
-
+
diff --git a/src/Firely.Fhir.Validation/Impl/BindingValidator.cs b/src/Firely.Fhir.Validation/Impl/BindingValidator.cs
index 88cc1419..ad1eaf9c 100644
--- a/src/Firely.Fhir.Validation/Impl/BindingValidator.cs
+++ b/src/Firely.Fhir.Validation/Impl/BindingValidator.cs
@@ -1,5 +1,4 @@
-
-/*
+/*
* Copyright (c) 2024, Firely (info@fire.ly) and contributors
* See the file CONTRIBUTORS for details.
*
@@ -120,6 +119,7 @@ ResultReport IValidatable.Validate(IScopedNode input, ValidationSettings vc, Val
// This would give informational messages even if the validation was run on a choice type with a binding, which is then
// only applicable to an instance which is bindable. So instead of a warning, we should just return as validation is
// not applicable to this instance.
+ // There is hack here, since CodeableReference is bindable, but not part of Base.
if (!ModelInspector.Base.IsBindable(input.InstanceType))
{
return vc.TraceResult(() =>
@@ -132,7 +132,7 @@ ResultReport IValidatable.Validate(IScopedNode input, ValidationSettings vc, Val
var result = verifyContentRequirements(input, bindable, s);
return result.IsSuccessful ?
- validateCode(input, bindable, vc, s)
+ validateCode(bindable, vc, s)
: result;
}
else
@@ -173,7 +173,7 @@ private static bool codeableConceptHasCode(CodeableConcept cc) =>
cc.Coding.Any(cd => !string.IsNullOrEmpty(cd.Code));
- private ResultReport validateCode(IScopedNode source, Element bindable, ValidationSettings vc, ValidationState s)
+ private ResultReport validateCode(Element bindable, ValidationSettings vc, ValidationState s)
{
//EK 20170605 - disabled inclusion of warnings/errors for all but required bindings since this will
// 1) create superfluous messages (both saying the code is not valid) coming from the validateResult + the outcome.AddIssue()
@@ -188,15 +188,15 @@ private ResultReport validateCode(IScopedNode source, Element bindable, Validati
ValidateCodeParameters buildParams()
{
- var parameters = new ValidateCodeParameters();
+ var vcp = new ValidateCodeParameters();
return bindable switch
{
- FhirString str => parameters.WithCode(str.Value, system: null, display: null, context: Context),
- FhirUri uri => parameters.WithCode(uri.Value, system: null, display: null, context: Context),
- Code co => parameters.WithCode(co.Value, system: null, display: null, context: Context),
- Coding cd => parameters.WithCoding(cd),
- CodeableConcept cc => parameters.WithCodeableConcept(cc),
+ FhirString str => vcp.WithCode(str.Value, system: null, display: null, context: Context),
+ FhirUri uri => vcp.WithCode(uri.Value, system: null, display: null, context: Context),
+ Code co => vcp.WithCode(co.Value, system: null, display: null, context: Context),
+ Coding cd => vcp.WithCoding(cd),
+ CodeableConcept cc => vcp.WithCodeableConcept(cc),
_ => throw Error.InvalidOperation($"Parsed bindable was of unexpected instance type '{bindable.TypeName}'.")
};
}
@@ -207,7 +207,7 @@ ValidateCodeParameters buildParams()
return result switch
{
(null, _) => ResultReport.SUCCESS,
- (Issue issue, var message) => new IssueAssertion(issue, message!).AsResult(s)
+ ({ } issue, var message) => new IssueAssertion(issue, message!).AsResult(s)
};
}
@@ -215,7 +215,7 @@ private static string buildCodingDisplay(ValidateCodeParameters p)
{
return p switch
{
- { Code: not null } code => "code " + codeToString(p.Code.Value, p.System?.Value),
+ { Code: not null } => "code " + codeToString(p.Code.Value, p.System?.Value),
{ Coding: { } coding } => "coding " + codeToString(coding.Code, coding.System),
{ CodeableConcept: { } cc } when !string.IsNullOrEmpty(cc.Text) => $"concept {cc.Text} with coding(s) {ccToString(cc)}",
{ CodeableConcept: { } cc } when string.IsNullOrEmpty(cc.Text) => $"concept with coding(s) {ccToString(cc)}",
@@ -239,8 +239,8 @@ public JToken ToJson()
var props = new JObject(new JProperty("abstractAllowed", AbstractAllowed));
if (Strength is not null)
props.Add(new JProperty("strength", Strength!.GetLiteral()));
- if (ValueSetUri is not null)
- props.Add(new JProperty("valueSet", (string)ValueSetUri));
+
+ props.Add(new JProperty("valueSet", (string)ValueSetUri));
return new JProperty("binding", props);
}
@@ -253,9 +253,9 @@ private static (Issue?, string?) interpretResults(Parameters parameters, string
return (result, message) switch
{
(true, null) => (null, null),
- (true, string) => (Issue.TERMINOLOGY_OUTPUT_WARNING, message),
+ (true, not null) => (Issue.TERMINOLOGY_OUTPUT_WARNING, message),
(false, null) => (Issue.TERMINOLOGY_OUTPUT_ERROR, display.Capitalize() + " is invalid, but the terminology service provided no further details."),
- (false, string) => (Issue.TERMINOLOGY_OUTPUT_ERROR, message)
+ (false, not null) => (Issue.TERMINOLOGY_OUTPUT_ERROR, message)
};
}
diff --git a/src/Firely.Fhir.Validation/Impl/ReferencedInstanceValidator.cs b/src/Firely.Fhir.Validation/Impl/ReferencedInstanceValidator.cs
index e4a4ead7..bce90b96 100644
--- a/src/Firely.Fhir.Validation/Impl/ReferencedInstanceValidator.cs
+++ b/src/Firely.Fhir.Validation/Impl/ReferencedInstanceValidator.cs
@@ -1,7 +1,7 @@
-/*
+/*
* Copyright (c) 2024, Firely (info@fire.ly) and contributors
* See the file CONTRIBUTORS for details.
- *
+ *
* This file is licensed under the BSD 3-Clause license
* available at https://github.com/FirelyTeam/firely-validator-api/blob/main/LICENSE
*/
@@ -13,6 +13,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.Serialization;
@@ -25,9 +26,9 @@ namespace Firely.Fhir.Validation
[DataContract]
[EditorBrowsable(EditorBrowsableState.Never)]
#if NET8_0_OR_GREATER
- [System.Diagnostics.CodeAnalysis.Experimental(diagnosticId: "ExperimentalApi")]
+ [Experimental(diagnosticId: "ExperimentalApi")]
#else
- [System.Obsolete("This function is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.")]
+ [Obsolete("This function is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.")]
#endif
public class ReferencedInstanceValidator : IValidatable
{
@@ -84,8 +85,9 @@ ResultReport IValidatable.Validate(IScopedNode input, ValidationSettings vc, Val
var reference = input.InstanceType switch
{
"Reference" => input.Children("reference").FirstOrDefault()?.Value as string,
+ "CodeableReference" => input.Children("reference").Children("reference").FirstOrDefault()?.Value as string,
"canonical" => input.Value as string,
- _ => throw new InvalidOperationException("Checking reference type should have been handled already.")
+ var unknown => throw new NotSupportedException($"Encountered unsupported reference type {unknown}.")
};
// It's ok for a reference to have no value (but, say, a description instead),
@@ -120,12 +122,12 @@ private record ResolutionResult(ITypedElement? ReferencedResource, AggregationMo
///
private (IReadOnlyCollection, ResolutionResult) fetchReference(IScopedNode input, string reference, ValidationSettings vc, ValidationState s)
{
- ResolutionResult resolution = new(null, null, null);
- List evidence = new();
-
- // First, try to resolve within this instance (in contained, Bundle.entry)
- evidence.Add(resolveLocally(input.ToScopedNode(), reference, s, out resolution));
-
+ List evidence =
+ [
+ // First, try to resolve within this instance (in contained, Bundle.entry)
+ resolveLocally(input.ToScopedNode(), reference, s, out var resolution)
+ ];
+
// Now that we have tried to fetch the reference locally, we have also determined the kind of
// reference we are dealing with, so check it for aggregation and versioning rules.
if (HasAggregation && AggregationRules?.Any(a => a == resolution.ReferenceKind) == false)
@@ -179,7 +181,7 @@ private static ResultReport resolveLocally(ScopedNode instance, string reference
resolution = new ResolutionResult(null, null, null);
var identity = new ResourceIdentity(reference);
- var (url, version, _) = new Canonical(reference);
+ var (_, version, _) = new Canonical(reference);
resolution = resolution with { VersioningKind = version is not null ? ReferenceVersionRules.Specific : ReferenceVersionRules.Independent };
if (identity.Form == ResourceIdentityForm.Undetermined)
@@ -240,7 +242,7 @@ private ResultReport validateReferencedResource(string reference, ValidationSett
///
public JToken ToJson()
{
- var result = new JObject()
+ var result = new JObject
{
new JProperty("schema", Schema.ToJson().MakeNestedProp())
};
@@ -254,8 +256,16 @@ public JToken ToJson()
}
///
- /// Whether this validator recognizes the given type as a reference type.
+ /// Whether this validator supports validating a given reference type.
+ ///
+ internal static bool IsSupportedReferenceType(string typeCode) =>
+ IsReferenceType(typeCode) && typeCode is not "canonical";
+
+ ///
+ /// Whether a type is a reference type.
///
- public static bool IsSupportedReferenceType(string typeCode) => typeCode is "Reference" or "CodeableReference";
+ ///
+ ///
+ internal static bool IsReferenceType(string typeCode) => typeCode is "Reference" or "CodeableReference" or "canonical";
}
}
diff --git a/src/Firely.Fhir.Validation/PublicAPI.Unshipped.txt b/src/Firely.Fhir.Validation/PublicAPI.Unshipped.txt
index 4e0acc69..c6cfb090 100644
--- a/src/Firely.Fhir.Validation/PublicAPI.Unshipped.txt
+++ b/src/Firely.Fhir.Validation/PublicAPI.Unshipped.txt
@@ -340,7 +340,6 @@ static Firely.Fhir.Validation.ExtensionSchema.GetExtensionUri(Firely.Fhir.Valida
static Firely.Fhir.Validation.FhirPathValidator.DefaultCompiler.get -> Hl7.FhirPath.FhirPathCompiler!
static Firely.Fhir.Validation.IssueAssertion.operator !=(Firely.Fhir.Validation.IssueAssertion? left, Firely.Fhir.Validation.IssueAssertion? right) -> bool
static Firely.Fhir.Validation.IssueAssertion.operator ==(Firely.Fhir.Validation.IssueAssertion? left, Firely.Fhir.Validation.IssueAssertion? right) -> bool
-static Firely.Fhir.Validation.ReferencedInstanceValidator.IsSupportedReferenceType(string! typeCode) -> bool
static Firely.Fhir.Validation.ResultReport.Combine(System.Collections.Generic.IReadOnlyCollection! reports) -> Firely.Fhir.Validation.ResultReport!
static Firely.Fhir.Validation.StructureDefinitionInformation.operator !=(Firely.Fhir.Validation.StructureDefinitionInformation? left, Firely.Fhir.Validation.StructureDefinitionInformation? right) -> bool
static Firely.Fhir.Validation.StructureDefinitionInformation.operator ==(Firely.Fhir.Validation.StructureDefinitionInformation? left, Firely.Fhir.Validation.StructureDefinitionInformation? right) -> bool
diff --git a/src/Firely.Fhir.Validation/Support/ScopedNodeExtensions.cs b/src/Firely.Fhir.Validation/Support/ScopedNodeExtensions.cs
index ef9f79ca..21d97aa2 100644
--- a/src/Firely.Fhir.Validation/Support/ScopedNodeExtensions.cs
+++ b/src/Firely.Fhir.Validation/Support/ScopedNodeExtensions.cs
@@ -67,7 +67,7 @@ internal static CodeableConcept ParseCodeableConcept(this IScopedNode instance)
#pragma warning disable CS0618 // Type or member is obsolete
=> instance.ParseCodeableConceptInternal();
#pragma warning restore CS0618 // Type or member is obsolete
-
+
///
/// Parses a bindeable type (code, Coding, CodeableConcept, Quantity, string, uri) into a FHIR coded datatype.
/// Extensions will be parsed from the 'value' of the (simple) extension.
@@ -84,36 +84,32 @@ internal static CodeableConcept ParseCodeableConcept(this IScopedNode instance)
/// 'string' => code
/// 'uri' => code
///
- internal static Element ParseBindable(this IScopedNode instance)
+ internal static Element? ParseBindable(this IScopedNode instance)
#pragma warning disable CS0618 // Type or member is obsolete
=> instance.ParseBindableInternal();
#pragma warning restore CS0618 // Type or member is obsolete
-
}
internal class ScopedNodeOnDictionary : IScopedNode
{
private readonly IReadOnlyDictionary _wrapped;
- private readonly IScopedNode? _parentNode;
private readonly ModelInspector _inspector;
- private readonly ClassMapping? _myClassMapping;
- private readonly string _name;
public ScopedNodeOnDictionary(ModelInspector inspector, string rootName, IReadOnlyDictionary wrapped, IScopedNode? parentNode = null)
{
- (_wrapped, _parentNode, _inspector, _name) = (wrapped, parentNode, inspector, rootName);
- _myClassMapping = _inspector.FindOrImportClassMapping(_wrapped.GetType());
- InstanceType = (_myClassMapping as IStructureDefinitionSummary)?.TypeName;
+ (_wrapped, Parent, _inspector, Name) = (wrapped, parentNode, inspector, rootName);
+ var myClassMapping = _inspector.FindOrImportClassMapping(_wrapped.GetType());
+ InstanceType = (myClassMapping as IStructureDefinitionSummary)?.TypeName;
}
- public IScopedNode? Parent => _parentNode;
+ public IScopedNode? Parent { get; }
- public string Name => _name;
+ public string Name { get; }
#pragma warning disable CS8766 // Nullability of reference types in return type doesn't match implicitly implemented member (possibly because of nullability attributes).
public string? InstanceType { get; private set; }
- public object? Value => _wrapped.TryGetValue("value", out var value) && isNETPrimitiveType(value) ? value : null;
+ public object? Value => _wrapped.TryGetValue("value", out var value) && isNetPrimitiveType(value) ? value : null;
#pragma warning restore CS8766 // Nullability of reference types in return type doesn't match implicitly implemented member (possibly because of nullability attributes).
public IEnumerable Children(string? name = null)
@@ -122,7 +118,7 @@ public IEnumerable Children(string? name = null)
{
not null =>
_wrapped.TryGetValue(name, out var value) && value is not null ?
- new KeyValuePair[] { KeyValuePair.Create(name, value) }
+ new[] { KeyValuePair.Create(name, value) }
: Enumerable.Empty>(),
_ => _wrapped
};
@@ -137,13 +133,13 @@ public IEnumerable Children(string? name = null)
}
else if (child.Value is IReadOnlyDictionary re)
yield return new ScopedNodeOnDictionary(_inspector, child.Key, re, this);
- else if (child.Key != "value" && isNETPrimitiveType(child.Value))
+ else if (child.Key != "value" && isNetPrimitiveType(child.Value))
yield return new ConstantElement(child.Key, child.Value.GetType().Name, child.Value, this);
}
}
- private bool isNETPrimitiveType(object a)
+ private static bool isNetPrimitiveType(object a)
=> a is string or bool or decimal or DateTimeOffset or int or long or byte[] or XHtml;
internal record ConstantElement(string Name, string InstanceType, object Value, IScopedNode Parent) : IScopedNode
diff --git a/test/Firely.Fhir.Validation.Compilation.Tests.R4/TestData/issue-165/fhirpkg.lock.json b/test/Firely.Fhir.Validation.Compilation.Tests.R4/TestData/issue-165/fhirpkg.lock.json
index d8f2804b..d558a044 100644
--- a/test/Firely.Fhir.Validation.Compilation.Tests.R4/TestData/issue-165/fhirpkg.lock.json
+++ b/test/Firely.Fhir.Validation.Compilation.Tests.R4/TestData/issue-165/fhirpkg.lock.json
@@ -1,5 +1,5 @@
{
- "updated": "2024-01-23T16:54:35.389115+01:00",
+ "updated": "2024-01-31T15:52:13.3434351+01:00",
"dependencies": {
"kbv.ita.erp": "1.0.2",
"hl7.fhir.r4.core": "4.0.1",
diff --git a/test/Firely.Fhir.Validation.Compilation.Tests.R5/SchemaSnaps/Composition.json b/test/Firely.Fhir.Validation.Compilation.Tests.R5/SchemaSnaps/Composition.json
index 4d5a1ab0..129ca932 100644
--- a/test/Firely.Fhir.Validation.Compilation.Tests.R5/SchemaSnaps/Composition.json
+++ b/test/Firely.Fhir.Validation.Compilation.Tests.R5/SchemaSnaps/Composition.json
@@ -556,6 +556,11 @@
},
"detail": {
"id": "#Composition.event.detail",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "example",
+ "valueSet": "http://terminology.hl7.org/ValueSet/v3-ActCode"
+ },
"FastInvariant-ele1": {},
"cardinality": "0..*",
"allOf": [
diff --git a/test/Firely.Fhir.Validation.Compilation.Tests.R5/SchemaSnaps/ProfiledEncounter.json b/test/Firely.Fhir.Validation.Compilation.Tests.R5/SchemaSnaps/ProfiledEncounter.json
new file mode 100644
index 00000000..36481ab1
--- /dev/null
+++ b/test/Firely.Fhir.Validation.Compilation.Tests.R5/SchemaSnaps/ProfiledEncounter.json
@@ -0,0 +1,1024 @@
+{
+ "id": "http://validationtest.org/fhir/StructureDefinition/ProfiledEncounterWithCodeableReference",
+ ".metadata": {
+ "schema-subtype": "resource",
+ "sd-info": {
+ "url": "http://validationtest.org/fhir/StructureDefinition/ProfiledEncounterWithCodeableReference",
+ "base": "http://hl7.org/fhir/StructureDefinition/Encounter,http://hl7.org/fhir/StructureDefinition/DomainResource,http://hl7.org/fhir/StructureDefinition/Resource,http://hl7.org/fhir/StructureDefinition/Base",
+ "datatype": "Encounter",
+ "abstract": false,
+ "derivation": "constraint"
+ }
+ },
+ "fhir-type-label": "Encounter",
+ "fhirPath-dom-2": {
+ "key": "dom-2",
+ "expression": "contained.contained.empty()",
+ "severity": "error",
+ "bestPractice": false,
+ "humanDescription": "If the resource is contained in another resource, it SHALL NOT contain nested Resources"
+ },
+ "fhirPath-dom-3": {
+ "key": "dom-3",
+ "expression": "contained.where((('#'+id in (%resource.descendants().reference | %resource.descendants().ofType(canonical) | %resource.descendants().ofType(uri) | %resource.descendants().ofType(url))) or descendants().where(reference = '#').exists() or descendants().where(ofType(canonical) = '#').exists() or descendants().where(ofType(canonical) = '#').exists()).not()).trace('unmatched', id).empty()",
+ "severity": "error",
+ "bestPractice": false,
+ "humanDescription": "If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource or SHALL refer to the containing resource"
+ },
+ "fhirPath-dom-4": {
+ "key": "dom-4",
+ "expression": "contained.meta.versionId.empty() and contained.meta.lastUpdated.empty()",
+ "severity": "error",
+ "bestPractice": false,
+ "humanDescription": "If a resource is contained in another resource, it SHALL NOT have a meta.versionId or a meta.lastUpdated"
+ },
+ "fhirPath-dom-5": {
+ "key": "dom-5",
+ "expression": "contained.meta.security.empty()",
+ "severity": "error",
+ "bestPractice": false,
+ "humanDescription": "If a resource is contained in another resource, it SHALL NOT have a security label"
+ },
+ "fhirPath-dom-6": {
+ "key": "dom-6",
+ "expression": "text.`div`.exists()",
+ "severity": "warning",
+ "bestPractice": true,
+ "humanDescription": "A resource should have narrative for robust management"
+ },
+ "children": {
+ "id": {
+ "id": "#Encounter.id",
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/id"
+ },
+ "meta": {
+ "id": "#Encounter.meta",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Meta"
+ },
+ "implicitRules": {
+ "id": "#Encounter.implicitRules",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/uri"
+ },
+ "language": {
+ "id": "#Encounter.language",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "required",
+ "valueSet": "http://hl7.org/fhir/ValueSet/all-languages|5.0.0"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/code"
+ },
+ "text": {
+ "id": "#Encounter.text",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Narrative"
+ },
+ "contained": {
+ "id": "#Encounter.contained",
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Resource"
+ },
+ "extension": {
+ "id": "#Encounter.extension",
+ "FastInvariant-ele1": {},
+ "FastInvariant-ext1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Extension"
+ },
+ "modifierExtension": {
+ "id": "#Encounter.modifierExtension",
+ "FastInvariant-ele1": {},
+ "FastInvariant-ext1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Extension"
+ },
+ "identifier": {
+ "id": "#Encounter.identifier",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Identifier"
+ },
+ "status": {
+ "id": "#Encounter.status",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "required",
+ "valueSet": "http://hl7.org/fhir/ValueSet/encounter-status|5.0.0"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "1..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/code"
+ },
+ "class": {
+ "id": "#Encounter.class",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "preferred",
+ "valueSet": "http://terminology.hl7.org/ValueSet/encounter-class"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ },
+ "priority": {
+ "id": "#Encounter.priority",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "example",
+ "valueSet": "http://terminology.hl7.org/ValueSet/v3-ActPriority"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ },
+ "type": {
+ "id": "#Encounter.type",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "example",
+ "valueSet": "http://hl7.org/fhir/ValueSet/encounter-type"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ },
+ "serviceType": {
+ "id": "#Encounter.serviceType",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "preferred",
+ "valueSet": "http://example.org/fhir/ValueSet"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableReference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "ref": "http://validationtest.org/fhir/StructureDefinition/ProfiledOrg1"
+ }
+ }
+ }
+ ]
+ },
+ "subject": {
+ "id": "#Encounter.subject",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Reference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "slice": {
+ "ordered": false,
+ "defaultAtEnd": false,
+ "case": [
+ {
+ "name": "forPatient",
+ "condition": {
+ "fhir-type-label": "Patient"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Patient"
+ }
+ },
+ {
+ "name": "forGroup",
+ "condition": {
+ "fhir-type-label": "Group"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Group"
+ }
+ }
+ ],
+ "default": {
+ "issue": {
+ "issueNumber": 1011,
+ "severity": "Error",
+ "message": "Referenced resource '%RESOURCEURL%' does not validate against any of the expected target profiles (http://hl7.org/fhir/StructureDefinition/Patient, http://hl7.org/fhir/StructureDefinition/Group). None of these are profiles on type %INSTANCETYPE% of the resource.",
+ "type": "Invalid"
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ },
+ "subjectStatus": {
+ "id": "#Encounter.subjectStatus",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "example",
+ "valueSet": "http://hl7.org/fhir/ValueSet/encounter-subject-status"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ },
+ "episodeOfCare": {
+ "id": "#Encounter.episodeOfCare",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Reference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/EpisodeOfCare"
+ }
+ }
+ }
+ ]
+ },
+ "basedOn": {
+ "id": "#Encounter.basedOn",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Reference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "slice": {
+ "ordered": false,
+ "defaultAtEnd": false,
+ "case": [
+ {
+ "name": "forCarePlan",
+ "condition": {
+ "fhir-type-label": "CarePlan"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/CarePlan"
+ }
+ },
+ {
+ "name": "forDeviceRequest",
+ "condition": {
+ "fhir-type-label": "DeviceRequest"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/DeviceRequest"
+ }
+ },
+ {
+ "name": "forMedicationRequest",
+ "condition": {
+ "fhir-type-label": "MedicationRequest"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/MedicationRequest"
+ }
+ },
+ {
+ "name": "forServiceRequest",
+ "condition": {
+ "fhir-type-label": "ServiceRequest"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/ServiceRequest"
+ }
+ }
+ ],
+ "default": {
+ "issue": {
+ "issueNumber": 1011,
+ "severity": "Error",
+ "message": "Referenced resource '%RESOURCEURL%' does not validate against any of the expected target profiles (http://hl7.org/fhir/StructureDefinition/CarePlan, http://hl7.org/fhir/StructureDefinition/DeviceRequest, http://hl7.org/fhir/StructureDefinition/MedicationRequest, http://hl7.org/fhir/StructureDefinition/ServiceRequest). None of these are profiles on type %INSTANCETYPE% of the resource.",
+ "type": "Invalid"
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ },
+ "careTeam": {
+ "id": "#Encounter.careTeam",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Reference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/CareTeam"
+ }
+ }
+ }
+ ]
+ },
+ "partOf": {
+ "id": "#Encounter.partOf",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Reference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Encounter"
+ }
+ }
+ }
+ ]
+ },
+ "serviceProvider": {
+ "id": "#Encounter.serviceProvider",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Reference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Organization"
+ }
+ }
+ }
+ ]
+ },
+ "participant": {
+ "id": "#Encounter.participant",
+ "FastInvariant-ele1": {},
+ "fhirPath-enc-1": {
+ "key": "enc-1",
+ "expression": "actor.exists() or type.exists()",
+ "severity": "error",
+ "bestPractice": false,
+ "humanDescription": "A type must be provided when no explicit actor is specified"
+ },
+ "fhirPath-enc-2": {
+ "key": "enc-2",
+ "expression": "actor.exists(resolve() is Patient or resolve() is Group) implies type.exists().not()",
+ "severity": "error",
+ "bestPractice": false,
+ "humanDescription": "A type cannot be provided for a patient or group participant"
+ },
+ "cardinality": "0..*",
+ "children": {
+ "id": {
+ "id": "#Encounter.participant.id",
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhirpath/System.String"
+ },
+ "extension": {
+ "id": "#Encounter.participant.extension",
+ "FastInvariant-ele1": {},
+ "FastInvariant-ext1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Extension"
+ },
+ "modifierExtension": {
+ "id": "#Encounter.participant.modifierExtension",
+ "FastInvariant-ele1": {},
+ "FastInvariant-ext1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Extension"
+ },
+ "type": {
+ "id": "#Encounter.participant.type",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "extensible",
+ "valueSet": "http://hl7.org/fhir/ValueSet/encounter-participant-type"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ },
+ "period": {
+ "id": "#Encounter.participant.period",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Period"
+ },
+ "actor": {
+ "id": "#Encounter.participant.actor",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Reference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "slice": {
+ "ordered": false,
+ "defaultAtEnd": false,
+ "case": [
+ {
+ "name": "forPatient",
+ "condition": {
+ "fhir-type-label": "Patient"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Patient"
+ }
+ },
+ {
+ "name": "forGroup",
+ "condition": {
+ "fhir-type-label": "Group"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Group"
+ }
+ },
+ {
+ "name": "forRelatedPerson",
+ "condition": {
+ "fhir-type-label": "RelatedPerson"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/RelatedPerson"
+ }
+ },
+ {
+ "name": "forPractitioner",
+ "condition": {
+ "fhir-type-label": "Practitioner"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Practitioner"
+ }
+ },
+ {
+ "name": "forPractitionerRole",
+ "condition": {
+ "fhir-type-label": "PractitionerRole"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/PractitionerRole"
+ }
+ },
+ {
+ "name": "forDevice",
+ "condition": {
+ "fhir-type-label": "Device"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Device"
+ }
+ },
+ {
+ "name": "forHealthcareService",
+ "condition": {
+ "fhir-type-label": "HealthcareService"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/HealthcareService"
+ }
+ }
+ ],
+ "default": {
+ "issue": {
+ "issueNumber": 1011,
+ "severity": "Error",
+ "message": "Referenced resource '%RESOURCEURL%' does not validate against any of the expected target profiles (http://hl7.org/fhir/StructureDefinition/Patient, http://hl7.org/fhir/StructureDefinition/Group, http://hl7.org/fhir/StructureDefinition/RelatedPerson, http://hl7.org/fhir/StructureDefinition/Practitioner, http://hl7.org/fhir/StructureDefinition/PractitionerRole, http://hl7.org/fhir/StructureDefinition/Device, http://hl7.org/fhir/StructureDefinition/HealthcareService). None of these are profiles on type %INSTANCETYPE% of the resource.",
+ "type": "Invalid"
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ "appointment": {
+ "id": "#Encounter.appointment",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Reference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Appointment"
+ }
+ }
+ }
+ ]
+ },
+ "virtualService": {
+ "id": "#Encounter.virtualService",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/VirtualServiceDetail"
+ },
+ "actualPeriod": {
+ "id": "#Encounter.actualPeriod",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Period"
+ },
+ "plannedStartDate": {
+ "id": "#Encounter.plannedStartDate",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/dateTime"
+ },
+ "plannedEndDate": {
+ "id": "#Encounter.plannedEndDate",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/dateTime"
+ },
+ "length": {
+ "id": "#Encounter.length",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Duration"
+ },
+ "reason": {
+ "id": "#Encounter.reason",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "children": {
+ "id": {
+ "id": "#Encounter.reason.id",
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhirpath/System.String"
+ },
+ "extension": {
+ "id": "#Encounter.reason.extension",
+ "FastInvariant-ele1": {},
+ "FastInvariant-ext1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Extension"
+ },
+ "modifierExtension": {
+ "id": "#Encounter.reason.modifierExtension",
+ "FastInvariant-ele1": {},
+ "FastInvariant-ext1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Extension"
+ },
+ "use": {
+ "id": "#Encounter.reason.use",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "example",
+ "valueSet": "http://hl7.org/fhir/ValueSet/encounter-reason-use"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ },
+ "value": {
+ "id": "#Encounter.reason.value",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "preferred",
+ "valueSet": "http://hl7.org/fhir/ValueSet/encounter-reason"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableReference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "slice": {
+ "ordered": false,
+ "defaultAtEnd": false,
+ "case": [
+ {
+ "name": "forCondition",
+ "condition": {
+ "fhir-type-label": "Condition"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Condition"
+ }
+ },
+ {
+ "name": "forDiagnosticReport",
+ "condition": {
+ "fhir-type-label": "DiagnosticReport"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/DiagnosticReport"
+ }
+ },
+ {
+ "name": "forObservation",
+ "condition": {
+ "fhir-type-label": "Observation"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Observation"
+ }
+ },
+ {
+ "name": "forImmunizationRecommendation",
+ "condition": {
+ "fhir-type-label": "ImmunizationRecommendation"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/ImmunizationRecommendation"
+ }
+ },
+ {
+ "name": "forProcedure",
+ "condition": {
+ "fhir-type-label": "Procedure"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Procedure"
+ }
+ }
+ ],
+ "default": {
+ "issue": {
+ "issueNumber": 1011,
+ "severity": "Error",
+ "message": "Referenced resource '%RESOURCEURL%' does not validate against any of the expected target profiles (http://hl7.org/fhir/StructureDefinition/Condition, http://hl7.org/fhir/StructureDefinition/DiagnosticReport, http://hl7.org/fhir/StructureDefinition/Observation, http://hl7.org/fhir/StructureDefinition/ImmunizationRecommendation, http://hl7.org/fhir/StructureDefinition/Procedure). None of these are profiles on type %INSTANCETYPE% of the resource.",
+ "type": "Invalid"
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ "diagnosis": {
+ "id": "#Encounter.diagnosis",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "children": {
+ "id": {
+ "id": "#Encounter.diagnosis.id",
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhirpath/System.String"
+ },
+ "extension": {
+ "id": "#Encounter.diagnosis.extension",
+ "FastInvariant-ele1": {},
+ "FastInvariant-ext1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Extension"
+ },
+ "modifierExtension": {
+ "id": "#Encounter.diagnosis.modifierExtension",
+ "FastInvariant-ele1": {},
+ "FastInvariant-ext1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Extension"
+ },
+ "condition": {
+ "id": "#Encounter.diagnosis.condition",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "example",
+ "valueSet": "http://hl7.org/fhir/ValueSet/condition-code"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableReference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Condition"
+ }
+ }
+ }
+ ]
+ },
+ "use": {
+ "id": "#Encounter.diagnosis.use",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "preferred",
+ "valueSet": "http://hl7.org/fhir/ValueSet/encounter-diagnosis-use"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ }
+ }
+ },
+ "account": {
+ "id": "#Encounter.account",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Reference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Account"
+ }
+ }
+ }
+ ]
+ },
+ "dietPreference": {
+ "id": "#Encounter.dietPreference",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "example",
+ "valueSet": "http://hl7.org/fhir/ValueSet/encounter-diet"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ },
+ "specialArrangement": {
+ "id": "#Encounter.specialArrangement",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "preferred",
+ "valueSet": "http://hl7.org/fhir/ValueSet/encounter-special-arrangements"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ },
+ "specialCourtesy": {
+ "id": "#Encounter.specialCourtesy",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "preferred",
+ "valueSet": "http://hl7.org/fhir/ValueSet/encounter-special-courtesy"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ },
+ "admission": {
+ "id": "#Encounter.admission",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "children": {
+ "id": {
+ "id": "#Encounter.admission.id",
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhirpath/System.String"
+ },
+ "extension": {
+ "id": "#Encounter.admission.extension",
+ "FastInvariant-ele1": {},
+ "FastInvariant-ext1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Extension"
+ },
+ "modifierExtension": {
+ "id": "#Encounter.admission.modifierExtension",
+ "FastInvariant-ele1": {},
+ "FastInvariant-ext1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Extension"
+ },
+ "preAdmissionIdentifier": {
+ "id": "#Encounter.admission.preAdmissionIdentifier",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Identifier"
+ },
+ "origin": {
+ "id": "#Encounter.admission.origin",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Reference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "slice": {
+ "ordered": false,
+ "defaultAtEnd": false,
+ "case": [
+ {
+ "name": "forLocation",
+ "condition": {
+ "fhir-type-label": "Location"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Location"
+ }
+ },
+ {
+ "name": "forOrganization",
+ "condition": {
+ "fhir-type-label": "Organization"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Organization"
+ }
+ }
+ ],
+ "default": {
+ "issue": {
+ "issueNumber": 1011,
+ "severity": "Error",
+ "message": "Referenced resource '%RESOURCEURL%' does not validate against any of the expected target profiles (http://hl7.org/fhir/StructureDefinition/Location, http://hl7.org/fhir/StructureDefinition/Organization). None of these are profiles on type %INSTANCETYPE% of the resource.",
+ "type": "Invalid"
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ },
+ "admitSource": {
+ "id": "#Encounter.admission.admitSource",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "preferred",
+ "valueSet": "http://hl7.org/fhir/ValueSet/encounter-admit-source"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ },
+ "reAdmission": {
+ "id": "#Encounter.admission.reAdmission",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "example",
+ "valueSet": "http://terminology.hl7.org/ValueSet/v2-0092"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ },
+ "destination": {
+ "id": "#Encounter.admission.destination",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Reference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "slice": {
+ "ordered": false,
+ "defaultAtEnd": false,
+ "case": [
+ {
+ "name": "forLocation",
+ "condition": {
+ "fhir-type-label": "Location"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Location"
+ }
+ },
+ {
+ "name": "forOrganization",
+ "condition": {
+ "fhir-type-label": "Organization"
+ },
+ "assertion": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Organization"
+ }
+ }
+ ],
+ "default": {
+ "issue": {
+ "issueNumber": 1011,
+ "severity": "Error",
+ "message": "Referenced resource '%RESOURCEURL%' does not validate against any of the expected target profiles (http://hl7.org/fhir/StructureDefinition/Location, http://hl7.org/fhir/StructureDefinition/Organization). None of these are profiles on type %INSTANCETYPE% of the resource.",
+ "type": "Invalid"
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ },
+ "dischargeDisposition": {
+ "id": "#Encounter.admission.dischargeDisposition",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "example",
+ "valueSet": "http://hl7.org/fhir/ValueSet/encounter-discharge-disposition"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ }
+ }
+ },
+ "location": {
+ "id": "#Encounter.location",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..*",
+ "children": {
+ "id": {
+ "id": "#Encounter.location.id",
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhirpath/System.String"
+ },
+ "extension": {
+ "id": "#Encounter.location.extension",
+ "FastInvariant-ele1": {},
+ "FastInvariant-ext1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Extension"
+ },
+ "modifierExtension": {
+ "id": "#Encounter.location.modifierExtension",
+ "FastInvariant-ele1": {},
+ "FastInvariant-ext1": {},
+ "cardinality": "0..*",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Extension"
+ },
+ "location": {
+ "id": "#Encounter.location.location",
+ "FastInvariant-ele1": {},
+ "cardinality": "1..1",
+ "allOf": [
+ {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Reference"
+ },
+ {
+ "validate": {
+ "schema": {
+ "ref": "http://hl7.org/fhir/StructureDefinition/Location"
+ }
+ }
+ }
+ ]
+ },
+ "status": {
+ "id": "#Encounter.location.status",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "required",
+ "valueSet": "http://hl7.org/fhir/ValueSet/encounter-location-status|5.0.0"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/code"
+ },
+ "form": {
+ "id": "#Encounter.location.form",
+ "binding": {
+ "abstractAllowed": true,
+ "strength": "example",
+ "valueSet": "http://hl7.org/fhir/ValueSet/location-form"
+ },
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/CodeableConcept"
+ },
+ "period": {
+ "id": "#Encounter.location.period",
+ "FastInvariant-ele1": {},
+ "cardinality": "0..1",
+ "ref": "http://hl7.org/fhir/StructureDefinition/Period"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTests/ValidationManifestTest.cs b/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTests/ValidationManifestTest.cs
index 9ef4f21f..71d1050a 100644
--- a/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTests/ValidationManifestTest.cs
+++ b/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTests/ValidationManifestTest.cs
@@ -43,6 +43,7 @@ public void RunSingleTest(TestCase testCase, string baseDirectory)
/// the single testcase to run
/// the base directory of the testcase
[DataTestMethod]
+ [TestCategory("LongRunner")]
[ValidationManifestDataSource(TEST_CASES_MANIFEST)]
public void RunFirelySdkTests(TestCase testCase, string baseDirectory)
=> _runner.RunTestCase(testCase, DotNetValidator.Create(), baseDirectory, AssertionOptions.OutputTextAssertion);
diff --git a/test/Firely.Fhir.Validation.Compilation.Tests.Shared/TestProfileArtifactSource.cs b/test/Firely.Fhir.Validation.Compilation.Tests.Shared/TestProfileArtifactSource.cs
index a27797c0..638f1a7f 100644
--- a/test/Firely.Fhir.Validation.Compilation.Tests.Shared/TestProfileArtifactSource.cs
+++ b/test/Firely.Fhir.Validation.Compilation.Tests.Shared/TestProfileArtifactSource.cs
@@ -36,6 +36,8 @@ internal class TestProfileArtifactSource : IResourceResolver
public const string PROFILEDORG2 = "http://validationtest.org/fhir/StructureDefinition/ProfiledOrg2";
public const string PROFILEDPROCEDURE = "http://validationtest.org/fhir/StructureDefinition/ProfiledProcedure";
public const string PROFILEDFLAG = "http://validationtest.org/fhir/StructureDefinition/ProfiledFlag";
+ public const string PROFILEDENCOUNTER =
+ "http://validationtest.org/fhir/StructureDefinition/ProfiledEncounterWithCodeableReference";
public const string PROFILEDBOOL = "http://validationtest.org/fhir/StructureDefinition/booleanProfile";
public const string PROFILEDSTRING = "http://validationtest.org/fhir/StructureDefinition/stringProfile";
@@ -43,17 +45,15 @@ internal class TestProfileArtifactSource : IResourceResolver
public const string BUNDLEWITHCONSTRAINEDCONTAINED = "http://validationtest.org/fhir/StructureDefinition/BundleWithConstrainedContained";
- public List TestProfiles = new()
- {
- // The next two test cases should produce the same outcome, since value and pattern
- // discriminators have been merged (at least, in R5).
+ public List TestProfiles =
+ [
buildValueOrPatternSliceTestcase(PATTERNSLICETESTCASE),
buildValueOrPatternSliceTestcase(VALUESLICETESTCASE),
buildValueOrPatternSliceTestcase(VALUESLICETESTCASEWITHDEFAULT),
buildValueOrPatternSliceTestcase(VALUESLICETESTCASEOPEN),
buildValueOrPatternSliceTestcase(DISCRIMINATORLESS),
buildTypeAndProfileSlice(),
- // buildTypeRenameSlicing(),
+ // buildTypeRenameSlicing(),
buildReferencedTypeAndProfileSlice(),
buildSliceWithSecondaryTargetReferenceDiscriminator(),
buildExistSliceTestcase(),
@@ -61,15 +61,35 @@ internal class TestProfileArtifactSource : IResourceResolver
buildIncompatibleCardinalityInIntro(),
buildProfiledBackboneAndContentref(),
buildObservationWithTargetProfilesAndChildDefs(),
- createTestSD(PROFILEDORG1, "NoopOrgProfile1", "A noop profile for an organization 1", FHIRAllTypes.Organization),
- createTestSD(PROFILEDORG2, "NoopOrgProfile2", "A noop profile for an organization 2", FHIRAllTypes.Organization),
- createTestSD(PROFILEDPROCEDURE, "NoopProcProfile", "A noop profile for a procedure", FHIRAllTypes.Procedure),
+ createTestSD(PROFILEDORG1, "NoopOrgProfile1", "A noop profile for an organization 1",
+ FHIRAllTypes.Organization),
+ createTestSD(PROFILEDORG2, "NoopOrgProfile2", "A noop profile for an organization 2",
+ FHIRAllTypes.Organization),
+ createTestSD(PROFILEDPROCEDURE, "NoopProcProfile", "A noop profile for a procedure",
+ FHIRAllTypes.Procedure),
buildFlagWithProfiledReferences(),
createTestSD(PROFILEDSTRING, "NoopStringProfile", "A noop profile for a string", FHIRAllTypes.String),
createTestSD(PROFILEDBOOL, "NoopBoolProfile", "A noop profile for a bool", FHIRAllTypes.Boolean),
buildPatientWithProfiledReferences(),
- bundleWithConstrainedContained()
- };
+ bundleWithConstrainedContained(),
+ buildProfiledEncounter()
+ ];
+
+ private static StructureDefinition buildProfiledEncounter()
+ {
+ var result = createTestSD(PROFILEDENCOUNTER, "ProfiledEncounterWithCodeableReference",
+ "An Encounter profile hat profiles a CodeableReference (in R5)", FHIRAllTypes.Encounter);
+ var cons = result.Differential.Element;
+
+ var crElementDef = new ElementDefinition("Encounter.serviceType")
+ .OfReference(new[] { PROFILEDORG1 })
+ .WithBinding("http://example.org/fhir/ValueSet", BindingStrength.Preferred);
+ crElementDef.Type.Single().Code = "CodeableReference"; // Will have been set to Reference by OfReference
+
+ cons.Add(crElementDef);
+ return result;
+
+ }
private static StructureDefinition buildFlagWithProfiledReferences()
{
diff --git a/test/Firely.Fhir.Validation.Tests/Firely.Fhir.Validation.Tests.csproj b/test/Firely.Fhir.Validation.Tests/Firely.Fhir.Validation.Tests.csproj
index 6c757911..5cf188dd 100644
--- a/test/Firely.Fhir.Validation.Tests/Firely.Fhir.Validation.Tests.csproj
+++ b/test/Firely.Fhir.Validation.Tests/Firely.Fhir.Validation.Tests.csproj
@@ -8,7 +8,8 @@
-
+
+
diff --git a/test/Firely.Fhir.Validation.Tests/Impl/BindingValidatorTests.cs b/test/Firely.Fhir.Validation.Tests/Impl/BindingValidatorTests.cs
index cc8bb797..9298721e 100644
--- a/test/Firely.Fhir.Validation.Tests/Impl/BindingValidatorTests.cs
+++ b/test/Firely.Fhir.Validation.Tests/Impl/BindingValidatorTests.cs
@@ -15,8 +15,8 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
+using System.Collections.Generic;
using System.Linq;
-using static Firely.Fhir.Validation.ValidationSettings;
using Assert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
namespace Firely.Fhir.Validation.Tests
@@ -55,40 +55,7 @@ public void ValidateTest()
var input = ElementNode.ForPrimitive(true);
_ = _bindingAssertion.Validate(input, _validationSettingsM);
}
-
- private static ITypedElement createCoding(string system, string code, string? display = null)
- {
- var codingValue = ElementNodeAdapter.Root("Coding");
- codingValue.Add("system", system, "uri");
- codingValue.Add("code", code, "string");
- if (display is not null)
- codingValue.Add("display", display, "string");
-
- return codingValue;
- }
-
-
- private static ITypedElement createConcept(ITypedElement[] coding, string? text = null)
- {
- var conceptValue = ElementNodeAdapter.Root("CodeableConcept");
-
- foreach (var item in coding)
- {
- conceptValue.Add(item, "coding");
- }
- if (text is not null)
- conceptValue.Add("text", text, "string");
- return conceptValue;
- }
-
- private static ITypedElement createQuantity(decimal value, string unit)
- {
- var quantityValue = ElementNodeAdapter.Root("Quantity");
- quantityValue.Add("value", value);
- quantityValue.Add("code", unit);
- return quantityValue;
- }
-
+
private void setup(bool success, string? message)
{
var result = new Parameters
@@ -109,8 +76,8 @@ private void setup(Exception e)
private void verify(Predicate pred)
{
- _validateCodeService.Verify(p =>
- p.ValueSetValidateCode(It.Is(p => pred(new ValidateCodeParameters(p))),
+ _validateCodeService.Verify(svc =>
+ svc.ValueSetValidateCode(It.Is(p => pred(new ValidateCodeParameters(p))),
It.IsAny(), It.IsAny()), Times.Once);
}
@@ -131,7 +98,7 @@ public void ValidateWithCode()
public void ValidateWithUri()
{
setup(true, null);
- var input = ElementNodeAdapter.Root("uri", value: "http://some.uri");
+ var input = new FhirUri("http://some.uri").ToTypedElement();
var result = _bindingAssertion.Validate(input, _validationSettingsM);
@@ -156,7 +123,7 @@ public void ValidateWithCoding()
{
setup(true, null);
- var input = createCoding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "masked");
+ var input = new Coding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "masked").ToTypedElement();
var result = _bindingAssertion.Validate(input, _validationSettingsM);
Assert.IsTrue(result.IsSuccessful);
@@ -167,11 +134,7 @@ public void ValidateWithCoding()
public void ValidateWithCodeableConcept()
{
setup(true, null);
- var codings = new[] { createCoding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "masked") ,
- createCoding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "masked")};
-
- var input = createConcept(codings);
-
+ var input = new CodeableConcept("http://terminology.hl7.org/CodeSystem/data-absent-reason", "masked").ToTypedElement();
var result = _bindingAssertion.Validate(input, _validationSettingsM);
Assert.IsTrue(result.IsSuccessful);
@@ -183,13 +146,27 @@ public void ValidateWithQuantity()
{
setup(true, null);
- var input = createQuantity(25, "s");
+ var input = new Quantity(25, "s").ToTypedElement();
var result = _bindingAssertion.Validate(input, _validationSettingsM);
Assert.IsTrue(result.IsSuccessful);
verify(ts => ts.Coding.IsExactly(new Coding("http://unitsofmeasure.org", "s")));
}
+ [TestMethod]
+ public void ValidateWithCodeableReference()
+ {
+ setup(true, null);
+
+ var inputCc = new CodeableConcept("http://terminology.hl7.org/CodeSystem/data-absent-reason", "masked");
+ var inputRef = new ResourceReference("http://some.uri");
+ var inputCr = new CodeableReference { Concept = inputCc, Reference = inputRef };
+ var result = _bindingAssertion.Validate(inputCr.ToTypedElement(), _validationSettingsM);
+
+ Assert.IsTrue(result.IsSuccessful);
+ verify(ts => ts.CodeableConcept.Coding.Single().IsExactly(new Coding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "masked")));
+ }
+
[TestMethod]
public void ValidateEmptyString()
{
@@ -203,10 +180,7 @@ public void ValidateEmptyString()
[TestMethod]
public void ValidateCodingWithoutCode()
{
-#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
- var input = createCoding("system", null, null);
-#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
-
+ var input = new Coding().ToTypedElement();
var result = _bindingAssertion.Validate(input, _validationSettingsM);
Assert.IsFalse(result.IsSuccessful);
@@ -218,7 +192,7 @@ public void ValidateInvalidCoding()
{
setup(false, "Not found");
- var input = createCoding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "UNKNOWN");
+ var input = new Coding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "UNKNOWN").ToTypedElement();
var result = _bindingAssertion.Validate(input, _validationSettingsM);
Assert.IsFalse(result.IsSuccessful);
@@ -230,7 +204,7 @@ public void ValidateWithUnreachableTerminologyServer()
{
setup(new FhirOperationException("Dummy", System.Net.HttpStatusCode.NotFound));
- var input = createCoding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "UNKNOWN");
+ var input = new Coding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "UNKNOWN").ToTypedElement();
var result = _bindingAssertion.Validate(input, _validationSettingsM);
result.Warnings.Should().OnlyContain(w => w.IssueNumber == Issue.TERMINOLOGY_OUTPUT_WARNING.Code);
@@ -244,13 +218,13 @@ public void ValidateCodeWithUnreachableTerminologyServerAndUserIntervention()
var validationSettings = ValidationSettings.BuildMinimalContext(_validateCodeService.Object);
validationSettings.HandleValidateCodeServiceFailure = userIntervention;
- var input = createCoding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "UNKNOWN");
+ var input = new Coding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "UNKNOWN").ToTypedElement();
var result = _bindingAssertion.Validate(input, validationSettings);
result.Warnings.Should().OnlyContain(w => w.IssueNumber == Issue.TERMINOLOGY_OUTPUT_WARNING.Code);
result.Errors.Should().BeEmpty();
- input = createCoding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "ERROR");
+ input = new Coding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "ERROR").ToTypedElement();
result = _bindingAssertion.Validate(input, validationSettings);
result.Warnings.Should().BeEmpty();
@@ -267,12 +241,14 @@ public void ValidateConceptWithUnreachableTerminologyServerAndUserIntervention()
var validationSettings = ValidationSettings.BuildMinimalContext(_validateCodeService.Object);
validationSettings.HandleValidateCodeServiceFailure = userIntervention;
- var codings = new[] {
- createCoding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "masked") ,
- createCoding("http://terminology.hl7.org/CodeSystem/data-absent-reason", "error")};
- var input = createConcept(codings);
+ var codings = new List {
+ new("http://terminology.hl7.org/CodeSystem/data-absent-reason", "masked") ,
+ new("http://terminology.hl7.org/CodeSystem/data-absent-reason", "error")};
+ var input = new CodeableConcept { Coding = codings }.ToTypedElement();
var result = _bindingAssertion.Validate(input, validationSettings);
+ Assert.IsFalse(result.IsSuccessful);
+ return;
static TerminologyServiceExceptionResult userIntervention(ValidateCodeParameters p, FhirOperationException e)
=> p.CodeableConcept.Coding.Last().Code.EndsWith("error") ? TerminologyServiceExceptionResult.Error : TerminologyServiceExceptionResult.Warning;
@@ -282,16 +258,16 @@ static TerminologyServiceExceptionResult userIntervention(ValidateCodeParameters
public void ExceptionMessageTest()
{
setup(new FhirOperationException("Dummy message", System.Net.HttpStatusCode.NotFound));
- var ValidationSettings = BuildMinimalContext(_validateCodeService.Object);
+ var validationSettings = ValidationSettings.BuildMinimalContext(_validateCodeService.Object);
var inputWithoutSystem = ElementNodeAdapter.Root("Coding");
inputWithoutSystem.Add("code", "aCode", "string");
- var result = _bindingAssertion.Validate(inputWithoutSystem, ValidationSettings);
+ var result = _bindingAssertion.Validate(inputWithoutSystem, validationSettings);
result.Warnings.Should().OnlyContain(w => w.Message.StartsWith("Terminology service failed while validating coding 'aCode': Dummy message"));
- var inputWithSystem = createCoding("aSystem", "aCode");
- result = _bindingAssertion.Validate(inputWithSystem, ValidationSettings);
+ var inputWithSystem = new Coding("aSystem", "aCode").ToTypedElement();
+ result = _bindingAssertion.Validate(inputWithSystem, validationSettings);
result.Warnings.Should().OnlyContain(w => w.Message.StartsWith("Terminology service failed while validating coding 'aCode' (system 'aSystem'): Dummy message"));
}
}
diff --git a/test/Firely.Fhir.Validation.Tests/Impl/CircularReferenceTests.cs b/test/Firely.Fhir.Validation.Tests/Impl/CircularReferenceTests.cs
index 879bf3b8..f3a3497a 100644
--- a/test/Firely.Fhir.Validation.Tests/Impl/CircularReferenceTests.cs
+++ b/test/Firely.Fhir.Validation.Tests/Impl/CircularReferenceTests.cs
@@ -35,14 +35,14 @@ public void CircularInReferencedResources()
resourceType = "Patient",
id = "http://example.com/pat1",
other = new { _type = "Reference", reference = "http://example.com/pat2" }
- }.ToTypedElement();
+ }.DictionaryToTypedElement();
var pat2 = new
{
resourceType = "Patient",
id = "http://example.com/pat2",
other = new { _type = "Reference", reference = "http://example.com/pat1" }
- }.ToTypedElement();
+ }.DictionaryToTypedElement();
var resolver = new TestResolver() { SCHEMA };
var vc = ValidationSettings.BuildMinimalContext(schemaResolver: resolver);
@@ -87,7 +87,7 @@ public void CircularInContainedResources()
}
};
- var result = test(SCHEMA, pat.ToTypedElement("Patient"));
+ var result = test(SCHEMA, pat.DictionaryToTypedElement("Patient"));
result.IsSuccessful.Should().BeTrue();
result.Evidence.Should().Contain(ass => (ass as IssueAssertion)!.IssueNumber == Issue.CONTENT_REFERENCE_CYCLE_DETECTED.Code);
}
@@ -114,7 +114,7 @@ public void MultipleReferencesToResource()
}
};
- var result = test(SCHEMA, pat.ToTypedElement("Patient"));
+ var result = test(SCHEMA, pat.DictionaryToTypedElement("Patient"));
result.IsSuccessful.Should().BeTrue();
}
diff --git a/test/Firely.Fhir.Validation.Tests/Impl/ReferencedInstanceValidatorTests.cs b/test/Firely.Fhir.Validation.Tests/Impl/ReferencedInstanceValidatorTests.cs
index b380d2f2..ee1788fb 100644
--- a/test/Firely.Fhir.Validation.Tests/Impl/ReferencedInstanceValidatorTests.cs
+++ b/test/Firely.Fhir.Validation.Tests/Impl/ReferencedInstanceValidatorTests.cs
@@ -7,7 +7,9 @@
*/
using Hl7.Fhir.ElementModel;
+using Hl7.Fhir.Model;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
using System.Collections.Generic;
using System.Linq;
@@ -17,38 +19,35 @@ namespace Firely.Fhir.Validation.Tests
public class ReferencedInstanceValidatorTests : BasicValidatorDataAttribute
{
private static readonly ElementSchema SCHEMA = new("http://fixedschema",
- new IssueAssertion(0, "Validation was triggered", Hl7.Fhir.Model.OperationOutcome.IssueSeverity.Information));
+ new IssueAssertion(0, "Validation was triggered", OperationOutcome.IssueSeverity.Information));
public override IEnumerable