roo 2.7.1 → 2.8.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.
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