roo 2.6.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/.codeclimate.yml +17 -0
- data/.github/issue_template.md +16 -0
- data/.github/pull_request_template.md +14 -0
- data/.rubocop.yml +186 -0
- data/.travis.yml +14 -11
- data/CHANGELOG.md +64 -2
- data/Gemfile +2 -4
- data/LICENSE +2 -0
- data/README.md +36 -10
- data/lib/roo/base.rb +82 -225
- data/lib/roo/constants.rb +5 -3
- data/lib/roo/csv.rb +100 -97
- 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 +44 -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 +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 +50 -19
- 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 +17 -9
- data/lib/roo/spreadsheet.rb +1 -1
- data/lib/roo/tempdir.rb +5 -10
- data/lib/roo/utils.rb +70 -20
- data/lib/roo/version.rb +1 -1
- data/lib/roo.rb +4 -1
- data/roo.gemspec +14 -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 +2 -6
- 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 +5 -5
- 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 +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 +88 -0
- data/test/roo/test_excelx.rb +330 -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 +32 -1787
- metadata +81 -29
- data/.github/ISSUE_TEMPLATE +0 -10
- data/Gemfile_ruby2 +0 -29
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
@@ -1,13 +1,9 @@
|
|
1
1
|
require 'simplecov'
|
2
2
|
require 'roo'
|
3
|
-
require 'vcr'
|
4
3
|
require 'helpers'
|
5
4
|
|
6
5
|
RSpec.configure do |c|
|
7
6
|
c.include Helpers
|
8
|
-
|
9
|
-
|
10
|
-
VCR.configure do |c|
|
11
|
-
c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
|
12
|
-
c.hook_into :webmock # or :fakeweb
|
7
|
+
c.color = true
|
8
|
+
c.formatter = :documentation if ENV["USE_REPORTERS"]
|
13
9
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class TestAttrReaderDefault < Minitest::Test
|
4
|
+
def base
|
5
|
+
Roo::Excelx::Cell::Base
|
6
|
+
end
|
7
|
+
|
8
|
+
def boolean
|
9
|
+
Roo::Excelx::Cell::Boolean
|
10
|
+
end
|
11
|
+
|
12
|
+
def class_date
|
13
|
+
Roo::Excelx::Cell::Date
|
14
|
+
end
|
15
|
+
|
16
|
+
def datetime
|
17
|
+
Roo::Excelx::Cell::DateTime
|
18
|
+
end
|
19
|
+
|
20
|
+
def empty
|
21
|
+
Roo::Excelx::Cell::Empty
|
22
|
+
end
|
23
|
+
|
24
|
+
def number
|
25
|
+
Roo::Excelx::Cell::Number
|
26
|
+
end
|
27
|
+
|
28
|
+
def string
|
29
|
+
Roo::Excelx::Cell::String
|
30
|
+
end
|
31
|
+
|
32
|
+
def base_date
|
33
|
+
::Date.new(1899, 12, 30)
|
34
|
+
end
|
35
|
+
|
36
|
+
def base_timestamp
|
37
|
+
::Date.new(1899, 12, 30).to_datetime.to_time.to_i
|
38
|
+
end
|
39
|
+
|
40
|
+
def class_time
|
41
|
+
Roo::Excelx::Cell::Time
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_cell_default_values
|
45
|
+
assert_values base.new(nil, nil, [], 1, nil, nil), default_type: :base, :@default_type => nil, style: 1, :@style => nil
|
46
|
+
assert_values boolean.new("1", nil, nil, nil, nil), default_type: :boolean, :@default_type => nil, cell_type: :boolean, :@cell_type => nil
|
47
|
+
assert_values class_date.new("41791", nil, [:numeric_or_formula, "mm-dd-yy"], 6, nil, base_date, nil), default_type: :date, :@default_type => nil
|
48
|
+
assert_values class_time.new("0.521", nil, [:numeric_or_formula, "hh:mm"], 6, nil, base_timestamp, nil), default_type: :time, :@default_type => nil
|
49
|
+
assert_values datetime.new("41791.521", nil, [:numeric_or_formula, "mm-dd-yy hh:mm"], 6, nil, base_timestamp, nil), default_type: :datetime, :@default_type => nil
|
50
|
+
assert_values empty.new(nil), default_type: nil, :@default_type => nil, style: nil, :@style => nil
|
51
|
+
assert_values number.new("42", nil, ["0"], nil, nil, nil), default_type: :float, :@default_type => nil
|
52
|
+
assert_values string.new("1", nil, nil, nil, nil), default_type: :string, :@default_type => nil, cell_type: :string, :@cell_type => nil
|
53
|
+
|
54
|
+
assert_values base.new(nil, nil, [], 2, nil, nil), style: 2, :@style => 2
|
55
|
+
end
|
56
|
+
|
57
|
+
def assert_values(object, value_hash)
|
58
|
+
value_hash.each do |attr_name, expected_value|
|
59
|
+
value = if attr_name.to_s.include?("@")
|
60
|
+
object.instance_variable_defined?(attr_name) ? object.instance_variable_get(attr_name) : nil
|
61
|
+
else
|
62
|
+
object.public_send(attr_name)
|
63
|
+
end
|
64
|
+
|
65
|
+
if expected_value
|
66
|
+
assert_equal expected_value, value
|
67
|
+
else
|
68
|
+
assert_nil value
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -25,6 +25,11 @@ class TestRooExcelxCellBase < Minitest::Test
|
|
25
25
|
refute cell.empty?
|
26
26
|
end
|
27
27
|
|
28
|
+
def test_presence
|
29
|
+
cell = base.new(value, nil, [], nil, nil, nil)
|
30
|
+
assert_equal cell, cell.presence
|
31
|
+
end
|
32
|
+
|
28
33
|
def test_cell_type_is_formula
|
29
34
|
formula = true
|
30
35
|
cell = base.new(value, formula, [], nil, nil, nil)
|
@@ -2,12 +2,12 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class TestRooExcelxCellDateTime < Minitest::Test
|
4
4
|
def test_cell_value_is_datetime
|
5
|
-
cell = datetime.new('30000.323212', nil, ['mm-dd-yy'], nil, nil,
|
5
|
+
cell = datetime.new('30000.323212', nil, ['mm-dd-yy'], nil, nil, base_timestamp, nil)
|
6
6
|
assert_kind_of ::DateTime, cell.value
|
7
7
|
end
|
8
8
|
|
9
9
|
def test_cell_type_is_datetime
|
10
|
-
cell = datetime.new('30000.323212', nil, [], nil, nil,
|
10
|
+
cell = datetime.new('30000.323212', nil, [], nil, nil, base_timestamp, nil)
|
11
11
|
assert_equal :datetime, cell.type
|
12
12
|
end
|
13
13
|
|
@@ -19,7 +19,7 @@ class TestRooExcelxCellDateTime < Minitest::Test
|
|
19
19
|
['mmm-yy', 'JAN-15'],
|
20
20
|
['m/d/yy h:mm', '1/25/15 8:15']
|
21
21
|
].each do |format, formatted_value|
|
22
|
-
cell = datetime.new '42029.34375', nil, [format], nil, nil,
|
22
|
+
cell = datetime.new '42029.34375', nil, [format], nil, nil, base_timestamp, nil
|
23
23
|
assert_equal formatted_value, cell.formatted_value
|
24
24
|
end
|
25
25
|
end
|
@@ -30,7 +30,7 @@ class TestRooExcelxCellDateTime < Minitest::Test
|
|
30
30
|
['h:mm:ss000 mm/yy', '8:15:00000 01/15'],
|
31
31
|
['mmm yyy', '2015-01-25 08:15:00']
|
32
32
|
].each do |format, formatted_value|
|
33
|
-
cell = datetime.new '42029.34375', nil, [format], nil, nil,
|
33
|
+
cell = datetime.new '42029.34375', nil, [format], nil, nil, base_timestamp, nil
|
34
34
|
assert_equal formatted_value, cell.formatted_value
|
35
35
|
end
|
36
36
|
end
|
@@ -39,7 +39,7 @@ class TestRooExcelxCellDateTime < Minitest::Test
|
|
39
39
|
Roo::Excelx::Cell::DateTime
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
43
|
-
|
42
|
+
def base_timestamp
|
43
|
+
DateTime.new(1899, 12, 30).to_time.to_i
|
44
44
|
end
|
45
45
|
end
|
@@ -4,4 +4,15 @@ class TestRooExcelxCellEmpty < Minitest::Test
|
|
4
4
|
def empty
|
5
5
|
Roo::Excelx::Cell::Empty
|
6
6
|
end
|
7
|
+
|
8
|
+
def test_empty?
|
9
|
+
cell = empty.new(nil)
|
10
|
+
assert_same true, cell.empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_nil_presence
|
14
|
+
cell = empty.new(nil)
|
15
|
+
assert_nil cell.presence
|
16
|
+
end
|
17
|
+
|
7
18
|
end
|
@@ -25,6 +25,11 @@ class TestRooExcelxCellNumber < Minitest::Test
|
|
25
25
|
assert_kind_of(Float, cell.value)
|
26
26
|
end
|
27
27
|
|
28
|
+
def test_very_simple_scientific_notation
|
29
|
+
cell = Roo::Excelx::Cell::Number.new '1e6', nil, ['0'], nil, nil, nil
|
30
|
+
assert_kind_of(Float, cell.value)
|
31
|
+
end
|
32
|
+
|
28
33
|
def test_percent
|
29
34
|
cell = Roo::Excelx::Cell::Number.new '42.1', nil, ['0.00%'], nil, nil, nil
|
30
35
|
assert_kind_of(Float, cell.value)
|
@@ -53,8 +58,12 @@ class TestRooExcelxCellNumber < Minitest::Test
|
|
53
58
|
def test_formats
|
54
59
|
[
|
55
60
|
['General', '1042'],
|
61
|
+
['GENERAL', '1042'],
|
56
62
|
['0', '1042'],
|
63
|
+
['000000', '001042'],
|
57
64
|
['0.00', '1042.00'],
|
65
|
+
['0.0000', '1042.0000'],
|
66
|
+
['0.000000000', '1042.000000000'],
|
58
67
|
['#,##0', '1,042'],
|
59
68
|
['#,##0.00', '1,042.00'],
|
60
69
|
['0%', '104200%'],
|
@@ -25,4 +25,24 @@ class TestRooExcelxCellString < Minitest::Test
|
|
25
25
|
cell = string.new '0', nil, nil, nil, nil
|
26
26
|
assert_equal '0', cell.value
|
27
27
|
end
|
28
|
+
|
29
|
+
def test_not_empty?
|
30
|
+
cell = string.new '1', nil, nil, nil, nil
|
31
|
+
assert_equal false, cell.empty?
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_empty?
|
35
|
+
cell = string.new '', nil, nil, nil, nil
|
36
|
+
assert_equal true, cell.empty?
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_presence
|
40
|
+
cell = string.new '1', nil, nil, nil, nil
|
41
|
+
assert_equal cell, cell.presence
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_nil_presence
|
45
|
+
cell = string.new '', nil, nil, nil, nil
|
46
|
+
assert_nil cell.presence
|
47
|
+
end
|
28
48
|
end
|