-
Notifications
You must be signed in to change notification settings - Fork 5
Implement conformsTo #109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Implement conformsTo #109
Changes from 1 commit
af4baf4
dd0aab5
6483704
e6e3be6
699fe19
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -157,6 +157,15 @@ specification across different FHIR versions. In particular, DateTime and Time i | |
| include partial time (e.g. missing minutes and seconds), which is not allowed in FHIR. Therefore, | ||
| new implementations are needed. | ||
|
|
||
| ### Profile validation | ||
|
|
||
| The `conformsTo()` function supports the base FHIR profiles | ||
| (`http://hl7.org/fhir/StructureDefinition/<Type>`): the input element's type is compared to the | ||
| type named by the structure. Custom profiles (e.g. US Core) would require profile validation, | ||
| which is not implemented. Passing a custom profile URL results in an error, consistent with the | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The spec does say this: so does it not mean we should return emtpy collection rather than throwing an error?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me clarify, that's the current spec text, but R4 says: https://hl7.org/fhir/R4/fhirpath.html#functions and testConformsTo3 expects an execution error for so returning empty would fail conformance. The doc link was pointing at the versionless (current, https://hl7.org/fhir/fhirpath.html#functions) spec though, which is misleading. I can fix the R4 link. But main point is, do we want to follow the latest spec, or refer to R4?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. very good question - one thing to note is that this part of the spec is part of FHIR and not actually part of FHIRPath... and we DO have FHIR version specific implementations - we have FhirEngine.forR4 forR4B and forR5... so if we're to be really serious about this, we can actually implement different behaviors for different verions... but I'm not sure if it's worth the effort. I don't have a super strong view here - but if we're not going to diverge between different fhir versions, it seems to make sense to implement the latest version. |
||
| specification's requirement to error when a structure cannot be resolved | ||
| (https://hl7.org/fhir/fhirpath.html#functions). | ||
|
|
||
| ### Timezone offset in date time values | ||
|
|
||
| This FHIRPath implementation adopts a strict, safety-first approach to date time comparisons, | ||
|
|
@@ -296,7 +305,6 @@ documented in the table below. | |
| | `testType22` | Implementation | | | `is` with an unknown `System` type should evaluate to false, but the type resolver throws. | | ||
| | `testType23` | Implementation | | | As `testType20`. | | ||
| | `testTypeA*` | Implementation | | | Evaluating `Parameters.parameter[x].value` crashes with `NoSuchElementException`. | | ||
| | `testConformsTo*` | Implementation | | | Function `conformsTo` is not implemented. | | ||
| | `LowBoundaryDateTimeMillisecond1` | Specification/Test | | | Diverges from FHIRPath specification. See [Discussion](https://chat.fhir.org/#narrow/channel/179266-fhirpath/topic/lowBoundary.20and.20highBoundary.20with.20incomplete.20date.20time/with/611113639). | | ||
| | `HighBoundaryDateTimeMillisecond1` | Specification/Test | | As above. | As above. | | ||
| | `HighBoundaryDateTimeMillisecond3` | Specification/Test | | As above. | As above. | | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| /* | ||
| * Copyright 2026 Open Health Stack Foundation | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| package dev.ohs.fhir.fhirpath | ||
|
|
||
| import dev.ohs.fhir.model.r4.Resource | ||
| import kotlin.test.Test | ||
| import kotlin.test.assertEquals | ||
| import kotlin.test.assertFailsWith | ||
| import kotlinx.serialization.json.Json | ||
|
|
||
| private val fhirPathEngine = FhirPathEngine.forR4() | ||
|
|
||
| private val patient: Resource = | ||
| Json { ignoreUnknownKeys = true } | ||
| .decodeFromString("""{"resourceType": "Patient", "name": [{"family": "Chalmers"}]}""") | ||
|
|
||
| class ConformsToTest { | ||
|
|
||
| @Test | ||
| fun `element conforms to its base data type profile`() { | ||
| assertEquals( | ||
| listOf(true), | ||
| fhirPathEngine | ||
| .evaluateExpression( | ||
| "name.first().conformsTo('http://hl7.org/fhir/StructureDefinition/HumanName')", | ||
| patient, | ||
| ) | ||
| .toList(), | ||
| ) | ||
| assertEquals( | ||
| listOf(false), | ||
| fhirPathEngine | ||
| .evaluateExpression( | ||
| "name.first().conformsTo('http://hl7.org/fhir/StructureDefinition/Address')", | ||
| patient, | ||
| ) | ||
| .toList(), | ||
| ) | ||
|
FikriMilano marked this conversation as resolved.
|
||
| } | ||
|
|
||
| @Test | ||
| fun `unresolvable structure throws`() { | ||
| assertFailsWith<Exception> { | ||
| fhirPathEngine.evaluateExpression( | ||
| "conformsTo('http://hl7.org/fhir/StructureDefinition/NotARealType')", | ||
| patient, | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| fun `structure resolving only to a System type throws`() { | ||
| // `String` is not a FHIR structure definition (FHIR's is lowercase `string`), so it must | ||
| // error rather than fall back to the System type and return false. The input element is a | ||
| // FHIR string, so with the lowercase URL this would return true; the error is about the | ||
| // structure being unresolvable, not about the input. | ||
| assertFailsWith<Exception> { | ||
| fhirPathEngine.evaluateExpression( | ||
| "name.first().family.conformsTo('http://hl7.org/fhir/StructureDefinition/String')", | ||
| patient, | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| fun `empty input returns empty`() { | ||
| assertEquals( | ||
| emptyList(), | ||
| fhirPathEngine | ||
| .evaluateExpression( | ||
| "{}.conformsTo('http://hl7.org/fhir/StructureDefinition/Patient')", | ||
| patient, | ||
| ) | ||
| .toList(), | ||
| ) | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.