inferno_core 0.4.8 → 0.4.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9fb2c95aa9d590f9c05ceb25a236f0552ae2a94e91c49de3a116dbe970e62de
4
- data.tar.gz: e81873f6d4c4a4b620fa2831298ce089567d07df5e2ca93b70cec127c2f67fbf
3
+ metadata.gz: 79e59753922bf1c5a06e2603a27f267e6b75aed91d46b5531b2ecffcf13a95a8
4
+ data.tar.gz: 318edf53524ede718e5331b9ec4eb626537553cd0d88ff2df3a4237dc83c2f3e
5
5
  SHA512:
6
- metadata.gz: b5195ed44f0fb45fa7688e5dd3f4c74cc5012a689205cf39f27ab08a1ca25713cc4ce7a2c1351a281c311b38e38c28b72b5e09cf1771f88a220ebd6735ff87fd
7
- data.tar.gz: 96b4316208dd689aad2e1205ac29c15e452d0086f72bbe1dff8ee349eccf5c579165bf7610196dfdb1cfcd2e959ad8d536e2978d8a00c60e598551a619447a34
6
+ metadata.gz: 6ab836f245a7172c320405d75649be9ab8281b9d7e9520818b160f75aecdac21a7a94aa8d91f9337361475e27560260b36896e7ee5c7f7f6b749123e4b75f4a4
7
+ data.tar.gz: 3c1f9dbd1209817b38114a609a20c4e6cca27c89743d7c91a8fe954be70a4450112ee72f07ceabf7e9e9c40a8140e7990a6280b70625f71596d8aa0b0ee2b569
@@ -18,12 +18,25 @@ module Inferno
18
18
  end
19
19
 
20
20
  desc 'start', 'Start Inferno'
21
+ option :watch,
22
+ default: false,
23
+ type: :boolean,
24
+ desc: 'Automatically restart Inferno when a file is changed.'
21
25
  def start
26
+ command = 'foreman start --env=/dev/null'
22
27
  if `gem list -i foreman`.chomp == 'false'
23
- puts "You must install foreman with 'gem install foreman' prior to running inferno."
28
+ puts "You must install foreman with 'gem install foreman' prior to running Inferno."
24
29
  end
25
30
 
26
- system 'foreman start --env=/dev/null'
31
+ if options[:watch]
32
+ if `gem list -i rerun`.chomp == 'false'
33
+ puts "You must install 'rerun' with 'gem install rerun' to restart on file changes."
34
+ end
35
+
36
+ command = "rerun \"#{command}\" --background"
37
+ end
38
+
39
+ system command
27
40
  end
28
41
 
29
42
  desc 'suites', 'List available test suites'
@@ -0,0 +1,40 @@
1
+ module Inferno
2
+ module Web
3
+ module Controllers
4
+ module TestSessions
5
+ class ClientShow < Controller
6
+ config.default_response_format = :html
7
+
8
+ CLIENT_PAGE =
9
+ ERB.new(
10
+ File.read(
11
+ File.join(
12
+ Inferno::Application.root, 'lib', 'inferno', 'apps', 'web', 'index.html.erb'
13
+ )
14
+ )
15
+ ).result.freeze
16
+
17
+ def handle(req, res)
18
+ test_session_id = req.params[:id]
19
+ test_suite_id = req.params[:test_suite_id]
20
+
21
+ test_session = repo.find(test_session_id)
22
+ halt 404 if test_session.nil?
23
+
24
+ if test_suite_id.blank? || test_suite_id != test_session.test_suite_id
25
+ test_suite_id = test_session.test_suite_id
26
+
27
+ res.redirect_to "#{Inferno::Application['base_url']}/#{test_suite_id}/#{test_session_id}"
28
+ end
29
+
30
+ test_suite = Inferno::Repositories::TestSuites.new.find(test_suite_id)
31
+
32
+ halt 404 if test_suite.nil?
33
+
34
+ res.body = CLIENT_PAGE
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -53,7 +53,6 @@ module Inferno
53
53
  # Should not need Content-Type header but GitHub Codespaces will not work without them.
54
54
  # This could be investigated and likely removed if addressed properly elsewhere.
55
55
  get '/', to: ->(_env) { [200, { 'Content-Type' => 'text/html' }, [client_page]] }
56
- get '/test_sessions/:id', to: ->(_env) { [200, { 'Content-Type' => 'text/html' }, [client_page]] }
57
56
 
58
57
  Inferno.routes.each do |route|
59
58
  cleaned_id = route[:suite].id.gsub(/[^a-zA-Z\d\-._~]/, '_')
@@ -70,6 +69,9 @@ module Inferno
70
69
  Application['logger'].info("Registering suite route: #{suite_path}")
71
70
  get suite_path, to: ->(_env) { [200, {}, [client_page]] }
72
71
  end
72
+
73
+ get '/test_sessions/:id', to: Inferno::Web::Controllers::TestSessions::ClientShow, as: :client_session_show
74
+ get '/:test_suite_id/:id', to: Inferno::Web::Controllers::TestSessions::ClientShow, as: :client_suite_session_show
73
75
  end
74
76
 
75
77
  Router = # rubocop:disable Naming/ConstantName
@@ -2,6 +2,10 @@ Inferno::Application.boot(:suites) do
2
2
  init do
3
3
  use :logging
4
4
 
5
+ require 'inferno/entities/test'
6
+ require 'inferno/entities/test_group'
7
+ require 'inferno/entities/test_suite'
8
+
5
9
  files_to_load = Dir.glob(File.join(Dir.pwd, 'lib', '*.rb'))
6
10
 
7
11
  if ENV['LOAD_DEV_SUITES'].present?
@@ -12,6 +12,7 @@ module Inferno
12
12
  # @param test a value whose truthiness will determine whether the
13
13
  # assertion passes or fails
14
14
  # @param message [String] failure message
15
+ # @return [void]
15
16
  def assert(test, message = '')
16
17
  raise Exceptions::AssertionException, message unless test
17
18
  end
@@ -21,12 +22,15 @@ module Inferno
21
22
  "Unexpected response status: expected #{Array.wrap(expected).join(', ')}, but received #{received}"
22
23
  end
23
24
 
24
- # Check an response's status
25
+ # Check a response's status
25
26
  #
26
27
  # @param status [Integer, Array<Integer>] a single integer or an array of
27
28
  # integer status codes
29
+ # @param request [Inferno::Entities::Request]
28
30
  # @param response [Hash]
29
- def assert_response_status(status, response: self.response)
31
+ # @return [void]
32
+ def assert_response_status(status, request: self.request, response: nil)
33
+ response ||= request&.response
30
34
  assert Array.wrap(status).include?(response[:status]), bad_response_status_message(status, response[:status])
31
35
  end
32
36
 
@@ -44,6 +48,7 @@ module Inferno
44
48
  # assert_resource_type(:capability_statement)
45
49
  # assert_resource_type('CapabilityStatement')
46
50
  # assert_resource_type(FHIR::CapabilityStatement)
51
+ # @return [void]
47
52
  def assert_resource_type(resource_type, resource: self.resource)
48
53
  resource_type_name = normalize_resource_type(resource_type)
49
54
 
@@ -61,8 +66,10 @@ module Inferno
61
66
  # @param resource [FHIR::Model]
62
67
  # @param profile_url [String] url of the profile to validate against,
63
68
  # defaults to validating against the base FHIR resource
64
- def assert_valid_resource(resource: self.resource, profile_url: nil)
65
- assert resource_is_valid?(resource:, profile_url:),
69
+ # @param validator [Symbol] the name of the validator to use
70
+ # @return [void]
71
+ def assert_valid_resource(resource: self.resource, profile_url: nil, validator: :default)
72
+ assert resource_is_valid?(resource:, profile_url:, validator:),
66
73
  invalid_resource_message(profile_url)
67
74
  end
68
75
 
@@ -93,6 +100,7 @@ module Inferno
93
100
  # 'Condition': nil
94
101
  # }
95
102
  # )
103
+ # @return [void]
96
104
  def assert_valid_bundle_entries(bundle: resource, resource_types: {})
97
105
  assert_resource_type('Bundle', resource: bundle)
98
106
 
@@ -148,6 +156,7 @@ module Inferno
148
156
  #
149
157
  # @param maybe_json_string [String]
150
158
  # @param message [String] extra failure message
159
+ # @return [void]
151
160
  def assert_valid_json(maybe_json_string, message = '')
152
161
  assert JSON.parse(maybe_json_string)
153
162
  rescue JSON::ParserError
@@ -158,15 +167,18 @@ module Inferno
158
167
  #
159
168
  # @param uri [String]
160
169
  # @param message [String] custom failure message
170
+ # @return [void]
161
171
  def assert_valid_http_uri(uri, message = '')
162
172
  error_message = message.presence || "\"#{uri}\" is not a valid URI"
163
173
  assert uri =~ /\A#{URI::DEFAULT_PARSER.make_regexp(['http', 'https'])}\z/, error_message
164
174
  end
165
175
 
166
- # Check the Content-Type header of a response
176
+ # Check the Content-Type header of a response. This assertion will fail if
177
+ # the response's content type does not begin with the provided type.
167
178
  #
168
179
  # @param type [String]
169
180
  # @param request [Inferno::Entities::Request]
181
+ # @return [void]
170
182
  def assert_response_content_type(type, request: self.request)
171
183
  header = request.response_header('Content-Type')
172
184
  assert header.present?, no_content_type_message
@@ -6,6 +6,7 @@ module Inferno
6
6
  # configuration provides a way to modify test behavior at boot time.
7
7
  #
8
8
  # The main features enabled by configuration are:
9
+ #
9
10
  # - Modifying the properties of a runnable's inputs. This could include
10
11
  # locking a particular input, making a particular input optional/required,
11
12
  # or changing an input's value.
@@ -81,6 +82,7 @@ module Inferno
81
82
  # will be applied to the runnable and all of its children.
82
83
  #
83
84
  # @param new_configuration [Hash]
85
+ # @return [Inferno::DSL::Configurable::Configuration]
84
86
  def config(new_configuration = {})
85
87
  @config ||= Configuration.new
86
88
 
@@ -243,6 +243,7 @@ module Inferno
243
243
  # @param block a block to configure the client
244
244
  # @see Inferno::FHIRClientBuilder Documentation for the client
245
245
  # configuration DSL
246
+ # @return [void]
246
247
  def fhir_client(name = :default, &block)
247
248
  fhir_client_definitions[name] = block
248
249
  end
@@ -99,7 +99,8 @@ module Inferno
99
99
  .select { |message| message.is_a? Hash }
100
100
  end
101
101
 
102
- # Filter out unwanted validation messages
102
+ # Filter out unwanted validation messages. Any messages for which the
103
+ # block evalutates to a truthy value will be excluded.
103
104
  #
104
105
  # @example
105
106
  # validator do
@@ -198,6 +198,7 @@ module Inferno
198
198
  # @param block a block to configure the client
199
199
  # @see Inferno::HTTPClientBuilder Documentation for the client
200
200
  # configuration DSL
201
+ # @return [void]
201
202
  def http_client(name = :default, &block)
202
203
  http_client_definitions[name] = block
203
204
  end
@@ -47,7 +47,7 @@ module Inferno
47
47
  # @param identifier [Symbol] identifier for the output
48
48
  # @param other_identifiers [Symbol] array of symbols if specifying multiple outputs
49
49
  # @param output_definition [Hash] options for output
50
- # @option output_definition [String] :type text | textarea | oauth_credentials
50
+ # @option output_definition [String] :type text, textarea, or oauth_credentials
51
51
  # @return [void]
52
52
  # @example
53
53
  # output :patient_id, :condition_id, :observation_id
@@ -89,6 +89,7 @@ module Inferno
89
89
  # Specify the named requests made by a test
90
90
  #
91
91
  # @param identifiers [Symbol] one or more request identifiers
92
+ # @return [void]
92
93
  def makes_request(*identifiers)
93
94
  named_requests_made.concat(identifiers).uniq!
94
95
  identifiers.each do |identifier|
@@ -99,6 +100,7 @@ module Inferno
99
100
  # Specify the name for a request received by a test
100
101
  #
101
102
  # @param identifier [Symbol]
103
+ # @return [void]
102
104
  def receives_request(identifier)
103
105
  config.add_request(identifier)
104
106
  @incoming_request_name = identifier
@@ -112,6 +114,7 @@ module Inferno
112
114
  # Specify the named requests used by a test
113
115
  #
114
116
  # @param identifiers [Symbol] one or more request identifiers
117
+ # @return [void]
115
118
  def uses_request(*identifiers)
116
119
  named_requests_used.concat(identifiers).uniq!
117
120
  identifiers.each do |identifier|
@@ -5,6 +5,7 @@ module Inferno
5
5
  # Halt execution of the current test and mark it as passed.
6
6
  #
7
7
  # @param message [String]
8
+ # @return [void]
8
9
  def pass(message = '')
9
10
  raise Exceptions::PassException, message
10
11
  end
@@ -14,6 +15,7 @@ module Inferno
14
15
  #
15
16
  # @param test [Boolean]
16
17
  # @param message [String]
18
+ # @return [void]
17
19
  def pass_if(test, message = '')
18
20
  raise Exceptions::PassException, message if test
19
21
  end
@@ -21,6 +23,7 @@ module Inferno
21
23
  # Halt execution of the current test and mark it as skipped.
22
24
  #
23
25
  # @param message [String]
26
+ # @return [void]
24
27
  def skip(message = '')
25
28
  raise Exceptions::SkipException, message
26
29
  end
@@ -30,6 +33,7 @@ module Inferno
30
33
  #
31
34
  # @param test [Boolean]
32
35
  # @param message [String]
36
+ # @return [void]
33
37
  def skip_if(test, message = '')
34
38
  raise Exceptions::SkipException, message if test
35
39
  end
@@ -37,6 +41,7 @@ module Inferno
37
41
  # Halt execution of the current test and mark it as omitted.
38
42
  #
39
43
  # @param message [String]
44
+ # @return [void]
40
45
  def omit(message = '')
41
46
  raise Exceptions::OmitException, message
42
47
  end
@@ -46,6 +51,7 @@ module Inferno
46
51
  #
47
52
  # @param test [Boolean]
48
53
  # @param message [String]
54
+ # @return [void]
49
55
  def omit_if(test, message = '')
50
56
  raise Exceptions::OmitException, message if test
51
57
  end
@@ -75,6 +81,7 @@ module Inferno
75
81
  # @param message [String]
76
82
  # @param timeout [Integer] Number of seconds to wait for an incoming
77
83
  # request
84
+ # @return [void]
78
85
  def wait(identifier:, message: '', timeout: 300)
79
86
  identifier(identifier)
80
87
  wait_timeout(timeout)
@@ -268,7 +268,6 @@ module Inferno
268
268
  #
269
269
  # @param optional [Boolean]
270
270
  # @return [void]
271
- #
272
271
  def optional(optional = true) # rubocop:disable Style/OptionalBooleanParameter
273
272
  @optional = optional
274
273
  end
@@ -347,6 +346,7 @@ module Inferno
347
346
  # route. The block has access to the `request` method which returns a
348
347
  # {Inferno::Entities::Request} object with the information for the
349
348
  # incoming request.
349
+ # @return [void]
350
350
  def resume_test_route(method, path, &block)
351
351
  route_class = Class.new(ResumeTestRoute) do |klass|
352
352
  klass.singleton_class.instance_variable_set(:@test_run_identifier_block, block)
@@ -368,6 +368,7 @@ module Inferno
368
368
  # compatible object (e.g. a `Proc` object, a [Sinatra
369
369
  # app](http://sinatrarb.com/)) as described in the [Hanami Router
370
370
  # documentation.](https://github.com/hanami/router/tree/f41001d4c3ee9e2d2c7bb142f74b43f8e1d3a265#mount-rack-applications)
371
+ # @return [void]
371
372
  def route(method, path, handler)
372
373
  Inferno.routes << { method:, path:, handler:, suite: }
373
374
  end
@@ -414,6 +415,7 @@ module Inferno
414
415
  # group from: :ig_v2_group do
415
416
  # required_suite_options ig_version: 'ig_v2'
416
417
  # end
418
+ # @return [void]
417
419
  def required_suite_options(suite_option_requirements)
418
420
  @suite_option_requirements =
419
421
  suite_option_requirements.map do |key, value|
@@ -436,6 +438,7 @@ module Inferno
436
438
  end
437
439
  end
438
440
 
441
+ # @private
439
442
  def inspect
440
443
  non_dynamic_ancestor = ancestors.find { |ancestor| !ancestor.to_s.start_with? '#' }
441
444
  "#<#{non_dynamic_ancestor}".tap do |inspect_string|
@@ -58,29 +58,29 @@ module Inferno
58
58
  # Find a response header
59
59
  #
60
60
  # @param name [String] the header name
61
- # @return [Inferno::Entities::RequestHeader, nil]
61
+ # @return [Inferno::Entities::Header, nil]
62
62
  def response_header(name)
63
63
  response_headers.find { |header| header.name.casecmp(name).zero? }
64
64
  end
65
65
 
66
66
  # Find a request header
67
67
  #
68
- # @param name [String] the header name
69
- # @return [Inferno::Entities::RequestHeader, nil]
68
+ # @param name [String] the header name.
69
+ # @return [Inferno::Entities::Header, nil]
70
70
  def request_header(name)
71
71
  request_headers.find { |header| header.name.casecmp(name).zero? }
72
72
  end
73
73
 
74
74
  # All of the request headers
75
75
  #
76
- # @return [Array<Inferno::Entities::RequestHeader>]
76
+ # @return [Array<Inferno::Entities::Header>]
77
77
  def request_headers
78
78
  headers.select(&:request?)
79
79
  end
80
80
 
81
81
  # All of the response headers
82
82
  #
83
- # @return [Array<Inferno::Entities::RequestHeader>]
83
+ # @return [Array<Inferno::Entities::Header>]
84
84
  def response_headers
85
85
  headers.select(&:response?)
86
86
  end
@@ -131,7 +131,7 @@ module Inferno
131
131
 
132
132
  # Return the FHIR resource from the response body.
133
133
  #
134
- # @return [FHIR::Model]
134
+ # @return [FHIR::Model, nil]
135
135
  def resource
136
136
  FHIR.from_contents(response_body)
137
137
  end
@@ -28,6 +28,11 @@ module Inferno
28
28
  @messages ||= []
29
29
  end
30
30
 
31
+ # Add a message to the result.
32
+ #
33
+ # @param type [String] error, warning, or info
34
+ # @param message [String]
35
+ # @return [void]
31
36
  def add_message(type, message)
32
37
  messages << { type: type.to_s, message: format_markdown(message) }
33
38
  end
@@ -40,7 +45,6 @@ module Inferno
40
45
  # @example
41
46
  # output(patient_id: '5', bearer_token: 'ABC')
42
47
  def output(outputs)
43
- # TODO: update to track outputs that need to be updated
44
48
  outputs.each do |key, value|
45
49
  send("#{key}=", value)
46
50
  outputs_to_persist[key] = value
@@ -158,6 +162,7 @@ module Inferno
158
162
  end
159
163
  end
160
164
 
165
+ # @private
161
166
  def repository
162
167
  Inferno::Repositories::Tests.new
163
168
  end
@@ -28,6 +28,7 @@ module Inferno
28
28
  end
29
29
 
30
30
  class << self
31
+ # @private
31
32
  def repository
32
33
  Inferno::Repositories::TestGroups.new
33
34
  end
@@ -53,12 +54,14 @@ module Inferno
53
54
  # Methods to configure Inferno::DSL::Runnable
54
55
 
55
56
  # Add a child group
57
+ # @return [void]
56
58
  def group(...)
57
59
  child_metadata(group_metadata)
58
60
  define_child(...)
59
61
  end
60
62
 
61
63
  # Add a test
64
+ # @return [void]
62
65
  def test(...)
63
66
  child_metadata(test_metadata)
64
67
  define_child(...)
@@ -108,6 +111,7 @@ module Inferno
108
111
  # UI, and this group must be run as a group.
109
112
  #
110
113
  # @param value [Boolean]
114
+ # @return [void]
111
115
  def run_as_group(value = true) # rubocop:disable Style/OptionalBooleanParameter
112
116
  @run_as_group = value
113
117
  end
@@ -40,7 +40,7 @@ module Inferno
40
40
 
41
41
  self.suite_options ||= []
42
42
 
43
- test_suite.suite_options&.each do |option|
43
+ test_suite&.suite_options&.each do |option|
44
44
  if suite_options.none? { |selected_option| selected_option.id == option.id }
45
45
  suite_options << DSL::SuiteOption.new(id: option.id, value: option.list_options.first[:value])
46
46
  end
@@ -28,6 +28,7 @@ module Inferno
28
28
  @default_group
29
29
  end
30
30
 
31
+ # @private
31
32
  def repository
32
33
  Inferno::Repositories::TestSuites.new
33
34
  end
@@ -44,6 +45,7 @@ module Inferno
44
45
  # Methods to configure Inferno::DSL::Runnable
45
46
 
46
47
  # Add a child group
48
+ # @return [void]
47
49
  def group(...)
48
50
  child_metadata(group_metadata)
49
51
  define_child(...)
@@ -93,6 +95,7 @@ module Inferno
93
95
  # @yieldreturn [Array<Hash>] An array of message hashes containing the
94
96
  # keys `:type` and `:message`. Type options are `info`, `warning`, and
95
97
  # `error`.
98
+ # @return [void]
96
99
  def check_configuration(&block)
97
100
  @check_configuration_block = block
98
101
  end
@@ -134,6 +137,7 @@ module Inferno
134
137
  # group from: :ig_v2_group do
135
138
  # required_suite_options ig_version: 'ig_v2'
136
139
  # end
140
+ # @return [void]
137
141
  def suite_option(identifier, **option_params)
138
142
  suite_options << DSL::SuiteOption.new(option_params.merge(id: identifier))
139
143
  end
@@ -27,7 +27,7 @@ end
27
27
  module InfernoJson
28
28
  def from_json(json)
29
29
  resource = super(json)
30
- resource.source_text = json
30
+ resource&.source_text = json
31
31
  resource
32
32
  end
33
33
  end
@@ -37,7 +37,7 @@ end
37
37
  module InfernoXml
38
38
  def from_xml(xml)
39
39
  resource = super(xml)
40
- resource.source_text = xml
40
+ resource&.source_text = xml
41
41
  resource
42
42
  end
43
43
  end