carin_for_blue_button_test_kit 0.11.1 → 0.12.0

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: 2268085cb042cfa92f88a145ad59ec88e334df6777c817ee5a3a0eff63fcc581
4
- data.tar.gz: 8a22b4b18ef0bd2bf9d864b6da0709ea3ce5949871a80b4397eb9fd31e1980c0
3
+ metadata.gz: f41fd8b880ca87da7f764f53bdd35d5c0ced19d31f698b77e0797c8ce573c454
4
+ data.tar.gz: 3b6a11364e422efda129ffb6e2e874f632a70e30a96e974ea97d4b365855f6d0
5
5
  SHA512:
6
- metadata.gz: 16474d66f8c73d723644d6f277d8e66a4ae48a8542e41ba2f90fbd2f10debc43004bd9db63fd51f6d370c5470909354a6721f057683adf20024ea3c674275ea9
7
- data.tar.gz: '0866be79f67aeea7f3246e1869b8ea09aa11fdf5ecb464aa13bec484a7e48938faed89b01a3ca76356d5bfcb8121e154d6055a023df0132ce4250de3fc080c46'
6
+ metadata.gz: 804e36426dadbd1c5d42abe58d25af010213c8cafd337540afb21729c3a8535a69ee1d71eb8efd2d984969cc78de6895194eaf4813ca87653e40038eba39dac7
7
+ data.tar.gz: c10305ff52761d02b4dd8bea9a37ec5b36f794257b9114a9eb3e0189c61445e244068d06626d08c2f97f802b5b847c5d9f809e53daa151553d2862b74177c1d9
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CarinForBlueButtonTestKit
4
- VERSION = '0.11.1'
4
+ VERSION = '0.12.0'
5
5
  end
@@ -1,3 +1,4 @@
1
+ require_relative 'inferno_requirements_tools/ext/inferno_core/runnable'
1
2
  require_relative 'carin_for_blue_button_test_kit/generated/v1.1.0/c4bb_test_suite'
2
3
  require_relative 'carin_for_blue_button_test_kit/generated/v2.0.0/c4bb_test_suite'
3
4
  require_relative 'carin_for_blue_button_test_kit/generated/v2.0.0-dev-nonfinancial/c4bb_test_suite'
@@ -0,0 +1,22 @@
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
@@ -0,0 +1,196 @@
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
@@ -0,0 +1,253 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'CSV'
4
+ require 'roo'
5
+ require_relative '../ext/inferno_core/runnable'
6
+
7
+ module InfernoRequirementsTools
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`
13
+ #
14
+ # The `run` method generates a CSV file at lib/carin_for_blue_button_test_kit/requirements/Requirements_Coverage.csv.
15
+ # This file will be identical to the input spreadsheet, plus an additional column which holds a comma separated
16
+ # list of inferno test IDs that test each requirement. These test IDs are Inferno short form IDs that represent the
17
+ # position of the test within its group and suite. For example, the fifth test in the second group will have an ID
18
+ # of 2.05. This ID is also shown in the Inferno web UI.
19
+ # The output file is also sorted by requirement ID.
20
+ #
21
+ # 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
29
+
30
+ # 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
34
+ SHORT_ID_HEADER = 'Short ID(s)'
35
+ FULL_ID_HEADER = 'Full ID(s)'
36
+ INPUT_FILE_NAME = "#{TEST_KIT_ID}_requirements.csv"
37
+ 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"
39
+ 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
42
+ OUTPUT_FILE = File.join(OUTPUT_FILE_DIRECTORY, OUTPUT_FILE_NAME).freeze
43
+ BOM = "\xEF\xBB\xBF"
44
+
45
+ def input_rows
46
+ @input_rows ||=
47
+ CSV.parse(File.open(INPUT_FILE, 'r:bom|utf-8'), headers: true).map do |row|
48
+ row.to_h.slice(*INPUT_HEADERS)
49
+ end
50
+ end
51
+
52
+ def not_tested_requirements_map
53
+ @not_tested_requirements_map ||= load_not_tested_requirements
54
+ end
55
+
56
+ def load_not_tested_requirements
57
+ return {} unless File.exist?(NOT_TESTED_FILE)
58
+
59
+ not_tested_requirements = {}
60
+ CSV.parse(File.open(NOT_TESTED_FILE, 'r:bom|utf-8'), headers: true).each do |row|
61
+ row_hash = row.to_h
62
+ not_tested_requirements["#{row_hash['Req Set']}##{row_hash['ID']}"] = row_hash
63
+ end
64
+
65
+ not_tested_requirements
66
+ end
67
+
68
+ # Of the form:
69
+ # {
70
+ # 'req-id-1': [
71
+ # { short_id: 'short-id-1', full_id: 'long-id-1', suite_id: 'suite-id-1' },
72
+ # { short_id: 'short-id-2', full_id: 'long-id-2', suite_id: 'suite-id-2' }
73
+ # ],
74
+ # 'req-id-2': [{ short_id: 'short-id-3', full_id: 'long-id-3', suite_id: 'suite-id-3' }],
75
+ # ...
76
+ # }
77
+ def inferno_requirements_map
78
+ @inferno_requirements_map ||= TEST_SUITES.each_with_object({}) do |suite, requirements_map|
79
+ serialize_requirements(suite, 'suite', suite.id, requirements_map)
80
+ suite.groups.each do |group|
81
+ map_group_requirements(group, suite.id, requirements_map)
82
+ end
83
+ end
84
+ end
85
+
86
+ def new_csv
87
+ @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
95
+ input_rows.each do |row| # NOTE: use row order from source file
96
+ row_actor = row['Actor']
97
+ TEST_SUITES.each do |suite|
98
+ 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
113
+ else
114
+ row["#{suite.title} #{SHORT_ID_HEADER}"] = 'NA'
115
+ row["#{suite.title} #{FULL_ID_HEADER}"] = 'NA'
116
+ end
117
+ end
118
+
119
+ csv << row.values
120
+ end
121
+ end
122
+ end
123
+
124
+ def input_requirement_ids
125
+ @input_requirement_ids ||= input_rows.map { |row| "#{row['Req Set']}##{row['ID']}" }
126
+ end
127
+
128
+ # The requirements present in Inferno that aren't in the input spreadsheet
129
+ def unmatched_requirements_map
130
+ @unmatched_requirements_map ||= inferno_requirements_map.filter do |requirement_id, _|
131
+ !input_requirement_ids.include?(requirement_id)
132
+ end
133
+ end
134
+
135
+ def old_csv
136
+ @old_csv ||= File.read(OUTPUT_FILE)
137
+ end
138
+
139
+ def run
140
+ unless File.exist?(INPUT_FILE)
141
+ puts "Could not find input file: #{INPUT_FILE}. Aborting requirements mapping..."
142
+ exit(1)
143
+ end
144
+
145
+ if unmatched_requirements_map.any?
146
+ puts "WARNING: The following requirements indicated in the test kit are not present in #{INPUT_FILE_NAME}"
147
+ output_requirements_map_table(unmatched_requirements_map)
148
+ end
149
+
150
+ if File.exist?(OUTPUT_FILE)
151
+ if old_csv == (BOM + new_csv)
152
+ puts "'#{OUTPUT_FILE_NAME}' file is up to date."
153
+ return
154
+ else
155
+ puts 'Requirements mapping has changed.'
156
+ end
157
+ else
158
+ puts "No existing #{OUTPUT_FILE_NAME}."
159
+ end
160
+
161
+ puts "Writing to file #{OUTPUT_FILE}..."
162
+ FileUtils.mkdir_p(OUTPUT_FILE_DIRECTORY)
163
+ File.write(OUTPUT_FILE, BOM + new_csv)
164
+ puts 'Done.'
165
+ end
166
+
167
+ def run_check
168
+ unless File.exist?(INPUT_FILE)
169
+ puts "Could not find input file: #{INPUT_FILE}. Aborting requirements mapping check..."
170
+ exit(1)
171
+ end
172
+
173
+ if unmatched_requirements_map.any?
174
+ puts "The following requirements indicated in the test kit are not present in #{INPUT_FILE_NAME}"
175
+ output_requirements_map_table(unmatched_requirements_map)
176
+ end
177
+
178
+ if File.exist?(OUTPUT_FILE)
179
+ if old_csv == (BOM + new_csv)
180
+ puts "'#{OUTPUT_FILE_NAME}' file is up to date."
181
+ return unless unmatched_requirements_map.any?
182
+ else
183
+ puts <<~MESSAGE
184
+ #{OUTPUT_FILE_NAME} file is out of date.
185
+ To regenerate the file, run:
186
+
187
+ bundle exec rake requirements:map_requirements
188
+
189
+ MESSAGE
190
+ end
191
+ else
192
+ puts <<~MESSAGE
193
+ No existing #{OUTPUT_FILE_NAME} file.
194
+ To generate the file, run:
195
+
196
+ bundle exec rake requirementss:map_requirements
197
+
198
+ MESSAGE
199
+ end
200
+
201
+ puts 'Check failed.'
202
+ exit(1)
203
+ end
204
+
205
+ def map_group_requirements(group, suite_id, requirements_map)
206
+ serialize_requirements(group, group.short_id, suite_id, requirements_map)
207
+ group.tests&.each { |test| serialize_requirements(test, test.short_id, suite_id, requirements_map) }
208
+ group.groups&.each { |subgroup| map_group_requirements(subgroup, suite_id, requirements_map) }
209
+ end
210
+
211
+ def serialize_requirements(runnable, short_id, suite_id, requirements_map)
212
+ runnable.verifies_requirements&.each do |requirement_id|
213
+ requirement_id_string = requirement_id.to_s
214
+
215
+ requirements_map[requirement_id_string] ||= []
216
+ requirements_map[requirement_id_string] << { short_id:, full_id: runnable.id, suite_id: }
217
+ end
218
+ end
219
+
220
+ # Output the requirements in the map like so:
221
+ #
222
+ # requirement_id | short_id | full_id
223
+ # ---------------+------------+----------
224
+ # req-id-1 | short-id-1 | full-id-1
225
+ # req-id-2 | short-id-2 | full-id-2
226
+ def output_requirements_map_table(requirements_map)
227
+ headers = %w[requirement_id short_id full_id]
228
+ col_widths = headers.map(&:length)
229
+ col_widths[0] = [col_widths[0], requirements_map.keys.map(&:length).max].max
230
+ col_widths[1] = ([col_widths[1]] + requirements_map.values.flatten.map { |item| item[:short_id].length }).max
231
+ col_widths[2] = ([col_widths[2]] + requirements_map.values.flatten.map { |item| item[:full_id].length }).max
232
+ col_widths.map { |width| width + 3 }
233
+
234
+ puts [
235
+ headers[0].ljust(col_widths[0]),
236
+ headers[1].ljust(col_widths[1]),
237
+ headers[2].ljust(col_widths[2])
238
+ ].join(' | ')
239
+ puts col_widths.map { |width| '-' * width }.join('-+-')
240
+ requirements_map.each do |requirement_id, runnables|
241
+ runnables.each do |runnable|
242
+ puts [
243
+ requirement_id.ljust(col_widths[0]),
244
+ runnable[:short_id].ljust(col_widths[1]),
245
+ runnable[:full_id].ljust(col_widths[2])
246
+ ].join(' | ')
247
+ end
248
+ end
249
+ puts
250
+ end
251
+ end
252
+ end
253
+ 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.11.1
4
+ version: 0.12.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-06-05 00:00:00.000000000 Z
11
+ date: 2024-11-06 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.4.37
19
+ version: 0.5.0
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.4.37
26
+ version: 0.5.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: smart_app_launch_test_kit
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '3.11'
97
+ - !ruby/object:Gem::Dependency
98
+ name: roo
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 2.7.1
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 2.7.1
97
111
  description: CARIN IG for Blue Button® Test Kit
98
112
  email:
99
113
  - jmorrison@leaporbit.com
@@ -663,6 +677,9 @@ files:
663
677
  - lib/carin_for_blue_button_test_kit/search_test_properties.rb
664
678
  - lib/carin_for_blue_button_test_kit/validation_test.rb
665
679
  - lib/carin_for_blue_button_test_kit/version.rb
680
+ - lib/inferno_requirements_tools/ext/inferno_core/runnable.rb
681
+ - lib/inferno_requirements_tools/tasks/collect_requirements.rb
682
+ - lib/inferno_requirements_tools/tasks/map_requirements.rb
666
683
  homepage: https://github.com/inferno-framework/carin-for-blue-button-test-kit
667
684
  licenses:
668
685
  - Apache-2.0