Class: InfernoRequirementsTools::Tasks::CollectRequirements
- Inherits:
-
Object
- Object
- InfernoRequirementsTools::Tasks::CollectRequirements
- Defined in:
- lib/inferno_requirements_tools/tasks/collect_requirements.rb
Overview
This class manages the collection of requirements details from requirements planning excel workbooks into a CSV representation. Currently splits out Requirements and Planned Not Tested Requirements into two separate files.
The ‘run` method will generate the files The `run_check` method will check whether the previously generated files are up-to-date.
Constant Summary collapse
- TEST_KIT_ID =
Update these constants based on the test kit.
'subscriptions-test-kit'
- INPUT_SETS =
['hl7.fhir.uv.subscriptions_1.1.0'].freeze
- TEST_KIT_CODE_FOLDER =
Derivative constants
TEST_KIT_ID.gsub('-', '_')
- INPUT_HEADERS =
[ 'ID*', 'URL*', 'Requirement*', 'Conformance*', 'Actor*', 'Sub-Requirement(s)', 'Conditionality', 'Verifiable?', 'Verifiability Details', 'Planning To Test?', 'Planning To Test Details' ].freeze
- REQUIREMENTS_OUTPUT_HEADERS =
[ 'Req Set', 'ID', 'URL', 'Requirement', 'Conformance', 'Actor', 'Sub-Requirement(s)', 'Conditionality' ].freeze
- REQUIREMENTS_OUTPUT_FILE_NAME =
"#{TEST_KIT_ID}_requirements.csv".freeze
- REQUIREMENTS_OUTPUT_FILE =
File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', REQUIREMENTS_OUTPUT_FILE_NAME).freeze
- PLANNED_NOT_TESTED_OUTPUT_HEADERS =
['Req Set', 'ID', 'Reason', 'Details'].freeze
- PLANNED_NOT_TESTED_OUTPUT_FILE_NAME =
"#{TEST_KIT_ID}_out_of_scope_requirements.csv".freeze
- PLANNED_NOT_TESTED_OUTPUT_FILE =
File.join('lib', TEST_KIT_CODE_FOLDER, 'requirements', PLANNED_NOT_TESTED_OUTPUT_FILE_NAME).freeze
Instance Method Summary collapse
- #available_input_worksheets ⇒ Object
- #check_presence_of_input_files ⇒ Object
-
#input_requirement_sets ⇒ Object
Of the form: { req_set_id_1: [row1, row2, row 3, …], req_set_id_2: [row1, row2, row 3, …] }.
- #new_planned_not_tested_csv ⇒ Object
- #new_requirements_csv ⇒ Object
- #old_planned_not_tested_csv ⇒ Object
- #old_requirements_csv ⇒ Object
- #run(input_directory) ⇒ Object
- #run_check(input_directory) ⇒ Object
- #spreadsheet_value_falsy?(str) ⇒ Boolean
Instance Method Details
#available_input_worksheets ⇒ Object
55 56 57 |
# File 'lib/inferno_requirements_tools/tasks/collect_requirements.rb', line 55 def available_input_worksheets @available_input_worksheets ||= Dir.glob(File.join(@input_directory, '*.xlsx')).reject { |f| f.include?('~$') } end |
#check_presence_of_input_files ⇒ Object
206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/inferno_requirements_tools/tasks/collect_requirements.rb', line 206 def check_presence_of_input_files input_requirement_sets.each do |req_set_id, rows| next unless rows.nil? puts %( Could not find input file for set #{req_set_id} in directory #{input_directory}. Aborting requirements collection..." ) exit(1) end end |
#input_requirement_sets ⇒ Object
Of the form:
req_set_id_1: [row1, row2, row 3, ...],
req_set_id_2: [row1, row2, row 3, ...]
64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/inferno_requirements_tools/tasks/collect_requirements.rb', line 64 def input_requirement_sets @input_requirement_sets ||= INPUT_SETS.each_with_object({}) do |req_set_id, hash| req_set_file = available_input_worksheets.find { |worksheet_file| worksheet_file.include?(req_set_id) } hash[req_set_id] = unless req_set_file.nil? CSV.parse(Roo::Spreadsheet.open(req_set_file).sheet('Requirements').to_csv, headers: true).map do |row| row.to_h.slice(*INPUT_HEADERS) end end end end |
#new_planned_not_tested_csv ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/inferno_requirements_tools/tasks/collect_requirements.rb', line 97 def new_planned_not_tested_csv @new_planned_not_tested_csv ||= CSV.generate(+"\xEF\xBB\xBF") do |csv| # start with an unnecessary BOM to make viewing in excel easier csv << PLANNED_NOT_TESTED_OUTPUT_HEADERS input_requirement_sets.each do |req_set_id, input_rows| input_rows.each do |row| if spreadsheet_value_falsy?(row['Verifiable?']) csv << [req_set_id, row['ID*'], 'Not Verifiable', row['Verifiability Details']] elsif spreadsheet_value_falsy?(row['Planning To Test?']) csv << [req_set_id, row['ID*'], 'Not Tested', row['Planning To Test Details']] end end end end end |
#new_requirements_csv ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/inferno_requirements_tools/tasks/collect_requirements.rb', line 78 def new_requirements_csv @new_requirements_csv ||= CSV.generate(+"\xEF\xBB\xBF") do |csv| # start with an unnecessary BOM to make viewing in excel easier csv << REQUIREMENTS_OUTPUT_HEADERS input_requirement_sets.each do |req_set_id, input_rows| input_rows.each do |input_row| # NOTE: use row order from source file csv << REQUIREMENTS_OUTPUT_HEADERS.map do |header| header == 'Req Set' ? req_set_id : input_row[header] || input_row["#{header}*"] end end end end end |
#old_planned_not_tested_csv ⇒ Object
114 115 116 |
# File 'lib/inferno_requirements_tools/tasks/collect_requirements.rb', line 114 def old_planned_not_tested_csv @old_planned_not_tested_csv ||= File.read(PLANNED_NOT_TESTED_OUTPUT_FILE) end |
#old_requirements_csv ⇒ Object
93 94 95 |
# File 'lib/inferno_requirements_tools/tasks/collect_requirements.rb', line 93 def old_requirements_csv @old_requirements_csv ||= File.read(REQUIREMENTS_OUTPUT_FILE) end |
#run(input_directory) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/inferno_requirements_tools/tasks/collect_requirements.rb', line 118 def run(input_directory) @input_directory = input_directory check_presence_of_input_files update_requirements = if File.exist?(REQUIREMENTS_OUTPUT_FILE) if old_requirements_csv == new_requirements_csv puts "'#{REQUIREMENTS_OUTPUT_FILE_NAME}' file is up to date." false else puts 'Requirements set has changed.' true end else puts "No existing #{REQUIREMENTS_OUTPUT_FILE_NAME}." true end if update_requirements puts "Writing to file #{REQUIREMENTS_OUTPUT_FILE}..." File.write(REQUIREMENTS_OUTPUT_FILE, new_requirements_csv, encoding: Encoding::UTF_8) end udpate_planned_not_tested = if File.exist?(PLANNED_NOT_TESTED_OUTPUT_FILE) if old_planned_not_tested_csv == new_planned_not_tested_csv puts "'#{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME}' file is up to date." false else puts 'Planned Not Tested Requirements set has changed.' true end else puts "No existing #{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME}." true end if udpate_planned_not_tested puts "Writing to file #{PLANNED_NOT_TESTED_OUTPUT_FILE}..." File.write(PLANNED_NOT_TESTED_OUTPUT_FILE, new_planned_not_tested_csv, encoding: Encoding::UTF_8) end puts 'Done.' end |
#run_check(input_directory) ⇒ Object
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/inferno_requirements_tools/tasks/collect_requirements.rb', line 163 def run_check(input_directory) @input_directory = input_directory check_presence_of_input_files requirements_ok = if File.exist?(REQUIREMENTS_OUTPUT_FILE) if old_requirements_csv == new_requirements_csv puts "'#{REQUIREMENTS_OUTPUT_FILE_NAME}' file is up to date." true else puts "#{REQUIREMENTS_OUTPUT_FILE_NAME} file is out of date." false end else puts "No existing #{REQUIREMENTS_OUTPUT_FILE_NAME} file." false end planned_not_tested_requirements_ok = if File.exist?(PLANNED_NOT_TESTED_OUTPUT_FILE) if old_planned_not_tested_csv == new_planned_not_tested_csv puts "'#{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME}' file is up to date." true else puts "#{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME} file is out of date." false end else puts "No existing #{PLANNED_NOT_TESTED_OUTPUT_FILE_NAME} file." false end return if planned_not_tested_requirements_ok && requirements_ok puts <<~MESSAGE Check Failed. To resolve, run: bundle exec rake "requirements:collect[<input_directory>]" MESSAGE exit(1) end |
#spreadsheet_value_falsy?(str) ⇒ Boolean
218 219 220 |
# File 'lib/inferno_requirements_tools/tasks/collect_requirements.rb', line 218 def spreadsheet_value_falsy?(str) str&.downcase == 'no' || str&.downcase == 'false' end |