Skip to content

Commit

Permalink
Merge pull request #367 from roo-rb/feature/roo_formatters
Browse files Browse the repository at this point in the history
Extracted testing classes for formatters
  • Loading branch information
stevendaniels committed Dec 31, 2016
2 parents 9287f90 + a3915b1 commit 5412249
Show file tree
Hide file tree
Showing 12 changed files with 371 additions and 357 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,16 @@ Roo's public methods have stayed relatively consistent between 1.13.x and 2.0.0,
5. Push to the branch (`git push origin my-new-feature`)
6. Create a new Pull Request

### Testing
Roo uses Minitest and RSpec. The best of both worlds! Run `bundle exec rake` to
run the tests/examples.

Roo also has a few tests that take a long time (5+ seconds). To run these, use
`LONG_RUN=true bundle exec rake`

When testing using Ruby 2.0 or 2.1, use this command:
`BUNDLE_GEMFILE=Gemfile_ruby2 bundle exec rake`

### Issues

If you find an issue, please create a gist and refer to it in an issue ([sample gist](https://gist.github.com/stevendaniels/98a05849036e99bb8b3c)). Here are some instructions for creating such a gist.
Expand Down
36 changes: 0 additions & 36 deletions lib/roo/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -221,32 +221,6 @@ def info
end
end

# # returns an XML representation of all sheets of a spreadsheet file
# def to_xml
# Nokogiri::XML::Builder.new do |xml|
# xml.spreadsheet do
# sheets.each do |sheet|
# self.default_sheet = sheet
# xml.sheet(name: sheet) do |x|
# if first_row && last_row && first_column && last_column
# # sonst gibt es Fehler bei leeren Blaettern
# first_row.upto(last_row) do |row|
# first_column.upto(last_column) do |col|
# next if empty?(row, col)
#
# x.cell(cell(row, col),
# row: row,
# column: col,
# type: celltype(row, col))
# end
# end
# end
# end
# end
# end
# end.to_xml
# end

# when a method like spreadsheet.a42 is called
# convert it to a call of spreadsheet.cell('a',42)
def method_missing(m, *args)
Expand Down Expand Up @@ -622,14 +596,4 @@ def process_zipfile_packed(zip, tmpdir, path = '')
ret
end
end

# # converts an integer value to a time string like '02:05:06'
# def integer_to_timestring(content)
# h = (content / 3600.0).floor
# content -= h * 3600
# m = (content / 60.0).floor
# content -= m * 60
# s = content
# sprintf('%02d:%02d:%02d', h, m, s)
# end
end
3 changes: 1 addition & 2 deletions lib/roo/formatters/csv.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ def write_csv_content(file = nil, sheet = nil, separator = ",")
end
end


# The content of a cell in the csv output
def cell_to_csv(row, col, sheet)
return "" if empty?(row, col, sheet)
Expand Down Expand Up @@ -65,7 +64,7 @@ def cell_to_csv(row, col, sheet)
else
onecell.to_s
end
when DateTime
when Date, DateTime, TrueClass, FalseClass
onecell.to_s
else
fail "unhandled onecell-class #{onecell.class}"
Expand Down
3 changes: 2 additions & 1 deletion lib/roo/formatters/yaml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ module YAML
# you can add additional attributes with the prefix parameter like:
# oo.to_yaml({"file"=>"flightdata_2007-06-26", "sheet" => "1"})
def to_yaml(prefix = {}, from_row = nil, from_column = nil, to_row = nil, to_column = nil, sheet = default_sheet)
return '' unless first_row # empty result if there is no first_row in a sheet
# return an empty string if there is no first_row, i.e. the sheet is empty
return "" unless first_row

from_row ||= first_row(sheet)
to_row ||= last_row(sheet)
Expand Down
26 changes: 26 additions & 0 deletions test/files/expected_results/time-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
cell_1_1:
row: 1
col: 1
celltype: string
value: Mittags:
cell_1_2:
row: 1
col: 2
celltype: time
value: 12:13:14
cell_1_3:
row: 1
col: 3
celltype: time
value: 15:16:00
cell_1_4:
row: 1
col: 4
celltype: time
value: 23:00:00
cell_2_1:
row: 2
col: 1
celltype: date
value: 2007-11-21
Binary file added test/files/formula_cell_types.xlsx
Binary file not shown.
119 changes: 119 additions & 0 deletions test/formatters/test_csv.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
require "test_helper"

class TestRooFormatterCSV < Minitest::Test
def test_date_time_to_csv
with_each_spreadsheet(name: "time-test") do |workbook|
Dir.mktmpdir do |tempdir|
csv_output = File.join(tempdir, "time_test.csv")
assert workbook.to_csv(csv_output)
assert File.exist?(csv_output)
assert_equal "", `diff --strip-trailing-cr #{TESTDIR}/time-test.csv #{csv_output}`
# --strip-trailing-cr is needed because the test-file use 0A and
# the test on an windows box generates 0D 0A as line endings
end
end
end

def test_boolean_to_csv
with_each_spreadsheet(name: "boolean") do |workbook|
Dir.mktmpdir do |tempdir|
csv_output = File.join(tempdir,"boolean.csv")
assert workbook.to_csv(csv_output)
assert File.exist?(csv_output)
assert_equal "", `diff --strip-trailing-cr #{TESTDIR}/boolean.csv #{csv_output}`
# --strip-trailing-cr is needed because the test-file use 0A and
# the test on an windows box generates 0D 0A as line endings
end
end
end

def test_link_to_csv
with_each_spreadsheet(name: "link", format: :excelx) do |workbook|
Dir.mktmpdir do |tempdir|
csv_output = File.join(tempdir, "link.csv")
assert workbook.to_csv(csv_output)
assert File.exist?(csv_output)
assert_equal "", `diff --strip-trailing-cr #{TESTDIR}/link.csv #{csv_output}`
# --strip-trailing-cr is needed because the test-file use 0A and
# the test on an windows box generates 0D 0A as line endings
end
end
end

# "/tmp/xxxx" darf man unter Windows nicht verwenden, weil das nicht erkannt
# wird.
# Besser: Methode um temporaeres Dir. portabel zu bestimmen
def test_huge_document_to_csv
skip unless ENV["LONG_RUN"]

original_csv_path = File.join(TESTDIR, "Bibelbund.csv")
with_each_spreadsheet(name: "Bibelbund", format: [:openoffice, :excelx]) do |workbook|
Dir.mktmpdir do |tempdir|
new_csv_path = File.join(tempdir, "Bibelbund.csv")
assert_equal "Tagebuch des Sekret\303\244rs. Letzte Tagung 15./16.11.75 Schweiz", workbook.cell(45, "A")
assert_equal "Tagebuch des Sekret\303\244rs. Nachrichten aus Chile", workbook.cell(46, "A")
assert_equal "Tagebuch aus Chile Juli 1977", workbook.cell(55, "A")
assert workbook.to_csv(new_csv_path)
assert File.exist?(new_csv_path)
assert FileUtils.identical?(original_csv_path, new_csv_path), "error in class #{workbook.class}"
end
end
end

def test_bug_empty_sheet
with_each_spreadsheet(name: "formula", format: [:openoffice, :excelx]) do |workbook|
workbook.default_sheet = "Sheet3" # is an empty sheet
Dir.mktmpdir do |tempdir|
workbook.to_csv(File.join(tempdir, "emptysheet.csv"))
assert_equal "", `cat #{File.join(tempdir, "emptysheet.csv")}`
end
end
end

def test_bug_quotes_excelx
skip unless ENV["LONG_RUN"]
# TODO: run this test with a much smaller document
with_each_spreadsheet(name: "Bibelbund", format: [:openoffice, :excelx]) do |workbook|
workbook.default_sheet = workbook.sheets.first
assert_equal(
'Einflüsse der neuen Theologie in "de gereformeerde Kerken van Nederland"',
workbook.cell("A", 76)
)
workbook.to_csv("csv#{$$}")
assert_equal(
'Einflüsse der neuen Theologie in "de gereformeerde Kerken van Nederland"',
workbook.cell("A", 78)
)
File.delete_if_exist("csv#{$$}")
end
end

def test_bug_datetime_to_csv
with_each_spreadsheet(name: "datetime") do |workbook|
Dir.mktmpdir do |tempdir|
datetime_csv_file = File.join(tempdir, "datetime.csv")

assert workbook.to_csv(datetime_csv_file)
assert File.exist?(datetime_csv_file)
assert_equal "", file_diff("#{TESTDIR}/so_datetime.csv", datetime_csv_file)
end
end
end

def test_true_class
assert_equal "true", cell_to_csv(1, 1)
end

def test_false_class
assert_equal "false", cell_to_csv(2, 1)
end

def test_date_class
assert_equal "2017-01-01", cell_to_csv(3, 1)
end

def cell_to_csv(row, col)
filename = File.join(TESTDIR, "formula_cell_types.xlsx")
Roo::Spreadsheet.open(filename).send("cell_to_csv", row, col, "Sheet1")
end
end
76 changes: 76 additions & 0 deletions test/formatters/test_matrix.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
require "test_helper"
require "matrix"

class TestRooFormatterMatrix < Minitest::Test
def test_matrix
expected_result = Matrix[
[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0],
[7.0, 8.0, 9.0]
]
with_each_spreadsheet(name: "matrix", format: :openoffice) do |workbook|
workbook.default_sheet = workbook.sheets.first
assert_equal expected_result, workbook.to_matrix
end
end

def test_matrix_selected_range
expected_result = Matrix[
[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0],
[7.0, 8.0, 9.0]
]
with_each_spreadsheet(name: "matrix", format: :openoffice) do |workbook|
workbook.default_sheet = "Sheet2"
assert_equal expected_result, workbook.to_matrix(3, 4, 5, 6)
end
end

def test_matrix_all_nil
expected_result = Matrix[
[nil, nil, nil],
[nil, nil, nil],
[nil, nil, nil]
]
with_each_spreadsheet(name: "matrix", format: :openoffice) do |workbook|
workbook.default_sheet = "Sheet2"
assert_equal expected_result, workbook.to_matrix(10, 10, 12, 12)
end
end

def test_matrix_values_and_nil
expected_result = Matrix[
[1.0, nil, 3.0],
[4.0, 5.0, 6.0],
[7.0, 8.0, nil]
]
with_each_spreadsheet(name: "matrix", format: :openoffice) do |workbook|
workbook.default_sheet = "Sheet3"
assert_equal expected_result, workbook.to_matrix(1, 1, 3, 3)
end
end

def test_matrix_specifying_sheet
expected_result = Matrix[
[1.0, nil, 3.0],
[4.0, 5.0, 6.0],
[7.0, 8.0, nil]
]
with_each_spreadsheet(name: "matrix", format: :openoffice) do |workbook|
workbook.default_sheet = workbook.sheets.first
assert_equal expected_result, workbook.to_matrix(nil, nil, nil, nil, "Sheet3")
end
end

# #to_matrix of an empty sheet should return an empty matrix and not result in
# an error message
# 2011-06-25
def test_bug_to_matrix_empty_sheet
options = { name: "emptysheets", format: [:openoffice, :excelx] }
with_each_spreadsheet(options) do |workbook|
workbook.default_sheet = workbook.sheets.first
workbook.to_matrix
assert_equal(Matrix.empty(0, 0), workbook.to_matrix)
end
end
end
74 changes: 74 additions & 0 deletions test/formatters/test_xml.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
require "test_helper"

class TestRooFormatterXML < Minitest::Test
def test_to_xml
expected_sheet_count = 5
with_each_spreadsheet(name: "numbers1", encoding: "utf8") do |workbook|
skip if defined? JRUBY_VERSION
workbook.to_xml
sheetname = workbook.sheets.first
doc = Nokogiri::XML(workbook.to_xml)
all_cells = init_all_cells(workbook, sheetname)

assert_equal expected_sheet_count, doc.xpath("//spreadsheet/sheet").count

doc.xpath("//spreadsheet/sheet").each do |xml_sheet|
assert_equal sheetname, xml_sheet.attributes["name"].value
xml_sheet.children.each_with_index do |cell, i|
next unless cell.attributes["name"]

expected = [
all_cells[i][:row],
all_cells[i][:column],
all_cells[i][:content],
all_cells[i][:type],
]
result = [
cell.attributes["row"],
cell.attributes["column"],
cell.content,
cell.attributes["type"],
]
assert_equal expected, result
end # end of sheet
sheetname = workbook.sheets[workbook.sheets.index(sheetname) + 1]
end
end
end

def test_bug_to_xml_with_empty_sheets
with_each_spreadsheet(name: "emptysheets", format: [:openoffice, :excelx]) do |workbook|
workbook.sheets.each do |sheet|
assert_nil workbook.first_row, "first_row not nil in sheet #{sheet}"
assert_nil workbook.last_row, "last_row not nil in sheet #{sheet}"
assert_nil workbook.first_column, "first_column not nil in sheet #{sheet}"
assert_nil workbook.last_column, "last_column not nil in sheet #{sheet}"
assert_nil workbook.first_row(sheet), "first_row not nil in sheet #{sheet}"
assert_nil workbook.last_row(sheet), "last_row not nil in sheet #{sheet}"
assert_nil workbook.first_column(sheet), "first_column not nil in sheet #{sheet}"
assert_nil workbook.last_column(sheet), "last_column not nil in sheet #{sheet}"
end
workbook.to_xml
end
end

# Erstellt eine Liste aller Zellen im Spreadsheet. Dies ist nötig, weil ein einfacher
# Textvergleich des XML-Outputs nicht funktioniert, da xml-builder die Attribute
# nicht immer in der gleichen Reihenfolge erzeugt.
def init_all_cells(workbook, sheet)
all = []
workbook.first_row(sheet).upto(workbook.last_row(sheet)) do |row|
workbook.first_column(sheet).upto(workbook.last_column(sheet)) do |col|
next if workbook.empty?(row, col, sheet)

all << {
row: row.to_s,
column: col.to_s,
content: workbook.cell(row, col, sheet).to_s,
type: workbook.celltype(row, col, sheet).to_s,
}
end
end
all
end
end
Loading

0 comments on commit 5412249

Please sign in to comment.