roo 2.3.0 → 2.10.1
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 +5 -5
- data/.codeclimate.yml +17 -0
- data/.github/issue_template.md +16 -0
- data/.github/pull_request_template.md +14 -0
- data/.github/workflows/pull-request.yml +15 -0
- data/.github/workflows/ruby.yml +34 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +186 -0
- data/CHANGELOG.md +148 -0
- data/Gemfile +4 -4
- data/LICENSE +2 -0
- data/README.md +84 -27
- data/Rakefile +1 -1
- data/lib/roo/base.rb +111 -237
- data/lib/roo/constants.rb +5 -3
- data/lib/roo/csv.rb +106 -85
- data/lib/roo/errors.rb +2 -0
- data/lib/roo/excelx/cell/base.rb +26 -12
- data/lib/roo/excelx/cell/boolean.rb +9 -6
- data/lib/roo/excelx/cell/date.rb +7 -7
- data/lib/roo/excelx/cell/datetime.rb +50 -44
- data/lib/roo/excelx/cell/empty.rb +3 -2
- data/lib/roo/excelx/cell/number.rb +60 -47
- data/lib/roo/excelx/cell/string.rb +3 -3
- data/lib/roo/excelx/cell/time.rb +17 -16
- data/lib/roo/excelx/cell.rb +11 -7
- data/lib/roo/excelx/comments.rb +3 -3
- data/lib/roo/excelx/coordinate.rb +11 -4
- data/lib/roo/excelx/extractor.rb +20 -3
- data/lib/roo/excelx/format.rb +38 -31
- data/lib/roo/excelx/images.rb +26 -0
- data/lib/roo/excelx/relationships.rb +12 -4
- data/lib/roo/excelx/shared.rb +10 -3
- data/lib/roo/excelx/shared_strings.rb +113 -9
- data/lib/roo/excelx/sheet.rb +49 -10
- data/lib/roo/excelx/sheet_doc.rb +101 -48
- data/lib/roo/excelx/styles.rb +4 -4
- data/lib/roo/excelx/workbook.rb +8 -3
- data/lib/roo/excelx.rb +85 -42
- data/lib/roo/formatters/base.rb +15 -0
- data/lib/roo/formatters/csv.rb +84 -0
- data/lib/roo/formatters/matrix.rb +23 -0
- data/lib/roo/formatters/xml.rb +31 -0
- data/lib/roo/formatters/yaml.rb +40 -0
- data/lib/roo/helpers/default_attr_reader.rb +20 -0
- data/lib/roo/helpers/weak_instance_cache.rb +41 -0
- data/lib/roo/open_office.rb +41 -27
- data/lib/roo/spreadsheet.rb +8 -2
- data/lib/roo/tempdir.rb +24 -0
- data/lib/roo/utils.rb +76 -26
- data/lib/roo/version.rb +1 -1
- data/lib/roo.rb +5 -0
- data/roo.gemspec +22 -12
- data/spec/lib/roo/base_spec.rb +65 -3
- data/spec/lib/roo/csv_spec.rb +19 -0
- data/spec/lib/roo/excelx/cell/time_spec.rb +15 -0
- data/spec/lib/roo/excelx/relationships_spec.rb +43 -0
- data/spec/lib/roo/excelx/sheet_doc_spec.rb +11 -0
- data/spec/lib/roo/excelx_spec.rb +237 -5
- data/spec/lib/roo/openoffice_spec.rb +2 -2
- data/spec/lib/roo/spreadsheet_spec.rb +1 -1
- data/spec/lib/roo/strict_spec.rb +43 -0
- data/spec/lib/roo/utils_spec.rb +22 -9
- data/spec/lib/roo/weak_instance_cache_spec.rb +92 -0
- data/spec/lib/roo_spec.rb +0 -0
- data/spec/spec_helper.rb +2 -7
- data/test/excelx/cell/test_attr_reader_default.rb +72 -0
- data/test/excelx/cell/test_base.rb +6 -2
- data/test/excelx/cell/test_boolean.rb +1 -3
- data/test/excelx/cell/test_date.rb +1 -6
- data/test/excelx/cell/test_datetime.rb +7 -10
- data/test/excelx/cell/test_empty.rb +12 -2
- data/test/excelx/cell/test_number.rb +28 -4
- data/test/excelx/cell/test_string.rb +21 -3
- data/test/excelx/cell/test_time.rb +7 -10
- data/test/excelx/test_coordinate.rb +51 -0
- data/test/formatters/test_csv.rb +136 -0
- data/test/formatters/test_matrix.rb +76 -0
- data/test/formatters/test_xml.rb +78 -0
- data/test/formatters/test_yaml.rb +20 -0
- data/test/helpers/test_accessing_files.rb +81 -0
- data/test/helpers/test_comments.rb +43 -0
- data/test/helpers/test_formulas.rb +9 -0
- data/test/helpers/test_labels.rb +103 -0
- data/test/helpers/test_sheets.rb +55 -0
- data/test/helpers/test_styles.rb +62 -0
- data/test/roo/test_base.rb +182 -0
- data/test/roo/test_csv.rb +88 -0
- data/test/roo/test_excelx.rb +360 -0
- data/test/roo/test_libre_office.rb +9 -0
- data/test/roo/test_open_office.rb +289 -0
- data/test/test_helper.rb +129 -14
- data/test/test_roo.rb +60 -1765
- metadata +91 -21
- data/.travis.yml +0 -14
@@ -0,0 +1,182 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class TestRooBase < Minitest::Test
|
4
|
+
def test_info
|
5
|
+
# NOTE: unfortunately, the ods and xlsx versions of numbers1 are not
|
6
|
+
# identical, so this test fails for Open Office.
|
7
|
+
expected_templ = File.read("#{TESTDIR}/expected_results/numbers_info.yml")
|
8
|
+
with_each_spreadsheet(name: "numbers1", format: [:excelx]) do |workbook|
|
9
|
+
ext = get_extension(workbook)
|
10
|
+
expected = Kernel.format(expected_templ, ext)
|
11
|
+
assert_equal expected.strip, workbook.info.strip
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_column
|
16
|
+
with_each_spreadsheet(name: "numbers1") do |workbook|
|
17
|
+
expected = [1.0, 5.0, nil, 10.0, Date.new(1961, 11, 21), "tata", nil, nil, nil, nil, "thisisa11", 41.0, nil, nil, 41.0, "einundvierzig", nil, Date.new(2007, 5, 31)]
|
18
|
+
assert_equal expected, workbook.column(1)
|
19
|
+
assert_equal expected, workbook.column("a")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_column_huge_document
|
24
|
+
skip_long_test
|
25
|
+
with_each_spreadsheet(name: "Bibelbund", format: [:openoffice, :excelx]) do |workbook|
|
26
|
+
workbook.default_sheet = workbook.sheets.first
|
27
|
+
assert_equal 3735, workbook.column("a").size
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_simple_spreadsheet_find_by_condition
|
32
|
+
with_each_spreadsheet(name: "simple_spreadsheet") do |workbook|
|
33
|
+
workbook.header_line = 3
|
34
|
+
results = workbook.find(:all, conditions: { "Comment" => "Task 1" })
|
35
|
+
assert_equal Date.new(2007, 05, 07), results[1]["Date"]
|
36
|
+
assert_equal 10.75, results[1]["Start time"]
|
37
|
+
assert_equal 12.50, results[1]["End time"]
|
38
|
+
assert_equal 0, results[1]["Pause"]
|
39
|
+
assert_equal 1.75, results[1]["Sum"]
|
40
|
+
assert_equal "Task 1", results[1]["Comment"]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_bug_bbu
|
45
|
+
expected_templ = File.read("#{TESTDIR}/expected_results/bbu_info.txt")
|
46
|
+
with_each_spreadsheet(name: "bbu", format: [:openoffice, :excelx]) do |workbook|
|
47
|
+
ext = get_extension(workbook)
|
48
|
+
expected_result = Kernel.format(expected_templ, ext)
|
49
|
+
assert_equal expected_result.strip, workbook.info.strip
|
50
|
+
|
51
|
+
workbook.default_sheet = workbook.sheets[1] # empty sheet
|
52
|
+
assert_nil workbook.first_row
|
53
|
+
assert_nil workbook.last_row
|
54
|
+
assert_nil workbook.first_column
|
55
|
+
assert_nil workbook.last_column
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_find_by_row_huge_document
|
60
|
+
skip_long_test
|
61
|
+
options = { name: "Bibelbund", format: [:openoffice, :excelx] }
|
62
|
+
with_each_spreadsheet(options) do |workbook|
|
63
|
+
workbook.default_sheet = workbook.sheets.first
|
64
|
+
result = workbook.find 20
|
65
|
+
assert result
|
66
|
+
assert_equal "Brief aus dem Sekretariat", result[0]
|
67
|
+
|
68
|
+
result = workbook.find 22
|
69
|
+
assert result
|
70
|
+
assert_equal "Brief aus dem Skretariat. Tagung in Amberg/Opf.", result[0]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_find_by_row
|
75
|
+
with_each_spreadsheet(name: "numbers1") do |workbook|
|
76
|
+
workbook.header_line = nil
|
77
|
+
result = workbook.find 16
|
78
|
+
assert result
|
79
|
+
assert_nil workbook.header_line
|
80
|
+
# keine Headerlines in diesem Beispiel definiert
|
81
|
+
assert_equal "einundvierzig", result[0]
|
82
|
+
# assert_equal false, results
|
83
|
+
result = workbook.find 15
|
84
|
+
assert result
|
85
|
+
assert_equal 41, result[0]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_find_by_row_if_header_line_is_not_nil
|
90
|
+
with_each_spreadsheet(name: "numbers1") do |workbook|
|
91
|
+
workbook.header_line = 2
|
92
|
+
refute_nil workbook.header_line
|
93
|
+
results = workbook.find 1
|
94
|
+
assert results
|
95
|
+
assert_equal 5, results[0]
|
96
|
+
assert_equal 6, results[1]
|
97
|
+
results = workbook.find 15
|
98
|
+
assert results
|
99
|
+
assert_equal "einundvierzig", results[0]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_find_by_conditions
|
104
|
+
skip_long_test
|
105
|
+
expected_results = [
|
106
|
+
{
|
107
|
+
"VERFASSER" => "Almassy, Annelene von",
|
108
|
+
"INTERNET" => nil,
|
109
|
+
"SEITE" => 316.0,
|
110
|
+
"KENNUNG" => "Aus dem Bibelbund",
|
111
|
+
"OBJEKT" => "Bibel+Gem",
|
112
|
+
"PC" => "#C:\\Bibelbund\\reprint\\BuG1982-3.pdf#",
|
113
|
+
"NUMMER" => "1982-3",
|
114
|
+
"TITEL" => "Brief aus dem Sekretariat"
|
115
|
+
},
|
116
|
+
{
|
117
|
+
"VERFASSER" => "Almassy, Annelene von",
|
118
|
+
"INTERNET" => nil,
|
119
|
+
"SEITE" => 222.0,
|
120
|
+
"KENNUNG" => "Aus dem Bibelbund",
|
121
|
+
"OBJEKT" => "Bibel+Gem",
|
122
|
+
"PC" => "#C:\\Bibelbund\\reprint\\BuG1983-2.pdf#",
|
123
|
+
"NUMMER" => "1983-2",
|
124
|
+
"TITEL" => "Brief aus dem Sekretariat"
|
125
|
+
}
|
126
|
+
]
|
127
|
+
|
128
|
+
expected_results_size = 2
|
129
|
+
options = { name: "Bibelbund", format: [:openoffice, :excelx] }
|
130
|
+
with_each_spreadsheet(options) do |workbook|
|
131
|
+
results = workbook.find(:all, conditions: { "TITEL" => "Brief aus dem Sekretariat" })
|
132
|
+
assert_equal expected_results_size, results.size
|
133
|
+
assert_equal expected_results, results
|
134
|
+
|
135
|
+
conditions = {
|
136
|
+
"TITEL" => "Brief aus dem Sekretariat",
|
137
|
+
"VERFASSER" => "Almassy, Annelene von"
|
138
|
+
}
|
139
|
+
results = workbook.find(:all, conditions: conditions)
|
140
|
+
assert_equal expected_results, results
|
141
|
+
assert_equal expected_results_size, results.size
|
142
|
+
|
143
|
+
results = workbook.find(:all, conditions: { "VERFASSER" => "Almassy, Annelene von" })
|
144
|
+
assert_equal 13, results.size
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_find_by_conditions_with_array_option
|
149
|
+
expected_results = [
|
150
|
+
[
|
151
|
+
"Brief aus dem Sekretariat",
|
152
|
+
"Almassy, Annelene von",
|
153
|
+
"Bibel+Gem",
|
154
|
+
"1982-3",
|
155
|
+
316.0,
|
156
|
+
nil,
|
157
|
+
"#C:\\Bibelbund\\reprint\\BuG1982-3.pdf#",
|
158
|
+
"Aus dem Bibelbund",
|
159
|
+
],
|
160
|
+
[
|
161
|
+
"Brief aus dem Sekretariat",
|
162
|
+
"Almassy, Annelene von",
|
163
|
+
"Bibel+Gem",
|
164
|
+
"1983-2",
|
165
|
+
222.0,
|
166
|
+
nil,
|
167
|
+
"#C:\\Bibelbund\\reprint\\BuG1983-2.pdf#",
|
168
|
+
"Aus dem Bibelbund",
|
169
|
+
]
|
170
|
+
]
|
171
|
+
options = { name: "Bibelbund", format: [:openoffice, :excelx] }
|
172
|
+
with_each_spreadsheet(options) do |workbook|
|
173
|
+
conditions = {
|
174
|
+
"TITEL" => "Brief aus dem Sekretariat",
|
175
|
+
"VERFASSER" => "Almassy, Annelene von"
|
176
|
+
}
|
177
|
+
results = workbook.find(:all, conditions: conditions, array: true)
|
178
|
+
assert_equal 2, results.size
|
179
|
+
assert_equal expected_results, results
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class TestRooCSV < Minitest::Test
|
4
|
+
def test_sheets
|
5
|
+
file = filename("numbers1")
|
6
|
+
workbook = roo_class.new(File.join(TESTDIR, file))
|
7
|
+
assert_equal ["default"], workbook.sheets
|
8
|
+
assert_raises(RangeError) { workbook.default_sheet = "no_sheet" }
|
9
|
+
assert_raises(TypeError) { workbook.default_sheet = [1, 2, 3] }
|
10
|
+
workbook.sheets.each do |sh|
|
11
|
+
workbook.default_sheet = sh
|
12
|
+
assert_equal sh, workbook.default_sheet
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_download_uri_with_query_string
|
17
|
+
file = filename("simple_spreadsheet")
|
18
|
+
port = 12_347
|
19
|
+
url = "#{local_server(port)}/#{file}?query-param=value"
|
20
|
+
|
21
|
+
start_local_server(file, port) do
|
22
|
+
csv = roo_class.new(url)
|
23
|
+
assert_equal "Task 1", csv.cell("f", 4)
|
24
|
+
assert_equal 1, csv.first_row
|
25
|
+
assert_equal 13, csv.last_row
|
26
|
+
assert_equal 1, csv.first_column
|
27
|
+
assert_equal 6, csv.last_column
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_open_stream
|
32
|
+
file = filename("Bibelbund")
|
33
|
+
file_contents = File.read File.join(TESTDIR, file)
|
34
|
+
stream = StringIO.new(file_contents)
|
35
|
+
csv = roo_class.new(stream)
|
36
|
+
|
37
|
+
assert_equal "Aktuelle Seite", csv.cell("h", 12)
|
38
|
+
assert_equal 1, csv.first_row
|
39
|
+
assert_equal 3735, csv.last_row
|
40
|
+
assert_equal 1, csv.first_column
|
41
|
+
assert_equal 8, csv.last_column
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_nil_rows_and_lines_csv
|
45
|
+
# x_123
|
46
|
+
oo = Roo::CSV.new(File.join(TESTDIR,'Bibelbund.csv'))
|
47
|
+
oo.default_sheet = oo.sheets.first
|
48
|
+
assert_equal 1, oo.first_row
|
49
|
+
assert_equal 3735, oo.last_row
|
50
|
+
assert_equal 1, oo.first_column
|
51
|
+
assert_equal 8, oo.last_column
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_empty_csv
|
55
|
+
# x_123
|
56
|
+
oo = Roo::CSV.new(File.join(TESTDIR,'emptysheets.csv'))
|
57
|
+
oo.default_sheet = oo.sheets.first
|
58
|
+
assert_equal 1, oo.first_row
|
59
|
+
assert_equal 1, oo.last_row
|
60
|
+
assert_equal 1, oo.first_column
|
61
|
+
assert_equal 1, oo.last_column
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_csv_parsing_with_headers
|
65
|
+
return unless CSV
|
66
|
+
headers = ["TITEL", "VERFASSER", "OBJEKT", "NUMMER", "SEITE", "INTERNET", "PC", "KENNUNG"]
|
67
|
+
|
68
|
+
oo = Roo::Spreadsheet.open(File.join(TESTDIR, "Bibelbund.csv"))
|
69
|
+
parsed = oo.parse(headers: true)
|
70
|
+
assert_equal headers, parsed[1].keys
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_iso_8859_1
|
74
|
+
file = File.open(File.join(TESTDIR, "iso_8859_1.csv"))
|
75
|
+
options = { csv_options: { col_sep: ";", encoding: Encoding::ISO_8859_1 } }
|
76
|
+
workbook = Roo::CSV.new(file.path, options)
|
77
|
+
result = workbook.last_column
|
78
|
+
assert_equal(19, result)
|
79
|
+
end
|
80
|
+
|
81
|
+
def roo_class
|
82
|
+
Roo::CSV
|
83
|
+
end
|
84
|
+
|
85
|
+
def filename(name)
|
86
|
+
"#{name}.csv"
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,360 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class TestRworkbookExcelx < Minitest::Test
|
4
|
+
def test_download_uri_with_invalid_host
|
5
|
+
assert_raises(RuntimeError) do
|
6
|
+
Roo::Excelx.new("http://examples.com/file.xlsx")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_download_uri_with_query_string
|
11
|
+
file = filename("simple_spreadsheet")
|
12
|
+
port = 12_344
|
13
|
+
url = "#{local_server(port)}/#{file}?query-param=value"
|
14
|
+
|
15
|
+
start_local_server(file, port) do
|
16
|
+
spreadsheet = roo_class.new(url)
|
17
|
+
assert_equal "Task 1", spreadsheet.cell("f", 4)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_should_raise_file_not_found_error
|
22
|
+
assert_raises(IOError) do
|
23
|
+
roo_class.new(File.join("testnichtvorhanden", "Bibelbund.xlsx"))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_file_warning_default
|
28
|
+
assert_raises(TypeError) { roo_class.new(File.join(TESTDIR, "numbers1.ods")) }
|
29
|
+
assert_raises(TypeError) { roo_class.new(File.join(TESTDIR, "numbers1.xls")) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_file_warning_error
|
33
|
+
%w(ods xls).each do |extension|
|
34
|
+
assert_raises(TypeError) do
|
35
|
+
options = { packed: false, file_warning: :error }
|
36
|
+
roo_class.new(File.join(TESTDIR, "numbers1. #{extension}"), options)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_file_warning_warning
|
42
|
+
options = { packed: false, file_warning: :warning }
|
43
|
+
assert_raises(ArgumentError) do
|
44
|
+
roo_class.new(File.join(TESTDIR, "numbers1.ods"), options)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_file_warning_ignore
|
49
|
+
options = { packed: false, file_warning: :ignore }
|
50
|
+
sheet = roo_class.new(File.join(TESTDIR, "type_excelx.ods"), options)
|
51
|
+
assert sheet, "Should not throw an error"
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_bug_xlsx_reference_cell
|
55
|
+
# NOTE: If cell A contains a string and cell B references cell A. When
|
56
|
+
# reading the value of cell B, the result will be "0.0" instead of the
|
57
|
+
# value of cell A.
|
58
|
+
#
|
59
|
+
# Before this test case, the following code:
|
60
|
+
#
|
61
|
+
# spreadsheet = Roo::Excelx.new("formula_string_error.xlsx")
|
62
|
+
# spreadsheet.default_sheet = "sheet1"
|
63
|
+
# p "A: #{spreadsheet.cell(1, 1)}" #=> "A: TestString"
|
64
|
+
# p "B: #{spreadsheet.cell(2, 1)}" #=> "B: 0.0"
|
65
|
+
#
|
66
|
+
# where the expected result is
|
67
|
+
# "A: TestString"
|
68
|
+
# "B: TestString"
|
69
|
+
xlsx = roo_class.new(File.join(TESTDIR, "formula_string_error.xlsx"))
|
70
|
+
assert_equal "Teststring", xlsx.cell("a", 1)
|
71
|
+
assert_equal "Teststring", xlsx.cell("a", 2)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_parsing_xslx_from_numbers
|
75
|
+
xlsx = roo_class.new(File.join(TESTDIR, "numbers-export.xlsx"))
|
76
|
+
|
77
|
+
xlsx.default_sheet = xlsx.sheets.first
|
78
|
+
assert_equal "Sheet 1", xlsx.cell("a", 1)
|
79
|
+
|
80
|
+
# Another buggy behavior of Numbers 3.1: if a warkbook has more than a
|
81
|
+
# single sheet, all sheets except the first one will have an extra row and
|
82
|
+
# column added to the beginning. That's why we assert against cell B2 and
|
83
|
+
# not A1
|
84
|
+
xlsx.default_sheet = xlsx.sheets.last
|
85
|
+
assert_equal "Sheet 2", xlsx.cell("b", 2)
|
86
|
+
end
|
87
|
+
|
88
|
+
def assert_cell_range_values(sheet, row_range, column_range, is_merged_range, expected_value)
|
89
|
+
row_range.each do |row|
|
90
|
+
column_range.each do |col|
|
91
|
+
value = sheet.cell(col, row)
|
92
|
+
if is_merged_range.call(row, col)
|
93
|
+
assert_equal expected_value, value
|
94
|
+
else
|
95
|
+
assert_nil value
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_expand_merged_range
|
102
|
+
options = { expand_merged_ranges: true }
|
103
|
+
xlsx = roo_class.new(File.join(TESTDIR, "merged_ranges.xlsx"), options)
|
104
|
+
|
105
|
+
[
|
106
|
+
{
|
107
|
+
rows: (3..7),
|
108
|
+
columns: ("a".."b"),
|
109
|
+
conditional: ->(row, col) { row > 3 && row < 7 && col == "a" },
|
110
|
+
expected_value: "vertical1"
|
111
|
+
},
|
112
|
+
{
|
113
|
+
rows: (3..11),
|
114
|
+
columns: ("f".."h"),
|
115
|
+
conditional: ->(row, col) { row > 3 && row < 11 && col == "g" },
|
116
|
+
expected_value: "vertical2"
|
117
|
+
},
|
118
|
+
{
|
119
|
+
rows: (3..5),
|
120
|
+
columns: ("b".."f"),
|
121
|
+
conditional: ->(row, col) { row == 4 && col > "b" && col < "f" },
|
122
|
+
expected_value: "horizontal"
|
123
|
+
},
|
124
|
+
{
|
125
|
+
rows: (8..13),
|
126
|
+
columns: ("a".."e"),
|
127
|
+
conditional: ->(row, col) { row > 8 && row < 13 && col > "a" && col < "e" },
|
128
|
+
expected_value: "block"
|
129
|
+
}
|
130
|
+
].each do |data|
|
131
|
+
rows, cols, conditional, expected_value = data.values
|
132
|
+
assert_cell_range_values(xlsx, rows, cols, conditional, expected_value)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_expand_merged_range_doesnt_insert_nil_values
|
137
|
+
options = { expand_merged_ranges: true }
|
138
|
+
xlsx = roo_class.new(File.join(TESTDIR, "merged_ranges.xlsx"), options)
|
139
|
+
|
140
|
+
refute_includes xlsx.sheet_for(0).cells.values, nil, "`nil` was copied into the cells hash from an empty merged range"
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_expand_merged_range_doesnt_raise_issue_506
|
144
|
+
# Issue 506 sent an example test.xlsx file that would raise an error upon parsing.
|
145
|
+
xl = Roo::Spreadsheet.open(File.join(TESTDIR, "expand_merged_ranges_issue_506.xlsx"), expand_merged_ranges: true)
|
146
|
+
data = xl.parse(one: /one/i, two: /two/i, clean: true)
|
147
|
+
assert_equal [{:one=>"John", :two=>"Johnson"}, {:one=>"Sam", :two=>nil}, {:one=>"Dave", :two=>nil}], data
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_noexpand_merged_range
|
151
|
+
xlsx = roo_class.new(File.join(TESTDIR, "merged_ranges.xlsx"))
|
152
|
+
|
153
|
+
[
|
154
|
+
{
|
155
|
+
rows: (3..7),
|
156
|
+
columns: ("a".."b"),
|
157
|
+
conditional: ->(row, col) { row == 4 && col == "a" },
|
158
|
+
expected_value: "vertical1"
|
159
|
+
},
|
160
|
+
{
|
161
|
+
rows: (3..11),
|
162
|
+
columns: ("f".."h"),
|
163
|
+
conditional: ->(row, col) { row == 4 && col == "g" },
|
164
|
+
expected_value: "vertical2"
|
165
|
+
},
|
166
|
+
{
|
167
|
+
rows: (3..5),
|
168
|
+
columns: ("b".."f"),
|
169
|
+
conditional: ->(row, col) { row == 4 && col == "c" },
|
170
|
+
expected_value: "horizontal"
|
171
|
+
},
|
172
|
+
{
|
173
|
+
rows: (8..13),
|
174
|
+
columns: ("a".."e"),
|
175
|
+
conditional: ->(row, col) { row == 9 && col == "b" },
|
176
|
+
expected_value: "block"
|
177
|
+
}
|
178
|
+
].each do |data|
|
179
|
+
rows, cols, conditional, expected_value = data.values
|
180
|
+
assert_cell_range_values(xlsx, rows, cols, conditional, expected_value)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_open_stream
|
185
|
+
file = filename(:numbers1)
|
186
|
+
file_contents = File.read File.join(TESTDIR, file), encoding: "BINARY"
|
187
|
+
stream = StringIO.new(file_contents)
|
188
|
+
xlsx = roo_class.new(stream)
|
189
|
+
expected_sheet_names = ["Tabelle1", "Name of Sheet 2", "Sheet3", "Sheet4", "Sheet5"]
|
190
|
+
assert_equal expected_sheet_names, xlsx.sheets
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_header_offset
|
194
|
+
xlsx = roo_class.new(File.join(TESTDIR, "header_offset.xlsx"))
|
195
|
+
data = xlsx.parse(column_1: "Header A1", column_2: "Header B1")
|
196
|
+
assert_equal "Data A2", data[0][:column_1]
|
197
|
+
assert_equal "Data B2", data[0][:column_2]
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_formula_excelx
|
201
|
+
with_each_spreadsheet(name: "formula", format: :excelx) do |workbook|
|
202
|
+
assert_equal 1, workbook.cell("A", 1)
|
203
|
+
assert_equal 2, workbook.cell("A", 2)
|
204
|
+
assert_equal 3, workbook.cell("A", 3)
|
205
|
+
assert_equal 4, workbook.cell("A", 4)
|
206
|
+
assert_equal 5, workbook.cell("A", 5)
|
207
|
+
assert_equal 6, workbook.cell("A", 6)
|
208
|
+
assert_equal 21, workbook.cell("A", 7)
|
209
|
+
assert_equal :formula, workbook.celltype("A", 7)
|
210
|
+
assert_nil workbook.formula("A", 6)
|
211
|
+
|
212
|
+
expected_result = [
|
213
|
+
[7, 1, "SUM(A1:A6)"],
|
214
|
+
[7, 2, "SUM($A$1:B6)"],
|
215
|
+
]
|
216
|
+
assert_equal expected_result, workbook.formulas(workbook.sheets.first)
|
217
|
+
|
218
|
+
# setting a cell
|
219
|
+
workbook.set("A", 15, 41)
|
220
|
+
assert_equal 41, workbook.cell("A", 15)
|
221
|
+
workbook.set("A", 16, "41")
|
222
|
+
assert_equal "41", workbook.cell("A", 16)
|
223
|
+
workbook.set("A", 17, 42.5)
|
224
|
+
assert_equal 42.5, workbook.cell("A", 17)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# TODO: temporaerer Test
|
229
|
+
def test_seiten_als_date
|
230
|
+
skip_long_test
|
231
|
+
|
232
|
+
with_each_spreadsheet(name: "Bibelbund", format: :excelx) do |workbook|
|
233
|
+
assert_equal "Bericht aus dem Sekretariat", workbook.cell(13, 1)
|
234
|
+
assert_equal "1981-4", workbook.cell(13, "D")
|
235
|
+
assert_equal String, workbook.excelx_type(13, "E")[1].class
|
236
|
+
assert_equal [:numeric_or_formula, "General"], workbook.excelx_type(13, "E")
|
237
|
+
assert_equal "428", workbook.excelx_value(13, "E")
|
238
|
+
assert_equal 428.0, workbook.cell(13, "E")
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def test_bug_simple_spreadsheet_time_bug
|
243
|
+
# really a bug? are cells really of type time?
|
244
|
+
# No! :float must be the correct type
|
245
|
+
with_each_spreadsheet(name: "simple_spreadsheet", format: :excelx) do |workbook|
|
246
|
+
# puts workbook.cell("B", 5).to_s
|
247
|
+
# assert_equal :time, workbook.celltype("B", 5)
|
248
|
+
assert_equal :float, workbook.celltype("B", 5)
|
249
|
+
assert_equal 10.75, workbook.cell("B", 5)
|
250
|
+
assert_equal 12.50, workbook.cell("C", 5)
|
251
|
+
assert_equal 0, workbook.cell("D", 5)
|
252
|
+
assert_equal 1.75, workbook.cell("E", 5)
|
253
|
+
assert_equal "Task 1", workbook.cell("F", 5)
|
254
|
+
assert_equal Date.new(2007, 5, 7), workbook.cell("A", 5)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_simple2_excelx
|
259
|
+
with_each_spreadsheet(name: "simple_spreadsheet", format: :excelx) do |workbook|
|
260
|
+
assert_equal [:numeric_or_formula, "yyyy\\-mm\\-dd"], workbook.excelx_type("A", 4)
|
261
|
+
assert_equal [:numeric_or_formula, "#,##0.00"], workbook.excelx_type("B", 4)
|
262
|
+
assert_equal [:numeric_or_formula, "#,##0.00"], workbook.excelx_type("c", 4)
|
263
|
+
assert_equal [:numeric_or_formula, "General"], workbook.excelx_type("d", 4)
|
264
|
+
assert_equal [:numeric_or_formula, "General"], workbook.excelx_type("e", 4)
|
265
|
+
assert_equal :string, workbook.excelx_type("f", 4)
|
266
|
+
|
267
|
+
assert_equal "39209", workbook.excelx_value("a", 4)
|
268
|
+
assert_equal "yyyy\\-mm\\-dd", workbook.excelx_format("a", 4)
|
269
|
+
assert_equal "9.25", workbook.excelx_value("b", 4)
|
270
|
+
assert_equal "10.25", workbook.excelx_value("c", 4)
|
271
|
+
assert_equal "0", workbook.excelx_value("d", 4)
|
272
|
+
# ... Sum-Spalte
|
273
|
+
# assert_equal "Task 1", workbook.excelx_value("f", 4)
|
274
|
+
assert_equal "Task 1", workbook.cell("f", 4)
|
275
|
+
assert_equal Date.new(2007, 05, 07), workbook.cell("a", 4)
|
276
|
+
assert_equal "9.25", workbook.excelx_value("b", 4)
|
277
|
+
assert_equal "#,##0.00", workbook.excelx_format("b", 4)
|
278
|
+
assert_equal 9.25, workbook.cell("b", 4)
|
279
|
+
assert_equal :float, workbook.celltype("b", 4)
|
280
|
+
assert_equal :float, workbook.celltype("d", 4)
|
281
|
+
assert_equal 0, workbook.cell("d", 4)
|
282
|
+
assert_equal :formula, workbook.celltype("e", 4)
|
283
|
+
assert_equal 1, workbook.cell("e", 4)
|
284
|
+
assert_equal "C4-B4-D4", workbook.formula("e", 4)
|
285
|
+
assert_equal :string, workbook.celltype("f", 4)
|
286
|
+
assert_equal "Task 1", workbook.cell("f", 4)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_bug_pfand_from_windows_phone_xlsx
|
291
|
+
# skip_jruby_incompatible_test
|
292
|
+
# TODO: Does JRUBY need to skip this test
|
293
|
+
return if defined? JRUBY_VERSION
|
294
|
+
|
295
|
+
options = { name: "Pfand_from_windows_phone", format: :excelx }
|
296
|
+
with_each_spreadsheet(options) do |workbook|
|
297
|
+
workbook.default_sheet = workbook.sheets.first
|
298
|
+
assert_equal ["Blatt1", "Blatt2", "Blatt3"], workbook.sheets
|
299
|
+
assert_equal "Summe", workbook.cell("b", 1)
|
300
|
+
|
301
|
+
assert_equal Date.new(2011, 9, 14), workbook.cell("a", 2)
|
302
|
+
assert_equal :date, workbook.celltype("a", 2)
|
303
|
+
assert_equal Date.new(2011, 9, 15), workbook.cell("a", 3)
|
304
|
+
assert_equal :date, workbook.celltype("a", 3)
|
305
|
+
|
306
|
+
assert_equal 3.81, workbook.cell("b", 2)
|
307
|
+
assert_equal "SUM(C2:L2)", workbook.formula("b", 2)
|
308
|
+
assert_equal 0.7, workbook.cell("c", 2)
|
309
|
+
end # each
|
310
|
+
end
|
311
|
+
|
312
|
+
def test_excelx_links
|
313
|
+
with_each_spreadsheet(name: "link", format: :excelx) do |workbook|
|
314
|
+
assert_equal "Google", workbook.cell(1, 1)
|
315
|
+
assert_equal "http://www.google.com", workbook.cell(1, 1).href
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
def test_handles_link_without_hyperlink
|
320
|
+
workbook = Roo::Spreadsheet.open(File.join(TESTDIR, "bad_link.xlsx"))
|
321
|
+
assert_equal "Test", workbook.cell(1, 1)
|
322
|
+
end
|
323
|
+
|
324
|
+
# Excel has two base date formats one from 1900 and the other from 1904.
|
325
|
+
# see #test_base_dates_in_excel
|
326
|
+
def test_base_dates_in_excelx
|
327
|
+
with_each_spreadsheet(name: "1900_base", format: :excelx) do |workbook|
|
328
|
+
assert_equal Date.new(2009, 06, 15), workbook.cell(1, 1)
|
329
|
+
assert_equal :date, workbook.celltype(1, 1)
|
330
|
+
end
|
331
|
+
with_each_spreadsheet(name: "1904_base", format: :excelx) do |workbook|
|
332
|
+
assert_equal Date.new(2009, 06, 15), workbook.cell(1, 1)
|
333
|
+
assert_equal :date, workbook.celltype(1, 1)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
def test_parsing_xlsx_with_richtext
|
338
|
+
xlsx = roo_class.new(File.join(TESTDIR, "richtext_example.xlsx"))
|
339
|
+
|
340
|
+
assert_equal "Example richtext", xlsx.cell("a", 1)
|
341
|
+
assert_equal "Example richtext", xlsx.cell("b", 1)
|
342
|
+
end
|
343
|
+
|
344
|
+
def test_implicit_coordinates
|
345
|
+
xlsx = roo_class.new(File.join(TESTDIR, 'implicit_coordinates.xlsx'))
|
346
|
+
|
347
|
+
assert_equal 'Test', xlsx.cell('a', 1)
|
348
|
+
assert_equal 'A2', xlsx.cell('a', 2)
|
349
|
+
assert_equal 'B2', xlsx.cell(2, 2)
|
350
|
+
assert_equal 'C2', xlsx.cell('c', 2)
|
351
|
+
end
|
352
|
+
|
353
|
+
def roo_class
|
354
|
+
Roo::Excelx
|
355
|
+
end
|
356
|
+
|
357
|
+
def filename(name)
|
358
|
+
"#{name}.xlsx"
|
359
|
+
end
|
360
|
+
end
|