inferno_core 0.0.8 → 0.1.1
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/web/controllers/test_runs/create.rb +2 -1
- data/lib/inferno/apps/web/serializers/result.rb +1 -0
- data/lib/inferno/apps/web/serializers/test.rb +4 -0
- data/lib/inferno/apps/web/serializers/test_group.rb +4 -0
- data/lib/inferno/apps/web/serializers/test_suite.rb +3 -0
- data/lib/inferno/db/migrations/001_create_initial_structure.rb +54 -53
- data/lib/inferno/db/migrations/002_add_wait_support.rb +2 -2
- data/lib/inferno/db/migrations/003_update_session_data.rb +7 -7
- data/lib/inferno/db/migrations/004_add_request_results_table.rb +2 -2
- data/lib/inferno/db/migrations/005_add_updated_at_index_to_results.rb +1 -1
- data/lib/inferno/db/migrations/006_remove_unused_tables.rb +38 -0
- data/lib/inferno/db/schema.rb +17 -43
- data/lib/inferno/dsl/configurable.rb +12 -5
- data/lib/inferno/dsl/fhir_client.rb +58 -6
- data/lib/inferno/dsl/fhir_client_builder.rb +16 -0
- data/lib/inferno/dsl/http_client.rb +62 -0
- data/lib/inferno/dsl/oauth_credentials.rb +119 -0
- data/lib/inferno/dsl/runnable.rb +87 -9
- data/lib/inferno/entities/has_runnable.rb +26 -0
- data/lib/inferno/entities/request.rb +7 -1
- data/lib/inferno/entities/result.rb +8 -4
- data/lib/inferno/entities/test_group.rb +4 -6
- data/lib/inferno/entities/test_run.rb +1 -18
- data/lib/inferno/entities/test_suite.rb +3 -4
- data/lib/inferno/entities.rb +1 -0
- data/lib/inferno/exceptions.rb +19 -0
- data/lib/inferno/ext/fhir_client.rb +13 -0
- data/lib/inferno/public/bundle.js +14 -14
- data/lib/inferno/repositories/session_data.rb +40 -6
- data/lib/inferno/result_summarizer.rb +40 -0
- data/lib/inferno/spec_support.rb +1 -1
- data/lib/inferno/test_runner.rb +13 -9
- data/lib/inferno/version.rb +1 -1
- data/spec/factories/request.rb +1 -1
- data/spec/factories/result.rb +2 -2
- data/spec/fixtures/basic_test_group.rb +1 -0
- metadata +7 -2
@@ -103,6 +103,68 @@ module Inferno
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
+
# Perform an HTTP DELETE request
|
107
|
+
#
|
108
|
+
# @param url [String] if this request is using a defined client, this will
|
109
|
+
# be appended to the client's url. Must be an absolute url for requests
|
110
|
+
# made without a defined client
|
111
|
+
# @param client [Symbol]
|
112
|
+
# @param name [Symbol] Name for this request to allow it to be used by
|
113
|
+
# other tests
|
114
|
+
# @return [Inferno::Entities::Request]
|
115
|
+
def delete(url = '', client: :default, name: :nil, **options)
|
116
|
+
store_request('outgoing', name) do
|
117
|
+
client = http_client(client)
|
118
|
+
|
119
|
+
if client
|
120
|
+
client.delete(url, nil, options[:headers])
|
121
|
+
elsif url.match?(%r{\Ahttps?://})
|
122
|
+
Faraday.delete(url, nil, options[:headers])
|
123
|
+
else
|
124
|
+
raise StandardError, 'Must use an absolute url or define an HTTP client with a base url'
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Perform an HTTP GET request and stream the response
|
130
|
+
#
|
131
|
+
# @param block [Proc] A Proc object whose input will be the string chunks
|
132
|
+
# received while streaming response to the get request.
|
133
|
+
# @param url [String] If this request is using a defined client, this will
|
134
|
+
# be appended to the client's url. Must be an absolute url for requests
|
135
|
+
# made without a defined client
|
136
|
+
# @param limit [Integer] The number of streamed-in chunks to be stored in
|
137
|
+
# the response body. This optional input defaults to 100.
|
138
|
+
# @param client [Symbol]
|
139
|
+
# @param name [Symbol] Name for this request to allow it to be used by
|
140
|
+
# other tests
|
141
|
+
# @option options [Hash] Input headers here - headers are optional and
|
142
|
+
# must be entered as the last piece of input to this method
|
143
|
+
# @return [Inferno::Entities::Request]
|
144
|
+
def stream(block, url = '', limit = 100, client: :default, name: nil, **options)
|
145
|
+
streamed = []
|
146
|
+
|
147
|
+
collector = proc do |chunk, bytes|
|
148
|
+
streamed << chunk if limit.positive?
|
149
|
+
limit -= 1
|
150
|
+
block.call(chunk, bytes)
|
151
|
+
end
|
152
|
+
|
153
|
+
store_request('outgoing', name) do
|
154
|
+
client = http_client(client)
|
155
|
+
|
156
|
+
if client
|
157
|
+
response = client.get(url, nil, options[:headers]) { |req| req.options.on_data = collector }
|
158
|
+
elsif url.match?(%r{\Ahttps?://})
|
159
|
+
response = Faraday.get(url, nil, options[:headers]) { |req| req.options.on_data = collector }
|
160
|
+
else
|
161
|
+
raise StandardError, 'Must use an absolute url or define an HTTP client with a base url'
|
162
|
+
end
|
163
|
+
response.env.body = streamed.join
|
164
|
+
response
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
106
168
|
module ClassMethods
|
107
169
|
# @private
|
108
170
|
def http_client_definitions
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require_relative '../entities/attributes'
|
2
|
+
|
3
|
+
module Inferno
|
4
|
+
module DSL
|
5
|
+
class OAuthCredentials
|
6
|
+
ATTRIBUTES = [
|
7
|
+
:access_token,
|
8
|
+
:refresh_token,
|
9
|
+
:token_url,
|
10
|
+
:client_id,
|
11
|
+
:client_secret,
|
12
|
+
:token_retrieval_time,
|
13
|
+
:expires_in,
|
14
|
+
:name
|
15
|
+
].freeze
|
16
|
+
|
17
|
+
include Entities::Attributes
|
18
|
+
|
19
|
+
attr_accessor :client
|
20
|
+
|
21
|
+
def initialize(raw_attributes_hash)
|
22
|
+
attributes_hash = raw_attributes_hash.symbolize_keys
|
23
|
+
|
24
|
+
invalid_keys = attributes_hash.keys - ATTRIBUTES
|
25
|
+
|
26
|
+
raise Exceptions::UnknownAttributeException.new(invalid_keys, self.class) if invalid_keys.present?
|
27
|
+
|
28
|
+
attributes_hash.each do |name, value|
|
29
|
+
value = DateTime.parse(value) if name == :token_retrieval_time && value.is_a?(String)
|
30
|
+
|
31
|
+
instance_variable_set(:"@#{name}", value)
|
32
|
+
end
|
33
|
+
|
34
|
+
self.token_retrieval_time = DateTime.now if token_retrieval_time.blank?
|
35
|
+
end
|
36
|
+
|
37
|
+
# @api private
|
38
|
+
def to_hash
|
39
|
+
self.class::ATTRIBUTES.each_with_object({}) do |attribute, hash|
|
40
|
+
value = send(attribute)
|
41
|
+
next if value.nil?
|
42
|
+
|
43
|
+
value = token_retrieval_time.iso8601 if attribute == :token_retrieval_time
|
44
|
+
|
45
|
+
hash[attribute] = value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# @api private
|
50
|
+
def to_s
|
51
|
+
JSON.generate(to_hash)
|
52
|
+
end
|
53
|
+
|
54
|
+
# @api private
|
55
|
+
def add_to_client(client)
|
56
|
+
client.oauth_credentials = self
|
57
|
+
self.client = client
|
58
|
+
|
59
|
+
return unless access_token.present?
|
60
|
+
|
61
|
+
client.set_bearer_token(access_token)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @api private
|
65
|
+
def need_to_refresh?
|
66
|
+
return false if access_token.blank? || refresh_token.blank?
|
67
|
+
|
68
|
+
return true if expires_in.blank?
|
69
|
+
|
70
|
+
token_retrieval_time.to_i + expires_in - DateTime.now.to_i < 60
|
71
|
+
end
|
72
|
+
|
73
|
+
# @api private
|
74
|
+
def able_to_refresh?
|
75
|
+
refresh_token.present? && token_url.present?
|
76
|
+
end
|
77
|
+
|
78
|
+
# @api private
|
79
|
+
def confidential_client?
|
80
|
+
client_id.present? && client_secret.present?
|
81
|
+
end
|
82
|
+
|
83
|
+
# @api private
|
84
|
+
def oauth2_refresh_params
|
85
|
+
{
|
86
|
+
'grant_type' => 'refresh_token',
|
87
|
+
'refresh_token' => refresh_token
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
# @api private
|
92
|
+
def oauth2_refresh_headers
|
93
|
+
base_headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
|
94
|
+
|
95
|
+
return base_headers unless confidential_client?
|
96
|
+
|
97
|
+
credentials = "#{client_id}:#{client_secret}"
|
98
|
+
|
99
|
+
base_headers.merge(
|
100
|
+
'Authorization' => "Basic #{Base64.strict_encode64(credentials)}"
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
def update_from_response_body(request)
|
105
|
+
token_response_body = JSON.parse(request.response_body)
|
106
|
+
|
107
|
+
expires_in = token_response_body['expires_in'].is_a?(Numeric) ? token_response_body['expires_in'] : nil
|
108
|
+
|
109
|
+
self.access_token = token_response_body['access_token']
|
110
|
+
self.refresh_token = token_response_body['refresh_token']
|
111
|
+
self.expires_in = expires_in
|
112
|
+
self.token_retrieval_time = DateTime.now
|
113
|
+
|
114
|
+
add_to_client(client)
|
115
|
+
self
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/lib/inferno/dsl/runnable.rb
CHANGED
@@ -85,7 +85,6 @@ module Inferno
|
|
85
85
|
|
86
86
|
klass.parent = self
|
87
87
|
|
88
|
-
child_metadata[:collection] << klass
|
89
88
|
children << klass
|
90
89
|
|
91
90
|
configure_child_class(klass, hash_args)
|
@@ -164,6 +163,8 @@ module Inferno
|
|
164
163
|
|
165
164
|
klass.config(config)
|
166
165
|
|
166
|
+
klass.children.select!(&:required?) if hash_args.delete(:exclude_optional)
|
167
|
+
|
167
168
|
hash_args.each do |key, value|
|
168
169
|
if value.is_a? Array
|
169
170
|
klass.send(key, *value)
|
@@ -212,6 +213,16 @@ module Inferno
|
|
212
213
|
@title = new_title
|
213
214
|
end
|
214
215
|
|
216
|
+
# Set/Get a runnable's short title
|
217
|
+
#
|
218
|
+
# @param new_short_title [String]
|
219
|
+
# @return [String] the short title
|
220
|
+
def short_title(new_short_title = nil)
|
221
|
+
return @short_title if new_short_title.nil?
|
222
|
+
|
223
|
+
@short_title = new_short_title
|
224
|
+
end
|
225
|
+
|
215
226
|
# Set/Get a runnable's description
|
216
227
|
#
|
217
228
|
# @param new_description [String]
|
@@ -222,6 +233,26 @@ module Inferno
|
|
222
233
|
@description = format_markdown(new_description)
|
223
234
|
end
|
224
235
|
|
236
|
+
# Set/Get a runnable's short one-sentence description
|
237
|
+
#
|
238
|
+
# @param new_short_description [String]
|
239
|
+
# @return [String] the one-sentence description
|
240
|
+
def short_description(new_short_description = nil)
|
241
|
+
return @short_description if new_short_description.nil?
|
242
|
+
|
243
|
+
@short_description = format_markdown(new_short_description)
|
244
|
+
end
|
245
|
+
|
246
|
+
# Set/Get a runnable's input instructions
|
247
|
+
#
|
248
|
+
# @param new_input_instructions [String]
|
249
|
+
# @return [String] the input instructions
|
250
|
+
def input_instructions(new_input_instructions = nil)
|
251
|
+
return @input_instructions if new_input_instructions.nil?
|
252
|
+
|
253
|
+
@input_instructions = format_markdown(new_input_instructions)
|
254
|
+
end
|
255
|
+
|
225
256
|
# Define inputs
|
226
257
|
#
|
227
258
|
# @param identifier [Symbol] identifier for the input
|
@@ -229,12 +260,14 @@ module Inferno
|
|
229
260
|
# @param input_definition [Hash] options for input such as type, description, or title
|
230
261
|
# @option input_definition [String] :title Human readable title for input
|
231
262
|
# @option input_definition [String] :description Description for the input
|
232
|
-
# @option input_definition [String] :type text | textarea
|
263
|
+
# @option input_definition [String] :type text | textarea | radio
|
233
264
|
# @option input_definition [String] :default The default value for the input
|
234
265
|
# @option input_definition [Boolean] :optional Set to true to not require input for test execution
|
266
|
+
# @option input_definition [Hash] :options Possible input option formats based on input type
|
267
|
+
# @option options [Array] :list_options Array of options for input formats that require a list of possible values
|
235
268
|
# @return [void]
|
236
269
|
# @example
|
237
|
-
# input :
|
270
|
+
# input :patient_id, title: 'Patient ID', description: 'The ID of the patient being searched for',
|
238
271
|
# default: 'default_patient_id'
|
239
272
|
# @example
|
240
273
|
# input :textarea, title: 'Textarea Input Example', type: 'textarea', optional: true
|
@@ -250,16 +283,60 @@ module Inferno
|
|
250
283
|
end
|
251
284
|
end
|
252
285
|
|
286
|
+
# Mark as optional. Tests are required by default.
|
287
|
+
#
|
288
|
+
# @param optional [Boolean]
|
289
|
+
# @return [void]
|
290
|
+
#
|
291
|
+
def optional(optional = true) # rubocop:disable Style/OptionalBooleanParameter
|
292
|
+
@optional = optional
|
293
|
+
end
|
294
|
+
|
295
|
+
# Mark as required
|
296
|
+
#
|
297
|
+
# Tests are required by default. This method is provided to make an
|
298
|
+
# existing optional test required.
|
299
|
+
#
|
300
|
+
# @param required[Boolean]
|
301
|
+
# @return [void]
|
302
|
+
def required(required = true) # rubocop:disable Style/OptionalBooleanParameter
|
303
|
+
@optional = !required
|
304
|
+
end
|
305
|
+
|
306
|
+
# The test or group is optional if true
|
307
|
+
#
|
308
|
+
# @return [Boolean]
|
309
|
+
def optional?
|
310
|
+
!!@optional
|
311
|
+
end
|
312
|
+
|
313
|
+
# The test or group is required if true
|
314
|
+
#
|
315
|
+
# @return [Boolean]
|
316
|
+
def required?
|
317
|
+
!optional?
|
318
|
+
end
|
319
|
+
|
253
320
|
# Define outputs
|
254
321
|
#
|
255
|
-
# @param
|
322
|
+
# @param identifier [Symbol] identifier for the output
|
323
|
+
# @param other_identifiers [Symbol] array of symbols if specifying multiple outputs
|
324
|
+
# @param output_definition [Hash] options for output
|
325
|
+
# @option output_definition [String] :type text | textarea | oauth_credentials
|
256
326
|
# @return [void]
|
257
327
|
# @example
|
258
|
-
# output :patient_id, :
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
328
|
+
# output :patient_id, :condition_id, :observation_id
|
329
|
+
# @example
|
330
|
+
# output :oauth_credentials, type: 'oauth_credentials'
|
331
|
+
def output(identifier, *other_identifiers, **output_definition)
|
332
|
+
if other_identifiers.present?
|
333
|
+
[identifier, *other_identifiers].compact.each do |output_identifier|
|
334
|
+
outputs << output_identifier
|
335
|
+
config.add_output(output_identifier)
|
336
|
+
end
|
337
|
+
else
|
338
|
+
outputs << identifier
|
339
|
+
config.add_output(identifier, output_definition)
|
263
340
|
end
|
264
341
|
end
|
265
342
|
|
@@ -395,6 +472,7 @@ module Inferno
|
|
395
472
|
required_inputs.map(&:to_s) - submitted_inputs.map { |input| input[:name] }
|
396
473
|
end
|
397
474
|
|
475
|
+
# @private
|
398
476
|
def user_runnable?
|
399
477
|
@user_runnable ||= parent.nil? ||
|
400
478
|
!parent.respond_to?(:run_as_group?) ||
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Inferno
|
2
|
+
module Entities
|
3
|
+
module HasRunnable
|
4
|
+
# Returns the Test, TestGroup, or TestSuite associated with this entity
|
5
|
+
#
|
6
|
+
# @return [Inferno::Entities::Test, Inferno::Entities::TestGroup, Inferno::Entities::TestSuite]
|
7
|
+
def runnable
|
8
|
+
return @runnable if @runnable
|
9
|
+
|
10
|
+
@runnable = (test || test_group || test_suite || load_runnable)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def load_runnable
|
16
|
+
if test_id.present?
|
17
|
+
@test = Inferno::Repositories::Tests.new.find(test_id)
|
18
|
+
elsif test_group_id.present?
|
19
|
+
@test_group = Inferno::Repositories::TestGroups.new.find(test_group_id)
|
20
|
+
elsif test_suite_id.present?
|
21
|
+
@test_suite = Inferno::Repositories::TestSuites.new.find(test_suite_id)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -186,6 +186,12 @@ module Inferno
|
|
186
186
|
.map { |header_name, value| Header.new(name: header_name.downcase, value: value, type: 'request') }
|
187
187
|
response_headers = response[:headers]
|
188
188
|
.map { |header_name, value| Header.new(name: header_name.downcase, value: value, type: 'response') }
|
189
|
+
request_body =
|
190
|
+
if request.dig(:headers, 'Content-Type')&.include?('application/x-www-form-urlencoded')
|
191
|
+
URI.encode_www_form(request[:payload])
|
192
|
+
else
|
193
|
+
request[:payload]
|
194
|
+
end
|
189
195
|
|
190
196
|
new(
|
191
197
|
verb: request[:method],
|
@@ -193,7 +199,7 @@ module Inferno
|
|
193
199
|
direction: direction,
|
194
200
|
name: name,
|
195
201
|
status: response[:code].to_i,
|
196
|
-
request_body:
|
202
|
+
request_body: request_body,
|
197
203
|
response_body: response[:body],
|
198
204
|
test_session_id: test_session_id,
|
199
205
|
headers: request_headers + response_headers
|
@@ -47,9 +47,10 @@ module Inferno
|
|
47
47
|
:test_session_id, :result, :result_message, :messages, :requests,
|
48
48
|
:input_json, :output_json
|
49
49
|
].freeze
|
50
|
-
RESULT_OPTIONS = ['cancel', 'wait', 'running', 'error', 'fail', 'skip', '
|
50
|
+
RESULT_OPTIONS = ['cancel', 'wait', 'running', 'error', 'fail', 'skip', 'pass', 'omit'].freeze
|
51
51
|
|
52
52
|
include Inferno::Entities::Attributes
|
53
|
+
include Inferno::Entities::HasRunnable
|
53
54
|
|
54
55
|
def initialize(params)
|
55
56
|
super(params, ATTRIBUTES - [:messages, :requests])
|
@@ -58,9 +59,12 @@ module Inferno
|
|
58
59
|
@requests = (params[:requests] || []).map { |request| Request.new(request) }
|
59
60
|
end
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
62
|
+
def optional?
|
63
|
+
runnable.optional?
|
64
|
+
end
|
65
|
+
|
66
|
+
def required?
|
67
|
+
!optional?
|
64
68
|
end
|
65
69
|
|
66
70
|
# @return [Boolean]
|
@@ -32,11 +32,11 @@ module Inferno
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def groups
|
35
|
-
|
35
|
+
children.select { |child| child < Inferno::Entities::TestGroup }
|
36
36
|
end
|
37
37
|
|
38
38
|
def tests
|
39
|
-
|
39
|
+
children.select { |child| child < Inferno::Entities::Test }
|
40
40
|
end
|
41
41
|
|
42
42
|
# Methods to configure Inferno::DSL::Runnable
|
@@ -54,16 +54,14 @@ module Inferno
|
|
54
54
|
def group_metadata
|
55
55
|
{
|
56
56
|
class: TestGroup,
|
57
|
-
repo: repository
|
58
|
-
collection: groups
|
57
|
+
repo: repository
|
59
58
|
}
|
60
59
|
end
|
61
60
|
|
62
61
|
def test_metadata
|
63
62
|
{
|
64
63
|
class: Test,
|
65
|
-
repo: Inferno::Repositories::Tests.new
|
66
|
-
collection: tests
|
64
|
+
repo: Inferno::Repositories::Tests.new
|
67
65
|
}
|
68
66
|
end
|
69
67
|
|
@@ -52,6 +52,7 @@ module Inferno
|
|
52
52
|
].freeze
|
53
53
|
|
54
54
|
include Inferno::Entities::Attributes
|
55
|
+
include Inferno::Entities::HasRunnable
|
55
56
|
|
56
57
|
attr_accessor :test_session
|
57
58
|
|
@@ -63,12 +64,6 @@ module Inferno
|
|
63
64
|
@test_session = params[:test_session]
|
64
65
|
end
|
65
66
|
|
66
|
-
def runnable
|
67
|
-
return @runnable if @runnable
|
68
|
-
|
69
|
-
@runnable = (test || test_group || test_suite || load_runnable)
|
70
|
-
end
|
71
|
-
|
72
67
|
def to_hash
|
73
68
|
super.merge(test_session: test_session).compact
|
74
69
|
end
|
@@ -76,18 +71,6 @@ module Inferno
|
|
76
71
|
def test_count
|
77
72
|
@test_count ||= runnable.test_count
|
78
73
|
end
|
79
|
-
|
80
|
-
private
|
81
|
-
|
82
|
-
def load_runnable
|
83
|
-
if test_id.present?
|
84
|
-
@test = Inferno::Repositories::Tests.new.find(test_id)
|
85
|
-
elsif test_group_id.present?
|
86
|
-
@test_group = Inferno::Repositories::TestGroups.new.find(test_group_id)
|
87
|
-
elsif test_suite_id.present?
|
88
|
-
@test_suite = Inferno::Repositories::TestSuites.new.find(test_suite_id)
|
89
|
-
end
|
90
|
-
end
|
91
74
|
end
|
92
75
|
end
|
93
76
|
end
|
@@ -22,7 +22,7 @@ module Inferno
|
|
22
22
|
return @default_group if @default_group
|
23
23
|
|
24
24
|
@default_group = Class.new(TestGroup)
|
25
|
-
|
25
|
+
children << @default_group
|
26
26
|
@default_group
|
27
27
|
end
|
28
28
|
|
@@ -31,7 +31,7 @@ module Inferno
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def groups
|
34
|
-
|
34
|
+
children.select { |child| child < Inferno::Entities::TestGroup }
|
35
35
|
end
|
36
36
|
|
37
37
|
# Methods to configure Inferno::DSL::Runnable
|
@@ -44,8 +44,7 @@ module Inferno
|
|
44
44
|
def group_metadata
|
45
45
|
{
|
46
46
|
class: TestGroup,
|
47
|
-
repo: Inferno::Repositories::TestGroups.new
|
48
|
-
collection: groups
|
47
|
+
repo: Inferno::Repositories::TestGroups.new
|
49
48
|
}
|
50
49
|
end
|
51
50
|
|
data/lib/inferno/entities.rb
CHANGED
data/lib/inferno/exceptions.rb
CHANGED
@@ -62,5 +62,24 @@ module Inferno
|
|
62
62
|
super('The chosen runnable must be run as part of a group')
|
63
63
|
end
|
64
64
|
end
|
65
|
+
|
66
|
+
class UnknownAttributeException < RuntimeError
|
67
|
+
def initialize(attributes, klass)
|
68
|
+
attributes_string = attributes.map { |attribute| "'#{attribute}'" }.join(', ')
|
69
|
+
super("Unknown attributes for #{klass.name}: #{attributes_string}")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class UnknownSessionDataType < RuntimeError
|
74
|
+
def initialize(output)
|
75
|
+
super("Unknown type '#{output[:type]}' for '#{output[:name]}'.")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class BadSessionDataType < RuntimeError
|
80
|
+
def initialize(name, expected_class, actual_class)
|
81
|
+
super("Expected '#{name}' to be a #{expected_class.name}, but found a #{actual_class.name}.")
|
82
|
+
end
|
83
|
+
end
|
65
84
|
end
|
66
85
|
end
|