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
data/spec/lib/roo/base_spec.rb
CHANGED
@@ -127,10 +127,22 @@ describe Roo::Base do
|
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
|
-
describe
|
131
|
-
it
|
130
|
+
describe "#row" do
|
131
|
+
it "should return the specified row" do
|
132
132
|
expect(spreadsheet.row(12)).to eq([41.0, 42.0, 43.0, 44.0, 45.0, nil, nil])
|
133
|
-
expect(spreadsheet.row(16)).to eq([nil, '"Hello world!"',
|
133
|
+
expect(spreadsheet.row(16)).to eq([nil, '"Hello world!"', "forty-three", "forty-four", "forty-five", nil, nil])
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should return the specified row if default_sheet is set by a string" do
|
137
|
+
spreadsheet.default_sheet = "my_sheet"
|
138
|
+
expect(spreadsheet.row(12)).to eq([41.0, 42.0, 43.0, 44.0, 45.0, nil, nil])
|
139
|
+
expect(spreadsheet.row(16)).to eq([nil, '"Hello world!"', "forty-three", "forty-four", "forty-five", nil, nil])
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should return the specified row if default_sheet is set by an integer" do
|
143
|
+
spreadsheet.default_sheet = 0
|
144
|
+
expect(spreadsheet.row(12)).to eq([41.0, 42.0, 43.0, 44.0, 45.0, nil, nil])
|
145
|
+
expect(spreadsheet.row(16)).to eq([nil, '"Hello world!"', "forty-three", "forty-four", "forty-five", nil, nil])
|
134
146
|
end
|
135
147
|
end
|
136
148
|
|
@@ -146,6 +158,11 @@ describe Roo::Base do
|
|
146
158
|
expect { spreadsheet.row_with([/Missing Header/]) }.to \
|
147
159
|
raise_error(Roo::HeaderRowNotFoundError)
|
148
160
|
end
|
161
|
+
|
162
|
+
it 'returns missing headers' do
|
163
|
+
expect { spreadsheet.row_with([/Header/, /Missing Header 1/, /Missing Header 2/]) }.to \
|
164
|
+
raise_error(Roo::HeaderRowNotFoundError, '[/Missing Header 1/, /Missing Header 2/]')
|
165
|
+
end
|
149
166
|
end
|
150
167
|
end
|
151
168
|
|
@@ -165,6 +182,26 @@ describe Roo::Base do
|
|
165
182
|
end
|
166
183
|
end
|
167
184
|
|
185
|
+
describe '#each_with_pagename' do
|
186
|
+
context 'when block given' do
|
187
|
+
it 'iterate with sheet and sheet_name' do
|
188
|
+
sheet_names = []
|
189
|
+
spreadsheet.each_with_pagename do |sheet_name, sheet|
|
190
|
+
sheet_names << sheet_name
|
191
|
+
end
|
192
|
+
expect(sheet_names).to eq ['my_sheet', 'blank sheet']
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context 'when called without block' do
|
197
|
+
it 'should return an enumerator with all the rows' do
|
198
|
+
each_with_pagename = spreadsheet.each_with_pagename
|
199
|
+
expect(each_with_pagename).to be_a(Enumerator)
|
200
|
+
expect(each_with_pagename.to_a.last).to eq([spreadsheet.default_sheet, spreadsheet])
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
168
205
|
describe '#each' do
|
169
206
|
it 'should return an enumerator with all the rows' do
|
170
207
|
each = spreadsheet.each
|
@@ -173,6 +210,31 @@ describe Roo::Base do
|
|
173
210
|
end
|
174
211
|
end
|
175
212
|
|
213
|
+
describe "#default_sheet=" do
|
214
|
+
it "should correctly set the default sheet if passed a string" do
|
215
|
+
spreadsheet.default_sheet = "my_sheet"
|
216
|
+
expect(spreadsheet.default_sheet).to eq("my_sheet")
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should correctly set the default sheet if passed an integer" do
|
220
|
+
spreadsheet.default_sheet = 0
|
221
|
+
expect(spreadsheet.default_sheet).to eq("my_sheet")
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should correctly set the default sheet if passed an integer for the second sheet" do
|
225
|
+
spreadsheet.default_sheet = 1
|
226
|
+
expect(spreadsheet.default_sheet).to eq("blank sheet")
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should raise an error if passed a sheet that does not exist as an integer" do
|
230
|
+
expect { spreadsheet.default_sheet = 10 }.to raise_error RangeError
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should raise an error if passed a sheet that does not exist as a string" do
|
234
|
+
expect { spreadsheet.default_sheet = "does_not_exist" }.to raise_error RangeError
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
176
238
|
describe '#to_yaml' do
|
177
239
|
it 'should convert the spreadsheet to yaml' do
|
178
240
|
expect(spreadsheet.to_yaml({}, 5, 1, 5, 1)).to eq("--- \n" + yaml_entry(5, 1, 'date', '1961-11-21'))
|
data/spec/lib/roo/csv_spec.rb
CHANGED
@@ -10,6 +10,13 @@ describe Roo::CSV do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
describe '.new with stream' do
|
14
|
+
let(:csv) { Roo::CSV.new(File.read(path)) }
|
15
|
+
it 'creates an instance' do
|
16
|
+
expect(csv).to be_a(Roo::CSV)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
13
20
|
describe '#parse' do
|
14
21
|
subject do
|
15
22
|
csv.parse(options)
|
@@ -59,4 +66,16 @@ describe Roo::CSV do
|
|
59
66
|
end
|
60
67
|
end
|
61
68
|
end
|
69
|
+
|
70
|
+
describe '#set_value' do
|
71
|
+
it 'returns the cell value' do
|
72
|
+
expect(csv.set_value('A', 1, 'some-value', nil)).to eq('some-value')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#set_type' do
|
77
|
+
it 'returns the cell type' do
|
78
|
+
expect(csv.set_type('A', 1, 'some-type', nil)).to eq('some-type')
|
79
|
+
end
|
80
|
+
end
|
62
81
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Roo::Excelx::Cell::Time do
|
4
|
+
it "should set the cell value to the correct number of seconds" do
|
5
|
+
value = 0.05513888888888888 # '1:19:24'
|
6
|
+
excelx_type = [:numeric_or_formula, "h:mm:ss"]
|
7
|
+
base_timestamp = Date.new(1899, 12, 30).to_time.to_i
|
8
|
+
time_cell = Roo::Excelx::Cell::Time.new(value, nil, excelx_type, 1, nil, base_timestamp, nil)
|
9
|
+
expect(time_cell.value).to eq(1*60*60 + 19*60 + 24) # '1:19:24' in seconds
|
10
|
+
# use case from https://github.com/roo-rb/roo/issues/310
|
11
|
+
value = 0.523761574074074 # '12:34:13' in seconds
|
12
|
+
time_cell = Roo::Excelx::Cell::Time.new(value, nil, excelx_type, 1, nil, base_timestamp, nil)
|
13
|
+
expect(time_cell.value).to eq(12*60*60 + 34*60 + 13) # 12:34:13 in seconds
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Roo::Excelx::Relationships do
|
6
|
+
subject(:relationships) { Roo::Excelx::Relationships.new Roo::Excelx.new(path).rels_files[0] }
|
7
|
+
|
8
|
+
describe "#include_type?" do
|
9
|
+
[
|
10
|
+
["with hyperlink type", "test/files/link.xlsx", true, false],
|
11
|
+
["with nil path", "test/files/Bibelbund.xlsx", false, false],
|
12
|
+
["with comments type", "test/files/comments-google.xlsx", false, true],
|
13
|
+
].each do |context_desc, file_path, hyperlink_value, comments_value|
|
14
|
+
context context_desc do
|
15
|
+
let(:path) { file_path }
|
16
|
+
|
17
|
+
it "should return #{hyperlink_value} for hyperlink" do
|
18
|
+
expect(subject.include_type?("hyperlink")).to be hyperlink_value
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return #{hyperlink_value} for link" do
|
22
|
+
expect(subject.include_type?("link")).to be hyperlink_value
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return false for hypelink" do
|
26
|
+
expect(subject.include_type?("hypelink")).to be false
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return false for coment" do
|
30
|
+
expect(subject.include_type?("coment")).to be false
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return #{comments_value} for comments" do
|
34
|
+
expect(subject.include_type?("comments")).to be comments_value
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return #{comments_value} for comment" do
|
38
|
+
expect(subject.include_type?("comment")).to be comments_value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/spec/lib/roo/excelx_spec.rb
CHANGED
@@ -6,6 +6,18 @@ describe Roo::Excelx do
|
|
6
6
|
Roo::Excelx.new(path)
|
7
7
|
end
|
8
8
|
|
9
|
+
describe 'Constants' do
|
10
|
+
describe 'ERROR_VALUES' do
|
11
|
+
it 'returns all possible errorr values' do
|
12
|
+
expect(described_class::ERROR_VALUES).to eq(%w(#N/A #REF! #NAME? #DIV/0! #NULL! #VALUE! #NUM!).to_set)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'is a set' do
|
16
|
+
expect(described_class::ERROR_VALUES).to be_an_instance_of(Set)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
9
21
|
describe '.new' do
|
10
22
|
let(:path) { 'test/files/numeric-link.xlsx' }
|
11
23
|
|
@@ -44,7 +56,6 @@ describe Roo::Excelx do
|
|
44
56
|
expect(subject).to be_a(Roo::Excelx)
|
45
57
|
end
|
46
58
|
end
|
47
|
-
|
48
59
|
end
|
49
60
|
|
50
61
|
describe '#cell' do
|
@@ -75,6 +86,14 @@ describe Roo::Excelx do
|
|
75
86
|
end
|
76
87
|
end
|
77
88
|
|
89
|
+
describe 'for a workbook with hidden sheets' do
|
90
|
+
let(:path) { 'test/files/hidden_sheets.xlsx' }
|
91
|
+
|
92
|
+
it 'returns the cell contents from the visible sheet' do
|
93
|
+
expect(Roo::Excelx.new(path, only_visible_sheets: true).cell('A', 1)).to eq "visible sheet 1"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
78
97
|
describe '#parse' do
|
79
98
|
let(:path) { 'test/files/numeric-link.xlsx' }
|
80
99
|
|
@@ -140,6 +159,22 @@ describe Roo::Excelx do
|
|
140
159
|
it 'returns the expected result' do
|
141
160
|
expect(subject.sheet_for("Tabelle1").instance_variable_get("@name")).to eq "Tabelle1"
|
142
161
|
end
|
162
|
+
|
163
|
+
it 'returns the expected result when passed a number' do
|
164
|
+
expect(subject.sheet_for(0).instance_variable_get("@name")).to eq "Tabelle1"
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'returns the expected result when passed a number that is not the first sheet' do
|
168
|
+
expect(subject.sheet_for(1).instance_variable_get("@name")).to eq "Name of Sheet 2"
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should raise an error if passed a sheet that does not exist as an integer" do
|
172
|
+
expect { subject.sheet_for(10) }.to raise_error RangeError
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should raise an error if passed a sheet that does not exist as a string" do
|
176
|
+
expect { subject.sheet_for("does_not_exist") }.to raise_error RangeError
|
177
|
+
end
|
143
178
|
end
|
144
179
|
|
145
180
|
describe '#row' do
|
@@ -283,6 +318,52 @@ describe Roo::Excelx do
|
|
283
318
|
end
|
284
319
|
end
|
285
320
|
|
321
|
+
describe '#formatted_value' do
|
322
|
+
context 'contains zero-padded numbers' do
|
323
|
+
let(:path) { 'test/files/zero-padded-number.xlsx' }
|
324
|
+
|
325
|
+
it 'returns a zero-padded number' do
|
326
|
+
expect(subject.formatted_value(4, 1)).to eq '05010'
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
context 'contains US currency' do
|
331
|
+
let(:path) { 'test/files/currency-us.xlsx' }
|
332
|
+
|
333
|
+
it 'returns a zero-padded number' do
|
334
|
+
expect(subject.formatted_value(4, 1)).to eq '$20.51'
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
context 'contains euro currency' do
|
339
|
+
let(:path) { 'test/files/currency-euro.xlsx' }
|
340
|
+
|
341
|
+
it 'returns a zero-padded number' do
|
342
|
+
expect(subject.formatted_value(4, 1)).to eq '€20.51'
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
context 'contains uk currency' do
|
347
|
+
let(:path) { 'test/files/currency-uk.xlsx' }
|
348
|
+
|
349
|
+
it 'returns a zero-padded number' do
|
350
|
+
expect(subject.formatted_value(4, 1)).to eq '£20.51'
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
describe '#row' do
|
356
|
+
context 'integers with leading zero'
|
357
|
+
let(:path) { 'test/files/number_with_zero_prefix.xlsx' }
|
358
|
+
|
359
|
+
it 'returns base 10 integer' do
|
360
|
+
(1..50).each do |row_index|
|
361
|
+
range_start = (row_index - 1) * 20 + 1
|
362
|
+
expect(subject.row(row_index)).to eq (range_start..(range_start+19)).to_a
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
286
367
|
describe '#excelx_format' do
|
287
368
|
let(:path) { 'test/files/style.xlsx' }
|
288
369
|
|
@@ -330,14 +411,50 @@ describe Roo::Excelx do
|
|
330
411
|
expect(subject.hyperlink?(1, 1)).to eq true
|
331
412
|
expect(subject.hyperlink?(1, 2)).to eq false
|
332
413
|
end
|
414
|
+
|
415
|
+
context 'defined on cell range' do
|
416
|
+
let(:path) { 'test/files/cell-range-link.xlsx' }
|
417
|
+
|
418
|
+
it 'returns the expected result' do
|
419
|
+
[[false]*3, *[[true, true, false]]*4, [false]*3].each.with_index(1) do |row, row_index|
|
420
|
+
row.each.with_index(1) do |value, col_index|
|
421
|
+
expect(subject.hyperlink?(row_index, col_index)).to eq(value)
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
333
426
|
end
|
334
427
|
|
335
428
|
describe '#hyperlink' do
|
336
|
-
|
429
|
+
context 'defined on cell range' do
|
430
|
+
let(:path) { 'test/files/cell-range-link.xlsx' }
|
337
431
|
|
338
|
-
|
339
|
-
|
340
|
-
|
432
|
+
it 'returns the expected result' do
|
433
|
+
link = "http://www.google.com"
|
434
|
+
[[nil]*3, *[[link, link, nil]]*4, [nil]*3].each.with_index(1) do |row, row_index|
|
435
|
+
row.each.with_index(1) do |value, col_index|
|
436
|
+
expect(subject.hyperlink(row_index, col_index)).to eq(value)
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
context 'without location' do
|
443
|
+
let(:path) { 'test/files/link.xlsx' }
|
444
|
+
|
445
|
+
it 'returns the expected result' do
|
446
|
+
expect(subject.hyperlink(1, 1)).to eq "http://www.google.com"
|
447
|
+
expect(subject.hyperlink(1, 2)).to eq nil
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
context 'with location' do
|
452
|
+
let(:path) { 'test/files/link_with_location.xlsx' }
|
453
|
+
|
454
|
+
it 'returns the expected result' do
|
455
|
+
expect(subject.hyperlink(1, 1)).to eq "http://www.google.com/#hey"
|
456
|
+
expect(subject.hyperlink(1, 2)).to eq nil
|
457
|
+
end
|
341
458
|
end
|
342
459
|
end
|
343
460
|
|
@@ -458,10 +575,125 @@ describe Roo::Excelx do
|
|
458
575
|
end
|
459
576
|
end
|
460
577
|
|
578
|
+
describe '#html_strings' do
|
579
|
+
describe "HTML Parsing Enabling" do
|
580
|
+
let(:path) { 'test/files/html_strings_formatting.xlsx' }
|
581
|
+
|
582
|
+
it 'returns the expected result' do
|
583
|
+
expect(subject.excelx_value(1, 1, "Sheet1")).to eq("This has no formatting.")
|
584
|
+
expect(subject.excelx_value(2, 1, "Sheet1")).to eq("<html>This has<b> bold </b>formatting.</html>")
|
585
|
+
expect(subject.excelx_value(2, 2, "Sheet1")).to eq("<html>This has <i>italics</i> formatting.</html>")
|
586
|
+
expect(subject.excelx_value(2, 3, "Sheet1")).to eq("<html>This has <u>underline</u> format.</html>")
|
587
|
+
expect(subject.excelx_value(2, 4, "Sheet1")).to eq("<html>Superscript. x<sup>123</sup></html>")
|
588
|
+
expect(subject.excelx_value(2, 5, "Sheet1")).to eq("<html>SubScript. T<sub>j</sub></html>")
|
589
|
+
|
590
|
+
expect(subject.excelx_value(3, 1, "Sheet1")).to eq("<html>Bold, italics <b><i>together</i></b>.</html>")
|
591
|
+
expect(subject.excelx_value(3, 2, "Sheet1")).to eq("<html>Bold, Underline <b><u>together</u></b>.</html>")
|
592
|
+
expect(subject.excelx_value(3, 3, "Sheet1")).to eq("<html>Bold, Superscript. <b>x</b><sup><b>N</b></sup></html>")
|
593
|
+
expect(subject.excelx_value(3, 4, "Sheet1")).to eq("<html>Bold, Subscript. <b>T</b><sub><b>abc</b></sub></html>")
|
594
|
+
expect(subject.excelx_value(3, 5, "Sheet1")).to eq("<html>Italics, Underline <i><u>together</u></i>.</html>")
|
595
|
+
expect(subject.excelx_value(3, 6, "Sheet1")).to eq("<html>Italics, Superscript. <i>X</i><sup><i>abc</i></sup></html>")
|
596
|
+
expect(subject.excelx_value(3, 7, "Sheet1")).to eq("<html>Italics, Subscript. <i>B</i><sub><i>efg</i></sub></html>")
|
597
|
+
expect(subject.excelx_value(4, 1, "Sheet1")).to eq("<html>Bold, italics underline,<b><i><u> together</u></i></b>.</html>")
|
598
|
+
expect(subject.excelx_value(4, 2, "Sheet1")).to eq("<html>Bold, italics, superscript. <b>X</b><sup><b><i>abc</i></b></sup><b><i>123</i></b></html>")
|
599
|
+
expect(subject.excelx_value(4, 3, "Sheet1")).to eq("<html>Bold, Italics, subscript. <b><i>Mg</i></b><sub><b><i>ha</i></b></sub><b><i>2</i></b></html>")
|
600
|
+
expect(subject.excelx_value(4, 4, "Sheet1")).to eq("<html>Bold, Underline, superscript. <b><u>AB</u></b><sup><b><u>C12</u></b></sup><b><u>3</u></b></html>")
|
601
|
+
expect(subject.excelx_value(4, 5, "Sheet1")).to eq("<html>Bold, Underline, subscript. <b><u>Good</u></b><sub><b><u>XYZ</u></b></sub></html>")
|
602
|
+
expect(subject.excelx_value(4, 6, "Sheet1")).to eq("<html>Italics, Underline, superscript. <i><u>Up</u></i><sup><i><u>swing</u></i></sup></html>")
|
603
|
+
expect(subject.excelx_value(4, 7, "Sheet1")).to eq("<html>Italics, Underline, subscript. <i><u>T</u></i><sub><i><u>swing</u></i></sub></html>")
|
604
|
+
expect(subject.excelx_value(5, 1, "Sheet1")).to eq("<html>Bold, italics, underline, superscript. <b><i><u>GHJK</u></i></b><sup><b><i><u>190</u></i></b></sup><b><i><u>4</u></i></b></html>")
|
605
|
+
expect(subject.excelx_value(5, 2, "Sheet1")).to eq("<html>Bold, italics, underline, subscript. <b><i><u>Mike</u></i></b><sub><b><i><u>drop</u></i></b></sub></html>")
|
606
|
+
expect(subject.excelx_value(6, 1, "Sheet1")).to eq("See that regular html tags do not create html tags.\n<ol>\n <li> Denver Broncos </li>\n <li> Carolina Panthers </li>\n <li> New England Patriots</li>\n <li>Arizona Panthers</li>\n</ol>")
|
607
|
+
expect(subject.excelx_value(7, 1, "Sheet1")).to eq("<html>Does create html tags when formatting is used..\n<ol>\n <li> <b>Denver Broncos</b> </li>\n <li> <i>Carolina Panthers </i></li>\n <li> <u>New England Patriots</u></li>\n <li>Arizona Panthers</li>\n</ol></html>")
|
608
|
+
end
|
609
|
+
end
|
610
|
+
end
|
611
|
+
|
461
612
|
describe '_x000D_' do
|
462
613
|
let(:path) { 'test/files/x000D.xlsx' }
|
463
614
|
it 'does not contain _x000D_' do
|
464
615
|
expect(subject.cell(2, 9)).not_to include('_x000D_')
|
465
616
|
end
|
466
617
|
end
|
618
|
+
|
619
|
+
describe 'opening a file with a chart sheet' do
|
620
|
+
let(:path) { 'test/files/chart_sheet.xlsx' }
|
621
|
+
it 'should not raise' do
|
622
|
+
expect{ subject }.to_not raise_error
|
623
|
+
end
|
624
|
+
end
|
625
|
+
|
626
|
+
describe 'opening a file with white space in the styles.xml' do
|
627
|
+
let(:path) { 'test/files/style_nodes_with_white_spaces.xlsx' }
|
628
|
+
subject(:xlsx) do
|
629
|
+
Roo::Spreadsheet.open(path, expand_merged_ranges: true, extension: :xlsx)
|
630
|
+
end
|
631
|
+
it 'should properly recognize formats' do
|
632
|
+
expect(subject.sheet(0).excelx_format(2,1)).to eq 'm/d/yyyy" "h:mm:ss" "AM/PM'
|
633
|
+
end
|
634
|
+
end
|
635
|
+
|
636
|
+
describe 'opening a file with filters' do
|
637
|
+
let(:path) { 'test/files/wrong_coordinates.xlsx' }
|
638
|
+
subject(:xlsx) do
|
639
|
+
Roo::Spreadsheet.open(path)
|
640
|
+
end
|
641
|
+
|
642
|
+
it 'should properly extract defined_names' do
|
643
|
+
expect(subject.sheet(0).workbook.defined_names.length).to eq(1)
|
644
|
+
end
|
645
|
+
end
|
646
|
+
|
647
|
+
describe 'images' do
|
648
|
+
let(:path) { 'test/files/images.xlsx' }
|
649
|
+
|
650
|
+
it 'returns array of images from default sheet' do
|
651
|
+
expect(subject.images).to be_kind_of(Array)
|
652
|
+
expect(subject.images.size).to eql(19)
|
653
|
+
end
|
654
|
+
|
655
|
+
it 'returns empty array if there is no images on the sheet' do
|
656
|
+
expect(subject.images("Sheet2")).to eql([])
|
657
|
+
end
|
658
|
+
end
|
659
|
+
end
|
660
|
+
|
661
|
+
describe 'Roo::Excelx with options set' do
|
662
|
+
subject(:xlsx) do
|
663
|
+
Roo::Excelx.new(path, disable_html_wrapper: true)
|
664
|
+
end
|
665
|
+
|
666
|
+
describe '#html_strings' do
|
667
|
+
describe "HTML Parsing Disabled" do
|
668
|
+
let(:path) { 'test/files/html_strings_formatting.xlsx' }
|
669
|
+
|
670
|
+
it 'returns the expected result' do
|
671
|
+
expect(subject.excelx_value(1, 1, "Sheet1")).to eq("This has no formatting.")
|
672
|
+
expect(subject.excelx_value(2, 1, "Sheet1")).to eq("This has bold formatting.")
|
673
|
+
expect(subject.excelx_value(2, 2, "Sheet1")).to eq("This has italics formatting.")
|
674
|
+
expect(subject.excelx_value(2, 3, "Sheet1")).to eq("This has underline format.")
|
675
|
+
expect(subject.excelx_value(2, 4, "Sheet1")).to eq("Superscript. x123")
|
676
|
+
expect(subject.excelx_value(2, 5, "Sheet1")).to eq("SubScript. Tj")
|
677
|
+
|
678
|
+
expect(subject.excelx_value(3, 1, "Sheet1")).to eq("Bold, italics together.")
|
679
|
+
expect(subject.excelx_value(3, 2, "Sheet1")).to eq("Bold, Underline together.")
|
680
|
+
expect(subject.excelx_value(3, 3, "Sheet1")).to eq("Bold, Superscript. xN")
|
681
|
+
expect(subject.excelx_value(3, 4, "Sheet1")).to eq("Bold, Subscript. Tabc")
|
682
|
+
expect(subject.excelx_value(3, 5, "Sheet1")).to eq("Italics, Underline together.")
|
683
|
+
expect(subject.excelx_value(3, 6, "Sheet1")).to eq("Italics, Superscript. Xabc")
|
684
|
+
expect(subject.excelx_value(3, 7, "Sheet1")).to eq("Italics, Subscript. Befg")
|
685
|
+
expect(subject.excelx_value(4, 1, "Sheet1")).to eq("Bold, italics underline, together.")
|
686
|
+
expect(subject.excelx_value(4, 2, "Sheet1")).to eq("Bold, italics, superscript. Xabc123")
|
687
|
+
expect(subject.excelx_value(4, 3, "Sheet1")).to eq("Bold, Italics, subscript. Mgha2")
|
688
|
+
expect(subject.excelx_value(4, 4, "Sheet1")).to eq("Bold, Underline, superscript. ABC123")
|
689
|
+
expect(subject.excelx_value(4, 5, "Sheet1")).to eq("Bold, Underline, subscript. GoodXYZ")
|
690
|
+
expect(subject.excelx_value(4, 6, "Sheet1")).to eq("Italics, Underline, superscript. Upswing")
|
691
|
+
expect(subject.excelx_value(4, 7, "Sheet1")).to eq("Italics, Underline, subscript. Tswing")
|
692
|
+
expect(subject.excelx_value(5, 1, "Sheet1")).to eq("Bold, italics, underline, superscript. GHJK1904")
|
693
|
+
expect(subject.excelx_value(5, 2, "Sheet1")).to eq("Bold, italics, underline, subscript. Mikedrop")
|
694
|
+
expect(subject.excelx_value(6, 1, "Sheet1")).to eq("See that regular html tags do not create html tags.\n<ol>\n <li> Denver Broncos </li>\n <li> Carolina Panthers </li>\n <li> New England Patriots</li>\n <li>Arizona Panthers</li>\n</ol>")
|
695
|
+
expect(subject.excelx_value(7, 1, "Sheet1")).to eq("Does create html tags when formatting is used..\n<ol>\n <li> Denver Broncos </li>\n <li> Carolina Panthers </li>\n <li> New England Patriots</li>\n <li>Arizona Panthers</li>\n</ol>")
|
696
|
+
end
|
697
|
+
end
|
698
|
+
end
|
467
699
|
end
|
@@ -13,10 +13,10 @@ describe Roo::OpenOffice do
|
|
13
13
|
context 'for float/integer values' do
|
14
14
|
context 'integer without point' do
|
15
15
|
it { expect(subject.cell(3,"A","Sheet4")).to eq(1234) }
|
16
|
-
it { expect(subject.cell(3,"A","Sheet4")).to be_a(
|
16
|
+
it { expect(subject.cell(3,"A","Sheet4")).to be_a(Integer) }
|
17
17
|
end
|
18
18
|
|
19
|
-
context 'float with point' do
|
19
|
+
context 'float with point' do
|
20
20
|
it { expect(subject.cell(3,"B","Sheet4")).to eq(1234.00) }
|
21
21
|
it { expect(subject.cell(3,"B","Sheet4")).to be_a(Float) }
|
22
22
|
end
|
@@ -25,7 +25,7 @@ describe Roo::Spreadsheet do
|
|
25
25
|
let(:filename) { tempfile.path }
|
26
26
|
|
27
27
|
it 'loads the proper type' do
|
28
|
-
expect(Roo::CSV).to receive(:new).with(filename, file_warning: :ignore).and_call_original
|
28
|
+
expect(Roo::CSV).to receive(:new).with(filename, {file_warning: :ignore}).and_call_original
|
29
29
|
expect(Roo::Spreadsheet.open(tempfile, extension: :csv)).to be_a(Roo::CSV)
|
30
30
|
end
|
31
31
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Roo::Excelx do
|
4
|
+
subject { Roo::Excelx.new('test/files/strict.xlsx') }
|
5
|
+
|
6
|
+
example '#sheets' do
|
7
|
+
expect(subject.sheets).to eq %w(Sheet1 Sheet2)
|
8
|
+
end
|
9
|
+
|
10
|
+
example '#sheet' do
|
11
|
+
expect(subject.sheet('Sheet1')).to be_a(Roo::Excelx)
|
12
|
+
end
|
13
|
+
|
14
|
+
example '#cell' do
|
15
|
+
expect(subject.cell(1, 1)).to eq 'Sheet 1'
|
16
|
+
expect(subject.cell(1, 1, 'Sheet2')).to eq 'Sheet 2'
|
17
|
+
end
|
18
|
+
|
19
|
+
example '#row' do
|
20
|
+
expect(subject.row(1)).to eq ['Sheet 1']
|
21
|
+
expect(subject.row(1, 'Sheet2')).to eq ['Sheet 2']
|
22
|
+
end
|
23
|
+
|
24
|
+
example '#first_row' do
|
25
|
+
expect(subject.first_row).to eq 1
|
26
|
+
expect(subject.first_row('Sheet2')).to eq 1
|
27
|
+
end
|
28
|
+
|
29
|
+
example '#last_row' do
|
30
|
+
expect(subject.last_row).to eq 1
|
31
|
+
expect(subject.last_row('Sheet2')).to eq 1
|
32
|
+
end
|
33
|
+
|
34
|
+
example '#first_column' do
|
35
|
+
expect(subject.first_column).to eq 1
|
36
|
+
expect(subject.first_column('Sheet2')).to eq 1
|
37
|
+
end
|
38
|
+
|
39
|
+
example '#last_column' do
|
40
|
+
expect(subject.last_column).to eq 1
|
41
|
+
expect(subject.last_column('Sheet2')).to eq 1
|
42
|
+
end
|
43
|
+
end
|
data/spec/lib/roo/utils_spec.rb
CHANGED
@@ -4,7 +4,7 @@ RSpec.describe ::Roo::Utils do
|
|
4
4
|
subject { described_class }
|
5
5
|
|
6
6
|
context '#number_to_letter' do
|
7
|
-
|
7
|
+
described_class::LETTERS.each_with_index do |letter, index|
|
8
8
|
it "should return '#{ letter }' when passed #{ index + 1 }" do
|
9
9
|
expect(described_class.number_to_letter(index + 1)).to eq(letter)
|
10
10
|
end
|
@@ -43,12 +43,12 @@ RSpec.describe ::Roo::Utils do
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
context '.
|
46
|
+
context '.extract_coordinate' do
|
47
47
|
it "returns the expected result" do
|
48
|
-
expect(described_class.
|
49
|
-
expect(described_class.
|
50
|
-
expect(described_class.
|
51
|
-
expect(described_class.
|
48
|
+
expect(described_class.extract_coordinate('A1')).to eq [1, 1]
|
49
|
+
expect(described_class.extract_coordinate('B2')).to eq [2, 2]
|
50
|
+
expect(described_class.extract_coordinate('R2')).to eq [2, 18]
|
51
|
+
expect(described_class.extract_coordinate('AR31')).to eq [31, 18 + 26]
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -81,26 +81,39 @@ RSpec.describe ::Roo::Utils do
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
+
context '.coordinates_in_range' do
|
85
|
+
it "returns the expected result" do
|
86
|
+
expect(described_class.coordinates_in_range('').to_a).to eq []
|
87
|
+
expect(described_class.coordinates_in_range('B2').to_a).to eq [[2, 2]]
|
88
|
+
expect(described_class.coordinates_in_range('D2:G3').to_a).to eq [[2, 4], [2, 5], [2, 6], [2, 7], [3, 4], [3, 5], [3, 6], [3, 7]]
|
89
|
+
expect(described_class.coordinates_in_range('G3:D2').to_a).to eq []
|
90
|
+
end
|
91
|
+
|
92
|
+
it "raises an error when appropriate" do
|
93
|
+
expect { described_class.coordinates_in_range('D2:G3:I5').to_a }.to raise_error(ArgumentError)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
84
97
|
context '.load_xml' do
|
85
98
|
it 'returns the expected result' do
|
86
99
|
expect(described_class.load_xml('test/files/sheet1.xml')).to be_a(Nokogiri::XML::Document)
|
87
100
|
expect(described_class.load_xml('test/files/sheet1.xml').
|
88
101
|
remove_namespaces!.xpath("/worksheet/dimension").map do |dim|
|
89
|
-
dim
|
102
|
+
dim["ref"] end.first).to eq "A1:B11"
|
90
103
|
end
|
91
104
|
end
|
92
105
|
|
93
106
|
context '.each_element' do
|
94
107
|
it 'returns the expected result' do
|
95
108
|
described_class.each_element('test/files/sheet1.xml', 'dimension') do |dim|
|
96
|
-
expect(dim
|
109
|
+
expect(dim["ref"]).to eq "A1:B11"
|
97
110
|
end
|
98
111
|
rows = []
|
99
112
|
described_class.each_element('test/files/sheet1.xml', 'row') do |row|
|
100
113
|
rows << row
|
101
114
|
end
|
102
115
|
expect(rows.size).to eq 11
|
103
|
-
expect(rows[2]
|
116
|
+
expect(rows[2]["r"]).to eq "3"
|
104
117
|
end
|
105
118
|
end
|
106
119
|
end
|