roo 1.13.2 → 2.0.0

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 (172) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -0
  3. data/.simplecov +4 -0
  4. data/.travis.yml +13 -0
  5. data/CHANGELOG.md +500 -0
  6. data/Gemfile +16 -10
  7. data/Guardfile +24 -0
  8. data/LICENSE +3 -1
  9. data/README.md +254 -0
  10. data/Rakefile +23 -23
  11. data/examples/roo_soap_client.rb +28 -31
  12. data/examples/roo_soap_server.rb +4 -6
  13. data/examples/write_me.rb +9 -10
  14. data/lib/roo/base.rb +303 -388
  15. data/lib/roo/csv.rb +120 -113
  16. data/lib/roo/excelx/comments.rb +24 -0
  17. data/lib/roo/excelx/extractor.rb +20 -0
  18. data/lib/roo/excelx/relationships.rb +26 -0
  19. data/lib/roo/excelx/shared_strings.rb +40 -0
  20. data/lib/roo/excelx/sheet_doc.rb +202 -0
  21. data/lib/roo/excelx/styles.rb +62 -0
  22. data/lib/roo/excelx/workbook.rb +59 -0
  23. data/lib/roo/excelx.rb +452 -484
  24. data/lib/roo/font.rb +17 -0
  25. data/lib/roo/libre_office.rb +5 -0
  26. data/lib/roo/link.rb +15 -0
  27. data/lib/roo/{openoffice.rb → open_office.rb} +678 -496
  28. data/lib/roo/spreadsheet.rb +20 -23
  29. data/lib/roo/utils.rb +78 -0
  30. data/lib/roo/version.rb +3 -0
  31. data/lib/roo.rb +18 -24
  32. data/roo.gemspec +20 -204
  33. data/spec/lib/roo/base_spec.rb +1 -4
  34. data/spec/lib/roo/csv_spec.rb +21 -13
  35. data/spec/lib/roo/excelx/format_spec.rb +7 -6
  36. data/spec/lib/roo/excelx_spec.rb +388 -11
  37. data/spec/lib/roo/libreoffice_spec.rb +16 -6
  38. data/spec/lib/roo/openoffice_spec.rb +2 -8
  39. data/spec/lib/roo/spreadsheet_spec.rb +40 -12
  40. data/spec/lib/roo/utils_spec.rb +106 -0
  41. data/spec/spec_helper.rb +2 -1
  42. data/test/test_generic_spreadsheet.rb +19 -67
  43. data/test/test_helper.rb +9 -56
  44. data/test/test_roo.rb +252 -477
  45. metadata +63 -302
  46. data/CHANGELOG +0 -417
  47. data/Gemfile.lock +0 -78
  48. data/README.markdown +0 -126
  49. data/VERSION +0 -1
  50. data/lib/roo/excel.rb +0 -355
  51. data/lib/roo/excel2003xml.rb +0 -300
  52. data/lib/roo/google.rb +0 -292
  53. data/lib/roo/roo_rails_helper.rb +0 -83
  54. data/lib/roo/worksheet.rb +0 -18
  55. data/spec/lib/roo/excel2003xml_spec.rb +0 -15
  56. data/spec/lib/roo/excel_spec.rb +0 -17
  57. data/spec/lib/roo/google_spec.rb +0 -64
  58. data/test/files/1900_base.xls +0 -0
  59. data/test/files/1900_base.xlsx +0 -0
  60. data/test/files/1904_base.xls +0 -0
  61. data/test/files/1904_base.xlsx +0 -0
  62. data/test/files/Bibelbund.csv +0 -3741
  63. data/test/files/Bibelbund.ods +0 -0
  64. data/test/files/Bibelbund.xls +0 -0
  65. data/test/files/Bibelbund.xlsx +0 -0
  66. data/test/files/Bibelbund.xml +0 -62518
  67. data/test/files/Bibelbund1.ods +0 -0
  68. data/test/files/Pfand_from_windows_phone.xlsx +0 -0
  69. data/test/files/bad_excel_date.xls +0 -0
  70. data/test/files/bbu.ods +0 -0
  71. data/test/files/bbu.xls +0 -0
  72. data/test/files/bbu.xlsx +0 -0
  73. data/test/files/bbu.xml +0 -152
  74. data/test/files/bode-v1.ods.zip +0 -0
  75. data/test/files/bode-v1.xls.zip +0 -0
  76. data/test/files/boolean.csv +0 -2
  77. data/test/files/boolean.ods +0 -0
  78. data/test/files/boolean.xls +0 -0
  79. data/test/files/boolean.xlsx +0 -0
  80. data/test/files/boolean.xml +0 -112
  81. data/test/files/borders.ods +0 -0
  82. data/test/files/borders.xls +0 -0
  83. data/test/files/borders.xlsx +0 -0
  84. data/test/files/borders.xml +0 -144
  85. data/test/files/bug-numbered-sheet-names.xlsx +0 -0
  86. data/test/files/bug-row-column-fixnum-float.xls +0 -0
  87. data/test/files/bug-row-column-fixnum-float.xml +0 -127
  88. data/test/files/comments.ods +0 -0
  89. data/test/files/comments.xls +0 -0
  90. data/test/files/comments.xlsx +0 -0
  91. data/test/files/csvtypes.csv +0 -1
  92. data/test/files/datetime.ods +0 -0
  93. data/test/files/datetime.xls +0 -0
  94. data/test/files/datetime.xlsx +0 -0
  95. data/test/files/datetime.xml +0 -142
  96. data/test/files/datetime_floatconv.xls +0 -0
  97. data/test/files/datetime_floatconv.xml +0 -148
  98. data/test/files/dreimalvier.ods +0 -0
  99. data/test/files/emptysheets.ods +0 -0
  100. data/test/files/emptysheets.xls +0 -0
  101. data/test/files/emptysheets.xlsx +0 -0
  102. data/test/files/emptysheets.xml +0 -105
  103. data/test/files/excel2003.xml +0 -21140
  104. data/test/files/false_encoding.xls +0 -0
  105. data/test/files/false_encoding.xml +0 -132
  106. data/test/files/file_item_error.xlsx +0 -0
  107. data/test/files/formula.ods +0 -0
  108. data/test/files/formula.xls +0 -0
  109. data/test/files/formula.xlsx +0 -0
  110. data/test/files/formula.xml +0 -134
  111. data/test/files/formula_parse_error.xls +0 -0
  112. data/test/files/formula_parse_error.xml +0 -1833
  113. data/test/files/formula_string_error.xlsx +0 -0
  114. data/test/files/html-escape.ods +0 -0
  115. data/test/files/link.xls +0 -0
  116. data/test/files/link.xlsx +0 -0
  117. data/test/files/matrix.ods +0 -0
  118. data/test/files/matrix.xls +0 -0
  119. data/test/files/named_cells.ods +0 -0
  120. data/test/files/named_cells.xls +0 -0
  121. data/test/files/named_cells.xlsx +0 -0
  122. data/test/files/no_spreadsheet_file.txt +0 -1
  123. data/test/files/numbers1.csv +0 -18
  124. data/test/files/numbers1.ods +0 -0
  125. data/test/files/numbers1.xls +0 -0
  126. data/test/files/numbers1.xlsx +0 -0
  127. data/test/files/numbers1.xml +0 -312
  128. data/test/files/numeric-link.xlsx +0 -0
  129. data/test/files/only_one_sheet.ods +0 -0
  130. data/test/files/only_one_sheet.xls +0 -0
  131. data/test/files/only_one_sheet.xlsx +0 -0
  132. data/test/files/only_one_sheet.xml +0 -67
  133. data/test/files/paragraph.ods +0 -0
  134. data/test/files/paragraph.xls +0 -0
  135. data/test/files/paragraph.xlsx +0 -0
  136. data/test/files/paragraph.xml +0 -127
  137. data/test/files/prova.xls +0 -0
  138. data/test/files/ric.ods +0 -0
  139. data/test/files/simple_spreadsheet.ods +0 -0
  140. data/test/files/simple_spreadsheet.xls +0 -0
  141. data/test/files/simple_spreadsheet.xlsx +0 -0
  142. data/test/files/simple_spreadsheet.xml +0 -225
  143. data/test/files/simple_spreadsheet_from_italo.ods +0 -0
  144. data/test/files/simple_spreadsheet_from_italo.xls +0 -0
  145. data/test/files/simple_spreadsheet_from_italo.xml +0 -242
  146. data/test/files/so_datetime.csv +0 -7
  147. data/test/files/style.ods +0 -0
  148. data/test/files/style.xls +0 -0
  149. data/test/files/style.xlsx +0 -0
  150. data/test/files/style.xml +0 -154
  151. data/test/files/time-test.csv +0 -2
  152. data/test/files/time-test.ods +0 -0
  153. data/test/files/time-test.xls +0 -0
  154. data/test/files/time-test.xlsx +0 -0
  155. data/test/files/time-test.xml +0 -131
  156. data/test/files/type_excel.ods +0 -0
  157. data/test/files/type_excel.xlsx +0 -0
  158. data/test/files/type_excelx.ods +0 -0
  159. data/test/files/type_excelx.xls +0 -0
  160. data/test/files/type_openoffice.xls +0 -0
  161. data/test/files/type_openoffice.xlsx +0 -0
  162. data/test/files/whitespace.ods +0 -0
  163. data/test/files/whitespace.xls +0 -0
  164. data/test/files/whitespace.xlsx +0 -0
  165. data/test/files/whitespace.xml +0 -184
  166. data/test/rm_sub_test.rb +0 -12
  167. data/test/rm_test.rb +0 -7
  168. data/website/index.html +0 -385
  169. data/website/index.txt +0 -423
  170. data/website/javascripts/rounded_corners_lite.inc.js +0 -285
  171. data/website/stylesheets/screen.css +0 -130
  172. data/website/template.rhtml +0 -48
@@ -1,37 +1,414 @@
1
+ # encoding: utf-8
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Roo::Excelx do
5
+ subject(:xlsx) do
6
+ Roo::Excelx.new(path)
7
+ end
8
+
4
9
  describe '.new' do
5
- subject {
6
- Roo::Excelx.new('test/files/numbers1.xlsx')
7
- }
10
+ let(:path) { 'test/files/numeric-link.xlsx' }
8
11
 
9
12
  it 'creates an instance' do
10
13
  expect(subject).to be_a(Roo::Excelx)
11
14
  end
12
15
 
13
16
  context 'given a file with missing rels' do
14
- subject {
15
- Roo::Excelx.new('test/files/file_item_error.xlsx')
16
- }
17
+ let(:path) { 'test/files/file_item_error.xlsx' }
17
18
 
18
19
  it 'creates an instance' do
19
20
  expect(subject).to be_a(Roo::Excelx)
20
21
  end
21
22
  end
23
+
24
+ context 'with more cells than specified max' do
25
+ let(:path) { 'test/files/only_one_sheet.xlsx' }
26
+
27
+ it 'raises an appropriate error' do
28
+ expect { Roo::Excelx.new(path, cell_max: 1) }.to raise_error(Roo::Excelx::ExceedsMaxError)
29
+ end
30
+ end
31
+
32
+ context 'with fewer cells than specified max' do
33
+ let(:path) { 'test/files/only_one_sheet.xlsx' }
34
+
35
+ it 'creates an instance' do
36
+ expect(Roo::Excelx.new(path, cell_max: 100)).to be_a(Roo::Excelx)
37
+ end
38
+ end
22
39
  end
23
40
 
24
41
  describe '#cell' do
25
42
  context 'for a link cell' do
26
43
  context 'with numeric contents' do
27
- subject {
28
- Roo::Excelx.new('test/files/numeric-link.xlsx').cell('A', 1)
29
- }
44
+ let(:path) { 'test/files/numeric-link.xlsx' }
45
+
46
+ subject do
47
+ xlsx.cell('A', 1)
48
+ end
30
49
 
31
50
  it 'returns a link with the number as a string value' do
32
- expect(subject).to be_a(Spreadsheet::Link)
33
- expect(subject).to eq("8675309.0")
51
+ expect(subject).to be_a(Roo::Link)
52
+ expect(subject).to eq('8675309.0')
53
+ end
54
+ end
55
+ end
56
+
57
+ context 'for a non-existent cell' do
58
+ let(:path) { 'test/files/numeric-link.xlsx' }
59
+ it 'return nil' do
60
+ expect(xlsx.cell('AAA', 999)).to eq nil
61
+ end
62
+ end
63
+ end
64
+
65
+ describe '#parse' do
66
+ let(:path) { 'test/files/numeric-link.xlsx' }
67
+
68
+ context 'with a columns hash' do
69
+ context 'when not present in the sheet' do
70
+ it 'does not raise' do
71
+ expect do
72
+ xlsx.sheet(0).parse(
73
+ this: 'This',
74
+ that: 'That'
75
+ )
76
+ end.to raise_error("Couldn't find header row.")
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ describe '#parse_with_clean_option' do
83
+ let(:path) { 'test/files/parse_with_clean_option.xlsx' }
84
+ let(:options) { {clean: true} }
85
+
86
+ context 'with clean: true' do
87
+
88
+ it 'does not raise' do
89
+ expect do
90
+ xlsx.parse(options)
91
+ end.not_to raise_error
92
+ end
93
+ end
94
+ end
95
+
96
+ describe '#parse_unicode_with_clean_option' do
97
+ let(:path) { 'test/files/parse_clean_with_unicode.xlsx' }
98
+ let(:options) { {clean: true, name: 'Name'} }
99
+
100
+ context 'with clean: true' do
101
+
102
+ it 'returns a non empty string' do
103
+ expect(xlsx.parse(options).last[:name]).to eql('凯')
104
+ end
105
+ end
106
+ end
107
+
108
+
109
+
110
+
111
+ describe '#sheets' do
112
+ let(:path) { 'test/files/numbers1.xlsx' }
113
+
114
+ it 'returns the expected result' do
115
+ expect(subject.sheets).to eq ["Tabelle1", "Name of Sheet 2", "Sheet3", "Sheet4", "Sheet5"]
116
+ end
117
+
118
+ describe 'only showing visible sheets' do
119
+ let(:path) { 'test/files/hidden_sheets.xlsx' }
120
+
121
+ it 'returns the expected result' do
122
+ expect(Roo::Excelx.new(path, only_visible_sheets: true).sheets).to eq ["VisibleSheet1"]
123
+ end
124
+ end
125
+ end
126
+
127
+ describe '#sheet_for' do
128
+ let(:path) { 'test/files/numbers1.xlsx' }
129
+
130
+ # This is kinda gross
131
+ it 'returns the expected result' do
132
+ expect(subject.sheet_for("Tabelle1").instance_variable_get("@name")).to eq "Tabelle1"
133
+ end
134
+ end
135
+
136
+ describe '#row' do
137
+ let(:path) { 'test/files/numbers1.xlsx' }
138
+
139
+ it 'returns the expected result' do
140
+ expect(subject.row(1, "Sheet5")).to eq [1.0, 5.0, 5.0, nil, nil]
141
+ end
142
+ end
143
+
144
+ describe '#column' do
145
+ let(:path) { 'test/files/numbers1.xlsx' }
146
+
147
+ it 'returns the expected result' do
148
+ expect(subject.column(1, "Sheet5")).to eq [1.0, 2.0, 3.0, Date.new(2007,11,21), 42.0, "ABC"]
149
+ end
150
+ end
151
+
152
+ describe '#first_row' do
153
+ let(:path) { 'test/files/numbers1.xlsx' }
154
+
155
+ it 'returns the expected result' do
156
+ expect(subject.first_row("Sheet5")).to eq 1
157
+ end
158
+ end
159
+
160
+ describe '#last_row' do
161
+ let(:path) { 'test/files/numbers1.xlsx' }
162
+
163
+ it 'returns the expected result' do
164
+ expect(subject.last_row("Sheet5")).to eq 6
165
+ end
166
+ end
167
+
168
+ describe '#first_column' do
169
+ let(:path) { 'test/files/numbers1.xlsx' }
170
+
171
+ it 'returns the expected result' do
172
+ expect(subject.first_column("Sheet5")).to eq 1
173
+ end
174
+ end
175
+
176
+ describe '#last_column' do
177
+ let(:path) { 'test/files/numbers1.xlsx' }
178
+
179
+ it 'returns the expected result' do
180
+ expect(subject.last_column("Sheet5")).to eq 5
181
+ end
182
+ end
183
+
184
+ describe '#set' do
185
+
186
+ before do
187
+ subject.set(1, 2, "Foo", "Sheet5")
188
+ end
189
+
190
+ let(:path) { 'test/files/numbers1.xlsx' }
191
+ let(:cell) { subject.cell(1, 2, "Sheet5") }
192
+
193
+ it 'returns the expected result' do
194
+ expect(cell).to eq "Foo"
195
+ end
196
+ end
197
+
198
+ describe '#formula' do
199
+ let(:path) { 'test/files/formula.xlsx' }
200
+
201
+ it 'returns the expected result' do
202
+ expect(subject.formula(1, 1, "Sheet1")).to eq nil
203
+ expect(subject.formula(7, 2, "Sheet1")).to eq "SUM($A$1:B6)"
204
+ expect(subject.formula(1000, 2000, "Sheet1")).to eq nil
205
+ end
206
+ end
207
+
208
+ describe '#formula?' do
209
+ let(:path) { 'test/files/formula.xlsx' }
210
+
211
+ it 'returns the expected result' do
212
+ expect(subject.formula?(1, 1, "Sheet1")).to eq false
213
+ expect(subject.formula?(7, 2, "Sheet1")).to eq true
214
+ expect(subject.formula?(1000, 2000, "Sheet1")).to eq false
215
+ end
216
+ end
217
+
218
+ describe '#formulas' do
219
+ let(:path) { 'test/files/formula.xlsx' }
220
+
221
+ it 'returns the expected result' do
222
+ expect(subject.formulas("Sheet1")).to eq [[7, 1, "SUM(A1:A6)"], [7, 2, "SUM($A$1:B6)"]]
223
+ end
224
+ end
225
+
226
+ describe '#font' do
227
+ let(:path) { 'test/files/style.xlsx' }
228
+
229
+ it 'returns the expected result' do
230
+ expect(subject.font(1, 1).bold?).to eq true
231
+ expect(subject.font(1, 1).italic?).to eq false
232
+ expect(subject.font(1, 1).underline?).to eq false
233
+
234
+ expect(subject.font(7, 1).bold?).to eq false
235
+ expect(subject.font(7, 1).italic?).to eq true
236
+ expect(subject.font(7, 1).underline?).to eq true
237
+ expect(subject.font(1000, 2000)).to eq nil
238
+ end
239
+ end
240
+
241
+ describe '#celltype' do
242
+ let(:path) { 'test/files/numbers1.xlsx' }
243
+
244
+ it 'returns the expected result' do
245
+ expect(subject.celltype(1, 1, "Sheet4")).to eq :date
246
+ expect(subject.celltype(1, 2, "Sheet4")).to eq :float
247
+ expect(subject.celltype(6, 2, "Sheet5")).to eq :string
248
+ expect(subject.celltype(1000, 2000, "Sheet5")).to eq nil
249
+ end
250
+ end
251
+
252
+ describe '#excelx_type' do
253
+ let(:path) { 'test/files/numbers1.xlsx' }
254
+
255
+ it 'returns the expected result' do
256
+ expect(subject.excelx_type(1, 1, "Sheet5")).to eq [:numeric_or_formula, "General"]
257
+ expect(subject.excelx_type(6, 2, "Sheet5")).to eq :string
258
+ expect(subject.excelx_type(1000, 2000, "Sheet5")).to eq nil
259
+ end
260
+ end
261
+
262
+ describe '#excelx_value' do
263
+ let(:path) { 'test/files/numbers1.xlsx' }
264
+
265
+ it 'returns the expected result' do
266
+ # These values are the index in the shared strings table, might be a better
267
+ # way to get these rather than hardcoding.
268
+ expect(subject.excelx_value(1, 1, "Sheet5")).to eq "1"
269
+ expect(subject.excelx_value(6, 2, "Sheet5")).to eq "16"
270
+ expect(subject.excelx_value(6000, 2000, "Sheet5")).to eq nil
271
+ end
272
+ end
273
+
274
+ describe '#excelx_format' do
275
+ let(:path) { 'test/files/style.xlsx' }
276
+
277
+ it 'returns the expected result' do
278
+ # These are the index of the style for a given document
279
+ # might be more reliable way to get this info.
280
+ expect(subject.excelx_format(1, 1)).to eq "General"
281
+ expect(subject.excelx_format(2, 2)).to eq "0.00"
282
+ expect(subject.excelx_format(5000, 1000)).to eq nil
283
+ end
284
+ end
285
+
286
+ describe '#empty?' do
287
+ let(:path) { 'test/files/style.xlsx' }
288
+
289
+ it 'returns the expected result' do
290
+ # These are the index of the style for a given document
291
+ # might be more reliable way to get this info.
292
+ expect(subject.empty?(1, 1)).to eq false
293
+ expect(subject.empty?(13, 1)).to eq true
294
+ end
295
+ end
296
+
297
+ describe '#label' do
298
+ let(:path) { 'test/files/named_cells.xlsx' }
299
+
300
+ it 'returns the expected result' do
301
+ expect(subject.label("berta")).to eq [4, 2, "Sheet1"]
302
+ expect(subject.label("dave")).to eq [nil, nil, nil]
303
+ end
304
+ end
305
+
306
+ describe '#labels' do
307
+ let(:path) { 'test/files/named_cells.xlsx' }
308
+
309
+ it 'returns the expected result' do
310
+ expect(subject.labels).to eq [["anton", [5, 3, "Sheet1"]], ["berta", [4, 2, "Sheet1"]], ["caesar", [7, 2, "Sheet1"]]]
311
+ end
312
+ end
313
+
314
+ describe '#hyperlink?' do
315
+ let(:path) { 'test/files/link.xlsx' }
316
+
317
+ it 'returns the expected result' do
318
+ expect(subject.hyperlink?(1, 1)).to eq true
319
+ expect(subject.hyperlink?(1, 2)).to eq false
320
+ end
321
+ end
322
+
323
+ describe '#hyperlink' do
324
+ let(:path) { 'test/files/link.xlsx' }
325
+
326
+ it 'returns the expected result' do
327
+ expect(subject.hyperlink(1, 1)).to eq "http://www.google.com"
328
+ expect(subject.hyperlink(1, 2)).to eq nil
329
+ end
330
+ end
331
+
332
+ describe '#comment' do
333
+ let(:path) { 'test/files/comments.xlsx' }
334
+
335
+ it 'returns the expected result' do
336
+ expect(subject.comment(4, 2)).to eq "Kommentar fuer B4"
337
+ expect(subject.comment(1, 2)).to eq nil
338
+ end
339
+ end
340
+
341
+ describe '#comment?' do
342
+ let(:path) { 'test/files/comments.xlsx' }
343
+
344
+ it 'returns the expected result' do
345
+ expect(subject.comment?(4, 2)).to eq true
346
+ expect(subject.comment?(1, 2)).to eq false
347
+ end
348
+ end
349
+
350
+ describe '#comments' do
351
+ let(:path) { 'test/files/comments.xlsx' }
352
+
353
+ it 'returns the expected result' do
354
+ expect(subject.comments).to eq [[4, 2, "Kommentar fuer B4"], [5, 2, "Kommentar fuer B5"]]
355
+ end
356
+ end
357
+
358
+ # nil, nil, nil, nil, nil
359
+ # nil, nil, nil, nil, nil
360
+ # Date Start time End time Pause Sum Comment
361
+ # 2007-05-07 9.25 10.25 0 1 Task 1
362
+ # 2007-05-07 10.75 12.50 0 1.75 Task 1
363
+ # 2007-05-07 18.00 19.00 0 1 Task 2
364
+ # 2007-05-08 9.25 10.25 0 1 Task 2
365
+ # 2007-05-08 14.50 15.50 0 1 Task 3
366
+ # 2007-05-08 8.75 9.25 0 0.5 Task 3
367
+ # 2007-05-14 21.75 22.25 0 0.5 Task 3
368
+ # 2007-05-14 22.50 23.00 0 0.5 Task 3
369
+ # 2007-05-15 11.75 12.75 0 1 Task 3
370
+ # 2007-05-07 10.75 10.75 0 0 Task 1
371
+ # nil
372
+ describe '#each_row_streaming' do
373
+ let(:path) { 'test/files/simple_spreadsheet.xlsx' }
374
+
375
+ let(:expected_rows) do
376
+ [
377
+ [nil, nil, nil, nil, nil],
378
+ [nil, nil, nil, nil, nil],
379
+ ["Date", "Start time", "End time", "Pause", "Sum", "Comment", nil, nil],
380
+ [Date.new(2007, 5, 7), 9.25, 10.25, 0.0, 1.0, "Task 1"],
381
+ [Date.new(2007, 5, 7), 10.75, 12.50, 0.0, 1.75, "Task 1"],
382
+ [Date.new(2007, 5, 7), 18.0, 19.0, 0.0, 1.0, "Task 2"],
383
+ [Date.new(2007, 5, 8), 9.25, 10.25, 0.0, 1.0, "Task 2"],
384
+ [Date.new(2007, 5, 8), 14.5, 15.5, 0.0, 1.0, "Task 3"],
385
+ [Date.new(2007, 5, 8), 8.75, 9.25, 0.0, 0.5, "Task 3"],
386
+ [Date.new(2007, 5, 14), 21.75, 22.25, 0.0, 0.5, "Task 3"],
387
+ [Date.new(2007, 5, 14), 22.5, 23.0, 0.0, 0.5, "Task 3"],
388
+ [Date.new(2007, 5, 15), 11.75, 12.75, 0.0, 1.0, "Task 3"],
389
+ [Date.new(2007, 5, 7), 10.75, 10.75, 0.0, 0.0, "Task 1"],
390
+ [nil]
391
+ ]
392
+ end
393
+
394
+ it 'returns the expected result' do
395
+ index = 0
396
+ subject.each_row_streaming do |row|
397
+ expect(row.map(&:value)).to eq expected_rows[index]
398
+ index += 1
399
+ end
400
+ end
401
+
402
+ context 'with max_rows options' do
403
+ it 'returns the expected result' do
404
+ index = 0
405
+ subject.each_row_streaming(max_rows: 3) do |row|
406
+ expect(row.map(&:value)).to eq expected_rows[index]
407
+ index += 1
34
408
  end
409
+ # Expect this to get incremented one time more than max (because of the increment at the end of the block)
410
+ # but it should not be near expected_rows.size
411
+ expect(index).to eq 4
35
412
  end
36
413
  end
37
414
  end
@@ -2,18 +2,28 @@ require 'spec_helper'
2
2
 
3
3
  describe Roo::LibreOffice do
4
4
  describe '.new' do
5
- subject {
5
+ subject do
6
6
  Roo::LibreOffice.new('test/files/numbers1.ods')
7
- }
7
+ end
8
8
 
9
9
  it 'creates an instance' do
10
10
  expect(subject).to be_a(Roo::LibreOffice)
11
11
  end
12
12
  end
13
- end
14
13
 
15
- describe Roo::Libreoffice do
16
- it 'is an alias of LibreOffice' do
17
- expect(Roo::Libreoffice).to eq(Roo::LibreOffice)
14
+ describe '#sheets' do
15
+ let(:path) { 'test/files/hidden_sheets.ods' }
16
+
17
+ describe 'showing all sheets' do
18
+ it 'returns the expected result' do
19
+ expect(Roo::LibreOffice.new(path).sheets).to eq ["HiddenSheet1", "VisibleSheet1", "HiddenSheet2"]
20
+ end
21
+ end
22
+
23
+ describe 'only showing visible sheets' do
24
+ it 'returns the expected result' do
25
+ expect(Roo::LibreOffice.new(path, only_visible_sheets: true).sheets).to eq ["VisibleSheet1"]
26
+ end
27
+ end
18
28
  end
19
29
  end
@@ -2,9 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  describe Roo::OpenOffice do
4
4
  describe '.new' do
5
- subject {
5
+ subject do
6
6
  Roo::OpenOffice.new('test/files/numbers1.ods')
7
- }
7
+ end
8
8
 
9
9
  it 'creates an instance' do
10
10
  expect(subject).to be_a(Roo::OpenOffice)
@@ -13,9 +13,3 @@ describe Roo::OpenOffice do
13
13
 
14
14
  # OpenOffice is an alias of LibreOffice. See libreoffice_spec.
15
15
  end
16
-
17
- describe Roo::Openoffice do
18
- it 'is an alias of LibreOffice' do
19
- expect(Roo::Openoffice).to eq(Roo::OpenOffice)
20
- end
21
- end
@@ -2,15 +2,34 @@ require 'spec_helper'
2
2
 
3
3
  describe Roo::Spreadsheet do
4
4
  describe '.open' do
5
+ context 'when the file name includes a space' do
6
+ let(:filename) { 'great scott.xlsx' }
7
+
8
+ it 'loads the proper type' do
9
+ expect(Roo::Excelx).to receive(:new).with(filename, {})
10
+ Roo::Spreadsheet.open(filename)
11
+ end
12
+ end
13
+
5
14
  context 'when the file extension is uppercase' do
6
- let(:filename) { 'file.XLS' }
15
+ let(:filename) { 'file.XLSX' }
7
16
 
8
17
  it 'loads the proper type' do
9
- expect(Roo::Excel).to receive(:new).with(filename, {})
18
+ expect(Roo::Excelx).to receive(:new).with(filename, {})
10
19
  Roo::Spreadsheet.open(filename)
11
20
  end
12
21
  end
13
22
 
23
+ context 'for a tempfile' do
24
+ let(:tempfile) { Tempfile.new('foo.csv') }
25
+ let(:filename) { tempfile.path }
26
+
27
+ it 'loads the proper type' do
28
+ expect(Roo::CSV).to receive(:new).with(filename, file_warning: :ignore).and_call_original
29
+ expect(Roo::Spreadsheet.open(tempfile, extension: :csv)).to be_a(Roo::CSV)
30
+ end
31
+ end
32
+
14
33
  context 'for a url' do
15
34
  context 'that is csv' do
16
35
  let(:filename) { 'http://example.com/file.csv?with=params#and=anchor' }
@@ -24,33 +43,42 @@ describe Roo::Spreadsheet do
24
43
 
25
44
  context 'for a csv file' do
26
45
  let(:filename) { 'file.csv' }
27
- let(:options) { {csv_options: {col_sep: '"'}} }
46
+ let(:options) { { csv_options: { col_sep: '"' } } }
28
47
 
29
- context 'with options' do
30
- it 'passes the options through' do
48
+ context 'with csv_options' do
49
+ it 'passes the csv_options through' do
31
50
  expect(Roo::CSV).to receive(:new).with(filename, options)
32
51
  Roo::Spreadsheet.open(filename, options)
33
52
  end
34
53
  end
35
54
  end
36
55
 
37
- context 'when the file extension' do
56
+ context 'with a file extension option' do
38
57
  let(:filename) { 'file.xls' }
39
58
 
40
- context "is xls" do
41
- let(:options) { { extension: "xls" } }
59
+ context ':xlsx' do
60
+ let(:options) { { extension: :xlsx } }
61
+
62
+ it 'loads with xls extension options' do
63
+ expect(Roo::Excelx).to receive(:new).with(filename, options)
64
+ Roo::Spreadsheet.open(filename, options)
65
+ end
66
+ end
67
+
68
+ context 'xlsx' do
69
+ let(:options) { { extension: 'xlsx' } }
42
70
 
43
71
  it 'loads with xls extension options' do
44
- expect(Roo::Excel).to receive(:new).with(filename, options)
72
+ expect(Roo::Excelx).to receive(:new).with(filename, options)
45
73
  Roo::Spreadsheet.open(filename, options)
46
74
  end
47
75
  end
48
76
 
49
- context "is .xls" do
50
- let(:options) { { extension: ".xls" } }
77
+ context '.xlsx' do
78
+ let(:options) { { extension: '.xlsx' } }
51
79
 
52
80
  it 'loads with .xls extension options' do
53
- expect(Roo::Excel).to receive(:new).with(filename, options)
81
+ expect(Roo::Excelx).to receive(:new).with(filename, options)
54
82
  Roo::Spreadsheet.open(filename, options)
55
83
  end
56
84
  end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ::Roo::Utils do
4
+ subject { described_class }
5
+
6
+ context '#number_to_letter' do
7
+ ('A'..'Z').to_a.each_with_index do |letter, index|
8
+ it "should return '#{ letter }' when passed #{ index + 1 }" do
9
+ expect(described_class.number_to_letter(index + 1)).to eq(letter)
10
+ end
11
+ end
12
+
13
+ {
14
+ 27 => 'AA', 26*2 => 'AZ', 26*3 => 'BZ', 26**2 + 26 => 'ZZ', 26**2 + 27 => 'AAA',
15
+ 26**3 + 26**2 + 26 => 'ZZZ', 1.0 => 'A', 676 => 'YZ', 677 => 'ZA'
16
+ }.each do |key, value|
17
+ it "should return '#{value}' when passed #{key}" do
18
+ expect(described_class.number_to_letter(key)).to eq(value)
19
+ end
20
+ end
21
+ end
22
+
23
+ context '#letter_to_number' do
24
+ it "should give 1 for 'A' and 'a'" do
25
+ expect(described_class.letter_to_number('A')).to eq(1)
26
+ expect(described_class.letter_to_number('a')).to eq(1)
27
+ end
28
+
29
+ it "should give the correct value for 'Z'" do
30
+ expect(described_class.letter_to_number('Z')).to eq(26)
31
+ end
32
+
33
+ it "should give the correct value for 'AA' regardless of case mixing" do
34
+ %w(AA aA Aa aa).each do |key|
35
+ expect(described_class.letter_to_number(key)).to eq(27)
36
+ end
37
+ end
38
+
39
+ { 'AB' => 28, 'AZ' => 26*2, 'BZ' => 26*3, 'ZZ' => 26**2 + 26 }.each do |key, value|
40
+ it "should give the correct value for '#{key}'" do
41
+ expect(described_class.letter_to_number(key)).to eq(value)
42
+ end
43
+ end
44
+ end
45
+
46
+ context '.split_coordinate' do
47
+ it "returns the expected result" do
48
+ expect(described_class.split_coordinate('A1')).to eq [1, 1]
49
+ expect(described_class.split_coordinate('B2')).to eq [2, 2]
50
+ expect(described_class.split_coordinate('R2')).to eq [2, 18]
51
+ expect(described_class.split_coordinate('AR31')).to eq [31, 18 + 26]
52
+ end
53
+ end
54
+
55
+ context '.split_coord' do
56
+ it "returns the expected result" do
57
+ expect(described_class.split_coord('A1')).to eq ["A", 1]
58
+ expect(described_class.split_coord('B2')).to eq ["B", 2]
59
+ expect(described_class.split_coord('R2')).to eq ["R", 2]
60
+ expect(described_class.split_coord('AR31')).to eq ["AR", 31]
61
+ end
62
+
63
+ it "raises an error when appropriate" do
64
+ expect { described_class.split_coord('A') }.to raise_error(ArgumentError)
65
+ expect { described_class.split_coord('2') }.to raise_error(ArgumentError)
66
+ end
67
+ end
68
+
69
+
70
+ context '.num_cells_in_range' do
71
+ it "returns the expected result" do
72
+ expect(described_class.num_cells_in_range('A1:B2')).to eq 4
73
+ expect(described_class.num_cells_in_range('B2:E3')).to eq 8
74
+ expect(described_class.num_cells_in_range('R2:Z10')).to eq 81
75
+ expect(described_class.num_cells_in_range('AR31:AR32')).to eq 2
76
+ expect(described_class.num_cells_in_range('A1')).to eq 1
77
+ end
78
+
79
+ it "raises an error when appropriate" do
80
+ expect { described_class.num_cells_in_range('A1:B1:B2') }.to raise_error(ArgumentError)
81
+ end
82
+ end
83
+
84
+ context '.load_xml' do
85
+ it 'returns the expected result' do
86
+ expect(described_class.load_xml('test/files/sheet1.xml')).to be_a(Nokogiri::XML::Document)
87
+ expect(described_class.load_xml('test/files/sheet1.xml').
88
+ remove_namespaces!.xpath("/worksheet/dimension").map do |dim|
89
+ dim.attributes["ref"].value end.first).to eq "A1:B11"
90
+ end
91
+ end
92
+
93
+ context '.each_element' do
94
+ it 'returns the expected result' do
95
+ described_class.each_element('test/files/sheet1.xml', 'dimension') do |dim|
96
+ expect(dim.attributes["ref"].value).to eq "A1:B11"
97
+ end
98
+ rows = []
99
+ described_class.each_element('test/files/sheet1.xml', 'row') do |row|
100
+ rows << row
101
+ end
102
+ expect(rows.size).to eq 11
103
+ expect(rows[2].attributes["r"].value).to eq "3"
104
+ end
105
+ end
106
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,5 @@
1
- require File.expand_path("../../lib/roo", __FILE__)
1
+ require 'simplecov'
2
+ require 'roo'
2
3
 
3
4
  require 'vcr'
4
5