diff --git a/Gemfile.lock b/Gemfile.lock index 7bc16a8ed..8d56e22bf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - kiba-extend (2.5.0) + kiba-extend (2.5.1) activesupport (~> 6.1.4) csv (~> 3.0) dry-configurable (~> 0.11) @@ -108,4 +108,4 @@ DEPENDENCIES simplecov BUNDLED WITH - 2.1.4 + 2.2.22 diff --git a/lib/kiba/extend/destinations/csv.rb b/lib/kiba/extend/destinations/csv.rb index 70e2e2321..6d2014055 100644 --- a/lib/kiba/extend/destinations/csv.rb +++ b/lib/kiba/extend/destinations/csv.rb @@ -27,6 +27,7 @@ def initialize(filename:, csv_options: nil, headers: nil, initial_headers: []) def write(row) @csv ||= ::CSV.open(filename, 'wb', **csv_options) @headers ||= row.keys + verify_initial_headers order_headers @headers_written ||= (csv << headers; true) csv << row.fetch_values(*@headers) @@ -39,10 +40,34 @@ def close private + def header_check_hash + @initial_headers.map{ |hdr| [hdr, headers.any?(hdr)] }.to_h + end + + def initial_headers_present? + header_check_hash.values.all?(true) + end + + def missing_initial_headers + header_check_hash.reject{ |hdr, present| present }.keys + end + def order_headers remainder = @headers - @initial_headers @headers = [@initial_headers, remainder].flatten end + + def verify_initial_headers + return if @initial_headers.empty? + return if initial_headers_present? + + missing = missing_initial_headers + + missing.each do |hdr| + puts "WARNING: Output data does not contain specified initial header: #{hdr}" + end + @initial_headers = @initial_headers - missing + end end end end diff --git a/lib/kiba/extend/version.rb b/lib/kiba/extend/version.rb index 4f6f88a67..62588ffef 100644 --- a/lib/kiba/extend/version.rb +++ b/lib/kiba/extend/version.rb @@ -2,6 +2,6 @@ module Kiba module Extend - VERSION = '2.5.0' + VERSION = '2.5.1' end end diff --git a/spec/kiba/extend/destinations/csv_spec.rb b/spec/kiba/extend/destinations/csv_spec.rb new file mode 100644 index 000000000..92235a67b --- /dev/null +++ b/spec/kiba/extend/destinations/csv_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Kiba::Extend::Destinations::CSV do + TEST_FILENAME = 'output.csv' + def run_job(input) + job = Kiba.parse do + source Kiba::Common::Sources::Enumerable, input + destination Kiba::Extend::Destinations::CSV, filename: TEST_FILENAME, initial_headers: %i[y z] + end + + Kiba.run(job) + + IO.read(TEST_FILENAME) + end + + after(:each){ File.delete(TEST_FILENAME) if File.exist?(TEST_FILENAME) } + + context 'when intial headers present' do + let(:input) do + [ + {a: 'and', y: 'yak', z: 'zebra'}, + {a: 'apple', y: 'yarrow', z: 'zizia'} + ] + end + let(:expected) do + "y,z,a\nyak,zebra,and\nyarrow,zizia,apple\n" + end + it 'produces CSV as expected' do + expect(run_job(input)).to eq(expected) + end + end + + context 'when intial headers specified but not present' do + let(:input) do + [ + {a: 'and', z: 'zebra'}, + {a: 'apple', z: 'zizia'} + ] + end + let(:expected) do + "z,a\nzebra,and\nzizia,apple\n" + end + it 'produces CSV as expected' do + expect(run_job(input)).to eq(expected) + end + it 'writes warning to STDOUT' do + msg = 'Output data does not contain specified initial header: y' + expect { run_job(input) }.to output(/#{msg}/).to_stdout + end + end +end + diff --git a/spec/kiba/extend/destinations/json_array_spec.rb b/spec/kiba/extend/destinations/json_array_spec.rb index d35887eab..e7b0833d1 100644 --- a/spec/kiba/extend/destinations/json_array_spec.rb +++ b/spec/kiba/extend/destinations/json_array_spec.rb @@ -2,20 +2,20 @@ require 'spec_helper' -TEST_FILENAME = 'output.json' +RSpec.describe Kiba::Extend::Destinations::JsonArray do + TEST_FILENAME = 'output.json' -def run_job(input) - job = Kiba.parse do - source Kiba::Common::Sources::Enumerable, input - destination Kiba::Extend::Destinations::JsonArray, filename: TEST_FILENAME - end + def run_job(input) + job = Kiba.parse do + source Kiba::Common::Sources::Enumerable, input + destination Kiba::Extend::Destinations::JsonArray, filename: TEST_FILENAME + end - Kiba.run(job) + Kiba.run(job) - IO.read(TEST_FILENAME) -end + IO.read(TEST_FILENAME) + end -RSpec.describe Kiba::Extend::Destinations::JsonArray do after(:each){ File.delete(TEST_FILENAME) if File.exist?(TEST_FILENAME) } context 'when simplest data ever' do