roo 2.7.1 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +5 -5
  2. data/.github/issue_template.md +16 -0
  3. data/.github/pull_request_template.md +14 -0
  4. data/.rubocop.yml +186 -0
  5. data/.travis.yml +12 -7
  6. data/CHANGELOG.md +31 -2
  7. data/LICENSE +2 -0
  8. data/README.md +25 -12
  9. data/lib/roo.rb +4 -1
  10. data/lib/roo/base.rb +65 -56
  11. data/lib/roo/constants.rb +5 -3
  12. data/lib/roo/csv.rb +20 -12
  13. data/lib/roo/excelx.rb +42 -16
  14. data/lib/roo/excelx/cell.rb +10 -6
  15. data/lib/roo/excelx/cell/base.rb +26 -12
  16. data/lib/roo/excelx/cell/boolean.rb +9 -6
  17. data/lib/roo/excelx/cell/date.rb +7 -7
  18. data/lib/roo/excelx/cell/datetime.rb +14 -18
  19. data/lib/roo/excelx/cell/empty.rb +3 -2
  20. data/lib/roo/excelx/cell/number.rb +35 -34
  21. data/lib/roo/excelx/cell/string.rb +3 -3
  22. data/lib/roo/excelx/cell/time.rb +4 -3
  23. data/lib/roo/excelx/comments.rb +3 -3
  24. data/lib/roo/excelx/coordinate.rb +11 -4
  25. data/lib/roo/excelx/extractor.rb +21 -3
  26. data/lib/roo/excelx/format.rb +38 -31
  27. data/lib/roo/excelx/images.rb +26 -0
  28. data/lib/roo/excelx/relationships.rb +3 -3
  29. data/lib/roo/excelx/shared.rb +10 -3
  30. data/lib/roo/excelx/shared_strings.rb +9 -15
  31. data/lib/roo/excelx/sheet.rb +49 -10
  32. data/lib/roo/excelx/sheet_doc.rb +86 -48
  33. data/lib/roo/excelx/styles.rb +3 -3
  34. data/lib/roo/excelx/workbook.rb +7 -3
  35. data/lib/roo/helpers/default_attr_reader.rb +20 -0
  36. data/lib/roo/helpers/weak_instance_cache.rb +41 -0
  37. data/lib/roo/open_office.rb +8 -6
  38. data/lib/roo/spreadsheet.rb +1 -1
  39. data/lib/roo/utils.rb +48 -19
  40. data/lib/roo/version.rb +1 -1
  41. data/roo.gemspec +13 -11
  42. data/spec/lib/roo/base_spec.rb +45 -3
  43. data/spec/lib/roo/excelx_spec.rb +125 -31
  44. data/spec/lib/roo/strict_spec.rb +43 -0
  45. data/spec/lib/roo/utils_spec.rb +12 -3
  46. data/spec/lib/roo/weak_instance_cache_spec.rb +92 -0
  47. data/spec/lib/roo_spec.rb +0 -0
  48. data/test/excelx/cell/test_attr_reader_default.rb +72 -0
  49. data/test/excelx/cell/test_base.rb +5 -0
  50. data/test/excelx/cell/test_datetime.rb +6 -6
  51. data/test/excelx/cell/test_empty.rb +11 -0
  52. data/test/excelx/cell/test_number.rb +9 -0
  53. data/test/excelx/cell/test_string.rb +20 -0
  54. data/test/excelx/cell/test_time.rb +4 -4
  55. data/test/excelx/test_coordinate.rb +51 -0
  56. data/test/formatters/test_csv.rb +17 -0
  57. data/test/formatters/test_xml.rb +4 -4
  58. data/test/roo/test_base.rb +2 -2
  59. data/test/roo/test_csv.rb +28 -0
  60. data/test/test_helper.rb +13 -0
  61. data/test/test_roo.rb +7 -7
  62. metadata +21 -11
  63. data/.github/ISSUE_TEMPLATE +0 -10
  64. data/Gemfile_ruby2 +0 -30
@@ -24,7 +24,7 @@ module Roo
24
24
  options[:file_warning] = :ignore
25
25
  extension.tr('.', '').downcase.to_sym
26
26
  else
27
- res = ::File.extname((path =~ /\A#{::URI.regexp}\z/) ? ::URI.parse(::URI.encode(path)).path : path)
27
+ res = ::File.extname((path =~ /\A#{::URI::DEFAULT_PARSER.make_regexp}\z/) ? ::URI.parse(::URI.encode(path)).path : path)
28
28
  res.tr('.', '').downcase.to_sym
29
29
  end
30
30
  end
@@ -4,27 +4,39 @@ module Roo
4
4
 
5
5
  LETTERS = ('A'..'Z').to_a
6
6
 
7
- def split_coordinate(str)
8
- @split_coordinate ||= {}
7
+ def extract_coordinate(s)
8
+ num = letter_num = 0
9
+ num_only = false
9
10
 
10
- @split_coordinate[str] ||= begin
11
- letter, number = split_coord(str)
12
- x = letter_to_number(letter)
13
- y = number
14
- [y, x]
11
+ s.each_byte do |b|
12
+ if !num_only && (index = char_index(b))
13
+ letter_num *= 26
14
+ letter_num += index
15
+ elsif index = num_index(b)
16
+ num_only = true
17
+ num *= 10
18
+ num += index
19
+ else
20
+ fail ArgumentError
21
+ end
15
22
  end
23
+ fail ArgumentError if letter_num == 0 || !num_only
24
+
25
+ Excelx::Coordinate.new(num, letter_num)
16
26
  end
17
27
 
18
- alias_method :ref_to_key, :split_coordinate
28
+ alias_method :ref_to_key, :extract_coordinate
19
29
 
20
- def split_coord(s)
21
- if s =~ /([a-zA-Z]+)([0-9]+)/
22
- letter = Regexp.last_match[1]
23
- number = Regexp.last_match[2].to_i
24
- else
25
- fail ArgumentError
26
- end
27
- [letter, number]
30
+ def split_coordinate(str)
31
+ warn "[DEPRECATION] `Roo::Utils.split_coordinate` is deprecated. Please use `Roo::Utils.extract_coordinate` instead."
32
+ extract_coordinate(str)
33
+ end
34
+
35
+
36
+
37
+ def split_coord(str)
38
+ coord = extract_coordinate(str)
39
+ [number_to_letter(coord.column), coord.row]
28
40
  end
29
41
 
30
42
  # convert a number to something like 'AB' (1 => 'A', 2 => 'B', ...)
@@ -56,8 +68,8 @@ module Roo
56
68
  cells = str.split(':')
57
69
  return 1 if cells.count == 1
58
70
  raise ArgumentError.new("invalid range string: #{str}. Supported range format 'A1:B2'") if cells.count != 2
59
- x1, y1 = split_coordinate(cells[0])
60
- x2, y2 = split_coordinate(cells[1])
71
+ x1, y1 = extract_coordinate(cells[0])
72
+ x2, y2 = extract_coordinate(cells[1])
61
73
  (x2 - (x1 - 1)) * (y2 - (y1 - 1))
62
74
  end
63
75
 
@@ -69,10 +81,27 @@ module Roo
69
81
 
70
82
  # Yield each element of a given type ('row', 'c', etc.) to caller
71
83
  def each_element(path, elements)
84
+ elements = Array(elements)
72
85
  Nokogiri::XML::Reader(::File.open(path, 'rb'), nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS).each do |node|
73
- next unless node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT && Array(elements).include?(node.name)
86
+ next unless node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT && elements.include?(node.name)
74
87
  yield Nokogiri::XML(node.outer_xml).root if block_given?
75
88
  end
76
89
  end
90
+
91
+ private
92
+
93
+ def char_index(byte)
94
+ if byte >= 65 && byte <= 90
95
+ byte - 64
96
+ elsif byte >= 97 && byte <= 122
97
+ byte - 96
98
+ end
99
+ end
100
+
101
+ def num_index(byte)
102
+ if byte >= 48 && byte <= 57
103
+ byte - 48
104
+ end
105
+ end
77
106
  end
78
107
  end
@@ -1,3 +1,3 @@
1
1
  module Roo
2
- VERSION = "2.7.1"
2
+ VERSION = "2.8.0"
3
3
  end
@@ -4,21 +4,23 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'roo/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = 'roo'
8
- spec.version = Roo::VERSION
9
- spec.authors = ['Thomas Preymesser', 'Hugh McGowan', 'Ben Woosley', 'Oleksandr Simonov', 'Steven Daniels']
10
- spec.email = ['ruby.ruby.ruby.roo@gmail.com', 'oleksandr@simonov.me']
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* Excelx\n* LibreOffice\n* CSV"
13
- spec.homepage = 'http://github.com/roo-rb/roo'
14
- spec.license = 'MIT'
7
+ spec.name = 'roo'
8
+ spec.version = Roo::VERSION
9
+ spec.authors = ['Thomas Preymesser', 'Hugh McGowan', 'Ben Woosley', 'Oleksandr Simonov', 'Steven Daniels', 'Anmol Chopra']
10
+ spec.email = ['ruby.ruby.ruby.roo@gmail.com', 'oleksandr@simonov.me']
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* Excelx\n* LibreOffice\n* CSV"
13
+ spec.homepage = 'https://github.com/roo-rb/roo'
14
+ spec.license = 'MIT'
15
15
 
16
- spec.files = `git ls-files -z`.split("\x0")
16
+ spec.files = `git ls-files -z`.split("\x0")
17
17
  spec.files.reject! { |fn| fn.include?('test/files') }
18
- spec.require_paths = ['lib']
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.required_ruby_version = ">= 2.3.0"
19
21
 
20
22
  spec.add_dependency 'nokogiri', '~> 1'
21
- spec.add_dependency 'rubyzip', '~> 1.1', '< 2.0.0'
23
+ spec.add_dependency 'rubyzip', '>= 1.2.1', '< 2.0.0'
22
24
 
23
25
  spec.add_development_dependency 'rake', '~> 10.1'
24
26
  spec.add_development_dependency 'minitest', '~> 5.4', '>= 5.4.3'
@@ -127,10 +127,22 @@ describe Roo::Base do
127
127
  end
128
128
  end
129
129
 
130
- describe '#row' do
131
- it 'should return the specified row' do
130
+ describe "#row" do
131
+ it "should return the specified row" do
132
132
  expect(spreadsheet.row(12)).to eq([41.0, 42.0, 43.0, 44.0, 45.0, nil, nil])
133
- expect(spreadsheet.row(16)).to eq([nil, '"Hello world!"', 'forty-three', 'forty-four', 'forty-five', nil, nil])
133
+ expect(spreadsheet.row(16)).to eq([nil, '"Hello world!"', "forty-three", "forty-four", "forty-five", nil, nil])
134
+ end
135
+
136
+ it "should return the specified row if default_sheet is set by a string" do
137
+ spreadsheet.default_sheet = "my_sheet"
138
+ expect(spreadsheet.row(12)).to eq([41.0, 42.0, 43.0, 44.0, 45.0, nil, nil])
139
+ expect(spreadsheet.row(16)).to eq([nil, '"Hello world!"', "forty-three", "forty-four", "forty-five", nil, nil])
140
+ end
141
+
142
+ it "should return the specified row if default_sheet is set by an integer" do
143
+ spreadsheet.default_sheet = 0
144
+ expect(spreadsheet.row(12)).to eq([41.0, 42.0, 43.0, 44.0, 45.0, nil, nil])
145
+ expect(spreadsheet.row(16)).to eq([nil, '"Hello world!"', "forty-three", "forty-four", "forty-five", nil, nil])
134
146
  end
135
147
  end
136
148
 
@@ -146,6 +158,11 @@ describe Roo::Base do
146
158
  expect { spreadsheet.row_with([/Missing Header/]) }.to \
147
159
  raise_error(Roo::HeaderRowNotFoundError)
148
160
  end
161
+
162
+ it 'returns missing headers' do
163
+ expect { spreadsheet.row_with([/Header/, /Missing Header 1/, /Missing Header 2/]) }.to \
164
+ raise_error(Roo::HeaderRowNotFoundError, '[/Missing Header 1/, /Missing Header 2/]')
165
+ end
149
166
  end
150
167
  end
151
168
 
@@ -173,6 +190,31 @@ describe Roo::Base do
173
190
  end
174
191
  end
175
192
 
193
+ describe "#default_sheet=" do
194
+ it "should correctly set the default sheet if passed a string" do
195
+ spreadsheet.default_sheet = "my_sheet"
196
+ expect(spreadsheet.default_sheet).to eq("my_sheet")
197
+ end
198
+
199
+ it "should correctly set the default sheet if passed an integer" do
200
+ spreadsheet.default_sheet = 0
201
+ expect(spreadsheet.default_sheet).to eq("my_sheet")
202
+ end
203
+
204
+ it "should correctly set the default sheet if passed an integer for the second sheet" do
205
+ spreadsheet.default_sheet = 1
206
+ expect(spreadsheet.default_sheet).to eq("blank sheet")
207
+ end
208
+
209
+ it "should raise an error if passed a sheet that does not exist as an integer" do
210
+ expect { spreadsheet.default_sheet = 10 }.to raise_error RangeError
211
+ end
212
+
213
+ it "should raise an error if passed a sheet that does not exist as a string" do
214
+ expect { spreadsheet.default_sheet = "does_not_exist" }.to raise_error RangeError
215
+ end
216
+ end
217
+
176
218
  describe '#to_yaml' do
177
219
  it 'should convert the spreadsheet to yaml' do
178
220
  expect(spreadsheet.to_yaml({}, 5, 1, 5, 1)).to eq("--- \n" + yaml_entry(5, 1, 'date', '1961-11-21'))
@@ -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
 
@@ -354,11 +382,22 @@ describe Roo::Excelx do
354
382
  end
355
383
 
356
384
  describe '#hyperlink' do
357
- let(:path) { 'test/files/link.xlsx' }
385
+ context 'without location' do
386
+ let(:path) { 'test/files/link.xlsx' }
358
387
 
359
- it 'returns the expected result' do
360
- expect(subject.hyperlink(1, 1)).to eq "http://www.google.com"
361
- expect(subject.hyperlink(1, 2)).to eq nil
388
+ it 'returns the expected result' do
389
+ expect(subject.hyperlink(1, 1)).to eq "http://www.google.com"
390
+ expect(subject.hyperlink(1, 2)).to eq nil
391
+ end
392
+ end
393
+
394
+ context 'with location' do
395
+ let(:path) { 'test/files/link_with_location.xlsx' }
396
+
397
+ it 'returns the expected result' do
398
+ expect(subject.hyperlink(1, 1)).to eq "http://www.google.com/#hey"
399
+ expect(subject.hyperlink(1, 2)).to eq nil
400
+ end
362
401
  end
363
402
  end
364
403
 
@@ -480,34 +519,36 @@ describe Roo::Excelx do
480
519
  end
481
520
 
482
521
  describe '#html_strings' do
483
- let(:path) { 'test/files/html_strings_formatting.xlsx' }
522
+ describe "HTML Parsing Enabling" do
523
+ let(:path) { 'test/files/html_strings_formatting.xlsx' }
484
524
 
485
- it 'returns the expected result' do
486
- expect(subject.excelx_value(1, 1, "Sheet1")).to eq "This has no formatting."
487
- expect(subject.excelx_value(2, 1, "Sheet1")).to eq "<html>This has<b> bold </b>formatting.</html>"
488
- expect(subject.excelx_value(2, 2, "Sheet1")).to eq "<html>This has <i>italics</i> formatting.</html>"
489
- expect(subject.excelx_value(2, 3, "Sheet1")).to eq "<html>This has <u>underline</u> format.</html>"
490
- expect(subject.excelx_value(2, 4, "Sheet1")).to eq "<html>Superscript. x<sup>123</sup></html>"
491
- expect(subject.excelx_value(2, 5, "Sheet1")).to eq "<html>SubScript. T<sub>j</sub></html>"
492
-
493
- expect(subject.excelx_value(3, 1, "Sheet1")).to eq "<html>Bold, italics <b><i>together</i></b>.</html>"
494
- expect(subject.excelx_value(3, 2, "Sheet1")).to eq "<html>Bold, Underline <b><u>together</u></b>.</html>"
495
- expect(subject.excelx_value(3, 3, "Sheet1")).to eq "<html>Bold, Superscript. <b>x</b><sup><b>N</b></sup></html>"
496
- expect(subject.excelx_value(3, 4, "Sheet1")).to eq "<html>Bold, Subscript. <b>T</b><sub><b>abc</b></sub></html>"
497
- expect(subject.excelx_value(3, 5, "Sheet1")).to eq "<html>Italics, Underline <i><u>together</u></i>.</html>"
498
- expect(subject.excelx_value(3, 6, "Sheet1")).to eq "<html>Italics, Superscript. <i>X</i><sup><i>abc</i></sup></html>"
499
- expect(subject.excelx_value(3, 7, "Sheet1")).to eq "<html>Italics, Subscript. <i>B</i><sub><i>efg</i></sub></html>"
500
- expect(subject.excelx_value(4, 1, "Sheet1")).to eq "<html>Bold, italics underline,<b><i><u> together</u></i></b>.</html>"
501
- 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>"
502
- 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>"
503
- 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>"
504
- 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>"
505
- 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>"
506
- 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>"
507
- 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>"
508
- 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>"
509
- 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>"
510
- 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>"
525
+ it 'returns the expected result' do
526
+ expect(subject.excelx_value(1, 1, "Sheet1")).to eq("This has no formatting.")
527
+ expect(subject.excelx_value(2, 1, "Sheet1")).to eq("<html>This has<b> bold </b>formatting.</html>")
528
+ expect(subject.excelx_value(2, 2, "Sheet1")).to eq("<html>This has <i>italics</i> formatting.</html>")
529
+ expect(subject.excelx_value(2, 3, "Sheet1")).to eq("<html>This has <u>underline</u> format.</html>")
530
+ expect(subject.excelx_value(2, 4, "Sheet1")).to eq("<html>Superscript. x<sup>123</sup></html>")
531
+ expect(subject.excelx_value(2, 5, "Sheet1")).to eq("<html>SubScript. T<sub>j</sub></html>")
532
+
533
+ expect(subject.excelx_value(3, 1, "Sheet1")).to eq("<html>Bold, italics <b><i>together</i></b>.</html>")
534
+ expect(subject.excelx_value(3, 2, "Sheet1")).to eq("<html>Bold, Underline <b><u>together</u></b>.</html>")
535
+ expect(subject.excelx_value(3, 3, "Sheet1")).to eq("<html>Bold, Superscript. <b>x</b><sup><b>N</b></sup></html>")
536
+ expect(subject.excelx_value(3, 4, "Sheet1")).to eq("<html>Bold, Subscript. <b>T</b><sub><b>abc</b></sub></html>")
537
+ expect(subject.excelx_value(3, 5, "Sheet1")).to eq("<html>Italics, Underline <i><u>together</u></i>.</html>")
538
+ expect(subject.excelx_value(3, 6, "Sheet1")).to eq("<html>Italics, Superscript. <i>X</i><sup><i>abc</i></sup></html>")
539
+ expect(subject.excelx_value(3, 7, "Sheet1")).to eq("<html>Italics, Subscript. <i>B</i><sub><i>efg</i></sub></html>")
540
+ expect(subject.excelx_value(4, 1, "Sheet1")).to eq("<html>Bold, italics underline,<b><i><u> together</u></i></b>.</html>")
541
+ 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>")
542
+ 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>")
543
+ 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>")
544
+ 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>")
545
+ 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>")
546
+ 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>")
547
+ 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>")
548
+ 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>")
549
+ 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>")
550
+ 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>")
551
+ end
511
552
  end
512
553
  end
513
554
 
@@ -534,4 +575,57 @@ describe Roo::Excelx do
534
575
  expect(subject.sheet(0).excelx_format(2,1)).to eq 'm/d/yyyy" "h:mm:ss" "AM/PM'
535
576
  end
536
577
  end
578
+
579
+ describe 'images' do
580
+ let(:path) { 'test/files/images.xlsx' }
581
+
582
+ it 'returns array of images from default sheet' do
583
+ expect(subject.images).to be_kind_of(Array)
584
+ expect(subject.images.size).to eql(19)
585
+ end
586
+
587
+ it 'returns empty array if there is no images on the sheet' do
588
+ expect(subject.images("Sheet2")).to eql([])
589
+ end
590
+ end
537
591
  end
592
+
593
+ describe 'Roo::Excelx with options set' do
594
+ subject(:xlsx) do
595
+ Roo::Excelx.new(path, disable_html_wrapper: true)
596
+ end
597
+
598
+ describe '#html_strings' do
599
+ describe "HTML Parsing Disabled" do
600
+ let(:path) { 'test/files/html_strings_formatting.xlsx' }
601
+
602
+ it 'returns the expected result' do
603
+ expect(subject.excelx_value(1, 1, "Sheet1")).to eq("This has no formatting.")
604
+ expect(subject.excelx_value(2, 1, "Sheet1")).to eq("This has bold formatting.")
605
+ expect(subject.excelx_value(2, 2, "Sheet1")).to eq("This has italics formatting.")
606
+ expect(subject.excelx_value(2, 3, "Sheet1")).to eq("This has underline format.")
607
+ expect(subject.excelx_value(2, 4, "Sheet1")).to eq("Superscript. x123")
608
+ expect(subject.excelx_value(2, 5, "Sheet1")).to eq("SubScript. Tj")
609
+
610
+ expect(subject.excelx_value(3, 1, "Sheet1")).to eq("Bold, italics together.")
611
+ expect(subject.excelx_value(3, 2, "Sheet1")).to eq("Bold, Underline together.")
612
+ expect(subject.excelx_value(3, 3, "Sheet1")).to eq("Bold, Superscript. xN")
613
+ expect(subject.excelx_value(3, 4, "Sheet1")).to eq("Bold, Subscript. Tabc")
614
+ expect(subject.excelx_value(3, 5, "Sheet1")).to eq("Italics, Underline together.")
615
+ expect(subject.excelx_value(3, 6, "Sheet1")).to eq("Italics, Superscript. Xabc")
616
+ expect(subject.excelx_value(3, 7, "Sheet1")).to eq("Italics, Subscript. Befg")
617
+ expect(subject.excelx_value(4, 1, "Sheet1")).to eq("Bold, italics underline, together.")
618
+ expect(subject.excelx_value(4, 2, "Sheet1")).to eq("Bold, italics, superscript. Xabc123")
619
+ expect(subject.excelx_value(4, 3, "Sheet1")).to eq("Bold, Italics, subscript. Mgha2")
620
+ expect(subject.excelx_value(4, 4, "Sheet1")).to eq("Bold, Underline, superscript. ABC123")
621
+ expect(subject.excelx_value(4, 5, "Sheet1")).to eq("Bold, Underline, subscript. GoodXYZ")
622
+ expect(subject.excelx_value(4, 6, "Sheet1")).to eq("Italics, Underline, superscript. Upswing")
623
+ expect(subject.excelx_value(4, 7, "Sheet1")).to eq("Italics, Underline, subscript. Tswing")
624
+ expect(subject.excelx_value(5, 1, "Sheet1")).to eq("Bold, italics, underline, superscript. GHJK1904")
625
+ expect(subject.excelx_value(5, 2, "Sheet1")).to eq("Bold, italics, underline, subscript. Mikedrop")
626
+ 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>")
627
+ 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>")
628
+ end
629
+ end
630
+ end
631
+ 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
@@ -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]
@@ -86,21 +95,21 @@ RSpec.describe ::Roo::Utils do
86
95
  expect(described_class.load_xml('test/files/sheet1.xml')).to be_a(Nokogiri::XML::Document)
87
96
  expect(described_class.load_xml('test/files/sheet1.xml').
88
97
  remove_namespaces!.xpath("/worksheet/dimension").map do |dim|
89
- dim.attributes["ref"].value end.first).to eq "A1:B11"
98
+ dim["ref"] end.first).to eq "A1:B11"
90
99
  end
91
100
  end
92
101
 
93
102
  context '.each_element' do
94
103
  it 'returns the expected result' do
95
104
  described_class.each_element('test/files/sheet1.xml', 'dimension') do |dim|
96
- expect(dim.attributes["ref"].value).to eq "A1:B11"
105
+ expect(dim["ref"]).to eq "A1:B11"
97
106
  end
98
107
  rows = []
99
108
  described_class.each_element('test/files/sheet1.xml', 'row') do |row|
100
109
  rows << row
101
110
  end
102
111
  expect(rows.size).to eq 11
103
- expect(rows[2].attributes["r"].value).to eq "3"
112
+ expect(rows[2]["r"]).to eq "3"
104
113
  end
105
114
  end
106
115
  end