Skip to content

Commit 6165c6f

Browse files
rename choice path helpers and improve empty value handling in fhir_resource_navigation and metadata_extractor
1 parent 18cf131 commit 6165c6f

File tree

4 files changed

+21
-40
lines changed

4 files changed

+21
-40
lines changed

lib/inferno/dsl/fhir_resource_navigation.rb

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def resolve_path(elements, path)
4242
# @param given_element [FHIR::Model, Array<FHIR::Model>]
4343
# @param path [String]
4444
# @param include_dar [Boolean]
45-
# @return [Array<FHIR::Model>]
45+
# @return [FHIR::Model, Object, false, nil] a single matching value, `false`, or `nil` if not found
4646
def find_a_value_at(given_element, path, include_dar: false, &block)
4747
return nil if given_element.nil?
4848

@@ -81,8 +81,8 @@ def get_next_value(element, property)
8181
property = property.to_s
8282
extension_url = property[/(?<=where\(url=').*(?='\))/]
8383
return extension_filter_value(element, extension_url) if extension_url.present?
84-
return typed_choice_value(element, property) if explicit_choice_path?(property)
85-
return populated_choice_value(element, property) if implicit_choice_path?(property)
84+
return sliced_choice_value(element, property) if sliced_choice_path?(property)
85+
return populated_choice_value(element, property) if choice_path?(property)
8686
return find_slice_via_discriminator(element, property) if slice_path?(property)
8787

8888
field_value(element, property)
@@ -96,12 +96,12 @@ def extension_filter_value(element, extension_url)
9696
end
9797

9898
# @private
99-
def explicit_choice_path?(property)
99+
def sliced_choice_path?(property)
100100
property.include?('[x]:')
101101
end
102102

103103
# @private
104-
def implicit_choice_path?(property)
104+
def choice_path?(property)
105105
property.end_with?('[x]')
106106
end
107107

@@ -111,9 +111,9 @@ def slice_path?(property)
111111
end
112112

113113
# @private
114-
def typed_choice_value(element, property)
115-
_choice_path, typed_field = property.split(':', 2)
116-
field_value(element, typed_field)
114+
def sliced_choice_value(element, property)
115+
_choice_path, sliced_field = property.split(':', 2)
116+
field_value(element, sliced_field)
117117
end
118118

119119
# @private
@@ -123,7 +123,7 @@ def populated_choice_value(element, property)
123123
Array.wrap(element.to_hash&.keys)
124124
.map(&:to_s)
125125
.find do |field_name|
126-
field_name.start_with?(choice_prefix) && value_present?(field_value(element, field_name))
126+
field_name.start_with?(choice_prefix) && value_not_empty?(field_value(element, field_name))
127127
end
128128

129129
return nil if populated_field.blank?
@@ -355,11 +355,11 @@ def current_and_child_values_match?(el_found, value_definitions_for_path)
355355
# @private
356356
def value_at_path_matches?(element, path, include_dar: false, &)
357357
value_found = find_a_value_at(element, path, include_dar:, &)
358-
value_present?(value_found)
358+
value_not_empty?(value_found)
359359
end
360360

361361
# @private
362-
def value_present?(value)
362+
def value_not_empty?(value)
363363
value.present? || value == false
364364
end
365365

lib/inferno/dsl/must_support_metadata_extractor.rb

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ def type_slices
259259
must_support_type_slice_elements.map do |current_element|
260260
discriminator = discriminators(sliced_element(current_element)).first
261261
type_path = discriminator_path(discriminator)
262-
type_element, type_path = find_type_slice_target(current_element, type_path)
262+
type_element = find_element_by_discriminator_path(current_element, type_path)
263263

264264
type_code = type_element.type.first.code
265265
discriminator_metadata = {
@@ -280,29 +280,6 @@ def type_slices
280280
end
281281
end
282282

283-
def find_type_slice_target(current_element, type_path)
284-
type_element = find_element_by_discriminator_path(current_element, type_path)
285-
286-
return [type_element, type_path] unless type_slice_requires_resource_path?(type_path, type_element)
287-
288-
resource_element = type_slice_resource_element(current_element)
289-
290-
return [type_element, type_path] unless resource_element.present?
291-
292-
[resource_element, resource_element.path.delete_prefix("#{current_element.path}.")]
293-
end
294-
295-
def type_slice_requires_resource_path?(type_path, type_element)
296-
type_path.blank? &&
297-
type_element&.type&.all? { |type| type.code == 'BackboneElement' }
298-
end
299-
300-
def type_slice_resource_element(current_element)
301-
profile_elements.find do |element|
302-
element.id == "#{current_element.id}.resource" && element.type.present?
303-
end
304-
end
305-
306283
def must_support_value_slice_elements
307284
must_support_slice_elements.select do |element|
308285
# discriminator type 'pattern' is deprecated in FHIR R5 and made equivalent to 'value'
@@ -339,7 +316,7 @@ def value_slices # rubocop:disable Metrics/CyclomaticComplexity
339316
type: 'unsupported',
340317
path: navigation_compatible_discriminator_path(discriminator_path)
341318
}
342-
elsif !pattern_element.fixed.nil?
319+
elsif value_not_empty?(pattern_element.fixed)
343320
fixed_values << {
344321
path: navigation_compatible_discriminator_path(discriminator_path),
345322
value: pattern_element.fixed
@@ -377,8 +354,12 @@ def element_part_of_slice_discrimination?(element)
377354
must_support_slice_elements.any? { |ms_slice| element.id.include?(ms_slice.id) }
378355
end
379356

357+
def value_not_empty?(value)
358+
value.present? || value == false
359+
end
360+
380361
def handle_fixed_values(metadata, element)
381-
if !element.fixed.nil?
362+
if value_not_empty?(element.fixed)
382363
metadata[:fixed_value] = element.fixed
383364
elsif element.patternCodeableConcept.present? && !element_part_of_slice_discrimination?(element)
384365
metadata[:fixed_value] = element.patternCodeableConcept.coding.first.code

spec/inferno/dsl/fhir_resource_navigation_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,13 @@ def metadata_fixture(filename)
121121
'value[x]:valueQuantity.code')).to eq('/min')
122122
end
123123

124-
it 'can find a populated choice element when the type is not explicit' do
124+
it 'can find a populated choice element on an unsliced choice path' do
125125
supporting_info = FHIR::Claim::SupportingInfo.new(timingDate: '2024-01-01')
126126

127127
expect(must_support_coverage_test.find_a_value_at(supporting_info, 'timing[x]')).to eq('2024-01-01')
128128
end
129129

130-
it 'can find a populated choice element when the type is explicit' do
130+
it 'can find a populated choice element on a sliced choice path' do
131131
supporting_info = FHIR::Claim::SupportingInfo.new(
132132
timingPeriod: FHIR::Period.new(start: '2024-01-01')
133133
)

spec/inferno/dsl/must_support_metadata_extractor_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@
111111
end
112112

113113
it 'extracts the discriminator path when the sliced type is on Bundle.entry.resource' do
114-
discriminator = FHIR::ElementDefinition::Slicing::Discriminator.new(type: 'type', path: '$this')
114+
discriminator = FHIR::ElementDefinition::Slicing::Discriminator.new(type: 'type', path: 'resource')
115115
slicing = FHIR::ElementDefinition::Slicing.new(discriminator: [discriminator])
116116

117117
backbone_type = instance_double(FHIR::ElementDefinition::Type, code: 'BackboneElement')

0 commit comments

Comments
 (0)