roo 2.7.0 → 2.8.3
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/.github/issue_template.md +16 -0
- data/.github/pull_request_template.md +14 -0
- data/.rubocop.yml +186 -0
- data/.travis.yml +12 -7
- data/CHANGELOG.md +53 -2
- data/LICENSE +2 -0
- data/README.md +29 -13
- data/lib/roo/base.rb +69 -61
- data/lib/roo/constants.rb +5 -3
- data/lib/roo/csv.rb +20 -12
- 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 +14 -18
- data/lib/roo/excelx/cell/empty.rb +3 -2
- data/lib/roo/excelx/cell/number.rb +35 -34
- data/lib/roo/excelx/cell/string.rb +3 -3
- data/lib/roo/excelx/cell/time.rb +4 -3
- data/lib/roo/excelx/cell.rb +10 -6
- data/lib/roo/excelx/comments.rb +3 -3
- data/lib/roo/excelx/coordinate.rb +11 -4
- data/lib/roo/excelx/extractor.rb +21 -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 +9 -15
- data/lib/roo/excelx/sheet.rb +49 -10
- data/lib/roo/excelx/sheet_doc.rb +89 -48
- data/lib/roo/excelx/styles.rb +3 -3
- data/lib/roo/excelx/workbook.rb +7 -3
- data/lib/roo/excelx.rb +42 -16
- 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 +8 -6
- data/lib/roo/spreadsheet.rb +1 -1
- data/lib/roo/utils.rb +70 -20
- data/lib/roo/version.rb +1 -1
- data/lib/roo.rb +4 -1
- data/roo.gemspec +13 -11
- data/spec/lib/roo/base_spec.rb +45 -3
- 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 +150 -31
- data/spec/lib/roo/strict_spec.rb +43 -0
- data/spec/lib/roo/utils_spec.rb +25 -3
- data/spec/lib/roo/weak_instance_cache_spec.rb +92 -0
- data/spec/lib/roo_spec.rb +0 -0
- data/spec/spec_helper.rb +1 -1
- data/test/excelx/cell/test_attr_reader_default.rb +72 -0
- data/test/excelx/cell/test_base.rb +5 -0
- data/test/excelx/cell/test_datetime.rb +6 -6
- data/test/excelx/cell/test_empty.rb +11 -0
- data/test/excelx/cell/test_number.rb +9 -0
- data/test/excelx/cell/test_string.rb +20 -0
- data/test/excelx/cell/test_time.rb +4 -4
- data/test/excelx/test_coordinate.rb +51 -0
- data/test/formatters/test_csv.rb +19 -2
- data/test/formatters/test_xml.rb +13 -9
- data/test/helpers/test_accessing_files.rb +60 -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 +37 -1
- data/test/roo/test_excelx.rb +157 -13
- data/test/roo/test_open_office.rb +196 -33
- data/test/test_helper.rb +66 -22
- data/test/test_roo.rb +32 -881
- metadata +32 -14
- data/.github/ISSUE_TEMPLATE +0 -10
- data/Gemfile_ruby2 +0 -30
data/lib/roo.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'roo/version'
|
1
4
|
require 'roo/constants'
|
2
5
|
require 'roo/errors'
|
3
6
|
require 'roo/spreadsheet'
|
@@ -9,7 +12,7 @@ module Roo
|
|
9
12
|
autoload :Excelx, 'roo/excelx'
|
10
13
|
autoload :CSV, 'roo/csv'
|
11
14
|
|
12
|
-
TEMP_PREFIX = 'roo_'
|
15
|
+
TEMP_PREFIX = 'roo_'
|
13
16
|
|
14
17
|
CLASS_FOR_EXTENSION = {
|
15
18
|
ods: Roo::OpenOffice,
|
data/roo.gemspec
CHANGED
@@ -4,21 +4,23 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'roo/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
spec.summary
|
12
|
-
spec.description
|
13
|
-
spec.homepage
|
14
|
-
spec.license
|
7
|
+
spec.name = 'roo'
|
8
|
+
spec.version = Roo::VERSION
|
9
|
+
spec.authors = ['Thomas Preymesser', 'Hugh McGowan', 'Ben Woosley', 'Oleksandr Simonov', 'Steven Daniels', 'Anmol Chopra']
|
10
|
+
spec.email = ['ruby.ruby.ruby.roo@gmail.com', 'oleksandr@simonov.me']
|
11
|
+
spec.summary = 'Roo can access the contents of various spreadsheet files.'
|
12
|
+
spec.description = "Roo can access the contents of various spreadsheet files. It can handle\n* OpenOffice\n* Excelx\n* LibreOffice\n* CSV"
|
13
|
+
spec.homepage = 'https://github.com/roo-rb/roo'
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
|
-
spec.files
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
17
|
spec.files.reject! { |fn| fn.include?('test/files') }
|
18
|
-
spec.require_paths
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
|
20
|
+
spec.required_ruby_version = ">= 2.3.0"
|
19
21
|
|
20
22
|
spec.add_dependency 'nokogiri', '~> 1'
|
21
|
-
spec.add_dependency 'rubyzip', '
|
23
|
+
spec.add_dependency 'rubyzip', '>= 1.3.0', '< 3.0.0'
|
22
24
|
|
23
25
|
spec.add_development_dependency 'rake', '~> 10.1'
|
24
26
|
spec.add_development_dependency 'minitest', '~> 5.4', '>= 5.4.3'
|
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
|
|
@@ -173,6 +190,31 @@ describe Roo::Base do
|
|
173
190
|
end
|
174
191
|
end
|
175
192
|
|
193
|
+
describe "#default_sheet=" do
|
194
|
+
it "should correctly set the default sheet if passed a string" do
|
195
|
+
spreadsheet.default_sheet = "my_sheet"
|
196
|
+
expect(spreadsheet.default_sheet).to eq("my_sheet")
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should correctly set the default sheet if passed an integer" do
|
200
|
+
spreadsheet.default_sheet = 0
|
201
|
+
expect(spreadsheet.default_sheet).to eq("my_sheet")
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should correctly set the default sheet if passed an integer for the second sheet" do
|
205
|
+
spreadsheet.default_sheet = 1
|
206
|
+
expect(spreadsheet.default_sheet).to eq("blank sheet")
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should raise an error if passed a sheet that does not exist as an integer" do
|
210
|
+
expect { spreadsheet.default_sheet = 10 }.to raise_error RangeError
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should raise an error if passed a sheet that does not exist as a string" do
|
214
|
+
expect { spreadsheet.default_sheet = "does_not_exist" }.to raise_error RangeError
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
176
218
|
describe '#to_yaml' do
|
177
219
|
it 'should convert the spreadsheet to yaml' do
|
178
220
|
expect(spreadsheet.to_yaml({}, 5, 1, 5, 1)).to eq("--- \n" + yaml_entry(5, 1, 'date', '1961-11-21'))
|
@@ -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
@@ -151,6 +151,22 @@ describe Roo::Excelx do
|
|
151
151
|
it 'returns the expected result' do
|
152
152
|
expect(subject.sheet_for("Tabelle1").instance_variable_get("@name")).to eq "Tabelle1"
|
153
153
|
end
|
154
|
+
|
155
|
+
it 'returns the expected result when passed a number' do
|
156
|
+
expect(subject.sheet_for(0).instance_variable_get("@name")).to eq "Tabelle1"
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'returns the expected result when passed a number that is not the first sheet' do
|
160
|
+
expect(subject.sheet_for(1).instance_variable_get("@name")).to eq "Name of Sheet 2"
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should raise an error if passed a sheet that does not exist as an integer" do
|
164
|
+
expect { subject.sheet_for(10) }.to raise_error RangeError
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should raise an error if passed a sheet that does not exist as a string" do
|
168
|
+
expect { subject.sheet_for("does_not_exist") }.to raise_error RangeError
|
169
|
+
end
|
154
170
|
end
|
155
171
|
|
156
172
|
describe '#row' do
|
@@ -304,6 +320,18 @@ describe Roo::Excelx do
|
|
304
320
|
end
|
305
321
|
end
|
306
322
|
|
323
|
+
describe '#row' do
|
324
|
+
context 'integers with leading zero'
|
325
|
+
let(:path) { 'test/files/number_with_zero_prefix.xlsx' }
|
326
|
+
|
327
|
+
it 'returns base 10 integer' do
|
328
|
+
(1..50).each do |row_index|
|
329
|
+
range_start = (row_index - 1) * 20 + 1
|
330
|
+
expect(subject.row(row_index)).to eq (range_start..(range_start+19)).to_a
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
307
335
|
describe '#excelx_format' do
|
308
336
|
let(:path) { 'test/files/style.xlsx' }
|
309
337
|
|
@@ -351,14 +379,50 @@ describe Roo::Excelx do
|
|
351
379
|
expect(subject.hyperlink?(1, 1)).to eq true
|
352
380
|
expect(subject.hyperlink?(1, 2)).to eq false
|
353
381
|
end
|
382
|
+
|
383
|
+
context 'defined on cell range' do
|
384
|
+
let(:path) { 'test/files/cell-range-link.xlsx' }
|
385
|
+
|
386
|
+
it 'returns the expected result' do
|
387
|
+
[[false]*3, *[[true, true, false]]*4, [false]*3].each.with_index(1) do |row, row_index|
|
388
|
+
row.each.with_index(1) do |value, col_index|
|
389
|
+
expect(subject.hyperlink?(row_index, col_index)).to eq(value)
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|
354
394
|
end
|
355
395
|
|
356
396
|
describe '#hyperlink' do
|
357
|
-
|
397
|
+
context 'defined on cell range' do
|
398
|
+
let(:path) { 'test/files/cell-range-link.xlsx' }
|
358
399
|
|
359
|
-
|
360
|
-
|
361
|
-
|
400
|
+
it 'returns the expected result' do
|
401
|
+
link = "http://www.google.com"
|
402
|
+
[[nil]*3, *[[link, link, nil]]*4, [nil]*3].each.with_index(1) do |row, row_index|
|
403
|
+
row.each.with_index(1) do |value, col_index|
|
404
|
+
expect(subject.hyperlink(row_index, col_index)).to eq(value)
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
context 'without location' do
|
411
|
+
let(:path) { 'test/files/link.xlsx' }
|
412
|
+
|
413
|
+
it 'returns the expected result' do
|
414
|
+
expect(subject.hyperlink(1, 1)).to eq "http://www.google.com"
|
415
|
+
expect(subject.hyperlink(1, 2)).to eq nil
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
context 'with location' do
|
420
|
+
let(:path) { 'test/files/link_with_location.xlsx' }
|
421
|
+
|
422
|
+
it 'returns the expected result' do
|
423
|
+
expect(subject.hyperlink(1, 1)).to eq "http://www.google.com/#hey"
|
424
|
+
expect(subject.hyperlink(1, 2)).to eq nil
|
425
|
+
end
|
362
426
|
end
|
363
427
|
end
|
364
428
|
|
@@ -480,34 +544,36 @@ describe Roo::Excelx do
|
|
480
544
|
end
|
481
545
|
|
482
546
|
describe '#html_strings' do
|
483
|
-
|
547
|
+
describe "HTML Parsing Enabling" do
|
548
|
+
let(:path) { 'test/files/html_strings_formatting.xlsx' }
|
484
549
|
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
550
|
+
it 'returns the expected result' do
|
551
|
+
expect(subject.excelx_value(1, 1, "Sheet1")).to eq("This has no formatting.")
|
552
|
+
expect(subject.excelx_value(2, 1, "Sheet1")).to eq("<html>This has<b> bold </b>formatting.</html>")
|
553
|
+
expect(subject.excelx_value(2, 2, "Sheet1")).to eq("<html>This has <i>italics</i> formatting.</html>")
|
554
|
+
expect(subject.excelx_value(2, 3, "Sheet1")).to eq("<html>This has <u>underline</u> format.</html>")
|
555
|
+
expect(subject.excelx_value(2, 4, "Sheet1")).to eq("<html>Superscript. x<sup>123</sup></html>")
|
556
|
+
expect(subject.excelx_value(2, 5, "Sheet1")).to eq("<html>SubScript. T<sub>j</sub></html>")
|
557
|
+
|
558
|
+
expect(subject.excelx_value(3, 1, "Sheet1")).to eq("<html>Bold, italics <b><i>together</i></b>.</html>")
|
559
|
+
expect(subject.excelx_value(3, 2, "Sheet1")).to eq("<html>Bold, Underline <b><u>together</u></b>.</html>")
|
560
|
+
expect(subject.excelx_value(3, 3, "Sheet1")).to eq("<html>Bold, Superscript. <b>x</b><sup><b>N</b></sup></html>")
|
561
|
+
expect(subject.excelx_value(3, 4, "Sheet1")).to eq("<html>Bold, Subscript. <b>T</b><sub><b>abc</b></sub></html>")
|
562
|
+
expect(subject.excelx_value(3, 5, "Sheet1")).to eq("<html>Italics, Underline <i><u>together</u></i>.</html>")
|
563
|
+
expect(subject.excelx_value(3, 6, "Sheet1")).to eq("<html>Italics, Superscript. <i>X</i><sup><i>abc</i></sup></html>")
|
564
|
+
expect(subject.excelx_value(3, 7, "Sheet1")).to eq("<html>Italics, Subscript. <i>B</i><sub><i>efg</i></sub></html>")
|
565
|
+
expect(subject.excelx_value(4, 1, "Sheet1")).to eq("<html>Bold, italics underline,<b><i><u> together</u></i></b>.</html>")
|
566
|
+
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>")
|
567
|
+
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>")
|
568
|
+
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>")
|
569
|
+
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>")
|
570
|
+
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>")
|
571
|
+
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>")
|
572
|
+
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>")
|
573
|
+
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>")
|
574
|
+
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>")
|
575
|
+
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>")
|
576
|
+
end
|
511
577
|
end
|
512
578
|
end
|
513
579
|
|
@@ -534,4 +600,57 @@ describe Roo::Excelx do
|
|
534
600
|
expect(subject.sheet(0).excelx_format(2,1)).to eq 'm/d/yyyy" "h:mm:ss" "AM/PM'
|
535
601
|
end
|
536
602
|
end
|
603
|
+
|
604
|
+
describe 'images' do
|
605
|
+
let(:path) { 'test/files/images.xlsx' }
|
606
|
+
|
607
|
+
it 'returns array of images from default sheet' do
|
608
|
+
expect(subject.images).to be_kind_of(Array)
|
609
|
+
expect(subject.images.size).to eql(19)
|
610
|
+
end
|
611
|
+
|
612
|
+
it 'returns empty array if there is no images on the sheet' do
|
613
|
+
expect(subject.images("Sheet2")).to eql([])
|
614
|
+
end
|
615
|
+
end
|
537
616
|
end
|
617
|
+
|
618
|
+
describe 'Roo::Excelx with options set' do
|
619
|
+
subject(:xlsx) do
|
620
|
+
Roo::Excelx.new(path, disable_html_wrapper: true)
|
621
|
+
end
|
622
|
+
|
623
|
+
describe '#html_strings' do
|
624
|
+
describe "HTML Parsing Disabled" do
|
625
|
+
let(:path) { 'test/files/html_strings_formatting.xlsx' }
|
626
|
+
|
627
|
+
it 'returns the expected result' do
|
628
|
+
expect(subject.excelx_value(1, 1, "Sheet1")).to eq("This has no formatting.")
|
629
|
+
expect(subject.excelx_value(2, 1, "Sheet1")).to eq("This has bold formatting.")
|
630
|
+
expect(subject.excelx_value(2, 2, "Sheet1")).to eq("This has italics formatting.")
|
631
|
+
expect(subject.excelx_value(2, 3, "Sheet1")).to eq("This has underline format.")
|
632
|
+
expect(subject.excelx_value(2, 4, "Sheet1")).to eq("Superscript. x123")
|
633
|
+
expect(subject.excelx_value(2, 5, "Sheet1")).to eq("SubScript. Tj")
|
634
|
+
|
635
|
+
expect(subject.excelx_value(3, 1, "Sheet1")).to eq("Bold, italics together.")
|
636
|
+
expect(subject.excelx_value(3, 2, "Sheet1")).to eq("Bold, Underline together.")
|
637
|
+
expect(subject.excelx_value(3, 3, "Sheet1")).to eq("Bold, Superscript. xN")
|
638
|
+
expect(subject.excelx_value(3, 4, "Sheet1")).to eq("Bold, Subscript. Tabc")
|
639
|
+
expect(subject.excelx_value(3, 5, "Sheet1")).to eq("Italics, Underline together.")
|
640
|
+
expect(subject.excelx_value(3, 6, "Sheet1")).to eq("Italics, Superscript. Xabc")
|
641
|
+
expect(subject.excelx_value(3, 7, "Sheet1")).to eq("Italics, Subscript. Befg")
|
642
|
+
expect(subject.excelx_value(4, 1, "Sheet1")).to eq("Bold, italics underline, together.")
|
643
|
+
expect(subject.excelx_value(4, 2, "Sheet1")).to eq("Bold, italics, superscript. Xabc123")
|
644
|
+
expect(subject.excelx_value(4, 3, "Sheet1")).to eq("Bold, Italics, subscript. Mgha2")
|
645
|
+
expect(subject.excelx_value(4, 4, "Sheet1")).to eq("Bold, Underline, superscript. ABC123")
|
646
|
+
expect(subject.excelx_value(4, 5, "Sheet1")).to eq("Bold, Underline, subscript. GoodXYZ")
|
647
|
+
expect(subject.excelx_value(4, 6, "Sheet1")).to eq("Italics, Underline, superscript. Upswing")
|
648
|
+
expect(subject.excelx_value(4, 7, "Sheet1")).to eq("Italics, Underline, subscript. Tswing")
|
649
|
+
expect(subject.excelx_value(5, 1, "Sheet1")).to eq("Bold, italics, underline, superscript. GHJK1904")
|
650
|
+
expect(subject.excelx_value(5, 2, "Sheet1")).to eq("Bold, italics, underline, subscript. Mikedrop")
|
651
|
+
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>")
|
652
|
+
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>")
|
653
|
+
end
|
654
|
+
end
|
655
|
+
end
|
656
|
+
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
@@ -52,6 +52,15 @@ RSpec.describe ::Roo::Utils do
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
context '.extract_coordinate' do
|
56
|
+
it "returns the expected result" do
|
57
|
+
expect(described_class.extract_coordinate('A1')).to eq [1, 1]
|
58
|
+
expect(described_class.extract_coordinate('B2')).to eq [2, 2]
|
59
|
+
expect(described_class.extract_coordinate('R2')).to eq [2, 18]
|
60
|
+
expect(described_class.extract_coordinate('AR31')).to eq [31, 18 + 26]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
55
64
|
context '.split_coord' do
|
56
65
|
it "returns the expected result" do
|
57
66
|
expect(described_class.split_coord('A1')).to eq ["A", 1]
|
@@ -81,26 +90,39 @@ RSpec.describe ::Roo::Utils do
|
|
81
90
|
end
|
82
91
|
end
|
83
92
|
|
93
|
+
context '.coordinates_in_range' do
|
94
|
+
it "returns the expected result" do
|
95
|
+
expect(described_class.coordinates_in_range('').to_a).to eq []
|
96
|
+
expect(described_class.coordinates_in_range('B2').to_a).to eq [[2, 2]]
|
97
|
+
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]]
|
98
|
+
expect(described_class.coordinates_in_range('G3:D2').to_a).to eq []
|
99
|
+
end
|
100
|
+
|
101
|
+
it "raises an error when appropriate" do
|
102
|
+
expect { described_class.coordinates_in_range('D2:G3:I5').to_a }.to raise_error(ArgumentError)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
84
106
|
context '.load_xml' do
|
85
107
|
it 'returns the expected result' do
|
86
108
|
expect(described_class.load_xml('test/files/sheet1.xml')).to be_a(Nokogiri::XML::Document)
|
87
109
|
expect(described_class.load_xml('test/files/sheet1.xml').
|
88
110
|
remove_namespaces!.xpath("/worksheet/dimension").map do |dim|
|
89
|
-
dim
|
111
|
+
dim["ref"] end.first).to eq "A1:B11"
|
90
112
|
end
|
91
113
|
end
|
92
114
|
|
93
115
|
context '.each_element' do
|
94
116
|
it 'returns the expected result' do
|
95
117
|
described_class.each_element('test/files/sheet1.xml', 'dimension') do |dim|
|
96
|
-
expect(dim
|
118
|
+
expect(dim["ref"]).to eq "A1:B11"
|
97
119
|
end
|
98
120
|
rows = []
|
99
121
|
described_class.each_element('test/files/sheet1.xml', 'row') do |row|
|
100
122
|
rows << row
|
101
123
|
end
|
102
124
|
expect(rows.size).to eq 11
|
103
|
-
expect(rows[2]
|
125
|
+
expect(rows[2]["r"]).to eq "3"
|
104
126
|
end
|
105
127
|
end
|
106
128
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
if RUBY_PLATFORM == "java"
|
4
|
+
require 'java'
|
5
|
+
java_import 'java.lang.System'
|
6
|
+
end
|
7
|
+
|
8
|
+
describe Roo::Helpers::WeakInstanceCache do
|
9
|
+
let(:klass) do
|
10
|
+
Class.new do
|
11
|
+
include Roo::Helpers::WeakInstanceCache
|
12
|
+
|
13
|
+
def memoized_data
|
14
|
+
instance_cache(:@memoized_data) do
|
15
|
+
"Some Costly Operation #{rand(1000)}" * 1_000
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
subject do
|
22
|
+
klass.new
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should be lazy' do
|
26
|
+
expect(subject.instance_variables).to_not include(:@memoized_data)
|
27
|
+
data = subject.memoized_data
|
28
|
+
expect(subject.instance_variables).to include(:@memoized_data)
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
it 'should be memoized' do
|
33
|
+
data = subject.memoized_data
|
34
|
+
expect(subject.memoized_data).to equal(data)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should recalculate after GC' do
|
38
|
+
expect(subject.instance_variables).to_not include(:@memoized_data)
|
39
|
+
GC.disable
|
40
|
+
subject.memoized_data && nil
|
41
|
+
expect(subject.instance_variables).to include(:@memoized_data)
|
42
|
+
|
43
|
+
force_gc
|
44
|
+
expect(subject.instance_variables).to_not include(:@memoized_data)
|
45
|
+
GC.disable
|
46
|
+
subject.memoized_data && nil
|
47
|
+
expect(subject.instance_variables).to include(:@memoized_data)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'must remove instance variable' do
|
51
|
+
expect(subject.instance_variables).to_not include(:@memoized_data)
|
52
|
+
GC.disable
|
53
|
+
subject.memoized_data && nil
|
54
|
+
expect(subject.instance_variables).to include(:@memoized_data)
|
55
|
+
|
56
|
+
force_gc
|
57
|
+
expect(subject.instance_variables).to_not include(:@memoized_data)
|
58
|
+
end
|
59
|
+
|
60
|
+
context '#inspect must not raise' do
|
61
|
+
it 'before calculation' do
|
62
|
+
expect{subject.inspect}.to_not raise_error
|
63
|
+
end
|
64
|
+
it 'after calculation' do
|
65
|
+
GC.disable
|
66
|
+
subject.memoized_data && nil
|
67
|
+
expect{subject.inspect}.to_not raise_error
|
68
|
+
expect(subject.inspect).to include("Some Costly Operation")
|
69
|
+
force_gc
|
70
|
+
end
|
71
|
+
it 'after GC' do
|
72
|
+
subject.memoized_data && nil
|
73
|
+
force_gc
|
74
|
+
expect(subject.instance_variables).to_not include(:@memoized_data)
|
75
|
+
expect{subject.inspect}.to_not raise_error
|
76
|
+
expect(subject.inspect).to_not include("Some Costly Operation")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
if RUBY_PLATFORM == "java"
|
81
|
+
def force_gc
|
82
|
+
System.gc
|
83
|
+
sleep(0.1)
|
84
|
+
end
|
85
|
+
else
|
86
|
+
def force_gc
|
87
|
+
GC.start(full_mark: true, immediate_sweep: true)
|
88
|
+
sleep(0.1)
|
89
|
+
GC.start(full_mark: true, immediate_sweep: true)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
File without changes
|
data/spec/spec_helper.rb
CHANGED