From 8cce6267c76ae3752b588e4bd6219aa8fde1bb50 Mon Sep 17 00:00:00 2001 From: mmsmits Date: Tue, 19 Nov 2024 13:37:50 +0100 Subject: [PATCH 1/5] start fixing validate code, need a new sdk for the rest --- .../SchemaBuilders/BindingBuilder.cs | 4 ++-- .../Impl/BindingValidator.cs | 22 +++++++------------ .../PublicAPI.Unshipped.txt | 3 +-- .../SlicingSchemaConverterTests.cs | 11 +++++----- .../Impl/BindingValidatorTests.cs | 6 ++--- 5 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/Firely.Fhir.Validation.Compilation.Shared/SchemaBuilders/BindingBuilder.cs b/src/Firely.Fhir.Validation.Compilation.Shared/SchemaBuilders/BindingBuilder.cs index 92057329..eaf70a12 100644 --- a/src/Firely.Fhir.Validation.Compilation.Shared/SchemaBuilders/BindingBuilder.cs +++ b/src/Firely.Fhir.Validation.Compilation.Shared/SchemaBuilders/BindingBuilder.cs @@ -28,9 +28,9 @@ public IEnumerable Build(ElementDefinitionNavigator nav, ElementConv if (def.Binding?.ValueSet is not null) #if STU3 - yield return new BindingValidator(convertSTU3Binding(def.Binding.ValueSet), convertStrength(def.Binding.Strength), true, $"{nav.StructureDefinition.Url}#{def.Path}"); + yield return new BindingValidator(convertSTU3Binding(def.Binding.ValueSet), convertStrength(def.Binding.Strength), true); #else - yield return new BindingValidator(def.Binding.ValueSet, convertStrength(def.Binding.Strength), true, $"{nav.StructureDefinition.Url}#{def.Path}"); + yield return new BindingValidator(def.Binding.ValueSet, convertStrength(def.Binding.Strength), true); #endif #if STU3 diff --git a/src/Firely.Fhir.Validation/Impl/BindingValidator.cs b/src/Firely.Fhir.Validation/Impl/BindingValidator.cs index 9439363f..8bbe248a 100644 --- a/src/Firely.Fhir.Validation/Impl/BindingValidator.cs +++ b/src/Firely.Fhir.Validation/Impl/BindingValidator.cs @@ -85,12 +85,6 @@ public enum BindingStrength [DataMember] public bool AbstractAllowed { get; private set; } - /// - /// The context of the value set, so that the server can resolve this to a value set to - /// validate against. - /// - [DataMember] - public string? Context { get; private set; } /// /// Constructs a validator for validating a coded element. @@ -98,13 +92,11 @@ public enum BindingStrength /// Value set Canonical URL /// Indicates the degree of conformance expectations associated with this binding /// - /// The context of the value set, so that the server can resolve this to a value set to validate against. - public BindingValidator(Canonical valueSetUri, BindingStrength? strength, bool abstractAllowed = true, string? context = null) + public BindingValidator(Canonical valueSetUri, BindingStrength? strength, bool abstractAllowed = true) { ValueSetUri = valueSetUri; Strength = strength; AbstractAllowed = abstractAllowed; - Context = context; } /// @@ -180,18 +172,20 @@ private ResultReport validateCode(Element bindable, ValidationSettings vc, Valid if (Strength != BindingStrength.Required) return ResultReport.SUCCESS; var parameters = buildParams() - .WithValueSet(ValueSetUri.ToString()) + .WithValueSet(ValueSetUri.Uri, null, null, ValueSetUri.Version) .WithAbstract(AbstractAllowed); ValidateCodeParameters buildParams() { var vcp = new ValidateCodeParameters(); + + return bindable switch { - 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), + FhirString str => vcp.WithCode(str.Value, system: null, display: null), + FhirUri uri => vcp.WithCode(uri.Value, system: null, display: null), + Code co => vcp.WithCode(co.Value, system: null, display: null), Coding cd => vcp.WithCoding(cd), CodeableConcept cc => vcp.WithCodeableConcept(cc), _ => throw Error.InvalidOperation($"Parsed bindable was of unexpected instance type '{bindable.TypeName}'.") @@ -236,7 +230,7 @@ public JToken ToJson() var props = new JObject(new JProperty("abstractAllowed", AbstractAllowed)); if (Strength is not null) props.Add(new JProperty("strength", Strength!.GetLiteral())); - + props.Add(new JProperty("valueSet", (string)ValueSetUri)); return new JProperty("binding", props); diff --git a/src/Firely.Fhir.Validation/PublicAPI.Unshipped.txt b/src/Firely.Fhir.Validation/PublicAPI.Unshipped.txt index e610aed2..72ed4a0e 100644 --- a/src/Firely.Fhir.Validation/PublicAPI.Unshipped.txt +++ b/src/Firely.Fhir.Validation/PublicAPI.Unshipped.txt @@ -41,8 +41,7 @@ Firely.Fhir.Validation.BindingValidator.BindingStrength.Example = 3 -> Firely.Fh Firely.Fhir.Validation.BindingValidator.BindingStrength.Extensible = 1 -> Firely.Fhir.Validation.BindingValidator.BindingStrength Firely.Fhir.Validation.BindingValidator.BindingStrength.Preferred = 2 -> Firely.Fhir.Validation.BindingValidator.BindingStrength Firely.Fhir.Validation.BindingValidator.BindingStrength.Required = 0 -> Firely.Fhir.Validation.BindingValidator.BindingStrength -Firely.Fhir.Validation.BindingValidator.BindingValidator(Firely.Fhir.Validation.Canonical! valueSetUri, Firely.Fhir.Validation.BindingValidator.BindingStrength? strength, bool abstractAllowed = true, string? context = null) -> void -Firely.Fhir.Validation.BindingValidator.Context.get -> string? +Firely.Fhir.Validation.BindingValidator.BindingValidator(Firely.Fhir.Validation.Canonical! valueSetUri, Firely.Fhir.Validation.BindingValidator.BindingStrength? strength, bool abstractAllowed = true) -> void Firely.Fhir.Validation.BindingValidator.Strength.get -> Firely.Fhir.Validation.BindingValidator.BindingStrength? Firely.Fhir.Validation.BindingValidator.ToJson() -> Newtonsoft.Json.Linq.JToken! Firely.Fhir.Validation.BindingValidator.ValueSetUri.get -> Firely.Fhir.Validation.Canonical! diff --git a/test/Firely.Fhir.Validation.Compilation.Tests.Shared/SlicingSchemaConverterTests.cs b/test/Firely.Fhir.Validation.Compilation.Tests.Shared/SlicingSchemaConverterTests.cs index 849e6137..c1a2df72 100644 --- a/test/Firely.Fhir.Validation.Compilation.Tests.Shared/SlicingSchemaConverterTests.cs +++ b/test/Firely.Fhir.Validation.Compilation.Tests.Shared/SlicingSchemaConverterTests.cs @@ -58,8 +58,7 @@ private static SliceValidator.SliceCase getPatternSlice(string profile) => new("PatternBinding", new PathSelectorValidator("system", new AllValidator(shortcircuitEvaluation: true, new PatternValidator(new FhirUri("http://example.com/someuri").ToTypedElement()), - new BindingValidator("http://example.com/demobinding", strength: BindingValidator.BindingStrength.Required, - context: $"{profile}#Patient.identifier.system"))), + new BindingValidator("http://example.com/demobinding", strength: BindingValidator.BindingStrength.Required))), new ElementSchema("#Patient.identifier:PatternBinding")); [Fact] @@ -225,11 +224,11 @@ public async T.Task TestResliceGeneration() var expectedSlice = new SliceValidator(false, true, ResultAssertion.SUCCESS, new SliceValidator.SliceCase("phone", new PathSelectorValidator("system", new AllValidator(shortcircuitEvaluation: true, new FixedValidator(new Code("phone").ToTypedElement()), - new BindingValidator(contactPointSystem, BindingValidator.BindingStrength.Required, context: "http://validationtest.org/fhir/StructureDefinition/ResliceTestcase#Patient.telecom.system"))), + new BindingValidator(contactPointSystem, BindingValidator.BindingStrength.Required))), new ElementSchema("#Patient.telecom:phone")), new SliceValidator.SliceCase("email", new PathSelectorValidator("system", new AllValidator(shortcircuitEvaluation: true, new FixedValidator(new Code("email").ToTypedElement()), - new BindingValidator(contactPointSystem, BindingValidator.BindingStrength.Required, context: "http://validationtest.org/fhir/StructureDefinition/ResliceTestcase#Patient.telecom.system"))), + new BindingValidator(contactPointSystem, BindingValidator.BindingStrength.Required))), new ElementSchema("#Patient.telecom:email")) ); @@ -247,11 +246,11 @@ void testResliceInSlice2(SliceValidator.SliceCase slice2) var email = new SliceValidator(false, false, _sliceClosedAssertion, new SliceValidator.SliceCase("email/home", new PathSelectorValidator("use", new AllValidator(shortcircuitEvaluation: true, new FixedValidator(new Code("home").ToTypedElement()), - new BindingValidator(contactPointUse, BindingValidator.BindingStrength.Required, context: "http://validationtest.org/fhir/StructureDefinition/ResliceTestcase#Patient.telecom.use"))), + new BindingValidator(contactPointUse, BindingValidator.BindingStrength.Required))), new ElementSchema("#Patient.telecom:email/home")), new SliceValidator.SliceCase("email/work", new PathSelectorValidator("use", new AllValidator(shortcircuitEvaluation: true, new FixedValidator(new Code("work").ToTypedElement()), - new BindingValidator(contactPointUse, BindingValidator.BindingStrength.Required, context: "http://validationtest.org/fhir/StructureDefinition/ResliceTestcase#Patient.telecom.use"))), + new BindingValidator(contactPointUse, BindingValidator.BindingStrength.Required))), new ElementSchema("#Patient.telecom:email/work")) ); diff --git a/test/Firely.Fhir.Validation.Tests/Impl/BindingValidatorTests.cs b/test/Firely.Fhir.Validation.Tests/Impl/BindingValidatorTests.cs index e6ba3e0a..7a33e69a 100644 --- a/test/Firely.Fhir.Validation.Tests/Impl/BindingValidatorTests.cs +++ b/test/Firely.Fhir.Validation.Tests/Impl/BindingValidatorTests.cs @@ -35,7 +35,7 @@ public BindingValidatorTests() { var valueSetUri = "http://hl7.org/fhir/ValueSet/data-absent-reason"; _bindingAssertion = - new BindingValidator(valueSetUri, BindingValidator.BindingStrength.Required, true, CONTEXT); + new BindingValidator(valueSetUri, BindingValidator.BindingStrength.Required, true); _validateCodeService = new Mock(); _validationSettingsM = @@ -231,11 +231,11 @@ public void ValidateCodeableReference() { Concept = new CodeableConcept("http://terminology.hl7.org/CodeSystem/data-absent-reason", "masked") }.ToTypedElement(); - + var result = _bindingAssertion.Validate(input, _validationSettingsM); result.Warnings.Should().OnlyContain(w => w.IssueNumber == Issue.TERMINOLOGY_OUTPUT_WARNING.Code); result.Errors.Should().BeEmpty(); - + input = new CodeableReference { Reference = new ResourceReference("http://some.uri") From 7e125858e9f7c3a15699ea8698431d0cd779d871 Mon Sep 17 00:00:00 2001 From: mmsmits Date: Mon, 25 Nov 2024 12:02:42 +0100 Subject: [PATCH 2/5] update to sdk 5.11.0 --- firely-validator-api-tests.props | 2 +- firely-validator-api.props | 2 +- src/Firely.Fhir.Validation/Impl/BindingValidator.cs | 12 +++++------- .../TestData/issue-165/fhirpkg.lock.json | 2 +- .../FhirTestCases | 2 +- .../FhirTests/ValidationManifestTest.cs | 4 ++-- 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/firely-validator-api-tests.props b/firely-validator-api-tests.props index 68e46367..1e7bfe68 100644 --- a/firely-validator-api-tests.props +++ b/firely-validator-api-tests.props @@ -8,7 +8,7 @@ - 5.10.3 + 5.11.1 diff --git a/firely-validator-api.props b/firely-validator-api.props index 4062ba5f..0b98b4a9 100644 --- a/firely-validator-api.props +++ b/firely-validator-api.props @@ -27,7 +27,7 @@ - 5.10.3 + 5.11.1 diff --git a/src/Firely.Fhir.Validation/Impl/BindingValidator.cs b/src/Firely.Fhir.Validation/Impl/BindingValidator.cs index 8bbe248a..2c293c2c 100644 --- a/src/Firely.Fhir.Validation/Impl/BindingValidator.cs +++ b/src/Firely.Fhir.Validation/Impl/BindingValidator.cs @@ -172,24 +172,22 @@ private ResultReport validateCode(Element bindable, ValidationSettings vc, Valid if (Strength != BindingStrength.Required) return ResultReport.SUCCESS; var parameters = buildParams() - .WithValueSet(ValueSetUri.Uri, null, null, ValueSetUri.Version) + .WithValueSet(ValueSetUri.ToString()) .WithAbstract(AbstractAllowed); ValidateCodeParameters buildParams() { var vcp = new ValidateCodeParameters(); - - return bindable switch { - FhirString str => vcp.WithCode(str.Value, system: null, display: null), - FhirUri uri => vcp.WithCode(uri.Value, system: null, display: null), - Code co => vcp.WithCode(co.Value, system: null, display: null), + FhirString str => vcp.WithCode(str.Value, system: null, display: null, systemVersion: null, displayLanguage: null, context: null, inferSystem: false), + FhirUri uri => vcp.WithCode(uri.Value, system: null, display: null, systemVersion: null, displayLanguage: null, context: null, inferSystem: false), + Code co => vcp.WithCode(co.Value, system: null, display: null, systemVersion: null, displayLanguage: null, context: null, inferSystem: true), Coding cd => vcp.WithCoding(cd), CodeableConcept cc => vcp.WithCodeableConcept(cc), _ => throw Error.InvalidOperation($"Parsed bindable was of unexpected instance type '{bindable.TypeName}'.") - }; + }; ; } var display = buildCodingDisplay(parameters); 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 aad7f301..e45dd7bf 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-10-02T15:57:47.311953+02:00", + "updated": "2024-11-25T11:47:12.2332604+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.Shared/FhirTestCases b/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTestCases index bb6a7c9e..85c38d8a 160000 --- a/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTestCases +++ b/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTestCases @@ -1 +1 @@ -Subproject commit bb6a7c9e21f1bae5964efedd81b8ed39e03990d7 +Subproject commit 85c38d8a4b267356612508608351c2173072110e 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 ec4540cc..e5cc66e1 100644 --- a/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTests/ValidationManifestTest.cs +++ b/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTests/ValidationManifestTest.cs @@ -32,7 +32,7 @@ public class ValidationManifestTest /// //[Ignore] [DataTestMethod] - [ValidationManifestDataSource(TEST_CASES_MANIFEST, singleTest: "mr-m-simple-nossystem")] + [ValidationManifestDataSource(TEST_CASES_MANIFEST, singleTest: "patient-translated-codes.profile.xml")] public void RunSingleTest(TestCase testCase, string baseDirectory) => _runner.RunTestCase(testCase, DotNetValidator.Create(), baseDirectory); @@ -59,7 +59,7 @@ public void RunFirelySdkTests(TestCase testCase, string baseDirectory) /// - The method `ClassCleanup` will gather all the testcases and serialize those to disk. The filename can be altered in /// that method /// - [Ignore("This test is only used to generate the Firely SDK results in the manifest. See the method for more info")] + //[Ignore("This test is only used to generate the Firely SDK results in the manifest. See the method for more info")] [TestMethod] public void AddFirelySdkValidatorResults() => _runner.AddOrEditValidatorResults(TEST_CASES_MANIFEST, new[] { DotNetValidator.Create() }); From e3890ff0f14e9e2d7296407997bc364f8caca4a8 Mon Sep 17 00:00:00 2001 From: mmsmits Date: Mon, 25 Nov 2024 14:15:30 +0100 Subject: [PATCH 3/5] revert unit test changes --- .../FhirTests/ValidationManifestTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 e5cc66e1..ec4540cc 100644 --- a/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTests/ValidationManifestTest.cs +++ b/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTests/ValidationManifestTest.cs @@ -32,7 +32,7 @@ public class ValidationManifestTest /// //[Ignore] [DataTestMethod] - [ValidationManifestDataSource(TEST_CASES_MANIFEST, singleTest: "patient-translated-codes.profile.xml")] + [ValidationManifestDataSource(TEST_CASES_MANIFEST, singleTest: "mr-m-simple-nossystem")] public void RunSingleTest(TestCase testCase, string baseDirectory) => _runner.RunTestCase(testCase, DotNetValidator.Create(), baseDirectory); @@ -59,7 +59,7 @@ public void RunFirelySdkTests(TestCase testCase, string baseDirectory) /// - The method `ClassCleanup` will gather all the testcases and serialize those to disk. The filename can be altered in /// that method /// - //[Ignore("This test is only used to generate the Firely SDK results in the manifest. See the method for more info")] + [Ignore("This test is only used to generate the Firely SDK results in the manifest. See the method for more info")] [TestMethod] public void AddFirelySdkValidatorResults() => _runner.AddOrEditValidatorResults(TEST_CASES_MANIFEST, new[] { DotNetValidator.Create() }); From de2510e84c3954d0a7068c313c086e6cfb11bff2 Mon Sep 17 00:00:00 2001 From: mmsmits Date: Mon, 25 Nov 2024 14:20:18 +0100 Subject: [PATCH 4/5] edit unit test --- test/Firely.Fhir.Validation.Tests/Impl/BindingValidatorTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Firely.Fhir.Validation.Tests/Impl/BindingValidatorTests.cs b/test/Firely.Fhir.Validation.Tests/Impl/BindingValidatorTests.cs index 7a33e69a..69696ea4 100644 --- a/test/Firely.Fhir.Validation.Tests/Impl/BindingValidatorTests.cs +++ b/test/Firely.Fhir.Validation.Tests/Impl/BindingValidatorTests.cs @@ -95,6 +95,7 @@ public void ValidateWithCode() Assert.IsTrue(result.IsSuccessful); verify(p => p.Code.IsExactly(new Code("CD123"))); + verify(p => p.InferSystem?.Value == true); } [TestMethod] From 2e32a8d928c009f852164277a359127c0c3a0551 Mon Sep 17 00:00:00 2001 From: Marten Smits <8956842+mmsmits@users.noreply.github.com> Date: Mon, 25 Nov 2024 15:30:51 +0100 Subject: [PATCH 5/5] remove extra colon --- src/Firely.Fhir.Validation/Impl/BindingValidator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Firely.Fhir.Validation/Impl/BindingValidator.cs b/src/Firely.Fhir.Validation/Impl/BindingValidator.cs index 2c293c2c..e7045abd 100644 --- a/src/Firely.Fhir.Validation/Impl/BindingValidator.cs +++ b/src/Firely.Fhir.Validation/Impl/BindingValidator.cs @@ -187,7 +187,7 @@ ValidateCodeParameters buildParams() Coding cd => vcp.WithCoding(cd), CodeableConcept cc => vcp.WithCodeableConcept(cc), _ => throw Error.InvalidOperation($"Parsed bindable was of unexpected instance type '{bindable.TypeName}'.") - }; ; + }; } var display = buildCodingDisplay(parameters);