roo 1.13.2 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.codeclimate.yml +17 -0
- data/.github/ISSUE_TEMPLATE +10 -0
- data/.gitignore +11 -0
- data/.simplecov +4 -0
- data/.travis.yml +17 -0
- data/CHANGELOG.md +626 -0
- data/Gemfile +17 -12
- data/Gemfile_ruby2 +30 -0
- data/Guardfile +23 -0
- data/LICENSE +3 -1
- data/README.md +285 -0
- data/Rakefile +23 -23
- data/examples/roo_soap_client.rb +28 -31
- data/examples/roo_soap_server.rb +4 -6
- data/examples/write_me.rb +9 -10
- data/lib/roo/base.rb +298 -495
- data/lib/roo/constants.rb +5 -0
- data/lib/roo/csv.rb +127 -113
- data/lib/roo/errors.rb +11 -0
- data/lib/roo/excelx/cell/base.rb +94 -0
- data/lib/roo/excelx/cell/boolean.rb +27 -0
- data/lib/roo/excelx/cell/date.rb +28 -0
- data/lib/roo/excelx/cell/datetime.rb +111 -0
- data/lib/roo/excelx/cell/empty.rb +19 -0
- data/lib/roo/excelx/cell/number.rb +87 -0
- data/lib/roo/excelx/cell/string.rb +19 -0
- data/lib/roo/excelx/cell/time.rb +43 -0
- data/lib/roo/excelx/cell.rb +106 -0
- data/lib/roo/excelx/comments.rb +55 -0
- data/lib/roo/excelx/coordinate.rb +12 -0
- data/lib/roo/excelx/extractor.rb +21 -0
- data/lib/roo/excelx/format.rb +64 -0
- data/lib/roo/excelx/relationships.rb +25 -0
- data/lib/roo/excelx/shared.rb +32 -0
- data/lib/roo/excelx/shared_strings.rb +157 -0
- data/lib/roo/excelx/sheet.rb +112 -0
- data/lib/roo/excelx/sheet_doc.rb +211 -0
- data/lib/roo/excelx/styles.rb +64 -0
- data/lib/roo/excelx/workbook.rb +59 -0
- data/lib/roo/excelx.rb +376 -602
- data/lib/roo/font.rb +17 -0
- 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/libre_office.rb +4 -0
- data/lib/roo/link.rb +34 -0
- data/lib/roo/open_office.rb +626 -0
- data/lib/roo/spreadsheet.rb +22 -23
- data/lib/roo/tempdir.rb +21 -0
- data/lib/roo/utils.rb +78 -0
- data/lib/roo/version.rb +3 -0
- data/lib/roo.rb +23 -24
- data/roo.gemspec +21 -204
- data/spec/helpers.rb +5 -0
- data/spec/lib/roo/base_spec.rb +229 -3
- data/spec/lib/roo/csv_spec.rb +38 -11
- data/spec/lib/roo/excelx/format_spec.rb +7 -6
- data/spec/lib/roo/excelx_spec.rb +510 -11
- data/spec/lib/roo/libreoffice_spec.rb +16 -6
- data/spec/lib/roo/openoffice_spec.rb +30 -8
- data/spec/lib/roo/spreadsheet_spec.rb +60 -12
- data/spec/lib/roo/utils_spec.rb +106 -0
- data/spec/spec_helper.rb +7 -6
- data/test/all_ss.rb +12 -11
- data/test/excelx/cell/test_base.rb +63 -0
- data/test/excelx/cell/test_boolean.rb +36 -0
- data/test/excelx/cell/test_date.rb +38 -0
- data/test/excelx/cell/test_datetime.rb +45 -0
- data/test/excelx/cell/test_empty.rb +7 -0
- data/test/excelx/cell/test_number.rb +74 -0
- data/test/excelx/cell/test_string.rb +28 -0
- data/test/excelx/cell/test_time.rb +30 -0
- data/test/formatters/test_csv.rb +119 -0
- data/test/formatters/test_matrix.rb +76 -0
- data/test/formatters/test_xml.rb +74 -0
- data/test/formatters/test_yaml.rb +20 -0
- data/test/roo/test_csv.rb +52 -0
- data/test/roo/test_excelx.rb +186 -0
- data/test/roo/test_libre_office.rb +9 -0
- data/test/roo/test_open_office.rb +126 -0
- data/test/test_helper.rb +73 -53
- data/test/test_roo.rb +1211 -2292
- metadata +119 -298
- data/CHANGELOG +0 -417
- data/Gemfile.lock +0 -78
- data/README.markdown +0 -126
- data/VERSION +0 -1
- data/lib/roo/excel.rb +0 -355
- data/lib/roo/excel2003xml.rb +0 -300
- data/lib/roo/google.rb +0 -292
- data/lib/roo/openoffice.rb +0 -496
- data/lib/roo/roo_rails_helper.rb +0 -83
- data/lib/roo/worksheet.rb +0 -18
- data/scripts/txt2html +0 -67
- data/spec/lib/roo/excel2003xml_spec.rb +0 -15
- data/spec/lib/roo/excel_spec.rb +0 -17
- data/spec/lib/roo/google_spec.rb +0 -64
- data/test/files/1900_base.xls +0 -0
- data/test/files/1900_base.xlsx +0 -0
- data/test/files/1904_base.xls +0 -0
- data/test/files/1904_base.xlsx +0 -0
- data/test/files/Bibelbund.csv +0 -3741
- data/test/files/Bibelbund.ods +0 -0
- data/test/files/Bibelbund.xls +0 -0
- data/test/files/Bibelbund.xlsx +0 -0
- data/test/files/Bibelbund.xml +0 -62518
- data/test/files/Bibelbund1.ods +0 -0
- data/test/files/Pfand_from_windows_phone.xlsx +0 -0
- data/test/files/bad_excel_date.xls +0 -0
- data/test/files/bbu.ods +0 -0
- data/test/files/bbu.xls +0 -0
- data/test/files/bbu.xlsx +0 -0
- data/test/files/bbu.xml +0 -152
- data/test/files/bode-v1.ods.zip +0 -0
- data/test/files/bode-v1.xls.zip +0 -0
- data/test/files/boolean.csv +0 -2
- data/test/files/boolean.ods +0 -0
- data/test/files/boolean.xls +0 -0
- data/test/files/boolean.xlsx +0 -0
- data/test/files/boolean.xml +0 -112
- data/test/files/borders.ods +0 -0
- data/test/files/borders.xls +0 -0
- data/test/files/borders.xlsx +0 -0
- data/test/files/borders.xml +0 -144
- data/test/files/bug-numbered-sheet-names.xlsx +0 -0
- data/test/files/bug-row-column-fixnum-float.xls +0 -0
- data/test/files/bug-row-column-fixnum-float.xml +0 -127
- data/test/files/comments.ods +0 -0
- data/test/files/comments.xls +0 -0
- data/test/files/comments.xlsx +0 -0
- data/test/files/csvtypes.csv +0 -1
- data/test/files/datetime.ods +0 -0
- data/test/files/datetime.xls +0 -0
- data/test/files/datetime.xlsx +0 -0
- data/test/files/datetime.xml +0 -142
- data/test/files/datetime_floatconv.xls +0 -0
- data/test/files/datetime_floatconv.xml +0 -148
- data/test/files/dreimalvier.ods +0 -0
- data/test/files/emptysheets.ods +0 -0
- data/test/files/emptysheets.xls +0 -0
- data/test/files/emptysheets.xlsx +0 -0
- data/test/files/emptysheets.xml +0 -105
- data/test/files/excel2003.xml +0 -21140
- data/test/files/false_encoding.xls +0 -0
- data/test/files/false_encoding.xml +0 -132
- data/test/files/file_item_error.xlsx +0 -0
- data/test/files/formula.ods +0 -0
- data/test/files/formula.xls +0 -0
- data/test/files/formula.xlsx +0 -0
- data/test/files/formula.xml +0 -134
- data/test/files/formula_parse_error.xls +0 -0
- data/test/files/formula_parse_error.xml +0 -1833
- data/test/files/formula_string_error.xlsx +0 -0
- data/test/files/html-escape.ods +0 -0
- data/test/files/link.xls +0 -0
- data/test/files/link.xlsx +0 -0
- data/test/files/matrix.ods +0 -0
- data/test/files/matrix.xls +0 -0
- data/test/files/named_cells.ods +0 -0
- data/test/files/named_cells.xls +0 -0
- data/test/files/named_cells.xlsx +0 -0
- data/test/files/no_spreadsheet_file.txt +0 -1
- data/test/files/numbers1.csv +0 -18
- data/test/files/numbers1.ods +0 -0
- data/test/files/numbers1.xls +0 -0
- data/test/files/numbers1.xlsx +0 -0
- data/test/files/numbers1.xml +0 -312
- data/test/files/numeric-link.xlsx +0 -0
- data/test/files/only_one_sheet.ods +0 -0
- data/test/files/only_one_sheet.xls +0 -0
- data/test/files/only_one_sheet.xlsx +0 -0
- data/test/files/only_one_sheet.xml +0 -67
- data/test/files/paragraph.ods +0 -0
- data/test/files/paragraph.xls +0 -0
- data/test/files/paragraph.xlsx +0 -0
- data/test/files/paragraph.xml +0 -127
- data/test/files/prova.xls +0 -0
- data/test/files/ric.ods +0 -0
- data/test/files/simple_spreadsheet.ods +0 -0
- data/test/files/simple_spreadsheet.xls +0 -0
- data/test/files/simple_spreadsheet.xlsx +0 -0
- data/test/files/simple_spreadsheet.xml +0 -225
- data/test/files/simple_spreadsheet_from_italo.ods +0 -0
- data/test/files/simple_spreadsheet_from_italo.xls +0 -0
- data/test/files/simple_spreadsheet_from_italo.xml +0 -242
- data/test/files/so_datetime.csv +0 -7
- data/test/files/style.ods +0 -0
- data/test/files/style.xls +0 -0
- data/test/files/style.xlsx +0 -0
- data/test/files/style.xml +0 -154
- data/test/files/time-test.csv +0 -2
- data/test/files/time-test.ods +0 -0
- data/test/files/time-test.xls +0 -0
- data/test/files/time-test.xlsx +0 -0
- data/test/files/time-test.xml +0 -131
- data/test/files/type_excel.ods +0 -0
- data/test/files/type_excel.xlsx +0 -0
- data/test/files/type_excelx.ods +0 -0
- data/test/files/type_excelx.xls +0 -0
- data/test/files/type_openoffice.xls +0 -0
- data/test/files/type_openoffice.xlsx +0 -0
- data/test/files/whitespace.ods +0 -0
- data/test/files/whitespace.xls +0 -0
- data/test/files/whitespace.xlsx +0 -0
- data/test/files/whitespace.xml +0 -184
- data/test/rm_sub_test.rb +0 -12
- data/test/rm_test.rb +0 -7
- data/test/test_generic_spreadsheet.rb +0 -259
- data/website/index.html +0 -385
- data/website/index.txt +0 -423
- data/website/javascripts/rounded_corners_lite.inc.js +0 -285
- data/website/stylesheets/screen.css +0 -130
- data/website/template.rhtml +0 -48
|
@@ -2,18 +2,28 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe Roo::LibreOffice do
|
|
4
4
|
describe '.new' do
|
|
5
|
-
subject
|
|
5
|
+
subject do
|
|
6
6
|
Roo::LibreOffice.new('test/files/numbers1.ods')
|
|
7
|
-
|
|
7
|
+
end
|
|
8
8
|
|
|
9
9
|
it 'creates an instance' do
|
|
10
10
|
expect(subject).to be_a(Roo::LibreOffice)
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
|
-
end
|
|
14
13
|
|
|
15
|
-
describe
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
describe '#sheets' do
|
|
15
|
+
let(:path) { 'test/files/hidden_sheets.ods' }
|
|
16
|
+
|
|
17
|
+
describe 'showing all sheets' do
|
|
18
|
+
it 'returns the expected result' do
|
|
19
|
+
expect(Roo::LibreOffice.new(path).sheets).to eq ["HiddenSheet1", "VisibleSheet1", "HiddenSheet2"]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe 'only showing visible sheets' do
|
|
24
|
+
it 'returns the expected result' do
|
|
25
|
+
expect(Roo::LibreOffice.new(path, only_visible_sheets: true).sheets).to eq ["VisibleSheet1"]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
18
28
|
end
|
|
19
29
|
end
|
|
@@ -2,20 +2,42 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe Roo::OpenOffice do
|
|
4
4
|
describe '.new' do
|
|
5
|
-
subject
|
|
5
|
+
subject do
|
|
6
6
|
Roo::OpenOffice.new('test/files/numbers1.ods')
|
|
7
|
-
|
|
7
|
+
end
|
|
8
8
|
|
|
9
9
|
it 'creates an instance' do
|
|
10
10
|
expect(subject).to be_a(Roo::OpenOffice)
|
|
11
11
|
end
|
|
12
|
-
end
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
context 'for float/integer values' do
|
|
14
|
+
context 'integer without point' do
|
|
15
|
+
it { expect(subject.cell(3,"A","Sheet4")).to eq(1234) }
|
|
16
|
+
it { expect(subject.cell(3,"A","Sheet4")).to be_a(Integer) }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context 'float with point' do
|
|
20
|
+
it { expect(subject.cell(3,"B","Sheet4")).to eq(1234.00) }
|
|
21
|
+
it { expect(subject.cell(3,"B","Sheet4")).to be_a(Float) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context 'float with point' do
|
|
25
|
+
it { expect(subject.cell(3,"C","Sheet4")).to eq(1234.12) }
|
|
26
|
+
it { expect(subject.cell(3,"C","Sheet4")).to be_a(Float) }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context 'file path is a Pathname' do
|
|
31
|
+
subject do
|
|
32
|
+
Roo::OpenOffice.new(Pathname.new('test/files/numbers1.ods'))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'creates an instance' do
|
|
36
|
+
expect(subject).to be_a(Roo::OpenOffice)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
16
39
|
|
|
17
|
-
describe Roo::Openoffice do
|
|
18
|
-
it 'is an alias of LibreOffice' do
|
|
19
|
-
expect(Roo::Openoffice).to eq(Roo::OpenOffice)
|
|
20
40
|
end
|
|
41
|
+
|
|
42
|
+
# OpenOffice is an alias of LibreOffice. See libreoffice_spec.
|
|
21
43
|
end
|
|
@@ -2,15 +2,34 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe Roo::Spreadsheet do
|
|
4
4
|
describe '.open' do
|
|
5
|
+
context 'when the file name includes a space' do
|
|
6
|
+
let(:filename) { 'great scott.xlsx' }
|
|
7
|
+
|
|
8
|
+
it 'loads the proper type' do
|
|
9
|
+
expect(Roo::Excelx).to receive(:new).with(filename, {})
|
|
10
|
+
Roo::Spreadsheet.open(filename)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
5
14
|
context 'when the file extension is uppercase' do
|
|
6
|
-
let(:filename) { 'file.
|
|
15
|
+
let(:filename) { 'file.XLSX' }
|
|
7
16
|
|
|
8
17
|
it 'loads the proper type' do
|
|
9
|
-
expect(Roo::
|
|
18
|
+
expect(Roo::Excelx).to receive(:new).with(filename, {})
|
|
10
19
|
Roo::Spreadsheet.open(filename)
|
|
11
20
|
end
|
|
12
21
|
end
|
|
13
22
|
|
|
23
|
+
context 'for a tempfile' do
|
|
24
|
+
let(:tempfile) { Tempfile.new('foo.csv') }
|
|
25
|
+
let(:filename) { tempfile.path }
|
|
26
|
+
|
|
27
|
+
it 'loads the proper type' do
|
|
28
|
+
expect(Roo::CSV).to receive(:new).with(filename, file_warning: :ignore).and_call_original
|
|
29
|
+
expect(Roo::Spreadsheet.open(tempfile, extension: :csv)).to be_a(Roo::CSV)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
14
33
|
context 'for a url' do
|
|
15
34
|
context 'that is csv' do
|
|
16
35
|
let(:filename) { 'http://example.com/file.csv?with=params#and=anchor' }
|
|
@@ -22,35 +41,64 @@ describe Roo::Spreadsheet do
|
|
|
22
41
|
end
|
|
23
42
|
end
|
|
24
43
|
|
|
44
|
+
context 'for a windows path' do
|
|
45
|
+
context 'that is xlsx' do
|
|
46
|
+
let(:filename) { 'c:\Users\Joe\Desktop\myfile.xlsx' }
|
|
47
|
+
|
|
48
|
+
it 'loads the proper type' do
|
|
49
|
+
expect(Roo::Excelx).to receive(:new).with(filename, {})
|
|
50
|
+
Roo::Spreadsheet.open(filename)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context 'for a xlsm file' do
|
|
56
|
+
let(:filename) { 'macros spreadsheet.xlsm' }
|
|
57
|
+
|
|
58
|
+
it 'loads the proper type' do
|
|
59
|
+
expect(Roo::Excelx).to receive(:new).with(filename, {})
|
|
60
|
+
Roo::Spreadsheet.open(filename)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
25
64
|
context 'for a csv file' do
|
|
26
65
|
let(:filename) { 'file.csv' }
|
|
27
|
-
let(:options) { {csv_options: {col_sep: '"'}} }
|
|
66
|
+
let(:options) { { csv_options: { col_sep: '"' } } }
|
|
28
67
|
|
|
29
|
-
context 'with
|
|
30
|
-
it 'passes the
|
|
68
|
+
context 'with csv_options' do
|
|
69
|
+
it 'passes the csv_options through' do
|
|
31
70
|
expect(Roo::CSV).to receive(:new).with(filename, options)
|
|
32
71
|
Roo::Spreadsheet.open(filename, options)
|
|
33
72
|
end
|
|
34
73
|
end
|
|
35
74
|
end
|
|
36
75
|
|
|
37
|
-
context '
|
|
76
|
+
context 'with a file extension option' do
|
|
38
77
|
let(:filename) { 'file.xls' }
|
|
39
78
|
|
|
40
|
-
context
|
|
41
|
-
let(:options) { { extension:
|
|
79
|
+
context ':xlsx' do
|
|
80
|
+
let(:options) { { extension: :xlsx } }
|
|
81
|
+
|
|
82
|
+
it 'loads with xls extension options' do
|
|
83
|
+
expect(Roo::Excelx).to receive(:new).with(filename, options)
|
|
84
|
+
Roo::Spreadsheet.open(filename, options)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context 'xlsx' do
|
|
89
|
+
let(:options) { { extension: 'xlsx' } }
|
|
42
90
|
|
|
43
91
|
it 'loads with xls extension options' do
|
|
44
|
-
expect(Roo::
|
|
92
|
+
expect(Roo::Excelx).to receive(:new).with(filename, options)
|
|
45
93
|
Roo::Spreadsheet.open(filename, options)
|
|
46
94
|
end
|
|
47
95
|
end
|
|
48
96
|
|
|
49
|
-
context
|
|
50
|
-
let(:options) { { extension:
|
|
97
|
+
context '.xlsx' do
|
|
98
|
+
let(:options) { { extension: '.xlsx' } }
|
|
51
99
|
|
|
52
100
|
it 'loads with .xls extension options' do
|
|
53
|
-
expect(Roo::
|
|
101
|
+
expect(Roo::Excelx).to receive(:new).with(filename, options)
|
|
54
102
|
Roo::Spreadsheet.open(filename, options)
|
|
55
103
|
end
|
|
56
104
|
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe ::Roo::Utils do
|
|
4
|
+
subject { described_class }
|
|
5
|
+
|
|
6
|
+
context '#number_to_letter' do
|
|
7
|
+
described_class::LETTERS.each_with_index do |letter, index|
|
|
8
|
+
it "should return '#{ letter }' when passed #{ index + 1 }" do
|
|
9
|
+
expect(described_class.number_to_letter(index + 1)).to eq(letter)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
{
|
|
14
|
+
27 => 'AA', 26*2 => 'AZ', 26*3 => 'BZ', 26**2 + 26 => 'ZZ', 26**2 + 27 => 'AAA',
|
|
15
|
+
26**3 + 26**2 + 26 => 'ZZZ', 1.0 => 'A', 676 => 'YZ', 677 => 'ZA'
|
|
16
|
+
}.each do |key, value|
|
|
17
|
+
it "should return '#{value}' when passed #{key}" do
|
|
18
|
+
expect(described_class.number_to_letter(key)).to eq(value)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context '#letter_to_number' do
|
|
24
|
+
it "should give 1 for 'A' and 'a'" do
|
|
25
|
+
expect(described_class.letter_to_number('A')).to eq(1)
|
|
26
|
+
expect(described_class.letter_to_number('a')).to eq(1)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should give the correct value for 'Z'" do
|
|
30
|
+
expect(described_class.letter_to_number('Z')).to eq(26)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "should give the correct value for 'AA' regardless of case mixing" do
|
|
34
|
+
%w(AA aA Aa aa).each do |key|
|
|
35
|
+
expect(described_class.letter_to_number(key)).to eq(27)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
{ 'AB' => 28, 'AZ' => 26*2, 'BZ' => 26*3, 'ZZ' => 26**2 + 26 }.each do |key, value|
|
|
40
|
+
it "should give the correct value for '#{key}'" do
|
|
41
|
+
expect(described_class.letter_to_number(key)).to eq(value)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context '.split_coordinate' do
|
|
47
|
+
it "returns the expected result" do
|
|
48
|
+
expect(described_class.split_coordinate('A1')).to eq [1, 1]
|
|
49
|
+
expect(described_class.split_coordinate('B2')).to eq [2, 2]
|
|
50
|
+
expect(described_class.split_coordinate('R2')).to eq [2, 18]
|
|
51
|
+
expect(described_class.split_coordinate('AR31')).to eq [31, 18 + 26]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context '.split_coord' do
|
|
56
|
+
it "returns the expected result" do
|
|
57
|
+
expect(described_class.split_coord('A1')).to eq ["A", 1]
|
|
58
|
+
expect(described_class.split_coord('B2')).to eq ["B", 2]
|
|
59
|
+
expect(described_class.split_coord('R2')).to eq ["R", 2]
|
|
60
|
+
expect(described_class.split_coord('AR31')).to eq ["AR", 31]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "raises an error when appropriate" do
|
|
64
|
+
expect { described_class.split_coord('A') }.to raise_error(ArgumentError)
|
|
65
|
+
expect { described_class.split_coord('2') }.to raise_error(ArgumentError)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
context '.num_cells_in_range' do
|
|
71
|
+
it "returns the expected result" do
|
|
72
|
+
expect(described_class.num_cells_in_range('A1:B2')).to eq 4
|
|
73
|
+
expect(described_class.num_cells_in_range('B2:E3')).to eq 8
|
|
74
|
+
expect(described_class.num_cells_in_range('R2:Z10')).to eq 81
|
|
75
|
+
expect(described_class.num_cells_in_range('AR31:AR32')).to eq 2
|
|
76
|
+
expect(described_class.num_cells_in_range('A1')).to eq 1
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "raises an error when appropriate" do
|
|
80
|
+
expect { described_class.num_cells_in_range('A1:B1:B2') }.to raise_error(ArgumentError)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
context '.load_xml' do
|
|
85
|
+
it 'returns the expected result' do
|
|
86
|
+
expect(described_class.load_xml('test/files/sheet1.xml')).to be_a(Nokogiri::XML::Document)
|
|
87
|
+
expect(described_class.load_xml('test/files/sheet1.xml').
|
|
88
|
+
remove_namespaces!.xpath("/worksheet/dimension").map do |dim|
|
|
89
|
+
dim.attributes["ref"].value end.first).to eq "A1:B11"
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
context '.each_element' do
|
|
94
|
+
it 'returns the expected result' do
|
|
95
|
+
described_class.each_element('test/files/sheet1.xml', 'dimension') do |dim|
|
|
96
|
+
expect(dim.attributes["ref"].value).to eq "A1:B11"
|
|
97
|
+
end
|
|
98
|
+
rows = []
|
|
99
|
+
described_class.each_element('test/files/sheet1.xml', 'row') do |row|
|
|
100
|
+
rows << row
|
|
101
|
+
end
|
|
102
|
+
expect(rows.size).to eq 11
|
|
103
|
+
expect(rows[2].attributes["r"].value).to eq "3"
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'simplecov'
|
|
2
|
+
require 'roo'
|
|
3
|
+
require 'helpers'
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
c.
|
|
7
|
-
c.hook_into :webmock # or :fakeweb
|
|
5
|
+
RSpec.configure do |c|
|
|
6
|
+
c.include Helpers
|
|
7
|
+
c.color = true
|
|
8
|
+
c.formatter = :documentation
|
|
8
9
|
end
|
data/test/all_ss.rb
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
require 'roo'
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
end
|
|
1
|
+
require 'roo'
|
|
2
|
+
|
|
3
|
+
Dir.glob('test/files/*.ods').each do |fn|
|
|
4
|
+
begin
|
|
5
|
+
oo = Roo::OpenOffice.new fn
|
|
6
|
+
print "#{File.basename(fn)} "
|
|
7
|
+
puts oo.officeversion
|
|
8
|
+
rescue Zip::ZipError, Errno::ENOENT => e
|
|
9
|
+
# file is not a real .ods spreadsheet file
|
|
10
|
+
puts e.message
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class TestRooExcelxCellBase < Minitest::Test
|
|
4
|
+
def base
|
|
5
|
+
Roo::Excelx::Cell::Base
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def value
|
|
9
|
+
'Hello World'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_cell_type_is_base
|
|
13
|
+
cell = base.new(value, nil, [], nil, nil, nil)
|
|
14
|
+
assert_equal :base, cell.type
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_cell_value
|
|
18
|
+
cell_value = value
|
|
19
|
+
cell = base.new(cell_value, nil, [], nil, nil, nil)
|
|
20
|
+
assert_equal cell_value, cell.cell_value
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_not_empty?
|
|
24
|
+
cell = base.new(value, nil, [], nil, nil, nil)
|
|
25
|
+
refute cell.empty?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_cell_type_is_formula
|
|
29
|
+
formula = true
|
|
30
|
+
cell = base.new(value, formula, [], nil, nil, nil)
|
|
31
|
+
assert_equal :formula, cell.type
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_formula?
|
|
35
|
+
formula = true
|
|
36
|
+
cell = base.new(value, formula, [], nil, nil, nil)
|
|
37
|
+
assert cell.formula?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_cell_type_is_link
|
|
41
|
+
link = 'http://example.com'
|
|
42
|
+
cell = base.new(value, nil, [], nil, link, nil)
|
|
43
|
+
assert_equal :link, cell.type
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_link?
|
|
47
|
+
link = 'http://example.com'
|
|
48
|
+
cell = base.new(value, nil, [], nil, link, nil)
|
|
49
|
+
assert cell.link?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_link_value
|
|
53
|
+
link = 'http://example.com'
|
|
54
|
+
cell = base.new(value, nil, [], nil, link, nil)
|
|
55
|
+
assert_equal value, cell.value
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def test_link_value_href
|
|
59
|
+
link = 'http://example.com'
|
|
60
|
+
cell = base.new(value, nil, [], nil, link, nil)
|
|
61
|
+
assert_equal link, cell.value.href
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class TestRooExcelxCellNumber < Minitest::Test
|
|
4
|
+
def boolean
|
|
5
|
+
Roo::Excelx::Cell::Boolean
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def test_formatted_value
|
|
9
|
+
cell = boolean.new '1', nil, nil, nil, nil
|
|
10
|
+
assert_equal 'TRUE', cell.formatted_value
|
|
11
|
+
|
|
12
|
+
cell = boolean.new '0', nil, nil, nil, nil
|
|
13
|
+
assert_equal 'FALSE', cell.formatted_value
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_to_s
|
|
17
|
+
cell = boolean.new '1', nil, nil, nil, nil
|
|
18
|
+
assert_equal 'TRUE', cell.to_s
|
|
19
|
+
|
|
20
|
+
cell = boolean.new '0', nil, nil, nil, nil
|
|
21
|
+
assert_equal 'FALSE', cell.to_s
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_cell_value
|
|
25
|
+
cell = boolean.new '1', nil, nil, nil, nil
|
|
26
|
+
assert_equal '1', cell.cell_value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_value
|
|
30
|
+
cell = boolean.new '1', nil, nil, nil, nil
|
|
31
|
+
assert_equal true, cell.value
|
|
32
|
+
|
|
33
|
+
cell = boolean.new '0', nil, nil, nil, nil
|
|
34
|
+
assert_equal false, cell.value
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class TestRooExcelxCellDate < Minitest::Test
|
|
4
|
+
def date_cell
|
|
5
|
+
Roo::Excelx::Cell::Date
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def base_date
|
|
9
|
+
::Date.new(1899, 12, 30)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def base_date_1904
|
|
13
|
+
::Date.new(1904, 01, 01)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_handles_1904_base_date
|
|
17
|
+
cell = date_cell.new('41791', nil, [:numeric_or_formula, 'mm-dd-yy'], 6, nil, base_date_1904, nil)
|
|
18
|
+
assert_equal ::Date.new(2018, 06, 02), cell.value
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_formatted_value
|
|
22
|
+
cell = date_cell.new('41791', nil, [:numeric_or_formula, 'mm-dd-yy'], 6, nil, base_date, nil)
|
|
23
|
+
assert_equal '06-01-14', cell.formatted_value
|
|
24
|
+
|
|
25
|
+
cell = date_cell.new('41791', nil, [:numeric_or_formula, 'yyyy-mm-dd'], 6, nil, base_date, nil)
|
|
26
|
+
assert_equal '2014-06-01', cell.formatted_value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_value_is_date
|
|
30
|
+
cell = date_cell.new('41791', nil, [:numeric_or_formula, 'mm-dd-yy'], 6, nil, base_date, nil)
|
|
31
|
+
assert_kind_of ::Date, cell.value
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_value
|
|
35
|
+
cell = date_cell.new('41791', nil, [:numeric_or_formula, 'mm-dd-yy'], 6, nil, base_date, nil)
|
|
36
|
+
assert_equal ::Date.new(2014, 06, 01), cell.value
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class TestRooExcelxCellDateTime < Minitest::Test
|
|
4
|
+
def test_cell_value_is_datetime
|
|
5
|
+
cell = datetime.new('30000.323212', nil, ['mm-dd-yy'], nil, nil, base_date, nil)
|
|
6
|
+
assert_kind_of ::DateTime, cell.value
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def test_cell_type_is_datetime
|
|
10
|
+
cell = datetime.new('30000.323212', nil, [], nil, nil, base_date, nil)
|
|
11
|
+
assert_equal :datetime, cell.type
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_standard_formatted_value
|
|
15
|
+
[
|
|
16
|
+
['mm-dd-yy', '01-25-15'],
|
|
17
|
+
['d-mmm-yy', '25-JAN-15'],
|
|
18
|
+
['d-mmm ', '25-JAN'],
|
|
19
|
+
['mmm-yy', 'JAN-15'],
|
|
20
|
+
['m/d/yy h:mm', '1/25/15 8:15']
|
|
21
|
+
].each do |format, formatted_value|
|
|
22
|
+
cell = datetime.new '42029.34375', nil, [format], nil, nil, base_date, nil
|
|
23
|
+
assert_equal formatted_value, cell.formatted_value
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_custom_formatted_value
|
|
28
|
+
[
|
|
29
|
+
['yyyy/mm/dd hh:mm:ss', '2015/01/25 08:15:00'],
|
|
30
|
+
['h:mm:ss000 mm/yy', '8:15:00000 01/15'],
|
|
31
|
+
['mmm yyy', '2015-01-25 08:15:00']
|
|
32
|
+
].each do |format, formatted_value|
|
|
33
|
+
cell = datetime.new '42029.34375', nil, [format], nil, nil, base_date, nil
|
|
34
|
+
assert_equal formatted_value, cell.formatted_value
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def datetime
|
|
39
|
+
Roo::Excelx::Cell::DateTime
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def base_date
|
|
43
|
+
Date.new(1899, 12, 30)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class TestRooExcelxCellNumber < Minitest::Test
|
|
4
|
+
def number
|
|
5
|
+
Roo::Excelx::Cell::Number
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def test_float
|
|
9
|
+
cell = Roo::Excelx::Cell::Number.new '42.1', nil, ['General'], nil, nil, nil
|
|
10
|
+
assert_kind_of(Float, cell.value)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_integer
|
|
14
|
+
cell = Roo::Excelx::Cell::Number.new '42', nil, ['0'], nil, nil, nil
|
|
15
|
+
assert_kind_of(Integer, cell.value)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_scientific_notation
|
|
19
|
+
cell = Roo::Excelx::Cell::Number.new '1.2E-3', nil, ['0'], nil, nil, nil
|
|
20
|
+
assert_kind_of(Float, cell.value)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_simple_scientific_notation
|
|
24
|
+
cell = Roo::Excelx::Cell::Number.new '1E-3', nil, ['0'], nil, nil, nil
|
|
25
|
+
assert_kind_of(Float, cell.value)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_percent
|
|
29
|
+
cell = Roo::Excelx::Cell::Number.new '42.1', nil, ['0.00%'], nil, nil, nil
|
|
30
|
+
assert_kind_of(Float, cell.value)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_formats_with_negative_numbers
|
|
34
|
+
[
|
|
35
|
+
['#,##0 ;(#,##0)', '(1,042)'],
|
|
36
|
+
['#,##0 ;[Red](#,##0)', '[Red](1,042)'],
|
|
37
|
+
['#,##0.00;(#,##0.00)', '(1,042.00)'],
|
|
38
|
+
['#,##0.00;[Red](#,##0.00)', '[Red](1,042.00)']
|
|
39
|
+
].each do |style_format, result|
|
|
40
|
+
cell = Roo::Excelx::Cell::Number.new '-1042', nil, [style_format], nil, nil, nil
|
|
41
|
+
assert_equal result, cell.formatted_value, "Style=#{style_format}"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_numbers_with_cell_errors
|
|
46
|
+
Roo::Excelx::ERROR_VALUES.each do |error|
|
|
47
|
+
cell = Roo::Excelx::Cell::Number.new error, nil, ['General'], nil, nil, nil
|
|
48
|
+
assert_equal error, cell.value
|
|
49
|
+
assert_equal error, cell.formatted_value
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def test_formats
|
|
54
|
+
[
|
|
55
|
+
['General', '1042'],
|
|
56
|
+
['0', '1042'],
|
|
57
|
+
['0.00', '1042.00'],
|
|
58
|
+
['#,##0', '1,042'],
|
|
59
|
+
['#,##0.00', '1,042.00'],
|
|
60
|
+
['0%', '104200%'],
|
|
61
|
+
['0.00%', '104200.00%'],
|
|
62
|
+
['0.00E+00', '1.04E+03'],
|
|
63
|
+
['#,##0 ;(#,##0)', '1,042'],
|
|
64
|
+
['#,##0 ;[Red](#,##0)', '1,042'],
|
|
65
|
+
['#,##0.00;(#,##0.00)', '1,042.00'],
|
|
66
|
+
['#,##0.00;[Red](#,##0.00)', '1,042.00'],
|
|
67
|
+
['##0.0E+0', '1.0E+03'],
|
|
68
|
+
['@', '1042']
|
|
69
|
+
].each do |style_format, result|
|
|
70
|
+
cell = Roo::Excelx::Cell::Number.new '1042', nil, [style_format], nil, nil, nil
|
|
71
|
+
assert_equal result, cell.formatted_value, "Style=#{style_format}"
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class TestRooExcelxCellString < Minitest::Test
|
|
4
|
+
def string
|
|
5
|
+
Roo::Excelx::Cell::String
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_formatted_value
|
|
10
|
+
cell = string.new '1', nil, nil, nil, nil
|
|
11
|
+
assert_equal '1', cell.formatted_value
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_to_s
|
|
15
|
+
cell = string.new '0', nil, nil, nil, nil
|
|
16
|
+
assert_equal '0', cell.to_s
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_cell_value
|
|
20
|
+
cell = string.new '1', nil, nil, nil, nil
|
|
21
|
+
assert_equal '1', cell.cell_value
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_value
|
|
25
|
+
cell = string.new '0', nil, nil, nil, nil
|
|
26
|
+
assert_equal '0', cell.value
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class TestRooExcelxCellTime < Minitest::Test
|
|
4
|
+
def roo_time
|
|
5
|
+
Roo::Excelx::Cell::Time
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def base_date
|
|
9
|
+
Date.new(1899, 12, 30)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_formatted_value
|
|
13
|
+
value = '0.0751' # 6488.64 seconds, or 1:48:08.64
|
|
14
|
+
[
|
|
15
|
+
['h:mm', '1:48'],
|
|
16
|
+
['h:mm:ss', '1:48:09'],
|
|
17
|
+
['mm:ss', '48:09'],
|
|
18
|
+
['[h]:mm:ss', '[1]:48:09'],
|
|
19
|
+
['mmss.0', '4809.0'] # Cell::Time always get rounded to the nearest second.
|
|
20
|
+
].each do |style_format, result|
|
|
21
|
+
cell = roo_time.new(value, nil, [:numeric_or_formula, style_format], 6, nil, base_date, nil)
|
|
22
|
+
assert_equal result, cell.formatted_value, "Style=#{style_format} is not properly formatted"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_value
|
|
27
|
+
cell = roo_time.new('0.0751', nil, [:numeric_or_formula, 'h:mm'], 6, nil, base_date, nil)
|
|
28
|
+
assert_kind_of Integer, cell.value
|
|
29
|
+
end
|
|
30
|
+
end
|