culturecode-roo 2.0.1 → 2.0.2

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.
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