carin_for_blue_button_test_kit 0.12.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/c4bb_client_test_suite.rb +227 -0
  3. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/client_claims_data_attestation_test.rb +32 -0
  4. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/coverage_claims_data_request_test.rb +25 -0
  5. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/eob_inpatient_claims_data_request_test.rb +26 -0
  6. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/eob_oral_claims_data_request_test.rb +25 -0
  7. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/eob_outpatient_claims_data_request_test.rb +28 -0
  8. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/eob_pharmacy_claims_data_request_test.rb +25 -0
  9. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/eob_professional_claims_data_request_test.rb +27 -0
  10. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/organization_claims_data_request_test.rb +26 -0
  11. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/patient_claims_data_request_test.rb +24 -0
  12. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/practitioner_claims_data_request_test.rb +25 -0
  13. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/relatedperson_claims_data_request_test.rb +25 -0
  14. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/client_validation_test.rb +93 -0
  15. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/collection.rb +19 -0
  16. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/endpoints/next_page_endpoint.rb +24 -0
  17. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/endpoints/resource_api_endpoint.rb +74 -0
  18. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/endpoints/resource_id_endpoint.rb +24 -0
  19. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/endpoints/token_endpoint.rb +24 -0
  20. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/initial_wait_test.rb +76 -0
  21. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/metadata/mock_capability_statement.json +535 -0
  22. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/metadata/mock_operation_outcome_resource.json +16 -0
  23. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/mock_server.rb +190 -0
  24. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/coverage_required_searches.rb +45 -0
  25. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/eob_required_searches.rb +71 -0
  26. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/organization_required_searches.rb +47 -0
  27. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/patient_required_searches.rb +71 -0
  28. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/practitioner_required_searches.rb +47 -0
  29. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/relatedperson_required_searches.rb +43 -0
  30. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/tags.rb +7 -0
  31. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/urls.rb +57 -0
  32. data/lib/carin_for_blue_button_test_kit/client/v2.0.0/user_input_response.rb +32 -0
  33. data/lib/carin_for_blue_button_test_kit/version.rb +1 -1
  34. data/lib/carin_for_blue_button_test_kit.rb +1 -0
  35. data/lib/inferno_requirements_tools/tasks/{map_requirements.rb → requirements_coverage.rb} +91 -60
  36. metadata +34 -4
  37. data/lib/inferno_requirements_tools/tasks/collect_requirements.rb +0 -196
@@ -1,46 +1,67 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'CSV'
4
- require 'roo'
3
+ require 'csv'
4
+ require 'yaml'
5
5
  require_relative '../ext/inferno_core/runnable'
6
6
 
7
7
  module InfernoRequirementsTools
8
8
  module Tasks
9
- # This class manages the mapping of IG requirements to test kit tests.
10
- # It expects a CSV file in the repo at lib/carin_for_blue_button_test_kit/requirements/Requirements.csv
11
- # This file must have a column with the header 'ID' which holds user-designated IDs for each requirement.
12
- # These requirement IDs must map to the IDs specified in the test kit using `verifies_requirements`
9
+ # This class manages the mapping of test kit tests to requirements that they verify
10
+ # and creates a CSV file with the tests that cover each requirement.
11
+ # It expects a CSV file in the repo at `lib/[test kit id]/requirements/[test kit id]_requirements.csv`
12
+ # that serves as the source of the requirement set for the test kit. The requirements in
13
+ # this files are identified by a requirement set and an id and tests, groups, and suites
14
+ # within in the test kit can claim that they verify a requirement by including a reference
15
+ # to that requirementin the form <requirement set>@<id> in their `verifies_requirements` field.
16
+ # Requirements that are out of scope can be listed in a companion file
17
+ # `lib/[test kit id]/requirements/[test kit id]_out_of_scope_requirements.csv`.
13
18
  #
14
- # The `run` method generates a CSV file at lib/carin_for_blue_button_test_kit/requirements/Requirements_Coverage.csv.
19
+ # The `run` method generates a CSV file at
20
+ # `lib/[test kit id]/requirements/generated/[test kit id]_requirements_coverage.csv``.
15
21
  # This file will be identical to the input spreadsheet, plus an additional column which holds a comma separated
16
22
  # list of inferno test IDs that test each requirement. These test IDs are Inferno short form IDs that represent the
17
23
  # position of the test within its group and suite. For example, the fifth test in the second group will have an ID
18
24
  # of 2.05. This ID is also shown in the Inferno web UI.
19
- # The output file is also sorted by requirement ID.
20
25
  #
21
26
  # The `run_check` method will check whether the previously generated file is up-to-date.
22
- class MapRequirements
23
- # Update these constants based on the test kit.
24
- TEST_KIT_ID = 'carin-for-blue-button-test-kit'
25
- TEST_SUITES = [CarinForBlueButtonTestKit::CARIN4BBV200::C4BBTestSuite].freeze # list of suite classes
26
- SUITE_ID_TO_ACTOR_MAP = {
27
- 'c4bb_v200' => 'Health Plan'
28
- }.freeze
27
+ class RequirementsCoverage
28
+ VERSION = '0.2.0' # update when making meaningful changes to this method for tracking used versions
29
+ CONFIG = YAML.load_file(File.join('lib', 'requirements_config.yaml'))
30
+
31
+ TEST_KIT_ID = CONFIG['test_kit_id']
32
+ TEST_SUITES = CONFIG['suites'].map do |test_suite|
33
+ Object.const_get(test_suite['class_name'])
34
+ end
35
+
36
+ SUITE_ID_TO_ACTOR_MAP = CONFIG['suites'].each_with_object({}) do |test_suite, hash|
37
+ hash[test_suite['id']] = test_suite['suite_actor']
38
+ end
29
39
 
30
40
  # Derivative constants
31
- TEST_KIT_CODE_FOLDER = TEST_KIT_ID.gsub('-', '_')
32
- INPUT_HEADERS = ['Req Set', 'ID', 'URL', 'Requirement', 'Conformance', 'Actor', 'Sub-Requirement(s)',
33
- 'Conditionality'].freeze
41
+ TEST_KIT_CODE_FOLDER = TEST_KIT_ID
42
+ DASHERIZED_TEST_KIT_ID = TEST_KIT_ID.gsub('_', '-')
43
+ INPUT_HEADERS = [
44
+ 'Req Set',
45
+ 'ID',
46
+ 'URL',
47
+ 'Requirement',
48
+ 'Conformance',
49
+ 'Actor',
50
+ 'Sub-Requirement(s)',
51
+ 'Conditionality'
52
+ ].freeze
34
53
  SHORT_ID_HEADER = 'Short ID(s)'
35
54
  FULL_ID_HEADER = 'Full ID(s)'
36
- INPUT_FILE_NAME = "#{TEST_KIT_ID}_requirements.csv"
55
+ INPUT_FILE_NAME = "#{DASHERIZED_TEST_KIT_ID}_requirements.csv".freeze
37
56
  INPUT_FILE = File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', INPUT_FILE_NAME).freeze
38
- NOT_TESTED_FILE_NAME = "#{TEST_KIT_ID}_out_of_scope_requirements.csv"
57
+ NOT_TESTED_FILE_NAME = "#{DASHERIZED_TEST_KIT_ID}_out_of_scope_requirements.csv".freeze
39
58
  NOT_TESTED_FILE = File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', NOT_TESTED_FILE_NAME).freeze
40
- OUTPUT_FILE_NAME = "#{TEST_KIT_ID}_requirements_coverage.csv"
41
- OUTPUT_FILE_DIRECTORY = File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', 'generated').freeze
59
+ OUTPUT_HEADERS = INPUT_HEADERS + TEST_SUITES.flat_map do |suite|
60
+ ["#{suite.title} #{SHORT_ID_HEADER}", "#{suite.title} #{FULL_ID_HEADER}"]
61
+ end
62
+ OUTPUT_FILE_NAME = "#{DASHERIZED_TEST_KIT_ID}_requirements_coverage.csv".freeze
63
+ OUTPUT_FILE_DIRECTORY = File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', 'generated')
42
64
  OUTPUT_FILE = File.join(OUTPUT_FILE_DIRECTORY, OUTPUT_FILE_NAME).freeze
43
- BOM = "\xEF\xBB\xBF"
44
65
 
45
66
  def input_rows
46
67
  @input_rows ||=
@@ -59,7 +80,7 @@ module InfernoRequirementsTools
59
80
  not_tested_requirements = {}
60
81
  CSV.parse(File.open(NOT_TESTED_FILE, 'r:bom|utf-8'), headers: true).each do |row|
61
82
  row_hash = row.to_h
62
- not_tested_requirements["#{row_hash['Req Set']}##{row_hash['ID']}"] = row_hash
83
+ not_tested_requirements["#{row_hash['Req Set']}@#{row_hash['ID']}"] = row_hash
63
84
  end
64
85
 
65
86
  not_tested_requirements
@@ -85,51 +106,56 @@ module InfernoRequirementsTools
85
106
 
86
107
  def new_csv
87
108
  @new_csv ||=
88
- CSV.generate do |csv|
89
- output_headers = TEST_SUITES.each_with_object(INPUT_HEADERS.dup) do |suite, headers|
90
- headers << "#{suite.title} #{SHORT_ID_HEADER}"
91
- headers << "#{suite.title} #{FULL_ID_HEADER}"
92
- end
93
-
94
- csv << output_headers
109
+ CSV.generate(+"\xEF\xBB\xBF") do |csv|
110
+ csv << OUTPUT_HEADERS
95
111
  input_rows.each do |row| # NOTE: use row order from source file
96
- row_actor = row['Actor']
112
+ next if row['Conformance'] == 'DEPRECATED' # filter out deprecated rows
113
+
97
114
  TEST_SUITES.each do |suite|
98
115
  suite_actor = SUITE_ID_TO_ACTOR_MAP[suite.id]
99
- if row_actor&.include?(suite_actor)
100
- set_and_req_id = "#{row['Req Set']}##{row['ID']}"
101
- suite_requirement_items = inferno_requirements_map[set_and_req_id]&.filter do |item|
102
- item[:suite_id] == suite.id
103
- end
104
- short_ids = suite_requirement_items&.map { |item| item[:short_id] }
105
- full_ids = suite_requirement_items&.map { |item| item[:full_id] }
106
- if short_ids.blank? && not_tested_requirements_map.has_key?(set_and_req_id)
107
- row["#{suite.title} #{SHORT_ID_HEADER}"] = 'Not Tested'
108
- row["#{suite.title} #{FULL_ID_HEADER}"] = 'Not Tested'
109
- else
110
- row["#{suite.title} #{SHORT_ID_HEADER}"] = short_ids&.join(', ')
111
- row["#{suite.title} #{FULL_ID_HEADER}"] = full_ids&.join(', ')
112
- end
116
+ if row['Actor']&.include?(suite_actor)
117
+ add_suite_tests_for_row(row, suite)
113
118
  else
114
119
  row["#{suite.title} #{SHORT_ID_HEADER}"] = 'NA'
115
120
  row["#{suite.title} #{FULL_ID_HEADER}"] = 'NA'
116
121
  end
117
122
  end
118
-
119
123
  csv << row.values
120
124
  end
121
125
  end
122
126
  end
123
127
 
128
+ def add_suite_tests_for_row(row, suite)
129
+ set_and_req_id = "#{row['Req Set']}@#{row['ID']}"
130
+ items = get_items_for_requirement(set_and_req_id, suite)
131
+ short_ids = items[0]
132
+ full_ids = items[1]
133
+ if short_ids.blank? && not_tested_requirements_map.key?(set_and_req_id)
134
+ row["#{suite.title} #{SHORT_ID_HEADER}"] = 'Not Tested'
135
+ row["#{suite.title} #{FULL_ID_HEADER}"] = 'Not Tested'
136
+ else
137
+ row["#{suite.title} #{SHORT_ID_HEADER}"] = short_ids&.join(', ')
138
+ row["#{suite.title} #{FULL_ID_HEADER}"] = full_ids&.join(', ')
139
+ end
140
+ end
141
+
142
+ def get_items_for_requirement(set_and_req_id, suite)
143
+ suite_requirement_items = inferno_requirements_map[set_and_req_id]&.filter do |item|
144
+ item[:suite_id] == suite.id
145
+ end
146
+ [
147
+ suite_requirement_items&.map { |item| item[:short_id] },
148
+ suite_requirement_items&.map { |item| item[:full_id] }
149
+ ]
150
+ end
151
+
124
152
  def input_requirement_ids
125
- @input_requirement_ids ||= input_rows.map { |row| "#{row['Req Set']}##{row['ID']}" }
153
+ @input_requirement_ids ||= input_rows.map { |row| "#{row['Req Set']}@#{row['ID']}" }
126
154
  end
127
155
 
128
156
  # The requirements present in Inferno that aren't in the input spreadsheet
129
157
  def unmatched_requirements_map
130
- @unmatched_requirements_map ||= inferno_requirements_map.filter do |requirement_id, _|
131
- !input_requirement_ids.include?(requirement_id)
132
- end
158
+ @unmatched_requirements_map ||= inferno_requirements_map.except(*input_requirement_ids)
133
159
  end
134
160
 
135
161
  def old_csv
@@ -138,7 +164,7 @@ module InfernoRequirementsTools
138
164
 
139
165
  def run
140
166
  unless File.exist?(INPUT_FILE)
141
- puts "Could not find input file: #{INPUT_FILE}. Aborting requirements mapping..."
167
+ puts "Could not find input file: #{INPUT_FILE}. Aborting requirements coverage generation..."
142
168
  exit(1)
143
169
  end
144
170
 
@@ -148,11 +174,11 @@ module InfernoRequirementsTools
148
174
  end
149
175
 
150
176
  if File.exist?(OUTPUT_FILE)
151
- if old_csv == (BOM + new_csv)
177
+ if old_csv == new_csv
152
178
  puts "'#{OUTPUT_FILE_NAME}' file is up to date."
153
179
  return
154
180
  else
155
- puts 'Requirements mapping has changed.'
181
+ puts 'Requirements coverage has changed.'
156
182
  end
157
183
  else
158
184
  puts "No existing #{OUTPUT_FILE_NAME}."
@@ -160,13 +186,13 @@ module InfernoRequirementsTools
160
186
 
161
187
  puts "Writing to file #{OUTPUT_FILE}..."
162
188
  FileUtils.mkdir_p(OUTPUT_FILE_DIRECTORY)
163
- File.write(OUTPUT_FILE, BOM + new_csv)
189
+ File.write(OUTPUT_FILE, new_csv)
164
190
  puts 'Done.'
165
191
  end
166
192
 
167
193
  def run_check
168
194
  unless File.exist?(INPUT_FILE)
169
- puts "Could not find input file: #{INPUT_FILE}. Aborting requirements mapping check..."
195
+ puts "Could not find input file: #{INPUT_FILE}. Aborting requirements coverage check..."
170
196
  exit(1)
171
197
  end
172
198
 
@@ -176,7 +202,7 @@ module InfernoRequirementsTools
176
202
  end
177
203
 
178
204
  if File.exist?(OUTPUT_FILE)
179
- if old_csv == (BOM + new_csv)
205
+ if old_csv == new_csv
180
206
  puts "'#{OUTPUT_FILE_NAME}' file is up to date."
181
207
  return unless unmatched_requirements_map.any?
182
208
  else
@@ -184,7 +210,7 @@ module InfernoRequirementsTools
184
210
  #{OUTPUT_FILE_NAME} file is out of date.
185
211
  To regenerate the file, run:
186
212
 
187
- bundle exec rake requirements:map_requirements
213
+ bundle exec rake requirements:generate_coverage
188
214
 
189
215
  MESSAGE
190
216
  end
@@ -193,7 +219,7 @@ module InfernoRequirementsTools
193
219
  No existing #{OUTPUT_FILE_NAME} file.
194
220
  To generate the file, run:
195
221
 
196
- bundle exec rake requirementss:map_requirements
222
+ bundle exec rake requirements:generate_coverage
197
223
 
198
224
  MESSAGE
199
225
  end
@@ -223,6 +249,7 @@ module InfernoRequirementsTools
223
249
  # ---------------+------------+----------
224
250
  # req-id-1 | short-id-1 | full-id-1
225
251
  # req-id-2 | short-id-2 | full-id-2
252
+ #
226
253
  def output_requirements_map_table(requirements_map)
227
254
  headers = %w[requirement_id short_id full_id]
228
255
  col_widths = headers.map(&:length)
@@ -237,6 +264,11 @@ module InfernoRequirementsTools
237
264
  headers[2].ljust(col_widths[2])
238
265
  ].join(' | ')
239
266
  puts col_widths.map { |width| '-' * width }.join('-+-')
267
+ output_requirements_map_table_contents(requirements_map, col_widths)
268
+ puts
269
+ end
270
+
271
+ def output_requirements_map_table_contents(requirements_map, col_widths)
240
272
  requirements_map.each do |requirement_id, runnables|
241
273
  runnables.each do |runnable|
242
274
  puts [
@@ -246,7 +278,6 @@ module InfernoRequirementsTools
246
278
  ].join(' | ')
247
279
  end
248
280
  end
249
- puts
250
281
  end
251
282
  end
252
283
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carin_for_blue_button_test_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.1
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-06 00:00:00.000000000 Z
11
+ date: 2024-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: inferno_core
@@ -110,6 +110,37 @@ files:
110
110
  - lib/carin_for_blue_button_test_kit/capability_statement/tests/json_support_test.rb
111
111
  - lib/carin_for_blue_button_test_kit/capability_statement/tests/profile_support_test.rb
112
112
  - lib/carin_for_blue_button_test_kit/carin_search_test.rb
113
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/c4bb_client_test_suite.rb
114
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/client_claims_data_attestation_test.rb
115
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/coverage_claims_data_request_test.rb
116
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/eob_inpatient_claims_data_request_test.rb
117
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/eob_oral_claims_data_request_test.rb
118
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/eob_outpatient_claims_data_request_test.rb
119
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/eob_pharmacy_claims_data_request_test.rb
120
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/eob_professional_claims_data_request_test.rb
121
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/organization_claims_data_request_test.rb
122
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/patient_claims_data_request_test.rb
123
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/practitioner_claims_data_request_test.rb
124
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/relatedperson_claims_data_request_test.rb
125
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/client_validation_test.rb
126
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/collection.rb
127
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/endpoints/next_page_endpoint.rb
128
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/endpoints/resource_api_endpoint.rb
129
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/endpoints/resource_id_endpoint.rb
130
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/endpoints/token_endpoint.rb
131
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/initial_wait_test.rb
132
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/metadata/mock_capability_statement.json
133
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/metadata/mock_operation_outcome_resource.json
134
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/mock_server.rb
135
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/coverage_required_searches.rb
136
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/eob_required_searches.rb
137
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/organization_required_searches.rb
138
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/patient_required_searches.rb
139
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/practitioner_required_searches.rb
140
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/relatedperson_required_searches.rb
141
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/tags.rb
142
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/urls.rb
143
+ - lib/carin_for_blue_button_test_kit/client/v2.0.0/user_input_response.rb
113
144
  - lib/carin_for_blue_button_test_kit/custom_groups/v1.1.0/c4bb_smart_launch_group.rb
114
145
  - lib/carin_for_blue_button_test_kit/custom_groups/v2.0.0-dev-nonfinancial/c4bb_smart_launch/smart_scopes_test.rb
115
146
  - lib/carin_for_blue_button_test_kit/custom_groups/v2.0.0-dev-nonfinancial/c4bb_smart_launch/well_known_capabilities_test.rb
@@ -664,8 +695,7 @@ files:
664
695
  - lib/carin_for_blue_button_test_kit/validation_test.rb
665
696
  - lib/carin_for_blue_button_test_kit/version.rb
666
697
  - lib/inferno_requirements_tools/ext/inferno_core/runnable.rb
667
- - lib/inferno_requirements_tools/tasks/collect_requirements.rb
668
- - lib/inferno_requirements_tools/tasks/map_requirements.rb
698
+ - lib/inferno_requirements_tools/tasks/requirements_coverage.rb
669
699
  homepage: https://github.com/inferno-framework/carin-for-blue-button-test-kit
670
700
  licenses:
671
701
  - Apache-2.0
@@ -1,196 +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_check` method will check whether the previously generated file is up-to-date.
14
- class CollectRequirements
15
- # Update these constants based on the test kit.
16
- TEST_KIT_ID = 'carin-for-blue-button-test-kit'
17
- INPUT_SETS = ['hl7.fhir.us.carin-bb_2.0.0'].freeze
18
-
19
- # Derivative constants
20
- TEST_KIT_CODE_FOLDER = TEST_KIT_ID.gsub('-', '_')
21
- INPUT_HEADERS = ['ID*', 'URL*', 'Requirement*', 'Conformance*', 'Actor*', 'Sub-Requirement(s)', 'Conditionality',
22
- 'Verifiable?', 'Verifiability Details', 'Planning To Test?', 'Planning To Test Details'].freeze
23
- REQUIREMENTS_OUTPUT_HEADERS = ['Req Set', 'ID', 'URL', 'Requirement', 'Conformance', 'Actor',
24
- 'Sub-Requirement(s)', 'Conditionality'].freeze
25
- REQUIREMENTS_OUTPUT_FILE_NAME = "#{TEST_KIT_ID}_requirements.csv"
26
- REQUIREMENTS_OUTPUT_FILE = File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements',
27
- REQUIREMENTS_OUTPUT_FILE_NAME).freeze
28
- PLANNED_NOT_TESTED_OUTPUT_HEADERS = ['Req Set', 'ID', 'Reason', 'Details'].freeze
29
- PLANNED_NOT_TESTED_OUTPUT_FILE_NAME = "#{TEST_KIT_ID}_out_of_scope_requirements.csv"
30
- PLANNED_NOT_TESTED_OUTPUT_FILE = File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements',
31
- PLANNED_NOT_TESTED_OUTPUT_FILE_NAME).freeze
32
- BOM = "\xEF\xBB\xBF"
33
-
34
- def input_file_map
35
- @input_file_map ||= {}
36
- end
37
-
38
- def input_rows
39
- @input_rows ||= {}
40
- end
41
-
42
- def input_rows_for_set(req_set_id)
43
- input_rows[req_set_id] = extract_input_rows_for_set(req_set_id) unless input_rows.has_key?(req_set_id)
44
- input_rows[req_set_id]
45
- end
46
-
47
- def extract_input_rows_for_set(req_set_id)
48
- CSV.parse(Roo::Spreadsheet.open(input_file_map[req_set_id]).sheet('Requirements').to_csv,
49
- headers: true).map do |row|
50
- row.to_h.slice(*INPUT_HEADERS)
51
- end
52
- end
53
-
54
- def new_requirements_csv
55
- @new_requirements_csv ||=
56
- CSV.generate do |csv|
57
- csv << REQUIREMENTS_OUTPUT_HEADERS
58
-
59
- INPUT_SETS.each do |req_set_id|
60
- input_rows = input_rows_for_set(req_set_id)
61
- input_rows.each do |row| # NOTE: use row order from source file
62
- row['Req Set'] = req_set_id
63
-
64
- csv << REQUIREMENTS_OUTPUT_HEADERS.map do |header|
65
- row.has_key?(header) ? row[header] : row["#{header}*"]
66
- end
67
- end
68
- end
69
- end
70
- end
71
-
72
- def old_requirements_csv
73
- @old_requirements_csv ||= File.read(REQUIREMENTS_OUTPUT_FILE)
74
- end
75
-
76
- def new_planned_not_tested_csv
77
- @new_planned_not_tested_csv ||=
78
- CSV.generate do |csv|
79
- csv << PLANNED_NOT_TESTED_OUTPUT_HEADERS
80
-
81
- INPUT_SETS.each do |req_set_id|
82
- input_rows = input_rows_for_set(req_set_id)
83
- input_rows.each do |row| # NOTE: use row order from source file
84
- not_verifiable = row['Verifiable?']&.downcase == 'no' || row['Verifiable?']&.downcase == 'false'
85
- not_tested = row['Planning To Test?']&.downcase == 'no' || row['Planning To Test?']&.downcase == 'false'
86
- next unless not_verifiable || not_tested
87
-
88
- csv << [req_set_id,
89
- row['ID*'],
90
- not_verifiable ? 'Not Verifiable' : 'Not Tested',
91
- not_verifiable ? row['Verifiability Details'] : row['Planning To Test Details']]
92
- end
93
- end
94
- end
95
- end
96
-
97
- def old_planned_not_tested_csv
98
- @old_planned_not_tested_csv ||= File.read(PLANNED_NOT_TESTED_OUTPUT_FILE)
99
- end
100
-
101
- def check_for_req_set_files(input_directory)
102
- available_worksheets = Dir.glob(File.join(input_directory, '*.xlsx')).reject { |f| f.include?('~$') }
103
-
104
- INPUT_SETS.each do |req_set_id|
105
- req_set_file = available_worksheets&.find { |worksheet_file| worksheet_file.include?(req_set_id) }
106
-
107
- if req_set_file&.empty?
108
- puts "Could not find input file for set #{req_set_id} in directory #{input_directory}. Aborting requirements collection..."
109
- exit(1)
110
- end
111
- input_file_map[req_set_id] = req_set_file
112
- end
113
- end
114
-
115
- def run(input_directory)
116
- check_for_req_set_files(input_directory)
117
-
118
- update_requirements = if File.exist?(REQUIREMENTS_OUTPUT_FILE)
119
- if old_requirements_csv == (BOM + new_requirements_csv)
120
- puts "'#{REQUIREMENTS_OUTPUT_FILE_NAME}' file is up to date."
121
- false
122
- else
123
- puts 'Requirements set has changed.'
124
- true
125
- end
126
- else
127
- puts "No existing #{REQUIREMENTS_OUTPUT_FILE_NAME}."
128
- true
129
- end
130
- if update_requirements
131
- puts "Writing to file #{REQUIREMENTS_OUTPUT_FILE}..."
132
- File.write(REQUIREMENTS_OUTPUT_FILE, BOM + new_requirements_csv, encoding: Encoding::UTF_8)
133
- end
134
-
135
- udpate_planned_not_tested = if File.exist?(PLANNED_NOT_TESTED_OUTPUT_FILE)
136
- if old_planned_not_tested_csv == (BOM + new_planned_not_tested_csv)
137
- puts "'#{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME}' file is up to date."
138
- false
139
- else
140
- puts 'Planned Not Tested Requirements set has changed.'
141
- true
142
- end
143
- else
144
- puts "No existing #{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME}."
145
- true
146
- end
147
- if udpate_planned_not_tested
148
- puts "Writing to file #{PLANNED_NOT_TESTED_OUTPUT_FILE}..."
149
- File.write(PLANNED_NOT_TESTED_OUTPUT_FILE, BOM + new_planned_not_tested_csv, encoding: Encoding::UTF_8)
150
- end
151
-
152
- puts 'Done.'
153
- end
154
-
155
- def run_check(input_directory)
156
- check_for_req_set_files(input_directory)
157
-
158
- requirements_ok = if File.exist?(REQUIREMENTS_OUTPUT_FILE)
159
- if old_requirements_csv == (BOM + new_requirements_csv)
160
- puts "'#{REQUIREMENTS_OUTPUT_FILE_NAME}' file is up to date."
161
- true
162
- else
163
- puts "#{REQUIREMENTS_OUTPUT_FILE_NAME} file is out of date."
164
- false
165
- end
166
- else
167
- puts "No existing #{REQUIREMENTS_OUTPUT_FILE_NAME} file."
168
- false
169
- end
170
-
171
- planned_not_tested_requirements_ok = if File.exist?(PLANNED_NOT_TESTED_OUTPUT_FILE)
172
- if old_planned_not_tested_csv == (BOM + new_planned_not_tested_csv)
173
- puts "'#{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME}' file is up to date."
174
- true
175
- else
176
- puts "#{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME} file is out of date."
177
- false
178
- end
179
- else
180
- puts "No existing #{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME} file."
181
- false
182
- end
183
-
184
- return if planned_not_tested_requirements_ok && requirements_ok
185
-
186
- puts <<~MESSAGE
187
- Check Failed. To resolve, run:
188
-
189
- bundle exec rake "requirements:collect_requirements[<input_directory>]"
190
-
191
- MESSAGE
192
- exit(1)
193
- end
194
- end
195
- end
196
- end