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.
Files changed (95) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +17 -0
  3. data/.github/issue_template.md +16 -0
  4. data/.github/pull_request_template.md +14 -0
  5. data/.github/workflows/pull-request.yml +15 -0
  6. data/.github/workflows/ruby.yml +34 -0
  7. data/.gitignore +4 -0
  8. data/.rubocop.yml +186 -0
  9. data/CHANGELOG.md +148 -0
  10. data/Gemfile +4 -4
  11. data/LICENSE +2 -0
  12. data/README.md +84 -27
  13. data/Rakefile +1 -1
  14. data/lib/roo/base.rb +111 -237
  15. data/lib/roo/constants.rb +5 -3
  16. data/lib/roo/csv.rb +106 -85
  17. data/lib/roo/errors.rb +2 -0
  18. data/lib/roo/excelx/cell/base.rb +26 -12
  19. data/lib/roo/excelx/cell/boolean.rb +9 -6
  20. data/lib/roo/excelx/cell/date.rb +7 -7
  21. data/lib/roo/excelx/cell/datetime.rb +50 -44
  22. data/lib/roo/excelx/cell/empty.rb +3 -2
  23. data/lib/roo/excelx/cell/number.rb +60 -47
  24. data/lib/roo/excelx/cell/string.rb +3 -3
  25. data/lib/roo/excelx/cell/time.rb +17 -16
  26. data/lib/roo/excelx/cell.rb +11 -7
  27. data/lib/roo/excelx/comments.rb +3 -3
  28. data/lib/roo/excelx/coordinate.rb +11 -4
  29. data/lib/roo/excelx/extractor.rb +20 -3
  30. data/lib/roo/excelx/format.rb +38 -31
  31. data/lib/roo/excelx/images.rb +26 -0
  32. data/lib/roo/excelx/relationships.rb +12 -4
  33. data/lib/roo/excelx/shared.rb +10 -3
  34. data/lib/roo/excelx/shared_strings.rb +113 -9
  35. data/lib/roo/excelx/sheet.rb +49 -10
  36. data/lib/roo/excelx/sheet_doc.rb +101 -48
  37. data/lib/roo/excelx/styles.rb +4 -4
  38. data/lib/roo/excelx/workbook.rb +8 -3
  39. data/lib/roo/excelx.rb +85 -42
  40. data/lib/roo/formatters/base.rb +15 -0
  41. data/lib/roo/formatters/csv.rb +84 -0
  42. data/lib/roo/formatters/matrix.rb +23 -0
  43. data/lib/roo/formatters/xml.rb +31 -0
  44. data/lib/roo/formatters/yaml.rb +40 -0
  45. data/lib/roo/helpers/default_attr_reader.rb +20 -0
  46. data/lib/roo/helpers/weak_instance_cache.rb +41 -0
  47. data/lib/roo/open_office.rb +41 -27
  48. data/lib/roo/spreadsheet.rb +8 -2
  49. data/lib/roo/tempdir.rb +24 -0
  50. data/lib/roo/utils.rb +76 -26
  51. data/lib/roo/version.rb +1 -1
  52. data/lib/roo.rb +5 -0
  53. data/roo.gemspec +22 -12
  54. data/spec/lib/roo/base_spec.rb +65 -3
  55. data/spec/lib/roo/csv_spec.rb +19 -0
  56. data/spec/lib/roo/excelx/cell/time_spec.rb +15 -0
  57. data/spec/lib/roo/excelx/relationships_spec.rb +43 -0
  58. data/spec/lib/roo/excelx/sheet_doc_spec.rb +11 -0
  59. data/spec/lib/roo/excelx_spec.rb +237 -5
  60. data/spec/lib/roo/openoffice_spec.rb +2 -2
  61. data/spec/lib/roo/spreadsheet_spec.rb +1 -1
  62. data/spec/lib/roo/strict_spec.rb +43 -0
  63. data/spec/lib/roo/utils_spec.rb +22 -9
  64. data/spec/lib/roo/weak_instance_cache_spec.rb +92 -0
  65. data/spec/lib/roo_spec.rb +0 -0
  66. data/spec/spec_helper.rb +2 -7
  67. data/test/excelx/cell/test_attr_reader_default.rb +72 -0
  68. data/test/excelx/cell/test_base.rb +6 -2
  69. data/test/excelx/cell/test_boolean.rb +1 -3
  70. data/test/excelx/cell/test_date.rb +1 -6
  71. data/test/excelx/cell/test_datetime.rb +7 -10
  72. data/test/excelx/cell/test_empty.rb +12 -2
  73. data/test/excelx/cell/test_number.rb +28 -4
  74. data/test/excelx/cell/test_string.rb +21 -3
  75. data/test/excelx/cell/test_time.rb +7 -10
  76. data/test/excelx/test_coordinate.rb +51 -0
  77. data/test/formatters/test_csv.rb +136 -0
  78. data/test/formatters/test_matrix.rb +76 -0
  79. data/test/formatters/test_xml.rb +78 -0
  80. data/test/formatters/test_yaml.rb +20 -0
  81. data/test/helpers/test_accessing_files.rb +81 -0
  82. data/test/helpers/test_comments.rb +43 -0
  83. data/test/helpers/test_formulas.rb +9 -0
  84. data/test/helpers/test_labels.rb +103 -0
  85. data/test/helpers/test_sheets.rb +55 -0
  86. data/test/helpers/test_styles.rb +62 -0
  87. data/test/roo/test_base.rb +182 -0
  88. data/test/roo/test_csv.rb +88 -0
  89. data/test/roo/test_excelx.rb +360 -0
  90. data/test/roo/test_libre_office.rb +9 -0
  91. data/test/roo/test_open_office.rb +289 -0
  92. data/test/test_helper.rb +129 -14
  93. data/test/test_roo.rb +60 -1765
  94. metadata +91 -21
  95. 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
@@ -0,0 +1,9 @@
1
+ require "test_helper"
2
+
3
+ class TestRooOpenOffice < Minitest::Test
4
+ def test_libre_office
5
+ oo = Roo::LibreOffice.new(File.join(TESTDIR, "numbers1.ods"))
6
+ oo.default_sheet = oo.sheets.first
7
+ assert_equal 41, oo.cell("a", 12)
8
+ end
9
+ end