roo 2.6.0 → 2.8.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|