Skip to content
This repository has been archived by the owner on Jan 23, 2024. It is now read-only.

Fi 898 generic generator from capability statement #477

Merged

Conversation

ghost
Copy link

@ghost ghost commented Aug 4, 2020

This PR adds search and interaction tests based off the capability statement for the generic generator. The search tests only perform the basic search and validate functionality. It doesn't handle comparators and modifiers yet.

It also defines a new generic_utilities file that is included in all the generated sequences. You can add functions that all the generated sequences can access through that file. This way, we don' need to modify sequence_base to create shared code.

It also adds the sequence definition files like there is in us core. Right now, it contains search parameter metadata, but it will later contain the terminology and must support information.

I also added a generic_generator_utilities file that is used to store shared code across the generator.

@radamson radamson force-pushed the fi-898-generic-generator-from-capability-statement branch from 81a0282 to d44eb61 Compare August 5, 2020 13:58
Copy link
Contributor

@Jammjammjamm Jammjammjamm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to do some more testing, but here are some initial thoughts.

end

def generate_sequence_definitions(metadata)
file_name = sequence_out_path + '/profile_definitions/' + metadata.file_name + '_definitions.rb'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
file_name = sequence_out_path + '/profile_definitions/' + metadata.file_name + '_definitions.rb'
output_directory = File.join(sequence_out_path, 'profile_definitions')
file_name = File.join(output_directory, metadata.file_name + '_definitions.rb')

This directory is used also used below. We should probably try to be consistent about using File.join.

# frozen_string_literal: true

module Inferno
module USCore310ProfileDefinitions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a new name.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@czh-orz renamed this to ProfileDefinitions

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can't just be ProfileDefinitions because then every generated sequence will share the same definitions. It needs to be Inferno::SOMETHING_UNIQUEProfileDefinitions or Inferno::SOMETHING_UNIQUE::ProfileDefinitions.

Copy link
Contributor

@radamson radamson Aug 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed so it includes the path.

If the module is in the ig directory it will be named IgProfileDefinitions and if its in the uscore directory it will be UscoreProfileDefinition. Not super familiar with all the metadata attributes that would be available to use here, but settled on this after talking with @czh-orz.

.find { |rest| rest['mode'] == 'server' }['resource']
.find { |resource| resource['type'] == profile['type'] }

@search_parameter_metadata = capabilities['searchParam']&.map do |param|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should seriously consider moving the search stuff to its own class in the near future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, but I think "near future" needs to be a future PR 🙂 .

generator/sequence_metadata.rb Outdated Show resolved Hide resolved
def search_combinations_from_capability_statement(capabilities)
search_combo_url = 'http://hl7.org/fhir/StructureDefinition/capabilitystatement-search-parameter-combination'
capabilities['extension']
&.select { |ext| ext['url'] == search_combo_url }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation is wonky in this method.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the spacing and removed the redundant variable.

The spacing is still a little wonky but Rubocop wants it this way 🤷‍♂️ .

generator/generic/static/generic_utilities.rb Outdated Show resolved Hide resolved
@radamson radamson force-pushed the fi-898-generic-generator-from-capability-statement branch from b308c72 to 31020e7 Compare August 6, 2020 16:50
capabilities['extension']
&.select { |ext| ext['url'] == search_combo_url }
&.map do |combo|
expectation = combo['extension'].find { |ext| ext['url'] == EXPECTATION_URL }['valueCode']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with the previous comment on this, rubocop has a problem with me fixing the indentation of the code in the do block.

I tried updating rubocop to see if that fixed it incase a recent update (like rubocop/rubocop#6749) had changed this, but no 🎲 .

Instead I added disabled the rubocop indentation checks for just that block of code. Hilariously, I also had to disable the CommentIndentation check as well to indent the rubocop:disable directive the way I wanted.


module Inferno
module Generator
module GenericGeneratorUtilties
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this module forms a cohesive unit.

  • structure_to_string is only used by GenericGenerator
  • create_search_validation is only used by SequenceMetadata
  • the other methods are helpers for create_search_validation

The name doesn't help you know why a method would be in here rather than in one of those classes.

Copy link
Author

@ghost ghost Aug 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to leave the create_search_validation stuff out of SequenceMetadata because I wanted to keep that file for just profile information. create_search_validation just uses the metadata to form code and doesn't add any metadata. I couldn't put it in search_test either because it doesn't go inside of a test itself. So I just put it in the utilities file because I didn't want to cluttter up SequenceMetadata with non-metadata stuff I guess.

structure_to_string is going to be needed later on when I add must support stuff.

begin
new_resource_json = JSON.parse(File.read(resource))
rescue JSON::ParserError # failed to parse json
next
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably log something here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

validate_functions
end

def search_param_match_found_code(type, element)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than duplicating this code in each sequence, can you stick this method's logic (without all the stringifying) into SequenceUtilities.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is reasonable. But I do remember Rob saying something about writing out functions explicitly like this in each sequence to make it easier to understand. But anyway, can we leave this to a future PR?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My preference in general is for it to be fairly obvious what a given test does without having to continually hop to other shared code locations. Yeah, it results in duplication of generated code, but that duplicated code never needs to managed indivdually (its managed as a group in the generator). Just a preference. But if we end up with a lot of tests that basically are just a call to a shared function that needs to be followed to understand what is going on at all i think we are doing it wrong.

Copy link
Contributor

@arscan arscan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good with this as a start. We may reconsider the name (SimpleSearchGenerator or something) -- our intent is to not have a Generic Generator that will be expanded to do everything. But we can explore that as we continue down this path.

Copy link
Contributor

@radamson radamson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just ran through it again and everything went smoothly.

@radamson radamson merged commit 1364e7b into development Aug 7, 2020
@radamson radamson deleted the fi-898-generic-generator-from-capability-statement branch August 7, 2020 19:18
@radamson radamson mentioned this pull request Aug 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants