inferno_core 0.0.5 → 0.0.8.pre2

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/bin/inferno +7 -0
  3. data/lib/inferno/apps/cli/console.rb +12 -0
  4. data/lib/inferno/apps/cli/main.rb +18 -0
  5. data/lib/inferno/apps/cli/migration.rb +14 -0
  6. data/lib/inferno/apps/cli.rb +8 -0
  7. data/lib/inferno/apps/web/controllers/test_runs/create.rb +15 -2
  8. data/lib/inferno/apps/web/index.html.erb +1 -0
  9. data/lib/inferno/apps/web/serializers/hash_value_extractor.rb +11 -0
  10. data/lib/inferno/apps/web/serializers/test.rb +3 -4
  11. data/lib/inferno/apps/web/serializers/test_group.rb +4 -6
  12. data/lib/inferno/config/application.rb +4 -0
  13. data/lib/inferno/config/boot/db.rb +1 -9
  14. data/lib/inferno/config/boot/logging.rb +2 -0
  15. data/lib/inferno/config/boot/suites.rb +4 -6
  16. data/lib/inferno/db/migrations/001_create_initial_structure.rb +1 -1
  17. data/lib/inferno/db/schema.rb +1 -1
  18. data/lib/inferno/dsl/assertions.rb +85 -0
  19. data/lib/inferno/dsl/configurable.rb +126 -0
  20. data/lib/inferno/dsl/fhir_client.rb +22 -16
  21. data/lib/inferno/dsl/fhir_client_builder.rb +3 -3
  22. data/lib/inferno/dsl/fhir_validation.rb +105 -1
  23. data/lib/inferno/dsl/http_client.rb +14 -12
  24. data/lib/inferno/dsl/http_client_builder.rb +3 -3
  25. data/lib/inferno/dsl/request_storage.rb +26 -17
  26. data/lib/inferno/dsl/results.rb +1 -1
  27. data/lib/inferno/dsl/resume_test_route.rb +10 -10
  28. data/lib/inferno/dsl/runnable.rb +104 -38
  29. data/lib/inferno/entities/header.rb +14 -7
  30. data/lib/inferno/entities/message.rb +16 -8
  31. data/lib/inferno/entities/request.rb +34 -21
  32. data/lib/inferno/entities/result.rb +36 -29
  33. data/lib/inferno/entities/session_data.rb +12 -6
  34. data/lib/inferno/entities/test.rb +29 -2
  35. data/lib/inferno/entities/test_group.rb +8 -0
  36. data/lib/inferno/entities/test_run.rb +29 -6
  37. data/lib/inferno/entities/test_session.rb +16 -10
  38. data/lib/inferno/exceptions.rb +12 -0
  39. data/lib/inferno/public/217.bundle.js +1 -1
  40. data/lib/inferno/public/bundle.js +154 -1
  41. data/lib/inferno/public/bundle.js.LICENSE.txt +15 -0
  42. data/lib/inferno/repositories/in_memory_repository.rb +1 -1
  43. data/lib/inferno/repositories/results.rb +1 -1
  44. data/lib/inferno/repositories/test_runs.rb +15 -0
  45. data/lib/inferno/spec_support.rb +1 -1
  46. data/lib/inferno/test_runner.rb +21 -19
  47. data/lib/inferno/utils/markdown_formatter.rb +15 -0
  48. data/lib/inferno/utils/middleware/request_logger.rb +9 -3
  49. data/lib/inferno/utils/migration.rb +17 -0
  50. data/lib/inferno/version.rb +1 -1
  51. data/lib/inferno.rb +0 -4
  52. data/spec/factories/request.rb +14 -7
  53. metadata +46 -10
  54. data/bin/inferno-console +0 -8
@@ -1,28 +1,34 @@
1
1
  require_relative '../dsl'
2
2
  require_relative '../repositories/tests'
3
+ require_relative '../utils/markdown_formatter'
4
+ require 'pry'
3
5
 
4
6
  module Inferno
5
7
  module Entities
6
8
  class Test
7
9
  extend Forwardable
8
10
  include DSL
11
+ include Inferno::Utils::MarkdownFormatter
9
12
 
10
13
  def_delegators 'self.class', :title, :id, :block, :inputs, :outputs
11
14
 
12
15
  attr_accessor :result_message
13
- attr_reader :test_session_id
16
+ attr_reader :test_session_id, :scratch
14
17
 
18
+ # @private
15
19
  def initialize(**params)
16
20
  params[:inputs]&.each { |key, value| instance_variable_set("@#{key}", value) }
21
+ @scratch = params[:scratch]
17
22
  @test_session_id = params[:test_session_id]
18
23
  end
19
24
 
25
+ # @private
20
26
  def messages
21
27
  @messages ||= []
22
28
  end
23
29
 
24
30
  def add_message(type, message)
25
- messages << { type: type.to_s, message: message }
31
+ messages << { type: type.to_s, message: format_markdown(message) }
26
32
  end
27
33
 
28
34
  # Set output values. Once set, these values will be available to any
@@ -33,11 +39,21 @@ module Inferno
33
39
  # @example
34
40
  # output(patient_id: '5', bearer_token: 'ABC')
35
41
  def output(outputs)
42
+ # TODO: update to track outputs that need to be updated
36
43
  outputs.each do |key, value|
37
44
  send("#{key}=", value)
45
+ outputs_to_persist[key] = value
38
46
  end
39
47
  end
40
48
 
49
+ # @api private
50
+ # A hash containing outputs that have been set during execution and need
51
+ # to be persisted. A test may not always update all outputs, so this is
52
+ # used to prevent overwriting an output with nil when it wasn't updated.
53
+ def outputs_to_persist
54
+ @outputs_to_persist ||= {}
55
+ end
56
+
41
57
  # Add an informational message to the results of a test. If passed a
42
58
  # block, a failed assertion will become an info message and test execution
43
59
  # will continue.
@@ -86,6 +102,7 @@ module Inferno
86
102
  add_message('warning', e.message)
87
103
  end
88
104
 
105
+ # @private
89
106
  def method_missing(name, *args, &block)
90
107
  parent_instance = self.class.parent&.new
91
108
  if parent_instance.respond_to?(name)
@@ -95,6 +112,7 @@ module Inferno
95
112
  end
96
113
  end
97
114
 
115
+ # @private
98
116
  def respond_to_missing?(name, _include_private = false)
99
117
  self.class.parent&.new&.respond_to?(name)
100
118
  end
@@ -141,6 +159,10 @@ module Inferno
141
159
  Inferno::Repositories::Tests.new
142
160
  end
143
161
 
162
+ # Set/Get the block that is executed when a Test is run
163
+ #
164
+ # @param block [Proc]
165
+ # @return [Proc] the block that is executed when a Test is run
144
166
  def block(&block)
145
167
  return @block unless block_given?
146
168
 
@@ -149,6 +171,7 @@ module Inferno
149
171
 
150
172
  alias run block
151
173
 
174
+ # @private
152
175
  def default_id
153
176
  return name if name.present?
154
177
 
@@ -156,16 +179,19 @@ module Inferno
156
179
  "Test#{suffix}"
157
180
  end
158
181
 
182
+ # @private
159
183
  def reference_hash
160
184
  {
161
185
  test_id: id
162
186
  }
163
187
  end
164
188
 
189
+ # @private
165
190
  def test_count
166
191
  1
167
192
  end
168
193
 
194
+ # @private
169
195
  def method_missing(name, *args, &block)
170
196
  parent_instance = parent&.new
171
197
  if parent_instance.respond_to?(name)
@@ -175,6 +201,7 @@ module Inferno
175
201
  end
176
202
  end
177
203
 
204
+ # @private
178
205
  def respond_to_missing?(name, _include_private = false)
179
206
  parent&.new&.respond_to?(name)
180
207
  end
@@ -79,6 +79,14 @@ module Inferno
79
79
  test_group_id: id
80
80
  }
81
81
  end
82
+
83
+ def run_as_group(value = true) # rubocop:disable Style/OptionalBooleanParameter
84
+ @run_as_group = value
85
+ end
86
+
87
+ def run_as_group?
88
+ @run_as_group || false
89
+ end
82
90
  end
83
91
  end
84
92
  end
@@ -2,12 +2,35 @@ module Inferno
2
2
  module Entities
3
3
  # A `TestRun` represents a request to execute an executable set of tests.
4
4
  #
5
- # @attr_accessor [String] id of the test input
6
- # @attr_accessor [String] test_session_id
7
- # @attr_accessor [String] status
8
- # @attr_accessor [String] test_suite_id
9
- # @attr_accessor [String] test_group_id
10
- # @attr_accessor [String] test_id
5
+ # @!attribute id
6
+ # @return [String] id of the test run
7
+ # @!attribute created_at
8
+ # @return [Time] creation timestamp
9
+ # @!attribute updated_at
10
+ # @return [Time] update timestamp
11
+ # @!attribute test_session_id
12
+ # @return [String]
13
+ # @!attribute status
14
+ # @return [String]
15
+ # @!attribute test_id
16
+ # @return [String, nil] id of the `Test` this result belongs to
17
+ # @!attribute test
18
+ # @return [Test, nil] the `Test` this result belongs to
19
+ # @!attribute test_group_id
20
+ # @return [String, nil] id of the `TestGroup` this result belongs to
21
+ # @!attribute test_group
22
+ # @return [TestGroup, nil] the `TestGroup` this result belongs to
23
+ # @!attribute test_suite_id
24
+ # @return [String, nil] id of the `TestSuite` this result belongs to
25
+ # @!attribute test_suite
26
+ # @return [TestSuite, nil] the `TestSuite` this result belongs to
27
+ # @!attribute inputs
28
+ # @return [Array<Hash>]
29
+ # @!attribute results
30
+ # @return [Array<Inferno::Entities::Result>]
31
+ # @!attribute identifier
32
+ # @return [String, nil] identfier for a waiting `TestRun`
33
+ # @!attribute wait_timeout
11
34
  class TestRun < Entity
12
35
  STATUS_OPTIONS = ['queued', 'running', 'waiting', 'done'].freeze
13
36
  ATTRIBUTES = [
@@ -2,17 +2,23 @@ module Inferno
2
2
  module Entities
3
3
  # A `TestSession` represents an individual testing session.
4
4
  #
5
- # @attr_accessor [String] id id of the session
6
- # @attr_accessor [Time] created_at creation timestamp
7
- # @attr_accessor [Time] updated_at update timestamp
8
- # @attr_accessor [String] test_suite_id id of the `TestSuite` being run in
9
- # this session
10
- # @attr_accessor [Inferno::Entities::TestSuite] test_suite the `TestSuite` being run in
11
- # this session
12
- # @attr_accessor [Array<Inferno::Entities::TestRun>] test_runs the `TestRuns`
5
+ # @!attribute id
6
+ # @return [String] id of the session
7
+ # @!attribute created_at
8
+ # @return [Time] creation timestamp
9
+ # @!attribute updated_at
10
+ # @return [Time] update timestamp
11
+ # @!attribute test_suite_id
12
+ # @return [String] id of the `TestSuite` being run in this session
13
+ # @!attribute test_suite
14
+ # @return [Inferno::Entities::TestSuite] the `TestSuite` being run in this
15
+ # session
16
+ # @!attribute test_runs
17
+ # @return [Array<Inferno::Entities::TestRun>] the `TestRuns` associated
18
+ # with this session
19
+ # @!attribute results
20
+ # @return [Array<Inferno::Entities::TestResult>] the `TestResults`
13
21
  # associated with this session
14
- # @attr_accessor [Array<Inferno::Entities::TestResult>] results the
15
- # `TestResults` associated with this session
16
22
  class TestSession < Entity
17
23
  ATTRIBUTES = [:id, :created_at, :updated_at, :test_suite_id, :test_suite, :test_runs, :results].freeze
18
24
 
@@ -50,5 +50,17 @@ module Inferno
50
50
  super("No '#{validator_name}' validator found")
51
51
  end
52
52
  end
53
+
54
+ class RequiredInputsNotFound < RuntimeError
55
+ def initialize(missing_inputs)
56
+ super("Missing the following required inputs: #{missing_inputs.join(', ')}")
57
+ end
58
+ end
59
+
60
+ class NotUserRunnableException < RuntimeError
61
+ def initialize
62
+ super('The chosen runnable must be run as part of a group')
63
+ end
64
+ end
53
65
  end
54
66
  end
@@ -1 +1 @@
1
- (self.webpackChunkinferno_web_app=self.webpackChunkinferno_web_app||[]).push([[217],{3217:(t,e,n)=>{"use strict";n.r(e),n.d(e,{getCLS:()=>v,getFCP:()=>g,getFID:()=>h,getLCP:()=>y,getTTFB:()=>F});var i,a,r=function(){return"".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)},o=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:-1;return{name:t,value:e,delta:0,entries:[],id:r(),isFinal:!1}},s=function(t,e){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var n=new PerformanceObserver((function(t){return t.getEntries().map(e)}));return n.observe({type:t,buffered:!0}),n}}catch(t){}},u=!1,c=!1,p=function(t){u=!t.persisted},f=function(){addEventListener("pagehide",p),addEventListener("beforeunload",(function(){}))},l=function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];c||(f(),c=!0),addEventListener("visibilitychange",(function(e){var n=e.timeStamp;"hidden"===document.visibilityState&&t({timeStamp:n,isUnloading:u})}),{capture:!0,once:e})},d=function(t,e,n,i){var a;return function(){n&&e.isFinal&&n.disconnect(),e.value>=0&&(i||e.isFinal||"hidden"===document.visibilityState)&&(e.delta=e.value-(a||0),(e.delta||e.isFinal||void 0===a)&&(t(e),a=e.value))}},v=function(t){var e,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=o("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),e())},r=s("layout-shift",a);r&&(e=d(t,i,r,n),l((function(t){var n=t.isUnloading;r.takeRecords().map(a),n&&(i.isFinal=!0),e()})))},m=function(){return void 0===i&&(i="hidden"===document.visibilityState?0:1/0,l((function(t){var e=t.timeStamp;return i=e}),!0)),{get timeStamp(){return i}}},g=function(t){var e,n=o("FCP"),i=m(),a=s("paint",(function(t){"first-contentful-paint"===t.name&&t.startTime<i.timeStamp&&(n.value=t.startTime,n.isFinal=!0,n.entries.push(t),e())}));a&&(e=d(t,n,a))},h=function(t){var e=o("FID"),n=m(),i=function(t){t.startTime<n.timeStamp&&(e.value=t.processingStart-t.startTime,e.entries.push(t),e.isFinal=!0,r())},a=s("first-input",i),r=d(t,e,a);a?l((function(){a.takeRecords().map(i),a.disconnect()}),!0):window.perfMetrics&&window.perfMetrics.onFirstInputDelay&&window.perfMetrics.onFirstInputDelay((function(t,i){i.timeStamp<n.timeStamp&&(e.value=t,e.isFinal=!0,e.entries=[{entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+t}],r())}))},S=function(){return a||(a=new Promise((function(t){return["scroll","keydown","pointerdown"].map((function(e){addEventListener(e,t,{once:!0,passive:!0,capture:!0})}))}))),a},y=function(t){var e,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=o("LCP"),a=m(),r=function(t){var n=t.startTime;n<a.timeStamp?(i.value=n,i.entries.push(t)):i.isFinal=!0,e()},u=s("largest-contentful-paint",r);if(u){e=d(t,i,u,n);var c=function(){i.isFinal||(u.takeRecords().map(r),i.isFinal=!0,e())};S().then(c),l(c,!0)}},F=function(t){var e,n=o("TTFB");e=function(){try{var e=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,e={entryType:"navigation",startTime:0};for(var n in t)"navigationStart"!==n&&"toJSON"!==n&&(e[n]=Math.max(t[n]-t.navigationStart,0));return e}();n.value=n.delta=e.responseStart,n.entries=[e],n.isFinal=!0,t(n)}catch(t){}},"complete"===document.readyState?setTimeout(e,0):addEventListener("pageshow",e)}}}]);
1
+ "use strict";(self.webpackChunkinferno_web_app=self.webpackChunkinferno_web_app||[]).push([[217],{3217:(t,e,n)=>{n.r(e),n.d(e,{getCLS:()=>v,getFCP:()=>g,getFID:()=>h,getLCP:()=>y,getTTFB:()=>F});var i,a,r=function(){return"".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)},o=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:-1;return{name:t,value:e,delta:0,entries:[],id:r(),isFinal:!1}},s=function(t,e){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var n=new PerformanceObserver((function(t){return t.getEntries().map(e)}));return n.observe({type:t,buffered:!0}),n}}catch(t){}},u=!1,c=!1,p=function(t){u=!t.persisted},f=function(){addEventListener("pagehide",p),addEventListener("beforeunload",(function(){}))},l=function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];c||(f(),c=!0),addEventListener("visibilitychange",(function(e){var n=e.timeStamp;"hidden"===document.visibilityState&&t({timeStamp:n,isUnloading:u})}),{capture:!0,once:e})},d=function(t,e,n,i){var a;return function(){n&&e.isFinal&&n.disconnect(),e.value>=0&&(i||e.isFinal||"hidden"===document.visibilityState)&&(e.delta=e.value-(a||0),(e.delta||e.isFinal||void 0===a)&&(t(e),a=e.value))}},v=function(t){var e,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=o("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),e())},r=s("layout-shift",a);r&&(e=d(t,i,r,n),l((function(t){var n=t.isUnloading;r.takeRecords().map(a),n&&(i.isFinal=!0),e()})))},m=function(){return void 0===i&&(i="hidden"===document.visibilityState?0:1/0,l((function(t){var e=t.timeStamp;return i=e}),!0)),{get timeStamp(){return i}}},g=function(t){var e,n=o("FCP"),i=m(),a=s("paint",(function(t){"first-contentful-paint"===t.name&&t.startTime<i.timeStamp&&(n.value=t.startTime,n.isFinal=!0,n.entries.push(t),e())}));a&&(e=d(t,n,a))},h=function(t){var e=o("FID"),n=m(),i=function(t){t.startTime<n.timeStamp&&(e.value=t.processingStart-t.startTime,e.entries.push(t),e.isFinal=!0,r())},a=s("first-input",i),r=d(t,e,a);a?l((function(){a.takeRecords().map(i),a.disconnect()}),!0):window.perfMetrics&&window.perfMetrics.onFirstInputDelay&&window.perfMetrics.onFirstInputDelay((function(t,i){i.timeStamp<n.timeStamp&&(e.value=t,e.isFinal=!0,e.entries=[{entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+t}],r())}))},S=function(){return a||(a=new Promise((function(t){return["scroll","keydown","pointerdown"].map((function(e){addEventListener(e,t,{once:!0,passive:!0,capture:!0})}))}))),a},y=function(t){var e,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=o("LCP"),a=m(),r=function(t){var n=t.startTime;n<a.timeStamp?(i.value=n,i.entries.push(t)):i.isFinal=!0,e()},u=s("largest-contentful-paint",r);if(u){e=d(t,i,u,n);var c=function(){i.isFinal||(u.takeRecords().map(r),i.isFinal=!0,e())};S().then(c),l(c,!0)}},F=function(t){var e,n=o("TTFB");e=function(){try{var e=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,e={entryType:"navigation",startTime:0};for(var n in t)"navigationStart"!==n&&"toJSON"!==n&&(e[n]=Math.max(t[n]-t.navigationStart,0));return e}();n.value=n.delta=e.responseStart,n.entries=[e],n.isFinal=!0,t(n)}catch(t){}},"complete"===document.readyState?setTimeout(e,0):addEventListener("pageshow",e)}}}]);