subscriptions_test_kit 0.11.1 → 0.11.2

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 (21) hide show
  1. checksums.yaml +4 -4
  2. data/lib/subscriptions_test_kit/common/notification_conformance_verification.rb +4 -4
  3. data/lib/subscriptions_test_kit/endpoints/subscription_create_endpoint.rb +1 -1
  4. data/lib/subscriptions_test_kit/jobs/send_subscription_notifications.rb +3 -1
  5. data/lib/subscriptions_test_kit/requirements/generated/subscriptions_r5_backport_r4_client_requirements_coverage.csv +17 -0
  6. data/lib/subscriptions_test_kit/requirements/generated/{subscriptions-test-kit_requirements_coverage.csv → subscriptions_r5_backport_r4_server_requirements_coverage.csv} +114 -132
  7. data/lib/subscriptions_test_kit/requirements/hl7.fhir.uv.subscriptions_1.1.0_requirements.xlsx +0 -0
  8. data/lib/subscriptions_test_kit/requirements/{subscriptions-test-kit_requirements.csv → subscriptions_test_kit_requirements.csv} +139 -141
  9. data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/common/subscription_simulation_utils.rb +3 -1
  10. data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/workflow/conformance_verification/processing_attestation_test.rb +0 -1
  11. data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client_suite.rb +8 -0
  12. data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/common/interaction/subscription_conformance_test.rb +1 -2
  13. data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/handshake_heartbeat/handshake_conformance_test.rb +0 -1
  14. data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server_suite.rb +8 -0
  15. data/lib/subscriptions_test_kit/version.rb +2 -2
  16. data/lib/subscriptions_test_kit.rb +0 -1
  17. metadata +8 -10
  18. data/lib/inferno_requirements_tools/ext/inferno_core/runnable.rb +0 -22
  19. data/lib/inferno_requirements_tools/tasks/collect_requirements.rb +0 -223
  20. data/lib/inferno_requirements_tools/tasks/requirements_coverage.rb +0 -266
  21. data/lib/subscriptions_test_kit/requirements/subscriptions-test-kit_out_of_scope_requirements.csv +0 -23
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: subscriptions_test_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.1
4
+ version: 0.11.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karl Naden, Emily Semple, Tom Strassner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-03 00:00:00.000000000 Z
11
+ date: 2025-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: inferno_core
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.6.4
19
+ version: 0.6.14
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.6.4
26
+ version: 0.6.14
27
27
  description: Inferno test kit for FHIR R5-style Subscriptions
28
28
  email:
29
29
  - inferno@groups.mitre.org
@@ -38,9 +38,6 @@ files:
38
38
  - config/presets/subscription_server_preset_empty.json.erb
39
39
  - config/presets/subscription_server_preset_full_resource.json.erb
40
40
  - config/presets/subscription_server_preset_id_only.json.erb
41
- - lib/inferno_requirements_tools/ext/inferno_core/runnable.rb
42
- - lib/inferno_requirements_tools/tasks/collect_requirements.rb
43
- - lib/inferno_requirements_tools/tasks/requirements_coverage.rb
44
41
  - lib/subscriptions_test_kit.rb
45
42
  - lib/subscriptions_test_kit/common/notification_conformance_verification.rb
46
43
  - lib/subscriptions_test_kit/common/subscription_conformance_verification.rb
@@ -57,9 +54,10 @@ files:
57
54
  - lib/subscriptions_test_kit/igs/README.md
58
55
  - lib/subscriptions_test_kit/jobs/send_subscription_notifications.rb
59
56
  - lib/subscriptions_test_kit/metadata.rb
60
- - lib/subscriptions_test_kit/requirements/generated/subscriptions-test-kit_requirements_coverage.csv
61
- - lib/subscriptions_test_kit/requirements/subscriptions-test-kit_out_of_scope_requirements.csv
62
- - lib/subscriptions_test_kit/requirements/subscriptions-test-kit_requirements.csv
57
+ - lib/subscriptions_test_kit/requirements/generated/subscriptions_r5_backport_r4_client_requirements_coverage.csv
58
+ - lib/subscriptions_test_kit/requirements/generated/subscriptions_r5_backport_r4_server_requirements_coverage.csv
59
+ - lib/subscriptions_test_kit/requirements/hl7.fhir.uv.subscriptions_1.1.0_requirements.xlsx
60
+ - lib/subscriptions_test_kit/requirements/subscriptions_test_kit_requirements.csv
63
61
  - lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/common/subscription_simulation_utils.rb
64
62
  - lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/fixtures/capability_statement.json
65
63
  - lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/workflow/conformance_verification/notification_input_payload_verification_test.rb
@@ -1,22 +0,0 @@
1
- module Inferno
2
- module DSL
3
- # This module contains the DSL for defining child entities in the test
4
- # definition framework.
5
- module Runnable
6
- # Set/Get the IDs of requirements verifed by this runnable
7
- # Set with [] to clear the list
8
- #
9
- # @param requirements [Array<String>]
10
- # @return [Array<String>] the requirement IDs
11
- def verifies_requirements(*requirement_ids)
12
- if requirement_ids.empty?
13
- @requirement_ids || []
14
- elsif requirement_ids == [[]]
15
- @requirement_ids = []
16
- else
17
- @requirement_ids = requirement_ids
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,223 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'csv'
4
- require 'roo'
5
-
6
- module InfernoRequirementsTools
7
- module Tasks
8
- # This class manages the collection of requirements details from
9
- # requirements planning excel workbooks into a CSV representation.
10
- # Currently splits out Requirements and Planned Not Tested Requirements
11
- # into two separate files.
12
- #
13
- # The `run` method will generate the files
14
- # The `run_check` method will check whether the previously generated files are up-to-date.
15
- class CollectRequirements
16
- # Update these constants based on the test kit.
17
- TEST_KIT_ID = 'subscriptions-test-kit'
18
- INPUT_SETS = ['hl7.fhir.uv.subscriptions_1.1.0'].freeze
19
-
20
- # Derivative constants
21
- TEST_KIT_CODE_FOLDER = TEST_KIT_ID.gsub('-', '_')
22
- INPUT_HEADERS =
23
- [
24
- 'ID*',
25
- 'URL*',
26
- 'Requirement*',
27
- 'Conformance*',
28
- 'Actor*',
29
- 'Sub-Requirement(s)',
30
- 'Conditionality',
31
- 'Verifiable?',
32
- 'Verifiability Details',
33
- 'Planning To Test?',
34
- 'Planning To Test Details'
35
- ].freeze
36
- REQUIREMENTS_OUTPUT_HEADERS =
37
- [
38
- 'Req Set',
39
- 'ID',
40
- 'URL',
41
- 'Requirement',
42
- 'Conformance',
43
- 'Actor',
44
- 'Sub-Requirement(s)',
45
- 'Conditionality'
46
- ].freeze
47
- REQUIREMENTS_OUTPUT_FILE_NAME = "#{TEST_KIT_ID}_requirements.csv".freeze
48
- REQUIREMENTS_OUTPUT_FILE =
49
- File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', REQUIREMENTS_OUTPUT_FILE_NAME).freeze
50
- PLANNED_NOT_TESTED_OUTPUT_HEADERS = ['Req Set', 'ID', 'Reason', 'Details'].freeze
51
- PLANNED_NOT_TESTED_OUTPUT_FILE_NAME = "#{TEST_KIT_ID}_out_of_scope_requirements.csv".freeze
52
- PLANNED_NOT_TESTED_OUTPUT_FILE =
53
- File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', PLANNED_NOT_TESTED_OUTPUT_FILE_NAME).freeze
54
-
55
- def available_input_worksheets
56
- @available_input_worksheets ||= Dir.glob(File.join(@input_directory, '*.xlsx')).reject { |f| f.include?('~$') }
57
- end
58
-
59
- # Of the form:
60
- # {
61
- # req_set_id_1: [row1, row2, row 3, ...],
62
- # req_set_id_2: [row1, row2, row 3, ...]
63
- # }
64
- def input_requirement_sets
65
- @input_requirement_sets ||= INPUT_SETS.each_with_object({}) do |req_set_id, hash|
66
- req_set_file = available_input_worksheets.find { |worksheet_file| worksheet_file.include?(req_set_id) }
67
-
68
- hash[req_set_id] =
69
- unless req_set_file.nil?
70
- CSV.parse(Roo::Spreadsheet.open(req_set_file).sheet('Requirements').to_csv,
71
- headers: true).map do |row|
72
- row.to_h.slice(*INPUT_HEADERS)
73
- end
74
- end
75
- end
76
- end
77
-
78
- def new_requirements_csv
79
- @new_requirements_csv ||=
80
- CSV.generate(+"\xEF\xBB\xBF") do |csv| # start with an unnecessary BOM to make viewing in excel easier
81
- csv << REQUIREMENTS_OUTPUT_HEADERS
82
-
83
- input_requirement_sets.each do |req_set_id, input_rows|
84
- input_rows.each do |input_row| # NOTE: use row order from source file
85
- csv << REQUIREMENTS_OUTPUT_HEADERS.map do |header|
86
- header == 'Req Set' ? req_set_id : input_row[header] || input_row["#{header}*"]
87
- end
88
- end
89
- end
90
- end
91
- end
92
-
93
- def old_requirements_csv
94
- @old_requirements_csv ||= File.read(REQUIREMENTS_OUTPUT_FILE)
95
- end
96
-
97
- def new_planned_not_tested_csv
98
- @new_planned_not_tested_csv ||=
99
- CSV.generate(+"\xEF\xBB\xBF") do |csv| # start with an unnecessary BOM to make viewing in excel easier
100
- csv << PLANNED_NOT_TESTED_OUTPUT_HEADERS
101
-
102
- input_requirement_sets.each do |req_set_id, input_rows|
103
- input_rows.each do |row|
104
- if spreadsheet_value_falsy?(row['Verifiable?'])
105
- csv << [req_set_id, row['ID*'], 'Not Verifiable', row['Verifiability Details']]
106
- elsif spreadsheet_value_falsy?(row['Planning To Test?'])
107
- csv << [req_set_id, row['ID*'], 'Not Tested', row['Planning To Test Details']]
108
- end
109
- end
110
- end
111
- end
112
- end
113
-
114
- def old_planned_not_tested_csv
115
- @old_planned_not_tested_csv ||= File.read(PLANNED_NOT_TESTED_OUTPUT_FILE)
116
- end
117
-
118
- def run(input_directory)
119
- @input_directory = input_directory
120
- check_presence_of_input_files
121
-
122
- update_requirements =
123
- if File.exist?(REQUIREMENTS_OUTPUT_FILE)
124
- if old_requirements_csv == new_requirements_csv
125
- puts "'#{REQUIREMENTS_OUTPUT_FILE_NAME}' file is up to date."
126
- false
127
- else
128
- puts 'Requirements set has changed.'
129
- true
130
- end
131
- else
132
- puts "No existing #{REQUIREMENTS_OUTPUT_FILE_NAME}."
133
- true
134
- end
135
-
136
- if update_requirements
137
- puts "Writing to file #{REQUIREMENTS_OUTPUT_FILE}..."
138
- File.write(REQUIREMENTS_OUTPUT_FILE, new_requirements_csv, encoding: Encoding::UTF_8)
139
- end
140
-
141
- udpate_planned_not_tested =
142
- if File.exist?(PLANNED_NOT_TESTED_OUTPUT_FILE)
143
- if old_planned_not_tested_csv == new_planned_not_tested_csv
144
- puts "'#{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME}' file is up to date."
145
- false
146
- else
147
- puts 'Planned Not Tested Requirements set has changed.'
148
- true
149
- end
150
- else
151
- puts "No existing #{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME}."
152
- true
153
- end
154
-
155
- if udpate_planned_not_tested
156
- puts "Writing to file #{PLANNED_NOT_TESTED_OUTPUT_FILE}..."
157
- File.write(PLANNED_NOT_TESTED_OUTPUT_FILE, new_planned_not_tested_csv, encoding: Encoding::UTF_8)
158
- end
159
-
160
- puts 'Done.'
161
- end
162
-
163
- def run_check(input_directory)
164
- @input_directory = input_directory
165
- check_presence_of_input_files
166
-
167
- requirements_ok =
168
- if File.exist?(REQUIREMENTS_OUTPUT_FILE)
169
- if old_requirements_csv == new_requirements_csv
170
- puts "'#{REQUIREMENTS_OUTPUT_FILE_NAME}' file is up to date."
171
- true
172
- else
173
- puts "#{REQUIREMENTS_OUTPUT_FILE_NAME} file is out of date."
174
- false
175
- end
176
- else
177
- puts "No existing #{REQUIREMENTS_OUTPUT_FILE_NAME} file."
178
- false
179
- end
180
-
181
- planned_not_tested_requirements_ok =
182
- if File.exist?(PLANNED_NOT_TESTED_OUTPUT_FILE)
183
- if old_planned_not_tested_csv == new_planned_not_tested_csv
184
- puts "'#{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME}' file is up to date."
185
- true
186
- else
187
- puts "#{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME} file is out of date."
188
- false
189
- end
190
- else
191
- puts "No existing #{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME} file."
192
- false
193
- end
194
-
195
- return if planned_not_tested_requirements_ok && requirements_ok
196
-
197
- puts <<~MESSAGE
198
- Check Failed. To resolve, run:
199
-
200
- bundle exec rake "requirements:collect[<input_directory>]"
201
-
202
- MESSAGE
203
- exit(1)
204
- end
205
-
206
- def check_presence_of_input_files
207
- input_requirement_sets.each do |req_set_id, rows|
208
- next unless rows.nil?
209
-
210
- puts %(
211
- Could not find input file for set #{req_set_id} in directory #{input_directory}. Aborting requirements
212
- collection..."
213
- )
214
- exit(1)
215
- end
216
- end
217
-
218
- def spreadsheet_value_falsy?(str)
219
- str&.downcase == 'no' || str&.downcase == 'false'
220
- end
221
- end
222
- end
223
- end
@@ -1,266 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'csv'
4
- require_relative '../ext/inferno_core/runnable'
5
-
6
- module InfernoRequirementsTools
7
- module Tasks
8
- # This class manages the mapping of test kit tests to requirements that they verify
9
- # and creates a CSV file with the tests that cover each requirement.
10
- # It expects a CSV file in the repo at `lib/[test kit id]/requirements/[test kit id]_requirements.csv`
11
- # that serves as the source of the requirement set for the test kit. The requirements in
12
- # this files are identified by a requirement set and an id and tests, groups, and suites
13
- # within in the test kit can claim that they verify a requirement by including a reference
14
- # to that requirementin the form <requirement set>@<id> in their `verifies_requirements` field.
15
- # Requirements that are out of scope can be listed in a companion file
16
- # `lib/[test kit id]/requirements/[test kit id]_out_of_scope_requirements.csv`.
17
- #
18
- # The `run` method generates a CSV file at
19
- # `lib/[test kit id]/requirements/generated/[test kit id]_requirements_coverage.csv``.
20
- # This file will be identical to the input spreadsheet, plus an additional column which holds a comma separated
21
- # list of inferno test IDs that test each requirement. These test IDs are Inferno short form IDs that represent the
22
- # position of the test within its group and suite. For example, the fifth test in the second group will have an ID
23
- # of 2.05. This ID is also shown in the Inferno web UI.
24
- #
25
- # The `run_check` method will check whether the previously generated file is up-to-date.
26
- class RequirementsCoverage
27
- # Update these constants based on the test kit.
28
- TEST_KIT_ID = 'subscriptions-test-kit'
29
- TEST_SUITES = [SubscriptionsTestKit::SubscriptionsR5BackportR4Client::SubscriptionsR5BackportR4ClientSuite,
30
- SubscriptionsTestKit::SubscriptionsR5BackportR4Server::SubscriptionsR5BackportR4ServerSuite].freeze
31
- SUITE_ID_TO_ACTOR_MAP = {
32
- 'subscriptions_r5_backport_r4_client' => 'Client',
33
- 'subscriptions_r5_backport_r4_server' => 'Server'
34
- }.freeze
35
-
36
- # Derivative constants
37
- TEST_KIT_CODE_FOLDER = TEST_KIT_ID.gsub('-', '_')
38
- INPUT_HEADERS = [
39
- 'Req Set',
40
- 'ID',
41
- 'URL',
42
- 'Requirement',
43
- 'Conformance',
44
- 'Actor',
45
- 'Sub-Requirement(s)',
46
- 'Conditionality'
47
- ].freeze
48
- SHORT_ID_HEADER = 'Short ID(s)'
49
- FULL_ID_HEADER = 'Full ID(s)'
50
- INPUT_FILE_NAME = "#{TEST_KIT_ID}_requirements.csv".freeze
51
- INPUT_FILE = File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', INPUT_FILE_NAME).freeze
52
- NOT_TESTED_FILE_NAME = "#{TEST_KIT_ID}_out_of_scope_requirements.csv".freeze
53
- NOT_TESTED_FILE = File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', NOT_TESTED_FILE_NAME).freeze
54
- OUTPUT_HEADERS = INPUT_HEADERS + TEST_SUITES.flat_map do |suite|
55
- ["#{suite.title} #{SHORT_ID_HEADER}", "#{suite.title} #{FULL_ID_HEADER}"]
56
- end
57
- OUTPUT_FILE_NAME = "#{TEST_KIT_ID}_requirements_coverage.csv".freeze
58
- OUTPUT_FILE = File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', 'generated', OUTPUT_FILE_NAME).freeze
59
-
60
- def input_rows
61
- @input_rows ||=
62
- CSV.parse(File.open(INPUT_FILE, 'r:bom|utf-8'), headers: true).map do |row|
63
- row.to_h.slice(*INPUT_HEADERS)
64
- end
65
- end
66
-
67
- def not_tested_requirements_map
68
- @not_tested_requirements_map ||= load_not_tested_requirements
69
- end
70
-
71
- def load_not_tested_requirements
72
- return {} unless File.exist?(NOT_TESTED_FILE)
73
-
74
- not_tested_requirements = {}
75
- CSV.parse(File.open(NOT_TESTED_FILE, 'r:bom|utf-8'), headers: true).each do |row|
76
- row_hash = row.to_h
77
- not_tested_requirements["#{row_hash['Req Set']}@#{row_hash['ID']}"] = row_hash
78
- end
79
-
80
- not_tested_requirements
81
- end
82
-
83
- # Of the form:
84
- # {
85
- # 'req-id-1': [
86
- # { short_id: 'short-id-1', full_id: 'long-id-1', suite_id: 'suite-id-1' },
87
- # { short_id: 'short-id-2', full_id: 'long-id-2', suite_id: 'suite-id-2' }
88
- # ],
89
- # 'req-id-2': [{ short_id: 'short-id-3', full_id: 'long-id-3', suite_id: 'suite-id-3' }],
90
- # ...
91
- # }
92
- def inferno_requirements_map
93
- @inferno_requirements_map ||= TEST_SUITES.each_with_object({}) do |suite, requirements_map|
94
- serialize_requirements(suite, 'suite', suite.id, requirements_map)
95
- suite.groups.each do |group|
96
- map_group_requirements(group, suite.id, requirements_map)
97
- end
98
- end
99
- end
100
-
101
- # rubocop:disable Metrics/CyclomaticComplexity
102
- def new_csv
103
- @new_csv ||=
104
- CSV.generate(+"\xEF\xBB\xBF") do |csv|
105
- csv << OUTPUT_HEADERS
106
- input_rows.each do |row| # NOTE: use row order from source file
107
- next if row['Conformance'] == 'DEPRECATED' # filter out deprecated rows
108
-
109
- TEST_SUITES.each do |suite|
110
- suite_actor = SUITE_ID_TO_ACTOR_MAP[suite.id]
111
- if row['Actor']&.include?(suite_actor)
112
- set_and_req_id = "#{row['Req Set']}@#{row['ID']}"
113
- suite_requirement_items = inferno_requirements_map[set_and_req_id]&.filter do |item|
114
- item[:suite_id] == suite.id
115
- end
116
- short_ids = suite_requirement_items&.map { |item| item[:short_id] }
117
- full_ids = suite_requirement_items&.map { |item| item[:full_id] }
118
- if short_ids.blank? && not_tested_requirements_map.key?(set_and_req_id)
119
- row["#{suite.title} #{SHORT_ID_HEADER}"] = 'Not Tested'
120
- row["#{suite.title} #{FULL_ID_HEADER}"] = 'Not Tested'
121
- else
122
- row["#{suite.title} #{SHORT_ID_HEADER}"] = short_ids&.join(', ')
123
- row["#{suite.title} #{FULL_ID_HEADER}"] = full_ids&.join(', ')
124
- end
125
- else
126
- row["#{suite.title} #{SHORT_ID_HEADER}"] = 'NA'
127
- row["#{suite.title} #{FULL_ID_HEADER}"] = 'NA'
128
- end
129
- end
130
-
131
- csv << row.values
132
- end
133
- end
134
- end
135
- # rubocop:enable Metrics/CyclomaticComplexity
136
-
137
- def input_requirement_ids
138
- @input_requirement_ids ||= input_rows.map { |row| "#{row['Req Set']}@#{row['ID']}" }
139
- end
140
-
141
- # The requirements present in Inferno that aren't in the input spreadsheet
142
- def unmatched_requirements_map
143
- @unmatched_requirements_map ||= inferno_requirements_map.except(*input_requirement_ids)
144
- end
145
-
146
- def old_csv
147
- @old_csv ||= File.read(OUTPUT_FILE)
148
- end
149
-
150
- def run
151
- unless File.exist?(INPUT_FILE)
152
- puts "Could not find input file: #{INPUT_FILE}. Aborting requirements coverage generation..."
153
- exit(1)
154
- end
155
-
156
- if unmatched_requirements_map.any?
157
- puts "WARNING: The following requirements indicated in the test kit are not present in #{INPUT_FILE_NAME}"
158
- output_requirements_map_table(unmatched_requirements_map)
159
- end
160
-
161
- if File.exist?(OUTPUT_FILE)
162
- if old_csv == new_csv
163
- puts "'#{OUTPUT_FILE_NAME}' file is up to date."
164
- return
165
- else
166
- puts 'Requirements coverage has changed.'
167
- end
168
- else
169
- puts "No existing #{OUTPUT_FILE_NAME}."
170
- end
171
-
172
- puts "Writing to file #{OUTPUT_FILE}..."
173
- File.write(OUTPUT_FILE, new_csv)
174
- puts 'Done.'
175
- end
176
-
177
- def run_check
178
- unless File.exist?(INPUT_FILE)
179
- puts "Could not find input file: #{INPUT_FILE}. Aborting requirements coverage check..."
180
- exit(1)
181
- end
182
-
183
- if unmatched_requirements_map.any?
184
- puts "The following requirements indicated in the test kit are not present in #{INPUT_FILE_NAME}"
185
- output_requirements_map_table(unmatched_requirements_map)
186
- end
187
-
188
- if File.exist?(OUTPUT_FILE)
189
- if old_csv == new_csv
190
- puts "'#{OUTPUT_FILE_NAME}' file is up to date."
191
- return unless unmatched_requirements_map.any?
192
- else
193
- puts <<~MESSAGE
194
- #{OUTPUT_FILE_NAME} file is out of date.
195
- To regenerate the file, run:
196
-
197
- bundle exec rake requirements:generate_coverage
198
-
199
- MESSAGE
200
- end
201
- else
202
- puts <<~MESSAGE
203
- No existing #{OUTPUT_FILE_NAME} file.
204
- To generate the file, run:
205
-
206
- bundle exec rake requirements:generate_coverage
207
-
208
- MESSAGE
209
- end
210
-
211
- puts 'Check failed.'
212
- exit(1)
213
- end
214
-
215
- def map_group_requirements(group, suite_id, requirements_map)
216
- serialize_requirements(group, group.short_id, suite_id, requirements_map)
217
- group.tests&.each { |test| serialize_requirements(test, test.short_id, suite_id, requirements_map) }
218
- group.groups&.each { |subgroup| map_group_requirements(subgroup, suite_id, requirements_map) }
219
- end
220
-
221
- def serialize_requirements(runnable, short_id, suite_id, requirements_map)
222
- runnable.verifies_requirements&.each do |requirement_id|
223
- requirement_id_string = requirement_id.to_s
224
-
225
- requirements_map[requirement_id_string] ||= []
226
- requirements_map[requirement_id_string] << { short_id:, full_id: runnable.id, suite_id: }
227
- end
228
- end
229
-
230
- # Output the requirements in the map like so:
231
- #
232
- # requirement_id | short_id | full_id
233
- # ---------------+------------+----------
234
- # req-id-1 | short-id-1 | full-id-1
235
- # req-id-2 | short-id-2 | full-id-2
236
- #
237
- # rubocop:disable Metrics/CyclomaticComplexity
238
- def output_requirements_map_table(requirements_map)
239
- headers = %w[requirement_id short_id full_id]
240
- col_widths = headers.map(&:length)
241
- col_widths[0] = [col_widths[0], requirements_map.keys.map(&:length).max].max
242
- col_widths[1] = ([col_widths[1]] + requirements_map.values.flatten.map { |item| item[:short_id].length }).max
243
- col_widths[2] = ([col_widths[2]] + requirements_map.values.flatten.map { |item| item[:full_id].length }).max
244
- col_widths.map { |width| width + 3 }
245
-
246
- puts [
247
- headers[0].ljust(col_widths[0]),
248
- headers[1].ljust(col_widths[1]),
249
- headers[2].ljust(col_widths[2])
250
- ].join(' | ')
251
- puts col_widths.map { |width| '-' * width }.join('-+-')
252
- requirements_map.each do |requirement_id, runnables|
253
- runnables.each do |runnable|
254
- puts [
255
- requirement_id.ljust(col_widths[0]),
256
- runnable[:short_id].ljust(col_widths[1]),
257
- runnable[:full_id].ljust(col_widths[2])
258
- ].join(' | ')
259
- end
260
- end
261
- puts
262
- end
263
- # rubocop:enable Metrics/CyclomaticComplexity
264
- end
265
- end
266
- end
@@ -1,23 +0,0 @@
1
- Req Set,ID,Reason,Details
2
- hl7.fhir.uv.subscriptions_1.1.0,3,Not Verifiable,Not precise enough to be consistently verified
3
- hl7.fhir.uv.subscriptions_1.1.0,4,Not Tested,"MAY requirement, support for which doesn't imply other requirements. Additionally, meeting this requirement is simply the absence of other features."
4
- hl7.fhir.uv.subscriptions_1.1.0,18,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
5
- hl7.fhir.uv.subscriptions_1.1.0,19,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
6
- hl7.fhir.uv.subscriptions_1.1.0,22,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
7
- hl7.fhir.uv.subscriptions_1.1.0,33,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
8
- hl7.fhir.uv.subscriptions_1.1.0,34,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
9
- hl7.fhir.uv.subscriptions_1.1.0,37,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
10
- hl7.fhir.uv.subscriptions_1.1.0,41,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
11
- hl7.fhir.uv.subscriptions_1.1.0,58,Not Tested,Conflicts with requirement 120 and is removed in future versions of the spec.
12
- hl7.fhir.uv.subscriptions_1.1.0,61,Not Verifiable,"In the context of this implementation guide, details on how to receive notifications over a custom channel do not exist."
13
- hl7.fhir.uv.subscriptions_1.1.0,80,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
14
- hl7.fhir.uv.subscriptions_1.1.0,84,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
15
- hl7.fhir.uv.subscriptions_1.1.0,88,Not Tested,"MAY requirement, support for which doesn't imply other requirements. Additionally, Inferno won't be able to accept non-R4 subscriptions."
16
- hl7.fhir.uv.subscriptions_1.1.0,92,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
17
- hl7.fhir.uv.subscriptions_1.1.0,100,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
18
- hl7.fhir.uv.subscriptions_1.1.0,104,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
19
- hl7.fhir.uv.subscriptions_1.1.0,105,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
20
- hl7.fhir.uv.subscriptions_1.1.0,117,Not Tested,"MAY requirement, support for which doesn't imply other requirements."
21
- hl7.fhir.uv.subscriptions_1.1.0,123,Not Tested,Used for Websocket channels that Inferno does not currently support
22
- hl7.fhir.uv.subscriptions_1.1.0,131,Not Verifiable,IG doesn't indicate what must support requirements are for the SubscriptionStatus profile (in contrast to the Subscription profile where they are provided)
23
- hl7.fhir.uv.subscriptions_1.1.0,132,Not Verifiable,IG doesn't indicate what must support requirements are for the SubscriptionStatus profile (in contrast to the Subscription profile where they are provided)