require_relative '../test_helper' require_relative '../support/storage_contract' class ExcelStorageTest < PipelineTest include StorageContract def contract_storage(dir, _purpose) = DataPipeline::ExcelStorage.new(file: "#{dir}/data.xlsx") # an empty text is an empty cell in excel def contract_rows(rows) = rows.map { |row| row.transform_values { |v| v == '' ? nil : v } } def test_text_stays_text_numbers_and_dates_keep_type with_tmpdir do |dir| rows = [{ 'lfdnr' => '0000000001', 'betrag' => 1.5, 'menge' => 3, 'datum' => Date.new(2025, 11, 3), 'text' => '=1+1' }] DataPipeline::ExcelStorage.new(file: "#{dir}/t.xlsx").write(rows) row = DataPipeline::ExcelStorage.new(file: "#{dir}/t.xlsx").read.first assert_equal '0000000001', row['lfdnr'] assert_in_delta 1.5, row['betrag'] assert_equal 3, row['menge'].to_i assert_equal Date.new(2025, 11, 3), row['datum'].to_date assert_equal '=1+1', row['text'] end end def test_columns_sheet_name_and_symbol_keys with_tmpdir do |dir| DataPipeline::ExcelStorage.new(file: "#{dir}/c.xlsx", sheet: 'Buchungen', columns: %w[b a]) .write([{ a: '1', b: '2' }, { 'b' => '4' }]) assert_equal [{ 'b' => '2', 'a' => '1' }, { 'b' => '4', 'a' => nil }], DataPipeline::ExcelStorage.new(file: "#{dir}/c.xlsx", sheet: 'Buchungen').read end end def test_without_header_and_skip_title_rows with_tmpdir do |dir| DataPipeline::ExcelStorage.new(file: "#{dir}/h.xlsx", headers: false).write([{ 'x' => 'Titel' }, { 'x' => 'Kopf' }, { 'x' => 'Wert' }]) assert_equal [{ 'name' => 'Titel' }, { 'name' => 'Kopf' }, { 'name' => 'Wert' }], DataPipeline::ExcelStorage.new(file: "#{dir}/h.xlsx", headers: false, columns: %w[name]).read assert_equal [{ 'Kopf' => 'Wert' }], DataPipeline::ExcelStorage.new(file: "#{dir}/h.xlsx", skip: 1).read end end def test_empty_rows_are_skipped_and_short_name with_tmpdir do |dir| DataPipeline.new do logger PipelineHelper::QUIET read MemoryStorage.new(rows: [{ 'a' => '1' }, { 'a' => nil }, { 'a' => '3' }]) write container(:xlsx, file: "#{dir}/e.xlsx") end.run assert_equal [{ 'a' => '1' }, { 'a' => '3' }], DataPipeline::ExcelStorage.new(file: "#{dir}/e.xlsx").read end end def test_file_required assert_raises(ArgumentError) { DataPipeline::ExcelStorage.new } end end