inferno_core 1.4.3 → 1.4.4

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: 044cfcbc6d3920cfba55d0d63fbf0fb3a1440f4f42a2e45d763beb78f280306a
4
- data.tar.gz: 243c006acc71fddd3eb165a2c400a1eab4e515f8c3f4915b27cd60fc8e41e734
3
+ metadata.gz: c8c3149fd821b0530f7481d6a01bdef6da32263f1cca74f7b852567edb67af43
4
+ data.tar.gz: df8cd12ccb8054d182655c7537c730cd0a1f6fa538552e98171b93c43300d17b
5
5
  SHA512:
6
- metadata.gz: a1c934c0c6bb863a66e34b2830807ee274f443323d7c74c10023bf078329abf2bc70d9125f481b388c3e9ac61a647c81a8f6ee6f7c156078a9dc4fc31adcb671
7
- data.tar.gz: 6a54d11609e88fadd4c4750966e66a1df705ab1a1c79b8c8c0b99f5d3a19467496c46db740dfb2937610c9c78e8a7bf14db7fe8112c7c8399bb43a16bdcd6937
6
+ metadata.gz: f6d6c9b29f44b0f3169bee590aac204520aa3fc24d651443b5136958cecfffc889d71172881b4c97323b6b17b65d78afd8fd8027a0b8d933037023345fed975d
7
+ data.tar.gz: 196c88889027e64aa05e3e7a9997749c9dfc5fab9fecdfa1a40437005d2cfd9a5390945f3efc3382ae4c2a3ea3f208ebc5720b5837ca1ad46fd5f08dfdab8678
@@ -9,6 +9,7 @@ require_relative 'suites'
9
9
  require_relative 'new'
10
10
  require_relative 'execute'
11
11
  require_relative 'execute_script'
12
+ require_relative '../../utils/execution_script_runner'
12
13
  require_relative '../../version'
13
14
 
14
15
  module Inferno
@@ -78,8 +79,31 @@ module Inferno
78
79
  desc 'requirements SUBCOMMAND ...ARGS', 'Perform requirements operations'
79
80
  subcommand 'requirements', Requirements
80
81
 
81
- desc 'execute_script YAML_FILE',
82
- 'Run a session orchestration script defined by a YAML config file.'
82
+ desc 'execute_script [PATTERN]',
83
+ 'Run one or more session orchestration scripts defined by YAML config file(s).'
84
+ long_desc <<-LONGDESC
85
+ Run a session orchestration script defined by a YAML config file.
86
+
87
+ PATTERN may be a single YAML file, or it may contain wildcards (e.g. glob
88
+ patterns like `*` or `**`) to match and run multiple scripts in sequence.
89
+ When PATTERN matches more than one file, each matching script is run in a
90
+ separate process; a summary of passed and failed scripts is printed at the
91
+ end, and the command exits non-zero if any script failed.
92
+
93
+ If PATTERN is omitted, it defaults to `execution_scripts/**/*.yaml`, running
94
+ every script under the execution_scripts directory.
95
+
96
+ Examples:
97
+
98
+ # Run every script under execution_scripts
99
+ `bundle exec inferno execute_script`
100
+
101
+ # Run a single script
102
+ `bundle exec inferno execute_script execution_scripts/demo/demo_individual_tests.yaml`
103
+
104
+ # Run every script in a directory
105
+ `bundle exec inferno execute_script "execution_scripts/demo/*.yaml"`
106
+ LONGDESC
83
107
  option :inferno_base_url,
84
108
  aliases: ['-I'],
85
109
  type: :string,
@@ -113,9 +137,26 @@ module Inferno
113
137
  type: :boolean,
114
138
  default: false,
115
139
  desc: 'Allow execution script steps that run arbitrary shell commands. ' \
116
- 'Scripts with command: steps will fail unless this flag is set.'
117
- def execute_script(yaml_file)
118
- ExecuteScript.new(yaml_file, options).run
140
+ 'Scripts with command: steps will fail unless this flag is set. ' \
141
+ 'When PATTERN matches multiple scripts, this also applies to all of them ' \
142
+ '(in addition to any individual script whose filename contains "_with_commands").'
143
+ def execute_script(pattern = 'execution_scripts/**/*.yaml')
144
+ matches = Dir.glob(pattern).select { |file| file.end_with?('.yaml', '.yml') }.sort
145
+
146
+ if matches.length > 1 || (matches.empty? && pattern.match?(/[*?\[\]{}]/))
147
+ Utils::ExecutionScriptRunner.run_all(
148
+ pattern:,
149
+ inferno_base_url: options[:inferno_base_url],
150
+ allow_commands: options[:allow_commands],
151
+ compare_messages: options[:compare_messages],
152
+ compare_result_message: options[:compare_result_message],
153
+ poll_interval: options[:poll_interval],
154
+ default_poll_timeout: options[:default_poll_timeout],
155
+ only_different_messages: options[:only_different_messages]
156
+ )
157
+ else
158
+ ExecuteScript.new(matches.first || pattern, options).run
159
+ end
119
160
  end
120
161
 
121
162
  desc 'session SUBCOMMAND ...ARGS', 'Perform session operations'
@@ -5,19 +5,6 @@ begin
5
5
  rescue LoadError # rubocop:disable Lint/SuppressedException
6
6
  end
7
7
 
8
- namespace :execute_scripts do
9
- desc 'Run all execution script YAML files against a local Inferno instance (already running). ' \
10
- 'Optional FILTER env var restricts by File.fnmatch pattern, e.g. FILTER="execution_scripts/demo/*". ' \
11
- 'Optional INFERNO_BASE_URL env var sets the target Inferno URL, e.g. INFERNO_BASE_URL="http://localhost:4567/"'
12
- task :run_all do
13
- require 'inferno/utils/execution_script_runner'
14
- Inferno::Utils::ExecutionScriptRunner.run_all(
15
- pattern: ENV.fetch('FILTER', 'execution_scripts/**/*.yaml'),
16
- inferno_base_url: ENV.fetch('INFERNO_BASE_URL', nil)
17
- )
18
- end
19
- end
20
-
21
8
  namespace :db do
22
9
  desc 'Apply changes to the database'
23
10
  task :migrate do
@@ -53,36 +53,6 @@ http {
53
53
  # the server will close connections after this time
54
54
  keepalive_timeout 600;
55
55
 
56
- location /validator {
57
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
58
- proxy_set_header Host $http_host;
59
- proxy_set_header X-Forwarded-Proto $scheme;
60
- proxy_set_header X-Forwarded-Port $server_port;
61
- proxy_redirect off;
62
- proxy_set_header Connection '';
63
- proxy_http_version 1.1;
64
- chunked_transfer_encoding off;
65
- proxy_buffering off;
66
- proxy_cache off;
67
-
68
- proxy_pass http://fhir_validator_app;
69
- }
70
-
71
- location /validatorapi/ {
72
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
73
- proxy_set_header Host $http_host;
74
- proxy_set_header X-Forwarded-Proto $scheme;
75
- proxy_set_header X-Forwarded-Port $server_port;
76
- proxy_redirect off;
77
- proxy_set_header Connection '';
78
- proxy_http_version 1.1;
79
- chunked_transfer_encoding off;
80
- proxy_buffering off;
81
- proxy_cache off;
82
-
83
- proxy_pass http://validator_service:4567/;
84
- }
85
-
86
56
  location /hl7validatorapi/ {
87
57
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
88
58
  proxy_set_header Host $http_host;
@@ -68,36 +68,6 @@ http {
68
68
  proxy_pass http://inferno:4567;
69
69
  }
70
70
 
71
- location /validator {
72
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
73
- proxy_set_header Host $http_host;
74
- proxy_set_header X-Forwarded-Proto $scheme;
75
- proxy_set_header X-Forwarded-Port $server_port;
76
- proxy_redirect off;
77
- proxy_set_header Connection '';
78
- proxy_http_version 1.1;
79
- chunked_transfer_encoding off;
80
- proxy_buffering off;
81
- proxy_cache off;
82
-
83
- proxy_pass http://fhir_validator_app;
84
- }
85
-
86
- location /validatorapi/ {
87
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
88
- proxy_set_header Host $http_host;
89
- proxy_set_header X-Forwarded-Proto $scheme;
90
- proxy_set_header X-Forwarded-Port $server_port;
91
- proxy_redirect off;
92
- proxy_set_header Connection '';
93
- proxy_http_version 1.1;
94
- chunked_transfer_encoding off;
95
- proxy_buffering off;
96
- proxy_cache off;
97
-
98
- proxy_pass http://validator_service:4567/;
99
- }
100
-
101
71
  location /hl7validatorapi/ {
102
72
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
103
73
  proxy_set_header Host $http_host;
@@ -1,4 +1,3 @@
1
- version: '3'
2
1
  services:
3
2
  hl7_validator_service:
4
3
  image: infernocommunity/inferno-resource-validator
@@ -11,18 +10,6 @@ services:
11
10
  # To let the service share your local FHIR package cache,
12
11
  # uncomment the below line
13
12
  # - ~/.fhir:/home/ktor/.fhir
14
- validator_service:
15
- image: infernocommunity/fhir-validator-service
16
- # Update this path to match your directory structure
17
- volumes:
18
- - ./data/igs:/home/igs
19
- fhir_validator_app:
20
- image: infernocommunity/fhir-validator-app
21
- depends_on:
22
- - validator_service
23
- environment:
24
- EXTERNAL_VALIDATOR_URL: http://localhost/validatorapi
25
- VALIDATOR_BASE_PATH: /validator
26
13
  fhirpath:
27
14
  image: infernocommunity/fhirpath-service
28
15
  ports:
@@ -35,7 +22,7 @@ services:
35
22
  - "80:80"
36
23
  command: [nginx, '-g', 'daemon off;']
37
24
  depends_on:
38
- - fhir_validator_app
25
+ - hl7_validator_service
39
26
  - fhirpath
40
27
  redis:
41
28
  image: redis
@@ -1,4 +1,3 @@
1
- version: '3'
2
1
  services:
3
2
  inferno:
4
3
  build:
@@ -6,7 +5,7 @@ services:
6
5
  volumes:
7
6
  - ./data:/opt/inferno/data
8
7
  depends_on:
9
- - validator_service
8
+ - hl7_validator_service
10
9
  worker:
11
10
  build:
12
11
  context: ./
@@ -19,14 +18,6 @@ services:
19
18
  extends:
20
19
  file: docker-compose.background.yml
21
20
  service: hl7_validator_service
22
- validator_service:
23
- extends:
24
- file: docker-compose.background.yml
25
- service: validator_service
26
- fhir_validator_app:
27
- extends:
28
- file: docker-compose.background.yml
29
- service: fhir_validator_app
30
21
  fhirpath:
31
22
  extends:
32
23
  file: docker-compose.background.yml
@@ -10,7 +10,7 @@ as `tx.fhir.org`.
10
10
 
11
11
  Execution scripts defined here will
12
12
  be [executed](https://inferno-framework.github.io/docs/advanced-test-features/scripting-execution.html#execution)
13
- automatically on pull requests as a part of the github
13
+ automatically on pull requests as a part of the GitHub
14
14
  workflows and can also be executed locally using the
15
- [`execute_script` CLI](https://inferno-framework.github.io/docs/getting-started/inferno-cli.html#complex-scripted-execution)
16
- on individual scripts or the `execute_scripts:run_all` rake task.
15
+ [`execute_script` CLI](https://inferno-framework.github.io/docs/getting-started/inferno-cli.html#complex-scripted-execution).
16
+ If no `.yaml` files are found under this directory, the GitHub workflow will be skipped.
@@ -0,0 +1,3 @@
1
+ Req Set,ID,URL,Requirement,Conformance,Actors,Sub-Requirement(s),Conditionality,Not Tested Reason,Not Tested Details
2
+ sample_v1,12,www.example.com/page.html#section,Requirement text SHALL go here,SHALL,Server,sample_v1@13,false,Not Tested,We've decided not to test this requirement
3
+ sample_v1,13,www.example.com/page.html#section,"This is a subsrequirement, and it SHOULD be implemented.",SHOULD,Server,,false,,
@@ -0,0 +1,12 @@
1
+ # Using Core Requirements Tools
2
+
3
+ This directory contains [requirement artifacts](https://inferno-framework.github.io/docs/advanced-test-features/requirements.html)
4
+ that contain example requirements that could be linked to tests
5
+ within this test kit and displayed within the UI as justification
6
+ for the tests.
7
+
8
+ Each `.xlsx` file defined in this directory will contribute towards the
9
+ test kit's requirements and a GitHub workflow executed automatically on pull
10
+ requests checks that these files are in sync with the generated requirement
11
+ list and coverage analysis `.csv` files. If no `.xlsx` files are found in
12
+ this directory, the GitHub workflow will be skipped.
@@ -0,0 +1 @@
1
+ Req Set,ID,URL,Requirement,Conformance,Actors,Conditionality,Not Tested Reason,Not Tested Details,<%= title_name %> Short ID(s),<%= title_name %> Full ID(s)
@@ -55,6 +55,19 @@ module Inferno
55
55
  @validator_session_repo ||= Inferno::Repositories::ValidatorSessions.new
56
56
  end
57
57
 
58
+ # Environment variable that, when set to a truthy-looking value,
59
+ # enables verbose validation logging (the validationContext sent
60
+ # with each request, and the resulting issues including which were
61
+ # filtered out) through Inferno's normal application logger, tagged
62
+ # with the validator definition and, when available, the test
63
+ # session and test that triggered the request.
64
+ VALIDATOR_DEBUG_LOGGING_ENV_VAR = 'FHIR_RESOURCE_VALIDATOR_DEBUG_LOGGING'.freeze
65
+
66
+ # @private
67
+ def debug_logging_enabled?
68
+ ENV.fetch(VALIDATOR_DEBUG_LOGGING_ENV_VAR, nil).present?
69
+ end
70
+
58
71
  # Set the url of the validator service
59
72
  #
60
73
  # @param validator_url [String]
@@ -212,6 +225,36 @@ module Inferno
212
225
  }
213
226
  end
214
227
 
228
+ # Environment variable that, when set, enables terminology server
229
+ # request logging by the validator itself. Its value is sent as
230
+ # `txLog` in the validationContext of every validation request,
231
+ # telling the validator where to log the terminology server
232
+ # requests it makes. Note that the log will appear within
233
+ # the container running the validator.
234
+ TX_LOG_ENV_VAR = 'FHIR_RESOURCE_VALIDATOR_TX_LOG'.freeze
235
+
236
+ # @private
237
+ def tx_log
238
+ ENV.fetch(TX_LOG_ENV_VAR, nil).presence
239
+ end
240
+
241
+ # @private
242
+ # Builds the validationContext sent with a request for the given
243
+ # profile. Pulled out on its own (rather than inlined in
244
+ # `wrap_target_for_hl7_wrapper`) so the same, resource-content-free
245
+ # context can also be used for logging in `log_validation_result`.
246
+ #
247
+ # @param profile_url [String]
248
+ # @return [Hash]
249
+ def build_validation_context(profile_url)
250
+ context = {
251
+ **validation_context.definition,
252
+ profiles: [profile_url]
253
+ }
254
+ context[:txLog] = tx_log if tx_log
255
+ context
256
+ end
257
+
215
258
  # @private
216
259
  # Used internally by perform_additional_validation
217
260
  def additional_validations
@@ -334,6 +377,7 @@ module Inferno
334
377
 
335
378
  # 4. Mark resources as filtered
336
379
  mark_issues_for_filtering(issues)
380
+ log_validation_result(profile_url, issues, runnable) if debug_logging_enabled?
337
381
 
338
382
  # 5. Add error messages to runnable
339
383
  filtered_issues = issues.reject(&:filtered)
@@ -447,12 +491,57 @@ module Inferno
447
491
  # @private
448
492
  def call_validator(target, profile_url)
449
493
  request_body = wrap_target_for_hl7_wrapper(target, profile_url)
494
+
450
495
  Faraday.new(
451
496
  url,
452
497
  request: { timeout: 600 }
453
498
  ).post('validate', request_body, content_type: 'application/json')
454
499
  end
455
500
 
501
+ # @private
502
+ # Logs the validationContext and expansionParameters sent with a
503
+ # request together with the resulting issues (including which were
504
+ # filtered out) in a single entry, tagged with enough context to
505
+ # trace it back to the validator definition and triggering test run.
506
+ #
507
+ # Deliberately omits the resource content itself (sent separately as
508
+ # `filesToValidate`): only the small, non-PHI-bearing
509
+ # validationContext and expansionParameters are logged, not the full
510
+ # request body.
511
+ #
512
+ # @param profile_url [String] the profile URL validated against
513
+ # @param issues [Array<ValidatorIssue>] the resulting issues, already marked for filtering
514
+ # @param runnable [Object] the runnable (typically a Test) that triggered the request
515
+ def log_validation_result(profile_url, issues, runnable)
516
+ payload = {
517
+ validator_name: name,
518
+ test_suite_id: test_suite_id,
519
+ test_session_id: runnable.respond_to?(:test_session_id) ? runnable.test_session_id : nil,
520
+ test_id: runnable.id,
521
+ validation_context: build_validation_context(profile_url),
522
+ expansion_parameters:,
523
+ issues: issues.map { |issue| issue_summary(issue) }
524
+ }.compact
525
+
526
+ Application[:logger].info("FHIR validation result: #{payload.to_json}")
527
+ end
528
+
529
+ # @private
530
+ # Recursively builds a loggable summary of a validation issue,
531
+ # including nested slice_info, without any resource content.
532
+ #
533
+ # @param issue [ValidatorIssue]
534
+ # @return [Hash]
535
+ def issue_summary(issue)
536
+ {
537
+ severity: issue.severity,
538
+ location: issue.location,
539
+ message: issue.message,
540
+ filtered: issue.filtered,
541
+ slice_info: issue.slice_info.any? ? issue.slice_info.map { |nested| issue_summary(nested) } : nil
542
+ }.compact
543
+ end
544
+
456
545
  # @private
457
546
  # Post an object to the validation service for validating.
458
547
  # Returns the raw validator response body.
@@ -703,10 +792,7 @@ module Inferno
703
792
  end
704
793
 
705
794
  wrapped_resource = {
706
- context_key => {
707
- **validation_context.definition,
708
- profiles: [profile_url]
709
- },
795
+ context_key => build_validation_context(profile_url),
710
796
  filesToValidate: [
711
797
  {
712
798
  fileName: "#{profile_url.split('/').last}.json",
@@ -3,7 +3,11 @@ require 'open3'
3
3
  module Inferno
4
4
  module Utils
5
5
  module ExecutionScriptRunner
6
- def self.run_all(pattern: 'execution_scripts/**/*.yaml', inferno_base_url: nil, allow_known_errors: false)
6
+ def self.run_all(pattern: 'execution_scripts/**/*.yaml', inferno_base_url: nil,
7
+ allow_known_errors: false, allow_commands: false,
8
+ compare_messages: true, compare_result_message: true,
9
+ poll_interval: 3, default_poll_timeout: 120,
10
+ only_different_messages: true)
7
11
  scripts = Dir.glob(pattern)
8
12
 
9
13
  if scripts.empty?
@@ -22,7 +26,10 @@ module Inferno
22
26
  next
23
27
  end
24
28
 
25
- result = run_script(config, inferno_base_url:, allow_known_errors:)
29
+ result = run_script(config, inferno_base_url:, allow_known_errors:, allow_commands:,
30
+ compare_messages:, compare_result_message:,
31
+ poll_interval:, default_poll_timeout:,
32
+ only_different_messages:)
26
33
  (result == :pass ? passed : failed) << config
27
34
 
28
35
  puts
@@ -31,19 +38,61 @@ module Inferno
31
38
  print_summary(passed, failed)
32
39
  end
33
40
 
34
- def self.run_script(config, inferno_base_url:, allow_known_errors:)
41
+ def self.run_script(config, inferno_base_url:, allow_known_errors:, allow_commands: false,
42
+ compare_messages: true, compare_result_message: true,
43
+ poll_interval: 3, default_poll_timeout: 120,
44
+ only_different_messages: true)
35
45
  puts '=' * 60
36
46
  puts "Running: #{config}"
37
47
  puts '=' * 60
38
48
 
39
- allow_commands = File.basename(config, '.yaml').include?('_with_commands')
49
+ allow_commands ||= File.basename(config, '.yaml').include?('_with_commands')
50
+ cmd = build_command(config, inferno_base_url:, allow_commands:, compare_messages:,
51
+ compare_result_message:, poll_interval:, default_poll_timeout:,
52
+ only_different_messages:)
53
+ output, exitstatus = stream_command(*cmd)
54
+
55
+ determine_result(config, exitstatus, output, allow_known_errors)
56
+ end
57
+
58
+ # @private
59
+ def self.build_command(config, inferno_base_url:, allow_commands:, compare_messages:,
60
+ compare_result_message:, poll_interval:, default_poll_timeout:,
61
+ only_different_messages:)
40
62
  cmd = ['bundle', 'exec', 'inferno', 'execute_script', config]
41
63
  cmd += ['--inferno-base-url', inferno_base_url] if inferno_base_url
42
64
  cmd += ['--allow-commands'] if allow_commands
43
- output, status = Open3.capture2e(*cmd)
44
- puts output
65
+ cmd += ['--poll-interval', poll_interval.to_s] if poll_interval != 3
66
+ cmd += ['--default-poll-timeout', default_poll_timeout.to_s] if default_poll_timeout != 120
67
+ cmd + comparison_flags(compare_messages:, compare_result_message:, only_different_messages:)
68
+ end
69
+
70
+ # @private
71
+ def self.comparison_flags(compare_messages:, compare_result_message:, only_different_messages:)
72
+ flags = []
73
+ flags << '--no-compare-messages' unless compare_messages
74
+ flags << '--no-compare-result-message' unless compare_result_message
75
+ flags << '--no-only-different-messages' unless only_different_messages
76
+ flags
77
+ end
78
+
79
+ # Runs +cmd+ as a subprocess, echoing its combined stdout/stderr to the console
80
+ # line-by-line as it's produced (rather than buffering until the process exits),
81
+ # while still returning the full captured output for result determination.
82
+ def self.stream_command(*cmd)
83
+ output = +''
84
+ exitstatus = nil
85
+
86
+ Open3.popen2e(*cmd) do |stdin, stdout_and_stderr, wait_thread|
87
+ stdin.close
88
+ stdout_and_stderr.each_line do |line|
89
+ puts line
90
+ output << line
91
+ end
92
+ exitstatus = wait_thread.value.exitstatus
93
+ end
45
94
 
46
- determine_result(config, status.exitstatus, output, allow_known_errors)
95
+ [output, exitstatus]
47
96
  end
48
97
 
49
98
  def self.determine_result(config, return_code, output, allow_known_errors)
@@ -1,4 +1,4 @@
1
1
  module Inferno
2
2
  # Standard patterns for gem versions: https://guides.rubygems.org/patterns/
3
- VERSION = '1.4.3'.freeze
3
+ VERSION = '1.4.4'.freeze
4
4
  end
data/spec/spec_helper.rb CHANGED
@@ -128,6 +128,24 @@ RSpec.configure do |config|
128
128
  DatabaseCleaner.cleaning { example.run }
129
129
  end
130
130
 
131
+ # Inferno::Entities::Test/TestGroup/TestSuite are meant to be used only as
132
+ # abstract bases -- real tests/groups/suites are always DSL-defined subclasses.
133
+ # Some specs instantiate the bare classes directly (e.g. `Inferno::Test.new`) as
134
+ # lightweight doubles. If anything then reads `.id` on one of those, `Runnable#id`
135
+ # permanently memoizes @id/@base_id/@database_id onto that *shared* class object
136
+ # (since it's a genuinely named Ruby class, `default_id` returns its `Module#name`).
137
+ # Left in place, that id leaks into every subsequently-defined anonymous subclass
138
+ # via `copy_instance_variables`, causing DuplicateEntityIdException collisions in
139
+ # unrelated, later-running examples. Reset it after every example so it can never
140
+ # survive to pollute a different example.
141
+ config.after do
142
+ [Inferno::Entities::Test, Inferno::Entities::TestGroup, Inferno::Entities::TestSuite].each do |klass|
143
+ klass.instance_variable_set(:@id, nil)
144
+ klass.instance_variable_set(:@base_id, nil)
145
+ klass.instance_variable_set(:@database_id, nil)
146
+ end
147
+ end
148
+
131
149
  config.include FactoryBot::Syntax::Methods
132
150
 
133
151
  config.before(:suite) do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inferno_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.3
4
+ version: 1.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen MacVicar
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2026-08-26 00:00:00.000000000 Z
13
+ date: 2026-09-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -556,7 +556,7 @@ files:
556
556
  - lib/inferno/apps/cli/templates/docs/_Sidebar.md
557
557
  - lib/inferno/apps/cli/templates/execution_scripts/%library_name%_script.yaml.tt
558
558
  - lib/inferno/apps/cli/templates/execution_scripts/%library_name%_script_expected.json.tt
559
- - lib/inferno/apps/cli/templates/execution_scripts/README.md.tt
559
+ - lib/inferno/apps/cli/templates/execution_scripts/README.md
560
560
  - lib/inferno/apps/cli/templates/lib/%library_name%.rb.tt
561
561
  - lib/inferno/apps/cli/templates/lib/%library_name%/example_suite.rb.tt
562
562
  - lib/inferno/apps/cli/templates/lib/%library_name%/example_suite/patient_group.rb.tt
@@ -564,9 +564,11 @@ files:
564
564
  - lib/inferno/apps/cli/templates/lib/%library_name%/igs/README.md
565
565
  - lib/inferno/apps/cli/templates/lib/%library_name%/igs/put_ig_package_dot_tgz_here
566
566
  - lib/inferno/apps/cli/templates/lib/%library_name%/metadata.rb.tt
567
+ - lib/inferno/apps/cli/templates/lib/%library_name%/requirements/%library_name%_requirements.csv
567
568
  - lib/inferno/apps/cli/templates/lib/%library_name%/requirements/Inferno Requirements
568
569
  Template.xlsx
569
- - lib/inferno/apps/cli/templates/lib/%library_name%/suite.rb.tt
570
+ - lib/inferno/apps/cli/templates/lib/%library_name%/requirements/README.md
571
+ - lib/inferno/apps/cli/templates/lib/%library_name%/requirements/generated/%test_suite_id%_requirements_coverage.csv.tt
570
572
  - lib/inferno/apps/cli/templates/lib/%library_name%/version.rb.tt
571
573
  - lib/inferno/apps/cli/templates/run.sh
572
574
  - lib/inferno/apps/cli/templates/setup.sh
@@ -1,59 +0,0 @@
1
- require_relative 'metadata'
2
- require_relative 'patient_group'
3
-
4
- module <%= module_name %>
5
- class Suite < Inferno::TestSuite
6
- id :<%= test_suite_id %>
7
- title '<%= title_name %> Test Suite'
8
- description '<%= human_name %> test suite.'
9
-
10
- # These inputs will be available to all tests in this suite
11
- input :url,
12
- title: 'FHIR Server Base Url'
13
-
14
- input :credentials,
15
- title: 'OAuth Credentials',
16
- type: :auth_info,
17
- optional: true
18
-
19
- # All FHIR requests in this suite will use this FHIR client
20
- fhir_client do
21
- url :url
22
- auth_info :credentials
23
- end
24
-
25
- # All FHIR validation requests will use this FHIR validator
26
- fhir_resource_validator do
27
- # igs 'identifier#version' # Use this method for published IGs/versions
28
- # igs 'igs/filename.tgz' # Use this otherwise
29
-
30
- exclude_message do |message|
31
- message.message.match?(/\A\S+: \S+: URL value '.*' does not resolve/)
32
- end
33
- end
34
-
35
- # Tests and TestGroups can be defined inline
36
- group do
37
- id :capability_statement
38
- title 'Capability Statement'
39
- description 'Verify that the server has a CapabilityStatement'
40
-
41
- test do
42
- id :capability_statement_read
43
- title 'Read CapabilityStatement'
44
- description 'Read CapabilityStatement from /metadata endpoint'
45
-
46
- run do
47
- fhir_get_capability_statement
48
-
49
- assert_response_status(200)
50
- assert_resource_type(:capability_statement)
51
- end
52
- end
53
- end
54
-
55
- # Tests and TestGroups can be written in separate files and then included
56
- # using their id
57
- group from: :patient_group
58
- end
59
- end