inferno_core 0.6.14 → 0.6.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/inferno/apps/cli/evaluate.rb +1 -1
- data/lib/inferno/apps/cli/requirements.rb +8 -0
- data/lib/inferno/apps/cli/requirements_coverage_checker.rb +1 -1
- data/lib/inferno/apps/cli/requirements_exporter.rb +78 -19
- data/lib/inferno/apps/web/serializers/requirement.rb +1 -1
- data/lib/inferno/dsl/assertions.rb +3 -2
- data/lib/inferno/dsl/fhir_resource_navigation.rb +1 -1
- data/lib/inferno/dsl/fhir_resource_validation.rb +25 -18
- data/lib/inferno/entities/requirement.rb +7 -2
- data/lib/inferno/feature.rb +4 -0
- data/lib/inferno/public/bundle.js +18 -18
- data/lib/inferno/repositories/requirements.rb +4 -8
- data/lib/inferno/version.rb +1 -1
- metadata +30 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bdded0041b27a81a8cedae003b073e738a719eda6671cb39b1556bd165a986c9
|
4
|
+
data.tar.gz: f9cb54ff76488ce34f8f9c9464bbc3588f67f3931d6eef284a78d1af32a0b78e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e53518c76be16a5cc631a503c84388b706d2030a30469048379f3b4d91d1525d5e1ee373cb454c191b97eb857c9682d821270c9c2a35cfe408b5fd7fa405a236
|
7
|
+
data.tar.gz: a078da89879d42f3cda28ebc8dca66feca2a85e9f735868bbcd4dbf70774ef268e613fd4aad4fe076002af1d3d7035bd02de8c2679d2ce17b8ee05a794f629ab
|
@@ -112,7 +112,7 @@ module Inferno
|
|
112
112
|
Inferno::DSL::FHIRResourceValidation::Validator.new(:default, 'evaluator_cli') do
|
113
113
|
igs(ig_path)
|
114
114
|
|
115
|
-
|
115
|
+
validation_context do
|
116
116
|
# For our purposes, code display mismatches should be warnings and not affect profile conformance
|
117
117
|
displayWarnings(true)
|
118
118
|
end
|
@@ -12,6 +12,9 @@ module Inferno
|
|
12
12
|
LONGDESC
|
13
13
|
def export_csv
|
14
14
|
ENV['NO_DB'] = 'true'
|
15
|
+
|
16
|
+
require_relative '../../../inferno'
|
17
|
+
|
15
18
|
RequirementsExporter.new.run
|
16
19
|
end
|
17
20
|
|
@@ -22,6 +25,11 @@ module Inferno
|
|
22
25
|
LONGDESC
|
23
26
|
def check
|
24
27
|
ENV['NO_DB'] = 'true'
|
28
|
+
|
29
|
+
require_relative '../../../inferno'
|
30
|
+
|
31
|
+
Inferno::Application.start(:requirements)
|
32
|
+
|
25
33
|
RequirementsExporter.new.run_check
|
26
34
|
end
|
27
35
|
|
@@ -176,7 +176,7 @@ module Inferno
|
|
176
176
|
if File.exist?(output_file_path)
|
177
177
|
if old_csv == new_csv
|
178
178
|
puts "'#{output_file_name}' file is up to date."
|
179
|
-
return
|
179
|
+
return
|
180
180
|
else
|
181
181
|
puts <<~MESSAGE
|
182
182
|
#{output_file_name} file is out of date.
|
@@ -70,21 +70,24 @@ module Inferno
|
|
70
70
|
# requirement_set_id_2: [row1, row2, row 3, ...]
|
71
71
|
# }
|
72
72
|
def input_requirement_sets
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
73
|
+
@input_requirement_sets ||=
|
74
|
+
begin
|
75
|
+
requirement_set_hash = Hash.new { |hash, key| hash[key] = [] }
|
76
|
+
available_input_worksheets.each_with_object(requirement_set_hash) do |worksheet_file, requirement_sets|
|
77
|
+
worksheet = Roo::Spreadsheet.open(worksheet_file)
|
78
|
+
set_identifier = requirement_set_id(worksheet)
|
79
|
+
|
80
|
+
CSV.parse(
|
81
|
+
worksheet.sheet('Requirements').to_csv,
|
82
|
+
headers: true
|
83
|
+
).each do |row|
|
84
|
+
row_hash = row.to_h.slice(*INPUT_HEADERS)
|
85
|
+
row_hash['Sub-Requirement(s)']&.delete_prefix!('mailto:')
|
86
|
+
|
87
|
+
requirement_sets[set_identifier] << row_hash
|
88
|
+
end
|
89
|
+
end
|
86
90
|
end
|
87
|
-
end
|
88
91
|
end
|
89
92
|
|
90
93
|
def new_requirements_csv # rubocop:disable Metrics/CyclomaticComplexity
|
@@ -125,6 +128,52 @@ module Inferno
|
|
125
128
|
@old_requirements_csv ||= File.read(requirements_output_file_path)
|
126
129
|
end
|
127
130
|
|
131
|
+
def missing_subrequirements
|
132
|
+
@missing_subrequirements =
|
133
|
+
{}.tap do |missing_requirements|
|
134
|
+
repo = Inferno::Repositories::Requirements.new
|
135
|
+
|
136
|
+
input_requirement_sets
|
137
|
+
.each do |requirement_set, requirements|
|
138
|
+
requirements.each do |requirement_hash|
|
139
|
+
missing_subrequirements =
|
140
|
+
Inferno::Entities::Requirement.expand_requirement_ids(requirement_hash['Sub-Requirement(s)'])
|
141
|
+
.reject { |requirement_id| repo.exists? requirement_id }
|
142
|
+
|
143
|
+
missing_subrequirements += missing_actor_subrequirements(requirement_hash['Sub-Requirement(s)'])
|
144
|
+
|
145
|
+
next if missing_subrequirements.blank?
|
146
|
+
|
147
|
+
id = "#{requirement_set}@#{requirement_hash['ID*']}"
|
148
|
+
|
149
|
+
missing_requirements[id] = missing_subrequirements
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def missing_actor_subrequirements(subrequirement_string)
|
156
|
+
return [] if subrequirement_string.blank?
|
157
|
+
|
158
|
+
return [] unless subrequirement_string.include? '#'
|
159
|
+
|
160
|
+
subrequirement_string
|
161
|
+
.split(',')
|
162
|
+
.map(&:strip)
|
163
|
+
.select { |requirement_string| requirement_string.include? '#' }
|
164
|
+
.select do |requirement_string|
|
165
|
+
Inferno::Entities::Requirement.expand_requirement_ids(requirement_string).blank?
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def check_subrequirements
|
170
|
+
return if missing_subrequirements.blank?
|
171
|
+
|
172
|
+
missing_subrequirements.each do |id, subrequirement_ids|
|
173
|
+
puts "#{id} is missing the following sub-requirements:\n #{subrequirement_ids.join(', ')}"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
128
177
|
def run
|
129
178
|
check_presence_of_input_files
|
130
179
|
|
@@ -147,6 +196,10 @@ module Inferno
|
|
147
196
|
File.write(requirements_output_file_path, new_requirements_csv, encoding: Encoding::UTF_8)
|
148
197
|
end
|
149
198
|
|
199
|
+
Inferno::Application.start(:requirements)
|
200
|
+
|
201
|
+
check_subrequirements
|
202
|
+
|
150
203
|
puts 'Done.'
|
151
204
|
end
|
152
205
|
|
@@ -167,14 +220,20 @@ module Inferno
|
|
167
220
|
false
|
168
221
|
end
|
169
222
|
|
170
|
-
|
223
|
+
unless requirements_ok
|
224
|
+
puts <<~MESSAGE
|
225
|
+
Check Failed. To resolve, run:
|
226
|
+
|
227
|
+
bundle exec inferno requirements export_csv
|
228
|
+
|
229
|
+
MESSAGE
|
230
|
+
exit(1)
|
231
|
+
end
|
171
232
|
|
172
|
-
|
173
|
-
Check Failed. To resolve, run:
|
233
|
+
check_subrequirements
|
174
234
|
|
175
|
-
|
235
|
+
return if missing_subrequirements.blank?
|
176
236
|
|
177
|
-
MESSAGE
|
178
237
|
exit(1)
|
179
238
|
end
|
180
239
|
|
@@ -66,8 +66,9 @@ module Inferno
|
|
66
66
|
# Validate a FHIR resource
|
67
67
|
#
|
68
68
|
# @param resource [FHIR::Model]
|
69
|
-
# @param profile_url [String] url of the profile to validate against,
|
70
|
-
#
|
69
|
+
# @param profile_url [String] canonical url of the profile to validate against,
|
70
|
+
# may include a version separated by a vertical bar (|),
|
71
|
+
# and defaults to validating against the base FHIR resource type
|
71
72
|
# @param validator [Symbol] the name of the validator to use
|
72
73
|
# @return [void]
|
73
74
|
def assert_valid_resource(resource: self.resource, profile_url: nil, validator: :default)
|
@@ -147,7 +147,7 @@ module Inferno
|
|
147
147
|
end
|
148
148
|
|
149
149
|
def matching_pattern_identifier_slice?(slice, discriminator)
|
150
|
-
slice.
|
150
|
+
slice.system == discriminator[:system]
|
151
151
|
end
|
152
152
|
|
153
153
|
def matching_value_slice?(slice, discriminator)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative '../ext/fhir_models'
|
2
|
+
require_relative '../feature'
|
2
3
|
module Inferno
|
3
4
|
module DSL
|
4
5
|
# This module contains the methods needed to configure a validator to
|
@@ -19,7 +20,7 @@ module Inferno
|
|
19
20
|
# { type: 'info', message: 'everything is ok' }
|
20
21
|
# end
|
21
22
|
# end
|
22
|
-
#
|
23
|
+
# validation_context do
|
23
24
|
# noExtensibleBindingMessages true
|
24
25
|
# allowExampleUrls true
|
25
26
|
# txServer nil
|
@@ -74,12 +75,12 @@ module Inferno
|
|
74
75
|
# igs("hl7.fhir.us.core#3.1.1", "hl7.fhir.us.core#6.0.0")
|
75
76
|
# @param validator_igs [Array<String>]
|
76
77
|
def igs(*validator_igs)
|
77
|
-
|
78
|
+
validation_context(igs: validator_igs) if validator_igs.any?
|
78
79
|
|
79
|
-
|
80
|
+
validation_context.igs
|
80
81
|
end
|
81
82
|
|
82
|
-
# Set the
|
83
|
+
# Set the validationContext used as part of each validation request.
|
83
84
|
# Fields may be passed as either a Hash or block.
|
84
85
|
# Note that all fields included here will be sent directly in requests,
|
85
86
|
# there is no check that the fields are correct.
|
@@ -88,7 +89,7 @@ module Inferno
|
|
88
89
|
# # Passing fields in a block
|
89
90
|
# fhir_resource_validator do
|
90
91
|
# url 'http://example.com/validator'
|
91
|
-
#
|
92
|
+
# validation_context do
|
92
93
|
# noExtensibleBindingMessages true
|
93
94
|
# allowExampleUrls true
|
94
95
|
# txServer nil
|
@@ -99,7 +100,7 @@ module Inferno
|
|
99
100
|
# # Passing fields in a Hash
|
100
101
|
# fhir_resource_validator do
|
101
102
|
# url 'http://example.org/validator'
|
102
|
-
#
|
103
|
+
# validation_context({
|
103
104
|
# noExtensibleBindingMessages: true,
|
104
105
|
# allowExampleUrls: true,
|
105
106
|
# txServer: nil
|
@@ -107,19 +108,21 @@ module Inferno
|
|
107
108
|
# end
|
108
109
|
#
|
109
110
|
# @param definition [Hash] raw fields to set, optional
|
110
|
-
def
|
111
|
-
if @
|
111
|
+
def validation_context(definition = nil, &)
|
112
|
+
if @validation_context
|
112
113
|
if definition
|
113
|
-
@
|
114
|
+
@validation_context.definition.merge!(definition.deep_symbolize_keys)
|
114
115
|
elsif block_given?
|
115
|
-
@
|
116
|
+
@validation_context.instance_eval(&)
|
116
117
|
end
|
117
118
|
else
|
118
|
-
@
|
119
|
+
@validation_context = ValidationContext.new(definition || {}, &)
|
119
120
|
end
|
120
|
-
@
|
121
|
+
@validation_context
|
121
122
|
end
|
122
123
|
|
124
|
+
alias cli_context validation_context
|
125
|
+
|
123
126
|
# @private
|
124
127
|
def additional_validations
|
125
128
|
@additional_validations ||= []
|
@@ -268,9 +271,13 @@ module Inferno
|
|
268
271
|
|
269
272
|
@session_id = validator_session_id if validator_session_id
|
270
273
|
|
274
|
+
# HL7 Validator Core 6.5.19+ renamed `cliContext` to `validationContext`.
|
275
|
+
# This allows backward compatibility until the validator-wrapper is updated.
|
276
|
+
context_key = Feature.use_validation_context_key? ? :validationContext : :cliContext
|
277
|
+
|
271
278
|
wrapped_resource = {
|
272
|
-
|
273
|
-
**
|
279
|
+
context_key => {
|
280
|
+
**validation_context.definition,
|
274
281
|
profiles: [profile_url]
|
275
282
|
},
|
276
283
|
filesToValidate: [
|
@@ -365,10 +372,10 @@ module Inferno
|
|
365
372
|
end
|
366
373
|
|
367
374
|
# @private
|
368
|
-
class
|
375
|
+
class ValidationContext
|
369
376
|
attr_reader :definition
|
370
377
|
|
371
|
-
|
378
|
+
VALIDATIONCONTEXT_DEFAULTS = {
|
372
379
|
sv: '4.0.1',
|
373
380
|
doNative: false,
|
374
381
|
extensions: ['any'],
|
@@ -377,13 +384,13 @@ module Inferno
|
|
377
384
|
|
378
385
|
# @private
|
379
386
|
def initialize(definition, &)
|
380
|
-
@definition =
|
387
|
+
@definition = VALIDATIONCONTEXT_DEFAULTS.merge(definition.deep_symbolize_keys)
|
381
388
|
instance_eval(&) if block_given?
|
382
389
|
end
|
383
390
|
|
384
391
|
# @private
|
385
392
|
def method_missing(method_name, *args)
|
386
|
-
# Interpret any other method as setting a field on
|
393
|
+
# Interpret any other method as setting a field on validationContext.
|
387
394
|
# Follow the same format as `Validator.url` here:
|
388
395
|
# only set the value if one is provided.
|
389
396
|
# args will be an empty array if no value is provided.
|
@@ -12,7 +12,8 @@ module Inferno
|
|
12
12
|
:requirement,
|
13
13
|
:conformance,
|
14
14
|
:actors,
|
15
|
-
:
|
15
|
+
:subrequirements,
|
16
|
+
:subrequirements_string,
|
16
17
|
:conditionality,
|
17
18
|
:not_tested_reason,
|
18
19
|
:not_tested_details
|
@@ -28,6 +29,10 @@ module Inferno
|
|
28
29
|
self.requirement_set = id.split(/[@#]/).first
|
29
30
|
end
|
30
31
|
|
32
|
+
def subrequirements
|
33
|
+
@subrequirements ||= self.class.expand_requirement_ids(subrequirements_string, requirement_set)
|
34
|
+
end
|
35
|
+
|
31
36
|
# Expand a comma-delimited list of requirement id references into an Array
|
32
37
|
# of full requirement ids
|
33
38
|
#
|
@@ -62,7 +67,7 @@ module Inferno
|
|
62
67
|
requirement_ids =
|
63
68
|
if actor.present?
|
64
69
|
return Repositories::Requirements.new.requirements_for_actor(current_set, actor).map(&:id)
|
65
|
-
elsif requirement_string.include?
|
70
|
+
elsif requirement_string.include?('-') && !requirement_string.match?(/[^\d\-]/)
|
66
71
|
start_id, end_id = requirement_string.split('-')
|
67
72
|
if start_id.match?(/^\d+$/) && end_id.match?(/^\d+$/)
|
68
73
|
(start_id..end_id).to_a
|
data/lib/inferno/feature.rb
CHANGED