require_relative 'naming' require_relative 'special_cases' module IpaTestKit class Generator class ProvenanceRevincludeSearchTestGenerator class << self def generate(ig_metadata) ig_metadata.groups .reject { |group| SpecialCases.exclude_resource? group.resource } .select { |group| group.revincludes.include? 'Provenance:target' } .each { |group| new(group, group.searches.first).generate } end end attr_accessor :group_metadata, :search_metadata def initialize(group_metadata, search_metadata) self.group_metadata = group_metadata self.search_metadata = search_metadata end def template @template ||= File.read(File.join(__dir__, 'templates', 'provenance_revinclude_search.rb.erb')) end def output @output ||= ERB.new(template).result(binding) end def base_output_file_name "#{class_name.underscore}.rb" end def output_file_directory File.join(__dir__, '..', 'generated', profile_identifier) end def output_file_name File.join(output_file_directory, base_output_file_name) end def profile_identifier Naming.snake_case_for_profile(group_metadata) end def test_id "ipa_010_#{profile_identifier}_#{search_identifier}_search_test" end def search_identifier 'provenance_revinclude' end def search_title search_identifier.camelize end def class_name "#{Naming.upper_camel_case_for_profile(group_metadata)}#{search_title}SearchTest" end def resource_type group_metadata.resource end def search_params @search_params ||= search_metadata[:names].map do |name| { name: name, path: search_definition(name)[:path] } end end def first_search? group_metadata.searches.first == search_metadata end def fixed_value_search? search_metadata[:names] != ['patient'] && !group_metadata.delayed? && resource_type != 'Patient' end def fixed_value_search_param_name (search_metadata[:names] - [:patient]).first end def search_param_name_string search_metadata[:names].join(' + ') + ' + revInclude:Provenance:target' end def needs_patient_id? search_metadata[:names].include?('patient') || (resource_type == 'Patient' && search_metadata[:names].include?('_id')) end def search_param_names search_params.map { |param| param[:name] } end def search_param_names_array array_of_strings(search_param_names) end def path_for_value(path) path == 'class' ? 'local_class' : path end def required_comparators_for_param(name) search_definition(name)[:comparators].select { |_comparator, expectation| expectation == 'SHALL' } end 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 # def patient_id_param?(param) # param[:name] == 'patient' || # (resource_type == 'Patient' && param[:name] == '_id') # end def search_definition(name) group_metadata.search_definitions[name.to_sym] end def saves_delayed_references? first_search? && group_metadata.delayed_references.present? end def possible_status_search? !search_metadata[:names].include?('status') && group_metadata.search_definitions.key?(:status) end def token_search_params @token_search_params ||= search_param_names.select do |name| ['Identifier', 'CodeableConcept', 'Coding'].include? group_metadata.search_definitions[name.to_sym][:type] end end def token_search_params_string array_of_strings(token_search_params) end def required_comparators_string array_of_strings(required_comparators.keys) end def array_of_strings(array) quoted_strings = array.map { |element| "'#{element}'" } "[#{quoted_strings.join(', ')}]" end def search_properties {}.tap do |properties| properties[:fixed_value_search] = 'true' if fixed_value_search? properties[:resource_type] = "'#{resource_type}'" properties[:search_param_names] = search_param_names_array properties[:possible_status_search] = 'true' if possible_status_search? end end def search_test_properties_string search_properties .map { |key, value| "#{' ' * 8}#{key}: #{value}" } .join(",\n") end def generate FileUtils.mkdir_p(output_file_directory) File.open(output_file_name, 'w') { |f| f.write(output) } group_metadata.add_test( id: test_id, file_name: base_output_file_name ) end end end end