Class: PacioInfernoCore::Generator::SearchTestGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/pacio_inferno_core/generator/search_test_generator.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(group_metadata, search_metadata, base_output_dir) ⇒ SearchTestGenerator

Returns a new instance of SearchTestGenerator.



22
23
24
25
26
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 22

def initialize(, , base_output_dir)
  self. = 
  self. = 
  self.base_output_dir = base_output_dir
end

Instance Attribute Details

#base_output_dirObject

Returns the value of attribute base_output_dir.



20
21
22
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 20

def base_output_dir
  @base_output_dir
end

#group_metadataObject

Returns the value of attribute group_metadata.



20
21
22
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 20

def 
  @group_metadata
end

#search_metadataObject

Returns the value of attribute search_metadata.



20
21
22
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 20

def 
  @search_metadata
end

Class Method Details

.generate(ig_metadata, base_output_dir) ⇒ Object



8
9
10
11
12
13
14
15
16
17
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 8

def generate(, base_output_dir)
  .groups
    .reject { |group| SpecialCases.exclude_group? group }
    .select { |group| group.searches.present? }
    .each do |group|
      group.searches.each do |search|
        new(group, search, base_output_dir).generate
      end
    end
end

Instance Method Details

#array_of_strings(array) ⇒ Object



183
184
185
186
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 183

def array_of_strings(array)
  quoted_strings = array.map { |element| "'#{element}'" }
  "[#{quoted_strings.join(', ')}]"
end

#base_output_file_nameObject



36
37
38
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 36

def base_output_file_name
  "#{class_name.underscore}.rb"
end

#class_nameObject



68
69
70
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 68

def class_name
  "#{naming.upper_camel_case_for_profile()}#{search_title}SearchTest"
end

#conformance_expectationObject



80
81
82
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 80

def conformance_expectation
  [:expectation]
end

#descriptionObject



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 281

def description
  <<~DESCRIPTION.gsub(/\n{3,}/, "\n\n")
    A server #{conformance_expectation} support searching by
    #{search_param_name_string} on the #{resource_type} resource. This test
    will pass if resources are returned and match the search criteria. If
    none are returned, the test is skipped.

    #{medication_inclusion_description}
    #{reference_search_description}
    #{first_search_description}
    #{post_search_description}

    [US Core Server CapabilityStatement](#{ig_link}/CapabilityStatement-us-core-server.html)
  DESCRIPTION
end

#first_search?Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 94

def first_search?
  .searches.first == 
end

#first_search_descriptionObject



251
252
253
254
255
256
257
258
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 251

def first_search_description
  return '' unless first_search?

  <<~FIRST_SEARCH_DESCRIPTION
    Because this is the first search of the sequence, resources in the
    response will be used for subsequent tests.
  FIRST_SEARCH_DESCRIPTION
end

#fixed_value_search?Boolean

Returns:

  • (Boolean)


98
99
100
101
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 98

def fixed_value_search?
  first_search? && [:names] != ['patient'] &&
    !.delayed? && resource_type != 'Patient'
end

#fixed_value_search_param_nameObject



103
104
105
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 103

def fixed_value_search_param_name
  ([:names] - [:patient]).first
end

#generateObject



230
231
232
233
234
235
236
237
238
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 230

def generate
  FileUtils.mkdir_p(output_file_directory)
  File.write(output_file_name, output)

  .add_test(
    id: test_id,
    file_name: base_output_file_name
  )
end


220
221
222
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 220

def ig_link
  Naming.ig_link(.version)
end

#medication_inclusion_descriptionObject



260
261
262
263
264
265
266
267
268
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 260

def medication_inclusion_description
  return '' unless test_medication_inclusion?

  <<~MEDICATION_INCLUSION_DESCRIPTION
    If any #{resource_type} resources use external references to
    Medications, the search will be repeated with
    `_include=#{resource_type}:medication`.
  MEDICATION_INCLUSION_DESCRIPTION
end

#module_name_with_versionObject



72
73
74
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 72

def module_name_with_version
  "#{naming.module_name}#{.reformatted_version.upcase}"
end

#namingObject



48
49
50
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 48

def naming
  self.class.module_parent::Naming
end

#needs_patient_id?Boolean

Returns:

  • (Boolean)


111
112
113
114
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 111

def needs_patient_id?
  [:names].include?('patient') ||
    (resource_type == 'Patient' && [:names].include?('_id'))
end

#optional?Boolean

Returns:

  • (Boolean)


140
141
142
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 140

def optional?
  conformance_expectation != 'SHALL' || ![:must_support_or_mandatory]
end

#outputObject



32
33
34
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 32

def output
  @output ||= ERB.new(template, trim_mode: '-').result(binding)
end

#output_file_directoryObject



40
41
42
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 40

def output_file_directory
  File.join(base_output_dir, profile_identifier)
end

#output_file_nameObject



44
45
46
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 44

def output_file_name
  File.join(output_file_directory, base_output_file_name)
end

#path_for_value(path) ⇒ Object



124
125
126
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 124

def path_for_value(path)
  path == 'class' ? 'local_class' : path
end

#possible_status_search?Boolean

Returns:

  • (Boolean)


152
153
154
155
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 152

def possible_status_search?
  [:names].none? { |name| name.include? 'status' } &&
    .search_definitions.keys.any? { |key| key.to_s.include? 'status' }
end

#post_search_descriptionObject



270
271
272
273
274
275
276
277
278
279
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 270

def post_search_description
  return '' unless test_post_search?

  <<~POST_SEARCH_DESCRIPTION
    Additionally, this test will check that GET and POST search methods
    return the same number of results. Search by POST is required by the
    FHIR R4 specification, and these tests interpret search by GET as a
    requirement of US Core #{.version}.
  POST_SEARCH_DESCRIPTION
end

#profile_identifierObject



52
53
54
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 52

def profile_identifier
  naming.snake_case_for_profile()
end

#reference_search_descriptionObject



240
241
242
243
244
245
246
247
248
249
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 240

def reference_search_description
  return '' unless test_reference_variants?

  <<~REFERENCE_SEARCH_DESCRIPTION
    This test verifies that the server supports searching by reference using
    the form `patient=[id]` as well as `patient=Patient/[id]`. The two
    different forms are expected to return the same number of results. US
    Core requires that both forms are supported by US Core responders.
  REFERENCE_SEARCH_DESCRIPTION
end

#required_comparatorsObject



132
133
134
135
136
137
138
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 132

def required_comparators
  @required_comparators ||=
    search_param_names.each_with_object({}) do |name, comparators|
      required_comparators = required_comparators_for_param(name)
      comparators[name] = required_comparators if required_comparators.present?
    end
end

#required_comparators_for_param(name) ⇒ Object



128
129
130
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 128

def required_comparators_for_param(name)
  search_definition(name)[:comparators].select { |_comparator, expectation| expectation == 'SHALL' }
end

#required_comparators_stringObject



179
180
181
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 179

def required_comparators_string
  array_of_strings(required_comparators.keys)
end

#required_multiple_or_search_paramsObject



168
169
170
171
172
173
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 168

def required_multiple_or_search_params
  @multiple_or_search_params ||=
    search_param_names.select do |name|
      search_definition(name)[:multiple_or] == 'SHALL'
    end
end

#required_multiple_or_search_params_stringObject



175
176
177
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 175

def required_multiple_or_search_params_string
  array_of_strings(required_multiple_or_search_params)
end

#resource_typeObject



76
77
78
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 76

def resource_type
  .resource
end

#saves_delayed_references?Boolean

Returns:

  • (Boolean)


148
149
150
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 148

def saves_delayed_references?
  first_search? && .delayed_references.present?
end

#search_definition(name) ⇒ Object



144
145
146
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 144

def search_definition(name)
  .search_definitions[name.to_sym]
end

#search_identifierObject



60
61
62
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 60

def search_identifier
  [:names].join('_').tr('-', '_')
end

#search_param_name_stringObject



107
108
109
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 107

def search_param_name_string
  [:names].join(' + ')
end

#search_param_namesObject



116
117
118
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 116

def search_param_names
  search_params.map { |param| param[:name] }
end

#search_param_names_arrayObject



120
121
122
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 120

def search_param_names_array
  array_of_strings(search_param_names)
end

#search_paramsObject



84
85
86
87
88
89
90
91
92
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 84

def search_params
  @search_params ||=
    [:names].map do |name|
      {
        name: name,
        path: search_definition(name)[:path]
      }
    end
end

#search_propertiesObject



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 200

def search_properties
  {}.tap do |properties|
    properties[:first_search] = 'true' if first_search?
    properties[:fixed_value_search] = 'true' if fixed_value_search?
    properties[:resource_type] = "'#{resource_type}'"
    properties[:search_param_names] = search_param_names_array
    properties[:saves_delayed_references] = 'true' if saves_delayed_references?
    properties[:possible_status_search] = 'true' if possible_status_search?
    properties[:test_medication_inclusion] = 'true' if test_medication_inclusion?
    properties[:token_search_params] = token_search_params_string if token_search_params.present?
    properties[:test_reference_variants] = 'true' if test_reference_variants?
    properties[:params_with_comparators] = required_comparators_string if required_comparators.present?
    if required_multiple_or_search_params.present?
      properties[:multiple_or_search_params] =
        required_multiple_or_search_params_string
    end
    properties[:test_post_search] = 'true' if first_search?
  end
end

#search_test_properties_stringObject



224
225
226
227
228
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 224

def search_test_properties_string
  search_properties
    .map { |key, value| "#{' ' * 8}#{key}: #{value}" }
    .join(",\n")
end

#search_titleObject



64
65
66
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 64

def search_title
  search_identifier.camelize
end

#templateObject



28
29
30
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 28

def template
  @template ||= File.read(File.join(__dir__, 'templates', 'search.rb.erb'))
end

#test_idObject



56
57
58
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 56

def test_id
  "#{naming.prefix}_#{.reformatted_version}_#{profile_identifier}_#{search_identifier}_search_test"
end

#test_medication_inclusion?Boolean

Returns:

  • (Boolean)


192
193
194
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 192

def test_medication_inclusion?
  %w[MedicationRequest MedicationDispense].include?(resource_type)
end

#test_post_search?Boolean

Returns:

  • (Boolean)


196
197
198
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 196

def test_post_search?
  first_search?
end

#test_reference_variants?Boolean

Returns:

  • (Boolean)


188
189
190
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 188

def test_reference_variants?
  first_search? && search_param_names.include?('patient')
end

#token_search_paramsObject



157
158
159
160
161
162
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 157

def token_search_params
  @token_search_params ||=
    search_param_names.select do |name|
      %w[Identifier CodeableConcept Coding].include? .search_definitions[name.to_sym][:type]
    end
end

#token_search_params_stringObject



164
165
166
# File 'lib/pacio_inferno_core/generator/search_test_generator.rb', line 164

def token_search_params_string
  array_of_strings(token_search_params)
end