culturecode-roo 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG.md +513 -0
  3. data/README.md +206 -73
  4. data/lib/roo.rb +3 -3
  5. data/lib/roo/base.rb +49 -33
  6. data/lib/roo/csv.rb +10 -0
  7. data/lib/roo/excelx.rb +187 -60
  8. data/lib/roo/excelx/comments.rb +2 -1
  9. data/lib/roo/excelx/sheet_doc.rb +30 -3
  10. data/lib/roo/open_office.rb +250 -221
  11. data/lib/roo/utils.rb +28 -31
  12. data/lib/roo/version.rb +1 -1
  13. data/roo.gemspec +10 -12
  14. data/spec/lib/roo/csv_spec.rb +14 -0
  15. data/spec/lib/roo/excelx_spec.rb +90 -2
  16. data/spec/lib/roo/libreoffice_spec.rb +16 -0
  17. data/spec/lib/roo/openoffice_spec.rb +11 -0
  18. data/spec/lib/roo/utils_spec.rb +5 -4
  19. data/test/test_roo.rb +113 -2
  20. metadata +29 -180
  21. data/CHANGELOG +0 -438
  22. data/scripts/txt2html +0 -67
  23. data/test/files/1900_base.xlsx +0 -0
  24. data/test/files/1904_base.xlsx +0 -0
  25. data/test/files/Bibelbund.csv +0 -3741
  26. data/test/files/Bibelbund.ods +0 -0
  27. data/test/files/Bibelbund.xlsx +0 -0
  28. data/test/files/Bibelbund1.ods +0 -0
  29. data/test/files/Pfand_from_windows_phone.xlsx +0 -0
  30. data/test/files/advanced_header.ods +0 -0
  31. data/test/files/bbu.ods +0 -0
  32. data/test/files/bbu.xlsx +0 -0
  33. data/test/files/bode-v1.ods.zip +0 -0
  34. data/test/files/bode-v1.xls.zip +0 -0
  35. data/test/files/boolean.csv +0 -2
  36. data/test/files/boolean.ods +0 -0
  37. data/test/files/boolean.xlsx +0 -0
  38. data/test/files/borders.ods +0 -0
  39. data/test/files/borders.xlsx +0 -0
  40. data/test/files/bug-numbered-sheet-names.xlsx +0 -0
  41. data/test/files/comments.ods +0 -0
  42. data/test/files/comments.xlsx +0 -0
  43. data/test/files/csvtypes.csv +0 -1
  44. data/test/files/datetime.ods +0 -0
  45. data/test/files/datetime.xlsx +0 -0
  46. data/test/files/dreimalvier.ods +0 -0
  47. data/test/files/emptysheets.ods +0 -0
  48. data/test/files/emptysheets.xlsx +0 -0
  49. data/test/files/encrypted-letmein.ods +0 -0
  50. data/test/files/file_item_error.xlsx +0 -0
  51. data/test/files/formula.ods +0 -0
  52. data/test/files/formula.xlsx +0 -0
  53. data/test/files/formula_string_error.xlsx +0 -0
  54. data/test/files/html-escape.ods +0 -0
  55. data/test/files/link.csv +0 -1
  56. data/test/files/link.xlsx +0 -0
  57. data/test/files/matrix.ods +0 -0
  58. data/test/files/named_cells.ods +0 -0
  59. data/test/files/named_cells.xlsx +0 -0
  60. data/test/files/no_spreadsheet_file.txt +0 -1
  61. data/test/files/numbers-export.xlsx +0 -0
  62. data/test/files/numbers1.csv +0 -18
  63. data/test/files/numbers1.ods +0 -0
  64. data/test/files/numbers1.xlsx +0 -0
  65. data/test/files/numbers1withnull.xlsx +0 -0
  66. data/test/files/numeric-link.xlsx +0 -0
  67. data/test/files/only_one_sheet.ods +0 -0
  68. data/test/files/only_one_sheet.xlsx +0 -0
  69. data/test/files/paragraph.ods +0 -0
  70. data/test/files/paragraph.xlsx +0 -0
  71. data/test/files/ric.ods +0 -0
  72. data/test/files/sheet1.xml +0 -109
  73. data/test/files/simple_spreadsheet.ods +0 -0
  74. data/test/files/simple_spreadsheet.xlsx +0 -0
  75. data/test/files/simple_spreadsheet_from_italo.ods +0 -0
  76. data/test/files/so_datetime.csv +0 -8
  77. data/test/files/style.ods +0 -0
  78. data/test/files/style.xlsx +0 -0
  79. data/test/files/time-test.csv +0 -2
  80. data/test/files/time-test.ods +0 -0
  81. data/test/files/time-test.xlsx +0 -0
  82. data/test/files/type_excel.ods +0 -0
  83. data/test/files/type_excel.xlsx +0 -0
  84. data/test/files/type_excelx.ods +0 -0
  85. data/test/files/type_openoffice.xlsx +0 -0
  86. data/test/files/whitespace.ods +0 -0
  87. data/test/files/whitespace.xlsx +0 -0
@@ -1,12 +1,16 @@
1
1
  module Roo
2
2
  module Utils
3
3
  extend self
4
- LETTERS = ('A'..'Z').to_a
4
+
5
5
  def split_coordinate(str)
6
- letter, number = split_coord(str)
7
- x = letter_to_number(letter)
8
- y = number
9
- [y, x]
6
+ @split_coordinate ||= {}
7
+
8
+ @split_coordinate[str] ||= begin
9
+ letter, number = split_coord(str)
10
+ x = letter_to_number(letter)
11
+ y = number
12
+ [y, x]
13
+ end
10
14
  end
11
15
 
12
16
  alias_method :ref_to_key, :split_coordinate
@@ -22,40 +26,33 @@ module Roo
22
26
  end
23
27
 
24
28
  # convert a number to something like 'AB' (1 => 'A', 2 => 'B', ...)
25
- def number_to_letter(n)
26
- letters = ''
27
- if n > 26
28
- while n % 26 == 0 && n != 0
29
- letters << 'Z'
30
- n = ((n - 26) / 26).to_i
31
- end
32
- while n > 0
33
- num = n % 26
34
- letters = LETTERS[num - 1] + letters
35
- n = (n / 26).to_i
36
- end
37
- else
38
- letters = LETTERS[n - 1]
29
+ def number_to_letter(num)
30
+ results = []
31
+ num = num.to_i
32
+
33
+ while (num > 0)
34
+ mod = (num - 1) % 26
35
+ results = [(65 + mod).chr] + results
36
+ num = ((num - mod) / 26)
39
37
  end
40
- letters
38
+
39
+ results.join
41
40
  end
42
41
 
43
- # convert letters like 'AB' to a number ('A' => 1, 'B' => 2, ...)
44
42
  def letter_to_number(letters)
45
- result = 0
46
- while letters && letters.length > 0
47
- character = letters[0, 1].upcase
48
- num = LETTERS.index(character)
49
- fail ArgumentError, "invalid column character '#{letters[0, 1]}'" if num.nil?
50
- num += 1
51
- result = result * 26 + num
52
- letters = letters[1..-1]
43
+ @letter_to_number ||= {}
44
+ @letter_to_number[letters] ||= begin
45
+ result = 0
46
+
47
+ # :bytes method returns an enumerator in 1.9.3 and an array in 2.0+
48
+ letters.bytes.to_a.map{|b| b > 96 ? b - 96 : b - 64 }.reverse.each_with_index{ |num, i| result += num * 26 ** i }
49
+
50
+ result
53
51
  end
54
- result
55
52
  end
56
53
 
57
54
  # Compute upper bound for cells in a given cell range.
58
- def self.num_cells_in_range(str)
55
+ def num_cells_in_range(str)
59
56
  cells = str.split(':')
60
57
  return 1 if cells.count == 1
61
58
  raise ArgumentError.new("invalid range string: #{str}. Supported range format 'A1:B2'") if cells.count != 2
@@ -1,3 +1,3 @@
1
1
  module Roo
2
- VERSION = "2.0.1"
2
+ VERSION = "2.0.2"
3
3
  end
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # encoding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'roo/version'
@@ -6,22 +6,20 @@ require 'roo/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'culturecode-roo'
8
8
  spec.version = Roo::VERSION
9
- spec.authors = ['Thomas Preymesser', 'Hugh McGowan', 'Ben Woosley']
10
- spec.email = ['ruby.ruby.ruby.roo@gmail.com']
9
+ spec.authors = ['Thomas Preymesser', 'Hugh McGowan', 'Ben Woosley', 'Oleksandr Simonov']
10
+ spec.email = ['ruby.ruby.ruby.roo@gmail.com', 'oleksandr@simonov.me']
11
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* Excel\n* Google spreadsheets\n* Excelx\n* LibreOffice\n* CSV"
13
- spec.homepage = 'http://github.com/Empact/roo'
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 = 'http://github.com/roo-rb/roo'
14
14
  spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.files.reject! { |fn| fn.include?('test/files') }
19
18
  spec.require_paths = ['lib']
20
19
 
21
- spec.add_dependency 'nokogiri'
22
- spec.add_dependency 'rubyzip', '>= 1.0.0'
20
+ spec.add_dependency 'nokogiri', '~> 1'
21
+ spec.add_dependency 'rubyzip', '~> 1.1', '< 2.0.0'
23
22
 
24
- spec.add_development_dependency 'bundler', '>= 1.7'
25
- spec.add_development_dependency 'rake', '>= 10.0'
26
- spec.add_development_dependency 'minitest', '>= 5.4.3'
23
+ spec.add_development_dependency 'rake', '~> 10.1'
24
+ spec.add_development_dependency 'minitest', '~> 5.4', '>= 5.4.3'
27
25
  end
@@ -23,6 +23,20 @@ describe Roo::CSV do
23
23
  end
24
24
  end
25
25
 
26
+ describe '#parse_with_clean_option' do
27
+ subject do
28
+ csv.parse(options)
29
+ end
30
+ context 'with clean: true' do
31
+ let(:options) { {clean: true} }
32
+ let(:path) { 'test/files/parse_with_clean_option.csv' }
33
+
34
+ it "doesn't blow up" do
35
+ expect { subject }.to_not raise_error
36
+ end
37
+ end
38
+ end
39
+
26
40
  describe '#csv_options' do
27
41
  context 'when created with the csv_options option' do
28
42
  let(:options) do
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Roo::Excelx do
@@ -35,6 +36,15 @@ describe Roo::Excelx do
35
36
  expect(Roo::Excelx.new(path, cell_max: 100)).to be_a(Roo::Excelx)
36
37
  end
37
38
  end
39
+
40
+ context 'file path is a Pathname' do
41
+ let(:path) { Pathname.new('test/files/file_item_error.xlsx') }
42
+
43
+ it 'creates an instance' do
44
+ expect(subject).to be_a(Roo::Excelx)
45
+ end
46
+ end
47
+
38
48
  end
39
49
 
40
50
  describe '#cell' do
@@ -52,6 +62,13 @@ describe Roo::Excelx do
52
62
  end
53
63
  end
54
64
  end
65
+
66
+ context 'for a non-existent cell' do
67
+ let(:path) { 'test/files/numeric-link.xlsx' }
68
+ it 'return nil' do
69
+ expect(xlsx.cell('AAA', 999)).to eq nil
70
+ end
71
+ end
55
72
  end
56
73
 
57
74
  describe '#parse' do
@@ -71,12 +88,49 @@ describe Roo::Excelx do
71
88
  end
72
89
  end
73
90
 
91
+ describe '#parse_with_clean_option' do
92
+ let(:path) { 'test/files/parse_with_clean_option.xlsx' }
93
+ let(:options) { {clean: true} }
94
+
95
+ context 'with clean: true' do
96
+
97
+ it 'does not raise' do
98
+ expect do
99
+ xlsx.parse(options)
100
+ end.not_to raise_error
101
+ end
102
+ end
103
+ end
104
+
105
+ describe '#parse_unicode_with_clean_option' do
106
+ let(:path) { 'test/files/parse_clean_with_unicode.xlsx' }
107
+ let(:options) { {clean: true, name: 'Name'} }
108
+
109
+ context 'with clean: true' do
110
+
111
+ it 'returns a non empty string' do
112
+ expect(xlsx.parse(options).last[:name]).to eql('凯')
113
+ end
114
+ end
115
+ end
116
+
117
+
118
+
119
+
74
120
  describe '#sheets' do
75
121
  let(:path) { 'test/files/numbers1.xlsx' }
76
122
 
77
123
  it 'returns the expected result' do
78
124
  expect(subject.sheets).to eq ["Tabelle1", "Name of Sheet 2", "Sheet3", "Sheet4", "Sheet5"]
79
125
  end
126
+
127
+ describe 'only showing visible sheets' do
128
+ let(:path) { 'test/files/hidden_sheets.xlsx' }
129
+
130
+ it 'returns the expected result' do
131
+ expect(Roo::Excelx.new(path, only_visible_sheets: true).sheets).to eq ["VisibleSheet1"]
132
+ end
133
+ end
80
134
  end
81
135
 
82
136
  describe '#sheet_for' do
@@ -156,6 +210,7 @@ describe Roo::Excelx do
156
210
  it 'returns the expected result' do
157
211
  expect(subject.formula(1, 1, "Sheet1")).to eq nil
158
212
  expect(subject.formula(7, 2, "Sheet1")).to eq "SUM($A$1:B6)"
213
+ expect(subject.formula(1000, 2000, "Sheet1")).to eq nil
159
214
  end
160
215
  end
161
216
 
@@ -165,6 +220,7 @@ describe Roo::Excelx do
165
220
  it 'returns the expected result' do
166
221
  expect(subject.formula?(1, 1, "Sheet1")).to eq false
167
222
  expect(subject.formula?(7, 2, "Sheet1")).to eq true
223
+ expect(subject.formula?(1000, 2000, "Sheet1")).to eq false
168
224
  end
169
225
  end
170
226
 
@@ -187,6 +243,7 @@ describe Roo::Excelx do
187
243
  expect(subject.font(7, 1).bold?).to eq false
188
244
  expect(subject.font(7, 1).italic?).to eq true
189
245
  expect(subject.font(7, 1).underline?).to eq true
246
+ expect(subject.font(1000, 2000)).to eq nil
190
247
  end
191
248
  end
192
249
 
@@ -197,6 +254,7 @@ describe Roo::Excelx do
197
254
  expect(subject.celltype(1, 1, "Sheet4")).to eq :date
198
255
  expect(subject.celltype(1, 2, "Sheet4")).to eq :float
199
256
  expect(subject.celltype(6, 2, "Sheet5")).to eq :string
257
+ expect(subject.celltype(1000, 2000, "Sheet5")).to eq nil
200
258
  end
201
259
  end
202
260
 
@@ -206,6 +264,7 @@ describe Roo::Excelx do
206
264
  it 'returns the expected result' do
207
265
  expect(subject.excelx_type(1, 1, "Sheet5")).to eq [:numeric_or_formula, "General"]
208
266
  expect(subject.excelx_type(6, 2, "Sheet5")).to eq :string
267
+ expect(subject.excelx_type(1000, 2000, "Sheet5")).to eq nil
209
268
  end
210
269
  end
211
270
 
@@ -217,6 +276,7 @@ describe Roo::Excelx do
217
276
  # way to get these rather than hardcoding.
218
277
  expect(subject.excelx_value(1, 1, "Sheet5")).to eq "1"
219
278
  expect(subject.excelx_value(6, 2, "Sheet5")).to eq "16"
279
+ expect(subject.excelx_value(6000, 2000, "Sheet5")).to eq nil
220
280
  end
221
281
  end
222
282
 
@@ -226,8 +286,9 @@ describe Roo::Excelx do
226
286
  it 'returns the expected result' do
227
287
  # These are the index of the style for a given document
228
288
  # might be more reliable way to get this info.
229
- expect(subject.excelx_value(1, 1)).to eq "0"
230
- expect(subject.excelx_value(5, 1)).to eq "4"
289
+ expect(subject.excelx_format(1, 1)).to eq "General"
290
+ expect(subject.excelx_format(2, 2)).to eq "0.00"
291
+ expect(subject.excelx_format(5000, 1000)).to eq nil
231
292
  end
232
293
  end
233
294
 
@@ -359,5 +420,32 @@ describe Roo::Excelx do
359
420
  expect(index).to eq 4
360
421
  end
361
422
  end
423
+
424
+ context 'with offset option' do
425
+ let(:offset) { 3 }
426
+
427
+ it 'returns the expected result' do
428
+ index = 0
429
+ subject.each_row_streaming(offset: offset) do |row|
430
+ expect(row.map(&:value)).to eq expected_rows[index + offset]
431
+ index += 1
432
+ end
433
+ expect(index).to eq 11
434
+ end
435
+ end
436
+
437
+ context 'with offset and max_rows options' do
438
+ let(:offset) { 3 }
439
+ let(:max_rows) { 3 }
440
+
441
+ it 'returns the expected result' do
442
+ index = 0
443
+ subject.each_row_streaming(offset: offset, max_rows: max_rows) do |row|
444
+ expect(row.map(&:value)).to eq expected_rows[index + offset]
445
+ index += 1
446
+ end
447
+ expect(index).to eq 4
448
+ end
449
+ end
362
450
  end
363
451
  end
@@ -10,4 +10,20 @@ describe Roo::LibreOffice do
10
10
  expect(subject).to be_a(Roo::LibreOffice)
11
11
  end
12
12
  end
13
+
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
28
+ end
13
29
  end
@@ -9,6 +9,17 @@ describe Roo::OpenOffice do
9
9
  it 'creates an instance' do
10
10
  expect(subject).to be_a(Roo::OpenOffice)
11
11
  end
12
+
13
+ context 'file path is a Pathname' do
14
+ subject do
15
+ Roo::OpenOffice.new(Pathname.new('test/files/numbers1.ods'))
16
+ end
17
+
18
+ it 'creates an instance' do
19
+ expect(subject).to be_a(Roo::OpenOffice)
20
+ end
21
+ end
22
+
12
23
  end
13
24
 
14
25
  # OpenOffice is an alias of LibreOffice. See libreoffice_spec.
@@ -2,16 +2,17 @@ require 'spec_helper'
2
2
 
3
3
  RSpec.describe ::Roo::Utils do
4
4
  subject { described_class }
5
+
5
6
  context '#number_to_letter' do
6
- ::Roo::Utils::LETTERS.each_with_index do |l, i|
7
- it "should return '#{l}' when passed #{i+1}" do
8
- expect(described_class.number_to_letter(i+1)).to eq(l)
7
+ ('A'..'Z').to_a.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)
9
10
  end
10
11
  end
11
12
 
12
13
  {
13
14
  27 => 'AA', 26*2 => 'AZ', 26*3 => 'BZ', 26**2 + 26 => 'ZZ', 26**2 + 27 => 'AAA',
14
- 26**3 + 26**2 + 26 => 'ZZZ', 1.0 => 'A'
15
+ 26**3 + 26**2 + 26 => 'ZZZ', 1.0 => 'A', 676 => 'YZ', 677 => 'ZA'
15
16
  }.each do |key, value|
16
17
  it "should return '#{value}' when passed #{key}" do
17
18
  expect(described_class.number_to_letter(key)).to eq(value)
@@ -18,6 +18,7 @@
18
18
  #STDERR.reopen "/dev/null","w"
19
19
 
20
20
  require 'test_helper'
21
+ require 'stringio'
21
22
 
22
23
  class TestRoo < Minitest::Test
23
24
 
@@ -63,7 +64,7 @@ class TestRoo < Minitest::Test
63
64
  yield Roo::Spreadsheet.open(File.join(TESTDIR,
64
65
  fixture_filename(options[:name], format)))
65
66
  rescue => e
66
- raise e, "#{e.message} for #{format}", e.backtrace
67
+ raise e, "#{e.message} for #{format}", e.backtrace unless options[:ignore_errors]
67
68
  end
68
69
  end
69
70
  end
@@ -935,6 +936,7 @@ Sheet 3:
935
936
 
936
937
  def test_to_xml
937
938
  with_each_spreadsheet(:name=>'numbers1', :encoding => 'utf8') do |oo|
939
+ skip if defined? JRUBY_VERSION
938
940
  oo.to_xml
939
941
  sheetname = oo.sheets.first
940
942
  doc = Nokogiri::XML(oo.to_xml)
@@ -1645,6 +1647,7 @@ where the expected result is
1645
1647
  end
1646
1648
 
1647
1649
  def test_bug_pfand_from_windows_phone_xlsx
1650
+ return if defined? JRUBY_VERSION
1648
1651
  with_each_spreadsheet(:name=>'Pfand_from_windows_phone', :format=>:excelx) do |oo|
1649
1652
  oo.default_sheet = oo.sheets.first
1650
1653
  assert_equal ['Blatt1','Blatt2','Blatt3'], oo.sheets
@@ -1686,6 +1689,11 @@ where the expected result is
1686
1689
  oo.default_sheet = oo.sheets[1]
1687
1690
  assert_equal [], oo.comments, "comments error in class #{oo.class}"
1688
1691
  end
1692
+
1693
+ with_each_spreadsheet(:name=>'comments-google', :format=>[:excelx]) do |oo|
1694
+ oo.default_sheet = oo.sheets.first
1695
+ assert_equal [[1, 1, "this is a comment\n\t-Steven Daniels"]], oo.comments(oo.sheets.first), "comments error in class #{oo.class}"
1696
+ end
1689
1697
  end
1690
1698
 
1691
1699
  ## PREVIOUSLY SKIPPED
@@ -1963,7 +1971,7 @@ where the expected result is
1963
1971
  xlsx.default_sheet = xlsx.sheets.last
1964
1972
  assert_equal 'Sheet 2', xlsx.cell('b',2)
1965
1973
  end
1966
-
1974
+
1967
1975
  def test_openoffice_encryption
1968
1976
  if OPENOFFICE
1969
1977
  assert_raises(ArgumentError) { Roo::LibreOffice.new(File.join(TESTDIR, "encrypted-letmein.ods")) }
@@ -1974,4 +1982,107 @@ where the expected result is
1974
1982
  end
1975
1983
  end
1976
1984
 
1985
+ def test_expand_merged_range
1986
+ return unless EXCELX
1987
+ xlsx = Roo::Excelx.new(File.join(TESTDIR, "merged_ranges.xlsx"), {:expand_merged_ranges => true})
1988
+ for row in 3..7 do
1989
+ for col in 'a'..'b'
1990
+ if row > 3 && row < 7 && col == 'a'
1991
+ assert_equal 'vertical1', xlsx.cell(col,row)
1992
+ else
1993
+ assert_nil xlsx.cell(col,row)
1994
+ end
1995
+ end
1996
+ end
1997
+ for row in 3..11 do
1998
+ for col in 'f'..'h'
1999
+ if row > 3 && row < 11 && col == 'g'
2000
+ assert_equal 'vertical2', xlsx.cell(col,row)
2001
+ else
2002
+ assert_nil xlsx.cell(col,row)
2003
+ end
2004
+ end
2005
+ end
2006
+ for row in 3..5 do
2007
+ for col in 'b'..'f'
2008
+ if row == 4 && col > 'b' && col < 'f'
2009
+ assert_equal 'horizontal', xlsx.cell(col,row)
2010
+ else
2011
+ assert_nil xlsx.cell(col,row)
2012
+ end
2013
+ end
2014
+ end
2015
+ for row in 8..13 do
2016
+ for col in 'a'..'e'
2017
+ if row > 8 && row < 13 && col > 'a' && col < 'e'
2018
+ assert_equal 'block', xlsx.cell(col,row)
2019
+ else
2020
+ assert_nil xlsx.cell(col,row)
2021
+ end
2022
+ end
2023
+ end
2024
+ end
2025
+
2026
+ def test_noexpand_merged_range
2027
+ return unless EXCELX
2028
+ xlsx = Roo::Excelx.new(File.join(TESTDIR, "merged_ranges.xlsx"))
2029
+ for row in 3..7 do
2030
+ for col in 'a'..'b'
2031
+ if row == 4 && col == 'a'
2032
+ assert_equal 'vertical1', xlsx.cell(col,row)
2033
+ else
2034
+ assert_nil xlsx.cell(col,row)
2035
+ end
2036
+ end
2037
+ end
2038
+ for row in 3..11 do
2039
+ for col in 'f'..'h'
2040
+ if row == 4 && col == 'g'
2041
+ assert_equal 'vertical2', xlsx.cell(col,row)
2042
+ else
2043
+ assert_nil xlsx.cell(col,row)
2044
+ end
2045
+ end
2046
+ end
2047
+ for row in 3..5 do
2048
+ for col in 'b'..'f'
2049
+ if row == 4 && col == 'c'
2050
+ assert_equal 'horizontal', xlsx.cell(col,row)
2051
+ else
2052
+ assert_nil xlsx.cell(col,row)
2053
+ end
2054
+ end
2055
+ end
2056
+ for row in 8..13 do
2057
+ for col in 'a'..'e'
2058
+ if row == 9 && col == 'b'
2059
+ assert_equal 'block', xlsx.cell(col,row)
2060
+ else
2061
+ assert_nil xlsx.cell(col,row)
2062
+ end
2063
+ end
2064
+ end
2065
+ end
2066
+
2067
+ def test_open_stream
2068
+ return unless EXCELX
2069
+ file_contents = File.read File.join(TESTDIR, fixture_filename(:numbers1, :excelx))
2070
+ stream = StringIO.new(file_contents)
2071
+ xlsx = Roo::Excelx.new(stream)
2072
+ assert_equal ["Tabelle1","Name of Sheet 2","Sheet3","Sheet4","Sheet5"], xlsx.sheets
2073
+ end
2074
+
2075
+ def test_close
2076
+ with_each_spreadsheet(:name=>'numbers1') do |oo|
2077
+ next unless (tempdir = oo.instance_variable_get('@tmpdir'))
2078
+ oo.close
2079
+ assert !File.exists?(tempdir), "Expected #{tempdir} to be cleaned up, but it still exists"
2080
+ end
2081
+ end
2082
+
2083
+ def test_cleanup_on_error
2084
+ old_temp_files = Dir.open(Dir.tmpdir).to_a
2085
+ with_each_spreadsheet(:name=>'non_existent_file', :ignore_errors=>true) do |oo|; end
2086
+ assert_equal Dir.open(Dir.tmpdir).to_a, old_temp_files
2087
+ end
1977
2088
  end # class