Module: Inferno::DSL::Runnable
- Includes:
- Utils::MarkdownFormatter
- Included in:
- Entities::TestGroup, Entities::TestSuite
- Defined in:
- lib/inferno/dsl/runnable.rb
Overview
This module contains the DSL for defining child entities in the test definition framework.
Constant Summary collapse
- VARIABLES_NOT_TO_COPY =
Class instance variables are used to hold the metadata for Runnable classes. When inheriting from a Runnable class, these class instance variables need to be copied. Some instance variables should not be copied, and will need to be repopulated from scratch on the new class. Any child Runnable classes will themselves need to be subclassed so that their parent can be updated.
[ :@id, # New runnable will have a different id :@parent, # New runnable unlikely to have the same parent :@all_children, # New subclasses have to be made for each child :@test_count, # Needs to be recalculated :@config, # Needs to be set by calling .config, which does extra work :@available_inputs, # Needs to be recalculated :@children_available_inputs # Needs to be recalculated ].freeze
Instance Attribute Summary collapse
-
#parent ⇒ Object
Returns the value of attribute parent.
-
#suite_option_requirements ⇒ Object
readonly
Returns the value of attribute suite_option_requirements.
Class Method Summary collapse
-
.extended(extending_class) ⇒ Object
When a class (e.g. TestSuite/TestGroup) uses this module, set it up so that subclassing it works correctly.
Instance Method Summary collapse
- #add_self_to_repository ⇒ Object
- #all_children ⇒ Object
-
#block(&block) ⇒ Proc
(also: #run)
Set/Get the block that is executed when a runnable is run.
- #child_metadata(metadata = nil) ⇒ Object
- #children(selected_suite_options = []) ⇒ Object
- #configure_child_class(klass, hash_args) ⇒ Object
- #copy_instance_variables(subclass) ⇒ Object
- #create_child_class(hash_args) ⇒ Object
- #default_id ⇒ Object
-
#define_child(*args) ⇒ Object
This method defines a child entity.
-
#description(new_description = nil) ⇒ String
Set/Get a runnable’s description.
- #handle_child_definition_block(klass) ⇒ Object
-
#id(new_id = nil) ⇒ String, Symbol
Set/Get a runnable’s id.
-
#input_instructions(new_input_instructions = nil) ⇒ String
Set/Get a runnable’s input instructions.
- #inspect ⇒ Object
-
#optional(optional = true) ⇒ void
Mark as optional.
-
#optional? ⇒ Boolean
The test or group is optional if true.
- #process_args(args) ⇒ Object
-
#repository ⇒ Object
An instance of the repository for the class using this module.
-
#required(required = true) ⇒ void
Mark as required.
-
#required? ⇒ Boolean
The test or group is required if true.
-
#required_suite_options(suite_option_requirements) ⇒ void
Set/get suite options required for this runnable to be executed.
-
#resume_test_route(method, path, tags: [], result: 'pass') { ... } ⇒ void
Create a route which will resume a test run when a request is received.
-
#route(method, path, handler) ⇒ void
Create a route to handle a request.
-
#short_description(new_short_description = nil) ⇒ String
Set/Get a runnable’s short one-sentence description.
-
#short_title(new_short_title = nil) ⇒ String
Set/Get a runnable’s short title.
- #suite ⇒ Object
-
#suite_endpoint(method, path, endpoint_class) ⇒ void
Create an endpoint to receive incoming requests during a Test Run.
- #test_count(selected_suite_options = []) ⇒ Object
-
#title(new_title = nil) ⇒ String
Set/Get a runnable’s title.
- #user_runnable? ⇒ Boolean
Methods included from Utils::MarkdownFormatter
Instance Attribute Details
#parent ⇒ Object
Returns the value of attribute parent.
12 13 14 |
# File 'lib/inferno/dsl/runnable.rb', line 12 def parent @parent end |
#suite_option_requirements ⇒ Object (readonly)
Returns the value of attribute suite_option_requirements.
13 14 15 |
# File 'lib/inferno/dsl/runnable.rb', line 13 def suite_option_requirements @suite_option_requirements end |
Class Method Details
.extended(extending_class) ⇒ Object
When a class (e.g. TestSuite/TestGroup) uses this module, set it up so that subclassing it works correctly.
-
add the subclass to the relevant repository when it is created
-
copy the class instance variables from the superclass
-
add a hook to the subclass so that its subclasses do the same
23 24 25 26 27 28 29 30 31 |
# File 'lib/inferno/dsl/runnable.rb', line 23 def self.extended(extending_class) super extending_class.extend Configurable extending_class.extend InputOutputHandling extending_class.define_singleton_method(:inherited) do |subclass| copy_instance_variables(subclass) end end |
Instance Method Details
#add_self_to_repository ⇒ Object
68 69 70 |
# File 'lib/inferno/dsl/runnable.rb', line 68 def add_self_to_repository repository.insert(self) end |
#all_children ⇒ Object
312 313 314 |
# File 'lib/inferno/dsl/runnable.rb', line 312 def all_children @all_children ||= [] end |
#block(&block) ⇒ Proc Also known as: run
Set/Get the block that is executed when a runnable is run
303 304 305 306 307 |
# File 'lib/inferno/dsl/runnable.rb', line 303 def block(&block) return @block unless block_given? @block = block end |
#child_metadata(metadata = nil) ⇒ Object
117 118 119 120 |
# File 'lib/inferno/dsl/runnable.rb', line 117 def ( = nil) @child_metadata = if @child_metadata end |
#children(selected_suite_options = []) ⇒ Object
456 457 458 459 460 461 462 463 464 465 466 467 468 |
# File 'lib/inferno/dsl/runnable.rb', line 456 def children( = []) return all_children if .blank? all_children.select do |child| requirements = child.suite_option_requirements if requirements.blank? true else requirements.all? { |requirement| .include? requirement } end end end |
#configure_child_class(klass, hash_args) ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/inferno/dsl/runnable.rb', line 136 def configure_child_class(klass, hash_args) # rubocop:disable Metrics/CyclomaticComplexity inputs.each do |name| next if klass.inputs.any? { |klass_input_name| klass_input_name == name } klass.input name end outputs.each do |output_name| next if klass.outputs.include? output_name klass.output output_name end new_fhir_client_definitions = klass.instance_variable_get(:@fhir_client_definitions) || {} fhir_client_definitions.each do |name, definition| next if new_fhir_client_definitions.include? name new_fhir_client_definitions[name] = definition.dup end klass.instance_variable_set(:@fhir_client_definitions, new_fhir_client_definitions) new_http_client_definitions = klass.instance_variable_get(:@http_client_definitions) || {} http_client_definitions.each do |name, definition| next if new_http_client_definitions.include? name new_http_client_definitions[name] = definition.dup end klass.instance_variable_set(:@http_client_definitions, new_http_client_definitions) klass.config(config) klass.all_children.select!(&:required?) if hash_args.delete(:exclude_optional) hash_args.each do |key, value| if value.is_a? Array klass.send(key, *value) else klass.send(key, value) end end klass.all_children.each do |child_class| klass.configure_child_class(child_class, {}) child_class.add_self_to_repository end end |
#copy_instance_variables(subclass) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/inferno/dsl/runnable.rb', line 51 def copy_instance_variables(subclass) instance_variables .reject { |variable| VARIABLES_NOT_TO_COPY.include? variable } .each { |variable| subclass.instance_variable_set(variable, instance_variable_get(variable).dup) } subclass.config(config) new_children = all_children.map do |child| Class.new(child).tap do |subclass_child| subclass_child.parent = subclass end end subclass.instance_variable_set(:@all_children, new_children) end |
#create_child_class(hash_args) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/inferno/dsl/runnable.rb', line 123 def create_child_class(hash_args) superclass_id = hash_args.delete :from return Class.new([:class]) if superclass_id.blank? superclass = [:repo].find(superclass_id) raise Exceptions::ParentNotLoadedException.new([:class], superclass_id) unless superclass Class.new(superclass) end |
#default_id ⇒ Object
295 296 297 |
# File 'lib/inferno/dsl/runnable.rb', line 295 def default_id to_s end |
#define_child(*args) ⇒ Object
This method defines a child entity. Classes using this module should alias the method name they wish to use to define child entities to this method.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/inferno/dsl/runnable.rb', line 82 def define_child(*args, &) hash_args = process_args(args) klass = create_child_class(hash_args) klass.parent = self all_children << klass configure_child_class(klass, hash_args) handle_child_definition_block(klass, &) klass.add_self_to_repository klass end |
#description(new_description = nil) ⇒ String
Set/Get a runnable’s description
235 236 237 238 239 |
# File 'lib/inferno/dsl/runnable.rb', line 235 def description(new_description = nil) return @description if new_description.nil? @description = format_markdown(new_description) end |
#handle_child_definition_block(klass) ⇒ Object
184 185 186 |
# File 'lib/inferno/dsl/runnable.rb', line 184 def handle_child_definition_block(klass, &) klass.class_eval(&) if block_given? end |
#id(new_id = nil) ⇒ String, Symbol
Set/Get a runnable’s id
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/inferno/dsl/runnable.rb', line 192 def id(new_id = nil) return @id if new_id.nil? && @id.present? prefix = if parent "#{parent.id}-" else '' end @base_id = new_id || @base_id || default_id final_id = "#{prefix}#{@base_id}" raise Exceptions::InvalidRunnableIdException, final_id if final_id.length > 255 @id = final_id end |
#input_instructions(new_input_instructions = nil) ⇒ String
Set/Get a runnable’s input instructions
255 256 257 258 259 |
# File 'lib/inferno/dsl/runnable.rb', line 255 def input_instructions(new_input_instructions = nil) return @input_instructions if new_input_instructions.nil? @input_instructions = format_markdown(new_input_instructions) end |
#inspect ⇒ Object
471 472 473 474 475 476 477 478 479 |
# File 'lib/inferno/dsl/runnable.rb', line 471 def inspect non_dynamic_ancestor = ancestors.find { |ancestor| !ancestor.to_s.start_with? '#' } "#<#{non_dynamic_ancestor}".tap do |inspect_string| inspect_string.concat(" @id=#{id.inspect},") inspect_string.concat(" @short_id=#{short_id.inspect},") if respond_to? :short_id inspect_string.concat(" @title=#{title.inspect}") inspect_string.concat('>') end end |
#optional(optional = true) ⇒ void
This method returns an undefined value.
Mark as optional. Tests are required by default.
265 266 267 |
# File 'lib/inferno/dsl/runnable.rb', line 265 def optional(optional = true) # rubocop:disable Style/OptionalBooleanParameter @optional = optional end |
#optional? ⇒ Boolean
The test or group is optional if true
283 284 285 |
# File 'lib/inferno/dsl/runnable.rb', line 283 def optional? !!@optional end |
#process_args(args) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/inferno/dsl/runnable.rb', line 101 def process_args(args) hash_args = if args[0].is_a? Hash args[0] elsif args[1].is_a? Hash args[1] else {} end hash_args[:title] = args[0] if args[0].is_a? String hash_args end |
#repository ⇒ Object
An instance of the repository for the class using this module
74 75 76 |
# File 'lib/inferno/dsl/runnable.rb', line 74 def repository nil end |
#required(required = true) ⇒ void
This method returns an undefined value.
Mark as required
Tests are required by default. This method is provided to make an existing optional test required.
276 277 278 |
# File 'lib/inferno/dsl/runnable.rb', line 276 def required(required = true) # rubocop:disable Style/OptionalBooleanParameter @optional = !required end |
#required? ⇒ Boolean
The test or group is required if true
290 291 292 |
# File 'lib/inferno/dsl/runnable.rb', line 290 def required? !optional? end |
#required_suite_options(suite_option_requirements) ⇒ void
This method returns an undefined value.
Set/get suite options required for this runnable to be executed.
448 449 450 451 452 453 |
# File 'lib/inferno/dsl/runnable.rb', line 448 def (suite_option_requirements) @suite_option_requirements = suite_option_requirements.map do |key, value| DSL::SuiteOption.new(id: key, value:) end end |
#resume_test_route(method, path, tags: [], result: 'pass') { ... } ⇒ void
This method returns an undefined value.
Create a route which will resume a test run when a request is received
359 360 361 362 363 364 365 366 367 |
# File 'lib/inferno/dsl/runnable.rb', line 359 def resume_test_route(method, path, tags: [], result: 'pass', &block) route_class = Class.new(ResumeTestRoute) do |klass| klass.singleton_class.instance_variable_set(:@test_run_identifier_block, block) klass.singleton_class.instance_variable_set(:@tags, ) klass.singleton_class.instance_variable_set(:@result, result) end route(method, path, route_class) end |
#route(method, path, handler) ⇒ void
This method returns an undefined value.
Create a route to handle a request
401 402 403 |
# File 'lib/inferno/dsl/runnable.rb', line 401 def route(method, path, handler) Inferno.routes << { method:, path:, handler:, suite: } end |
#short_description(new_short_description = nil) ⇒ String
Set/Get a runnable’s short one-sentence description
245 246 247 248 249 |
# File 'lib/inferno/dsl/runnable.rb', line 245 def short_description(new_short_description = nil) return @short_description if new_short_description.nil? @short_description = format_markdown(new_short_description) end |
#short_title(new_short_title = nil) ⇒ String
Set/Get a runnable’s short title
225 226 227 228 229 |
# File 'lib/inferno/dsl/runnable.rb', line 225 def short_title(new_short_title = nil) return @short_title if new_short_title.nil? @short_title = new_short_title end |
#suite ⇒ Object
317 318 319 320 321 |
# File 'lib/inferno/dsl/runnable.rb', line 317 def suite return self if ancestors.include? Inferno::Entities::TestSuite parent.suite end |
#suite_endpoint(method, path, endpoint_class) ⇒ void
This method returns an undefined value.
Create an endpoint to receive incoming requests during a Test Run.
383 384 385 |
# File 'lib/inferno/dsl/runnable.rb', line 383 def suite_endpoint(method, path, endpoint_class) route(method, path, endpoint_class) end |
#test_count(selected_suite_options = []) ⇒ Object
406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/inferno/dsl/runnable.rb', line 406 def test_count( = []) @test_counts ||= {} = .to_json return @test_counts[] if @test_counts[] @test_counts[] = children() &.reduce(0) { |sum, child| sum + child.test_count() } || 0 end |
#title(new_title = nil) ⇒ String
Set/Get a runnable’s title
215 216 217 218 219 |
# File 'lib/inferno/dsl/runnable.rb', line 215 def title(new_title = nil) return @title if new_title.nil? @title = new_title end |
#user_runnable? ⇒ Boolean
419 420 421 422 423 |
# File 'lib/inferno/dsl/runnable.rb', line 419 def user_runnable? @user_runnable ||= parent.nil? || !parent.respond_to?(:run_as_group?) || (parent.user_runnable? && !parent.run_as_group?) end |