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.
- checksums.yaml +4 -4
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/c4bb_client_test_suite.rb +227 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/client_claims_data_attestation_test.rb +32 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/coverage_claims_data_request_test.rb +25 -0
- 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
- 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
- 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
- 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
- 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
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/organization_claims_data_request_test.rb +26 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/patient_claims_data_request_test.rb +24 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/practitioner_claims_data_request_test.rb +25 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/claim_data_request_tests/relatedperson_claims_data_request_test.rb +25 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/client_validation_test.rb +93 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/collection.rb +19 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/endpoints/next_page_endpoint.rb +24 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/endpoints/resource_api_endpoint.rb +74 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/endpoints/resource_id_endpoint.rb +24 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/endpoints/token_endpoint.rb +24 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/initial_wait_test.rb +76 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/metadata/mock_capability_statement.json +535 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/metadata/mock_operation_outcome_resource.json +16 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/mock_server.rb +190 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/coverage_required_searches.rb +45 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/eob_required_searches.rb +71 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/organization_required_searches.rb +47 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/patient_required_searches.rb +71 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/practitioner_required_searches.rb +47 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/required_searches_tests/relatedperson_required_searches.rb +43 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/tags.rb +7 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/urls.rb +57 -0
- data/lib/carin_for_blue_button_test_kit/client/v2.0.0/user_input_response.rb +32 -0
- data/lib/carin_for_blue_button_test_kit/version.rb +1 -1
- data/lib/carin_for_blue_button_test_kit.rb +1 -0
- data/lib/inferno_requirements_tools/tasks/{map_requirements.rb → requirements_coverage.rb} +91 -60
- metadata +34 -4
- 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 '
|
4
|
-
require '
|
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
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
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
|
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
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
32
|
-
|
33
|
-
|
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 = "#{
|
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 = "#{
|
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
|
-
|
41
|
-
|
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']}
|
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
|
-
|
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
|
-
|
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
|
100
|
-
|
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']}
|
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.
|
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
|
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 ==
|
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
|
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,
|
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
|
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 ==
|
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:
|
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
|
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.
|
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
|
+
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/
|
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
|