Fi 898 generic generator from capability statement #477
Fi 898 generic generator from capability statement #477
Conversation
81a0282
to
d44eb61
Compare
There was a problem hiding this 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' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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| |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
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 } |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 🤷♂️ .
Co-authored-by: Stephen MacVicar <Jammjammjamm@users.noreply.github.com>
b308c72
to
31020e7
Compare
generator/sequence_metadata.rb
Outdated
capabilities['extension'] | ||
&.select { |ext| ext['url'] == search_combo_url } | ||
&.map do |combo| | ||
expectation = combo['extension'].find { |ext| ext['url'] == EXPECTATION_URL }['valueCode'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 byGenericGenerator
create_search_validation
is only used bySequenceMetadata
- 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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
There was a problem hiding this 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.
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.