inferno_core 0.6.10 → 0.6.12

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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/inferno/apps/cli/evaluate.rb +8 -7
  3. data/lib/inferno/apps/cli/execute.rb +17 -21
  4. data/lib/inferno/apps/cli/main.rb +12 -1
  5. data/lib/inferno/apps/cli/requirements.rb +49 -0
  6. data/lib/inferno/apps/cli/requirements_coverage_checker.rb +238 -0
  7. data/lib/inferno/apps/cli/suite.rb +9 -0
  8. data/lib/inferno/apps/web/controllers/test_sessions/results/io_value.rb +68 -0
  9. data/lib/inferno/apps/web/router.rb +13 -5
  10. data/lib/inferno/apps/web/serializers/result.rb +2 -2
  11. data/lib/inferno/apps/web/serializers/serializer.rb +7 -0
  12. data/lib/inferno/apps/web/serializers/test.rb +1 -1
  13. data/lib/inferno/apps/web/serializers/test_group.rb +1 -1
  14. data/lib/inferno/apps/web/serializers/test_suite.rb +2 -2
  15. data/lib/inferno/dsl/fhir_client.rb +9 -1
  16. data/lib/inferno/dsl/http_client.rb +9 -1
  17. data/lib/inferno/dsl/runnable.rb +15 -30
  18. data/lib/inferno/dsl/suite_requirements.rb +26 -26
  19. data/lib/inferno/entities/result.rb +39 -0
  20. data/lib/inferno/entities/test_kit.rb +4 -0
  21. data/lib/inferno/feature.rb +9 -0
  22. data/lib/inferno/public/bundle.js +34 -34
  23. data/lib/inferno/repositories/repository.rb +19 -0
  24. data/lib/inferno/repositories/requirements.rb +4 -3
  25. data/lib/inferno/repositories/results.rb +6 -3
  26. data/lib/inferno/repositories/runnable_repository.rb +29 -0
  27. data/lib/inferno/repositories/test_groups.rb +2 -2
  28. data/lib/inferno/repositories/test_sessions.rb +1 -0
  29. data/lib/inferno/repositories/test_suites.rb +2 -2
  30. data/lib/inferno/repositories/tests.rb +2 -2
  31. data/lib/inferno/repositories.rb +1 -0
  32. data/lib/inferno/version.rb +1 -1
  33. metadata +6 -3
  34. data/spec/features_helper.rb +0 -12
@@ -38,7 +38,7 @@ module Inferno
38
38
  suite_options = options[:suite_options]
39
39
  Input.render_as_hash(suite.available_inputs(suite_options).values)
40
40
  end
41
- field :requirement_sets, if: :field_present? do |suite, options|
41
+ field :requirement_sets, if: :field_present_and_requirements_enabled? do |suite, options|
42
42
  selected_options = options[:suite_options] || []
43
43
  requirement_sets = suite.requirement_sets.select do |requirement_set|
44
44
  requirement_set.suite_options.all? { |suite_option| selected_options.include? suite_option }
@@ -46,7 +46,7 @@ module Inferno
46
46
 
47
47
  RequirementSet.render_as_hash(requirement_sets)
48
48
  end
49
- field :verifies_requirements, if: :field_present?
49
+ field :verifies_requirements, if: :field_present_and_requirements_enabled?
50
50
  end
51
51
  end
52
52
  end
@@ -52,7 +52,11 @@ module Inferno
52
52
  # @see Inferno::DSL::FHIRClientBuilder
53
53
  def fhir_client(client = :default)
54
54
  fhir_clients[client] ||=
55
- FHIRClientBuilder.new.build(self, self.class.fhir_client_definitions[client])
55
+ FHIRClientBuilder.new.build(self, find_fhir_client_definition(client))
56
+ end
57
+
58
+ def find_fhir_client_definition(client)
59
+ self.class.find_fhir_client_definition(client)
56
60
  end
57
61
 
58
62
  # @private
@@ -443,6 +447,10 @@ module Inferno
443
447
  @fhir_client_definitions ||= {}
444
448
  end
445
449
 
450
+ def find_fhir_client_definition(client)
451
+ fhir_client_definitions[client] || parent&.find_fhir_client_definition(client)
452
+ end
453
+
446
454
  # Define a FHIR client to be used by a Runnable.
447
455
  #
448
456
  # @param name [Symbol] a name used to reference this particular client
@@ -46,7 +46,7 @@ module Inferno
46
46
  def http_client(client = :default)
47
47
  return http_clients[client] if http_clients[client]
48
48
 
49
- definition = self.class.http_client_definitions[client]
49
+ definition = find_http_client_definition(client)
50
50
  return nil if definition.nil?
51
51
 
52
52
  tcp_exception_handler do
@@ -54,6 +54,10 @@ module Inferno
54
54
  end
55
55
  end
56
56
 
57
+ def find_http_client_definition(client)
58
+ self.class.find_http_client_definition(client)
59
+ end
60
+
57
61
  # @private
58
62
  def http_clients
59
63
  @http_clients ||= {}
@@ -196,6 +200,10 @@ module Inferno
196
200
  @http_client_definitions ||= {}
197
201
  end
198
202
 
203
+ def find_http_client_definition(client)
204
+ http_client_definitions[client] || parent&.find_http_client_definition(client)
205
+ end
206
+
199
207
  # Define a HTTP client to be used by a Runnable.
200
208
  #
201
209
  # @param name [Symbol] a name used to reference this particular client
@@ -39,6 +39,7 @@ module Inferno
39
39
  # @private
40
40
  VARIABLES_NOT_TO_COPY = [
41
41
  :@id, # New runnable will have a different id
42
+ :@database_id, # New runnable will have a different database_id
42
43
  :@parent, # New runnable unlikely to have the same parent
43
44
  :@all_children, # New subclasses have to be made for each child
44
45
  :@test_count, # Needs to be recalculated
@@ -164,22 +165,6 @@ module Inferno
164
165
  klass.output output_name
165
166
  end
166
167
 
167
- new_fhir_client_definitions = klass.instance_variable_get(:@fhir_client_definitions) || {}
168
- fhir_client_definitions.each do |name, definition|
169
- next if new_fhir_client_definitions.include? name
170
-
171
- new_fhir_client_definitions[name] = definition.dup
172
- end
173
- klass.instance_variable_set(:@fhir_client_definitions, new_fhir_client_definitions)
174
-
175
- new_http_client_definitions = klass.instance_variable_get(:@http_client_definitions) || {}
176
- http_client_definitions.each do |name, definition|
177
- next if new_http_client_definitions.include? name
178
-
179
- new_http_client_definitions[name] = definition.dup
180
- end
181
- klass.instance_variable_set(:@http_client_definitions, new_http_client_definitions)
182
-
183
168
  klass.config(config)
184
169
 
185
170
  klass.all_children.select!(&:required?) if hash_args.delete(:exclude_optional)
@@ -210,20 +195,20 @@ module Inferno
210
195
  def id(new_id = nil)
211
196
  return @id if new_id.nil? && @id.present?
212
197
 
213
- prefix =
214
- if parent
215
- "#{parent.id}-"
216
- else
217
- ''
218
- end
219
-
198
+ prefix = parent ? "#{parent.id}-" : ''
220
199
  @base_id = new_id || @base_id || default_id
200
+ @id = "#{prefix}#{@base_id}"
221
201
 
222
- final_id = "#{prefix}#{@base_id}"
202
+ if @id.length > 255
203
+ hash = Digest::SHA1.hexdigest(@id)[0...10]
204
+ @database_id = "#{@id[0...244]}-#{hash}"
205
+ end
223
206
 
224
- raise Exceptions::InvalidRunnableIdException, final_id if final_id.length > 255
207
+ @id
208
+ end
225
209
 
226
- @id = final_id
210
+ def database_id
211
+ @database_id ||= id
227
212
  end
228
213
 
229
214
  # Set/Get a runnable's title
@@ -571,10 +556,10 @@ module Inferno
571
556
  end
572
557
 
573
558
  # @private
574
- def all_requirements(suite_options = [])
575
- children(suite_options).flat_map do |child|
576
- child.verifies_requirements + child.all_requirements(suite_options)
577
- end
559
+ def all_verified_requirements(suite_options = [])
560
+ verifies_requirements + children(suite_options).flat_map do |child|
561
+ child.all_verified_requirements(suite_options)
562
+ end.uniq
578
563
  end
579
564
 
580
565
  # @private
@@ -9,33 +9,33 @@ module Inferno
9
9
  # @return [Array<Inferno::DSL::RequirementSet>]
10
10
  #
11
11
  # @example
12
- # class Suite < Inferno::TestSuite
13
- # requirement_sets(
14
- # {
15
- # identifier: 'example-regulation-1',
16
- # title: 'Example Regulation 1',
17
- # actor: 'Provider' # Only include requirements for the 'Provider'
18
- # # actor
19
- # },
20
- # {
21
- # identifier: 'example-ig-1',
22
- # title: 'Example Implementation Guide 1',
23
- # actor: 'Provider',
24
- # requirements: '2, 4-5' # Only include these specific requirements
25
- # },
26
- # {
27
- # identifier: 'example-ig-2',
28
- # title: 'Example Implementation Guide 2',
29
- # requirements: 'Referenced', # Only include requirements from this
30
- # # set that are referenced by other
31
- # # included requirements
32
- # actor: 'Server',
33
- # suite_options: { # Only include these requirements if the ig
34
- # ig_version: '3.0.0' # version 3.0.0 suite option is selected
12
+ # class Suite < Inferno::TestSuite
13
+ # requirement_sets(
14
+ # {
15
+ # identifier: 'example-regulation-1',
16
+ # title: 'Example Regulation 1',
17
+ # actor: 'Provider' # Only include requirements for the 'Provider'
18
+ # # actor
19
+ # },
20
+ # {
21
+ # identifier: 'example-ig-1',
22
+ # title: 'Example Implementation Guide 1',
23
+ # actor: 'Provider',
24
+ # requirements: '2, 4-5' # Only include these specific requirements
25
+ # },
26
+ # {
27
+ # identifier: 'example-ig-2',
28
+ # title: 'Example Implementation Guide 2',
29
+ # requirements: 'Referenced', # Only include requirements from this
30
+ # # set that are referenced by other
31
+ # # included requirements
32
+ # actor: 'Server',
33
+ # suite_options: { # Only include these requirements if the ig
34
+ # ig_version: '3.0.0' # version 3.0.0 suite option is selected
35
+ # }
35
36
  # }
36
- # }
37
- # )
38
- # end
37
+ # )
38
+ # end
39
39
  def requirement_sets(*sets)
40
40
  @requirement_sets = sets.map { |set| RequirementSet.new(**set) } if sets.present?
41
41
 
@@ -71,6 +71,45 @@ module Inferno
71
71
  def waiting?
72
72
  result == 'wait'
73
73
  end
74
+
75
+ def inputs
76
+ input_json.present? ? JSON.parse(input_json) : []
77
+ end
78
+
79
+ def outputs
80
+ output_json.present? ? JSON.parse(output_json) : []
81
+ end
82
+
83
+ # Flags large inputs or outputs and replaces their values with a reference message.
84
+ #
85
+ # This method inspects either the `inputs` or `outputs` array and,
86
+ # for each item whose `value` exceeds the configured size threshold, sets `is_large: true`
87
+ # and replaces the `value` with a message pointing to the full content endpoint.
88
+ #
89
+ # @param io_type [String] Must be either `'inputs'` or `'outputs'`.
90
+ # @return [Array<Hash>] The mutated list of inputs or outputs.
91
+ def handle_large_io(io_type)
92
+ io_array = public_send(io_type)
93
+
94
+ io_array.each do |io|
95
+ next unless io_is_large?(io['value'])
96
+
97
+ io['is_large'] = true
98
+ io['value'] = <<~MESSAGE
99
+ #{io_type.singularize.capitalize} is too large to display, please visit
100
+ #{Inferno::Application['base_url']}/api/test_sessions/#{test_session_id}/results/#{id}/io/#{io_type}/#{io['name']}
101
+ for details
102
+ MESSAGE
103
+ end
104
+
105
+ io_array
106
+ end
107
+
108
+ # @private
109
+ def io_is_large?(io_value)
110
+ size_in_char = io_value.is_a?(String) ? io_value.length : io_value.to_json.length
111
+ size_in_char > ENV.fetch('MAX_IO_DISPLAY_CHAR', 10000).to_i
112
+ end
74
113
  end
75
114
  end
76
115
  end
@@ -149,6 +149,10 @@ module Inferno
149
149
  @options = suites.each_with_object({}) { |suite, hash| hash[suite.id] = suite.suite_options }
150
150
  end
151
151
 
152
+ def contains_test_suite?(test_suite_id)
153
+ suite_ids.map(&:to_sym).include? test_suite_id.to_sym
154
+ end
155
+
152
156
  # @private
153
157
  def add_self_to_repository
154
158
  repository.insert(self)
@@ -0,0 +1,9 @@
1
+ module Inferno
2
+ module Feature
3
+ class << self
4
+ def requirements_enabled?
5
+ ENV.fetch('ENABLE_REQUIREMENTS', 'false')&.casecmp?('true')
6
+ end
7
+ end
8
+ end
9
+ end