roo 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 97a621e940844c1142964501c7a78fa0cd054c86
4
- data.tar.gz: 9db0bb973c120511a2bba167b152b3ff6dadb488
3
+ metadata.gz: 53d37d09a786f9536fd5bb00c7cacf9888c8b032
4
+ data.tar.gz: 284974b328b26668c58e3b952a12b8777439037f
5
5
  SHA512:
6
- metadata.gz: 0831fd41e73b58b153b04ebda1ccbed591219b15d69070e4a5b50c4298c2b12a396feb0ffcd3f0d6a0b94ea6848897ae2324cd12cee721c38beea82c8e512b26
7
- data.tar.gz: e409801f0e341dcde7333830ec08b4150ec7e8310924583fac260ace3816c2bb950bb419c3d2060578fbd1b7e129c34bb2f825ffcde60fdde1c4a9fb384f2937
6
+ metadata.gz: 4b0e6d58d52600710fc5feb49e7483fc81e4bca65fa9013a3fa1004f5526107392b02f982ae981676544e301056a0246b4b85e38d3959565174c247ce49695a9
7
+ data.tar.gz: 5c3beb6580bece8aa730d1f29b6316889ebb7ce5a7003d8f654edcb1c9800a9f939021fd0d88749489ffdee6ebf496739664e5fede43aeb0067a2a16ad46f2f5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [2.1.1] - 2015-08-02
2
+ ### Fixed invalid new lines with _x000D_ character[#231](https://github.com/roo-rb/roo/pull/231)
3
+ ### Fixed missing URI issue. [#245](https://github.com/roo-rb/roo/pull/245)
4
+
1
5
  ## [2.1.0] - 2015-07-18
2
6
  ### Added
3
7
  - Added support for Excel 2007 `xlsm` files. [#232](https://github.com/roo-rb/roo/pull/232)
data/README.md CHANGED
@@ -3,14 +3,11 @@
3
3
  [![Build Status](https://img.shields.io/travis/roo-rb/roo.svg?style=flat-square)](https://travis-ci.org/roo-rb/roo) [![Code Climate](https://img.shields.io/codeclimate/github/roo-rb/roo.svg?style=flat-square)](https://codeclimate.com/github/roo-rb/roo) [![Coverage Status](https://img.shields.io/coveralls/roo-rb/roo.svg?style=flat-square)](https://coveralls.io/r/roo-rb/roo) [![Gem Version](https://img.shields.io/gem/v/roo.svg?style=flat-square)](https://rubygems.org/gems/roo)
4
4
 
5
5
  Roo implements read access for all common spreadsheet types. It can handle:
6
-
7
- * Excelx
8
- * OpenOffice / LibreOffice
6
+ * Excel 2007 - 2013 formats (xlsx, xlsm)
7
+ * LibreOffice / OpenOffice.org formats (ods)
9
8
  * CSV
10
-
11
- ## Additional Libraries
12
-
13
- In addition, the [roo-xls](https://github.com/roo-rb/roo-xls) and [roo-google](https://github.com/roo-rb/roo-google) gems exist to extend Roo to support reading classic Excel formats (i.e. `.xls` and ``Excel2003XML``) and read/write access for Google spreadsheets.
9
+ * Excel 97, Excel 2002 XML, and Excel 2003 XML formats when using the [roo-xls](https://github.com/roo-rb/roo-xls) gem (xls, xml)
10
+ * Google spreadsheets with read/write access when using [roo-google](https://github.com/roo-rb/roo-google)
14
11
 
15
12
  ## Installation
16
13
 
data/lib/roo/base.rb CHANGED
@@ -91,7 +91,7 @@ class Roo::Base
91
91
  first_column = [first_column, key.last.to_i].min
92
92
  last_column = [last_column, key.last.to_i].max
93
93
  end if @cell[sheet]
94
- {first_row: first_row, first_column: first_column, last_row: last_row, last_column: last_column}
94
+ { first_row: first_row, first_column: first_column, last_row: last_row, last_column: last_column }
95
95
  end
96
96
 
97
97
  %w(first_row last_row first_column last_column).each do |key|
@@ -117,22 +117,23 @@ class Roo::Base
117
117
  result = "--- \n"
118
118
  from_row.upto(to_row) do |row|
119
119
  from_column.upto(to_column) do |col|
120
- unless empty?(row, col, sheet)
121
- result << "cell_#{row}_#{col}: \n"
122
- prefix.each do|k, v|
123
- result << " #{k}: #{v} \n"
124
- end
125
- result << " row: #{row} \n"
126
- result << " col: #{col} \n"
127
- result << " celltype: #{celltype(row, col, sheet)} \n"
128
- value = cell(row, col, sheet)
129
- if celltype(row, col, sheet) == :time
130
- value = integer_to_timestring(value)
131
- end
132
- result << " value: #{value} \n"
120
+ next if empty?(row, col, sheet)
121
+
122
+ result << "cell_#{row}_#{col}: \n"
123
+ prefix.each do|k, v|
124
+ result << " #{k}: #{v} \n"
125
+ end
126
+ result << " row: #{row} \n"
127
+ result << " col: #{col} \n"
128
+ result << " celltype: #{celltype(row, col, sheet)} \n"
129
+ value = cell(row, col, sheet)
130
+ if celltype(row, col, sheet) == :time
131
+ value = integer_to_timestring(value)
133
132
  end
133
+ result << " value: #{value} \n"
134
134
  end
135
135
  end
136
+
136
137
  result
137
138
  end
138
139
 
@@ -170,7 +171,7 @@ class Roo::Base
170
171
  end
171
172
 
172
173
  def inspect
173
- "<##{ self.class }:#{ self.object_id.to_s(8) } #{ self.instance_variables.join(' ') }>"
174
+ "<##{self.class}:#{object_id.to_s(8)} #{instance_variables.join(' ')}>"
174
175
  end
175
176
 
176
177
  # find a row either by row number or a condition
@@ -217,7 +218,7 @@ class Roo::Base
217
218
  row, col = normalize(row, col)
218
219
  cell_type = cell_type_by_value(value)
219
220
  set_value(row, col, value, sheet)
220
- set_type(row, col, cell_type , sheet)
221
+ set_type(row, col, cell_type, sheet)
221
222
  end
222
223
 
223
224
  def cell_type_by_value(value)
@@ -225,7 +226,7 @@ class Roo::Base
225
226
  when Fixnum then :float
226
227
  when String, Float then :string
227
228
  else
228
- raise ArgumentError, "Type for #{value} not set"
229
+ fail ArgumentError, "Type for #{value} not set"
229
230
  end
230
231
  end
231
232
 
@@ -256,13 +257,13 @@ class Roo::Base
256
257
  sheets.each do|sheet|
257
258
  self.default_sheet = sheet
258
259
  result << 'Sheet ' + n.to_s + ":\n"
259
- unless first_row
260
- result << ' - empty -'
261
- else
260
+ if first_row
262
261
  result << " First row: #{first_row}\n"
263
262
  result << " Last row: #{last_row}\n"
264
263
  result << " First column: #{::Roo::Utils.number_to_letter(first_column)}\n"
265
264
  result << " Last column: #{::Roo::Utils.number_to_letter(last_column)}"
265
+ else
266
+ result << ' - empty -'
266
267
  end
267
268
  result << "\n" if sheet != sheets.last
268
269
  n += 1
@@ -282,12 +283,12 @@ class Roo::Base
282
283
  # sonst gibt es Fehler bei leeren Blaettern
283
284
  first_row.upto(last_row) do |row|
284
285
  first_column.upto(last_column) do |col|
285
- unless empty?(row, col)
286
- x.cell(cell(row, col),
286
+ next if empty?(row, col)
287
+
288
+ x.cell(cell(row, col),
287
289
  row: row,
288
290
  column: col,
289
291
  type: celltype(row, col))
290
- end
291
292
  end
292
293
  end
293
294
  end
@@ -318,7 +319,7 @@ class Roo::Base
318
319
  # access different worksheets by calling spreadsheet.sheet(1)
319
320
  # or spreadsheet.sheet('SHEETNAME')
320
321
  def sheet(index, name = false)
321
- self.default_sheet = String === index ? index : sheets[index]
322
+ self.default_sheet = index.is_a?(::String) ? index : sheets[index]
322
323
  name ? [default_sheet, self] : self
323
324
  end
324
325
 
@@ -352,25 +353,23 @@ class Roo::Base
352
353
  # control characters and white spaces around columns
353
354
 
354
355
  def each(options = {})
355
- if block_given?
356
- if options.empty?
357
- 1.upto(last_row) do |line|
358
- yield row(line)
359
- end
360
- else
361
- clean_sheet_if_need(options)
362
- search_or_set_header(options)
363
- headers = @headers ||
364
- Hash[(first_column..last_column).map do |col|
365
- [cell(@header_line, col), col]
366
- end]
367
-
368
- @header_line.upto(last_row) do |line|
369
- yield(Hash[headers.map { |k, v| [k, cell(line, v)] }])
370
- end
356
+ return to_enum(:each, options) unless block_given?
357
+
358
+ if options.empty?
359
+ 1.upto(last_row) do |line|
360
+ yield row(line)
371
361
  end
372
362
  else
373
- to_enum(:each, options)
363
+ clean_sheet_if_need(options)
364
+ search_or_set_header(options)
365
+ headers = @headers ||
366
+ Hash[(first_column..last_column).map do |col|
367
+ [cell(@header_line, col), col]
368
+ end]
369
+
370
+ @header_line.upto(last_row) do |line|
371
+ yield(Hash[headers.map { |k, v| [k, cell(line, v)] }])
372
+ end
374
373
  end
375
374
  end
376
375
 
@@ -409,23 +408,24 @@ class Roo::Base
409
408
  filename = File.basename(filename, File.extname(filename))
410
409
  end
411
410
 
412
- if uri?(filename) && qs_begin = filename.rindex('?')
411
+ if uri?(filename) && (qs_begin = filename.rindex('?'))
413
412
  filename = filename[0..qs_begin - 1]
414
413
  end
415
414
  exts = Array(exts)
416
- if !exts.include?(File.extname(filename).downcase)
417
- case warning_level
418
- when :error
419
- warn file_type_warning_message(filename, exts)
420
- fail TypeError, "#{filename} is not #{name} file"
421
- when :warning
422
- warn "are you sure, this is #{name} spreadsheet file?"
423
- warn file_type_warning_message(filename, exts)
424
- when :ignore
425
- # ignore
426
- else
427
- fail "#{warning_level} illegal state of file_warning"
428
- end
415
+
416
+ return if exts.include?(File.extname(filename).downcase)
417
+
418
+ case warning_level
419
+ when :error
420
+ warn file_type_warning_message(filename, exts)
421
+ fail TypeError, "#{filename} is not #{name} file"
422
+ when :warning
423
+ warn "are you sure, this is #{name} spreadsheet file?"
424
+ warn file_type_warning_message(filename, exts)
425
+ when :ignore
426
+ # ignore
427
+ else
428
+ fail "#{warning_level} illegal state of file_warning"
429
429
  end
430
430
  end
431
431
 
@@ -476,9 +476,9 @@ class Roo::Base
476
476
  return if is_stream?(filename)
477
477
  filename = download_uri(filename, tmpdir) if uri?(filename)
478
478
  filename = unzip(filename, tmpdir) if packed == :zip
479
- unless File.file?(filename)
480
- fail IOError, "file #{filename} does not exist"
481
- end
479
+
480
+ fail IOError, "file #{filename} does not exist" unless File.file?(filename)
481
+
482
482
  filename
483
483
  end
484
484
 
@@ -536,11 +536,8 @@ class Roo::Base
536
536
  end
537
537
 
538
538
  def make_tmpdir(prefix = nil, root = nil, &block)
539
- prefix = if prefix
540
- TEMP_PREFIX + prefix
541
- else
542
- TEMP_PREFIX
543
- end
539
+ prefix = "#{TEMP_PREFIX}#{prefix}"
540
+
544
541
  ::Dir.mktmpdir(prefix, root || ENV['ROO_TMP'], &block).tap do |result|
545
542
  block_given? || track_tmpdir!(result)
546
543
  end
@@ -588,9 +585,9 @@ class Roo::Base
588
585
  fail ArgumentError
589
586
  end
590
587
  end
591
- if col.is_a?(::String)
592
- col = ::Roo::Utils.letter_to_number(col)
593
- end
588
+
589
+ col = ::Roo::Utils.letter_to_number(col) if col.is_a?(::String)
590
+
594
591
  [row, col]
595
592
  end
596
593
 
@@ -641,7 +638,7 @@ class Roo::Base
641
638
  fail RangeError, "sheet index #{sheet} not found"
642
639
  end
643
640
  when String
644
- unless sheets.include? sheet
641
+ unless sheets.include?(sheet)
645
642
  fail RangeError, "sheet '#{sheet}' not found"
646
643
  end
647
644
  else
@@ -670,14 +667,14 @@ class Roo::Base
670
667
  # parameter is nil the output goes to STDOUT
671
668
  def write_csv_content(file = nil, sheet = nil, separator = ',')
672
669
  file ||= STDOUT
673
- if first_row(sheet) # sheet is not empty
674
- 1.upto(last_row(sheet)) do |row|
675
- 1.upto(last_column(sheet)) do |col|
676
- file.print(separator) if col > 1
677
- file.print cell_to_csv(row, col, sheet)
678
- end
679
- file.print("\n")
680
- end # sheet not empty
670
+ return unless first_row(sheet) # The sheet is empty
671
+
672
+ 1.upto(last_row(sheet)) do |row|
673
+ 1.upto(last_column(sheet)) do |col|
674
+ file.print(separator) if col > 1
675
+ file.print cell_to_csv(row, col, sheet)
676
+ end
677
+ file.print("\n")
681
678
  end
682
679
  end
683
680
 
@@ -729,9 +726,9 @@ class Roo::Base
729
726
  # converts an integer value to a time string like '02:05:06'
730
727
  def integer_to_timestring(content)
731
728
  h = (content / 3600.0).floor
732
- content = content - h * 3600
729
+ content -= h * 3600
733
730
  m = (content / 60.0).floor
734
- content = content - m * 60
731
+ content -= m * 60
735
732
  s = content
736
733
  sprintf('%02d:%02d:%02d', h, m, s)
737
734
  end
@@ -13,9 +13,19 @@ module Roo
13
13
 
14
14
  private
15
15
 
16
+ def fix_invalid_shared_strings(doc)
17
+ invalid = { '_x000D_' => "\n" }
18
+ xml = doc.to_s
19
+
20
+ if xml[/#{invalid.keys.join('|')}/]
21
+ @doc = ::Nokogiri::XML(xml.gsub(/#{invalid.keys.join('|')}/, invalid))
22
+ end
23
+ end
24
+
16
25
  def extract_shared_strings
17
26
  return [] unless doc_exists?
18
27
 
28
+ fix_invalid_shared_strings(doc)
19
29
  # read the shared strings xml document
20
30
  doc.xpath('/sst/si').map do |si|
21
31
  shared_string = ''
@@ -1,3 +1,5 @@
1
+ require 'uri'
2
+
1
3
  module Roo
2
4
  class Spreadsheet
3
5
  class << self
data/lib/roo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Roo
2
- VERSION = "2.1.0"
2
+ VERSION = "2.1.1"
3
3
  end
data/spec/helpers.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Helpers
2
+ def yaml_entry(row,col,type,value)
3
+ "cell_#{row}_#{col}: \n row: #{row} \n col: #{col} \n celltype: #{type} \n value: #{value} \n"
4
+ end
5
+ end
@@ -1,4 +1,216 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Roo::Base do
4
+ let(:klass) do
5
+ Class.new(Roo::Base) do
6
+ def initialize(filename, data = {})
7
+ super(filename)
8
+ @data ||= data
9
+ end
10
+
11
+ def read_cells(sheet = default_sheet)
12
+ return if @cells_read[sheet]
13
+ type_map = { String => :string, Date => :date, Numeric => :float }
14
+
15
+ @cell[sheet] = @data
16
+ @cell_type[sheet] = Hash[@data.map { |k, v| [k, type_map.find {|type,_| v.is_a?(type) }.last ] }]
17
+ @first_row[sheet] = @data.map { |k, _| k[0] }.min
18
+ @last_row[sheet] = @data.map { |k, _| k[0] }.max
19
+ @first_column[sheet] = @data.map { |k, _| k[1] }.min
20
+ @last_column[sheet] = @data.map { |k, _| k[1] }.max
21
+ @cells_read[sheet] = true
22
+ end
23
+
24
+ def cell(row, col, sheet = nil)
25
+ sheet ||= default_sheet
26
+ read_cells(sheet)
27
+ @cell[sheet][[row, col]]
28
+ end
29
+
30
+ def celltype(row, col, sheet = nil)
31
+ sheet ||= default_sheet
32
+ read_cells(sheet)
33
+ @cell_type[sheet][[row, col]]
34
+ end
35
+
36
+ def sheets
37
+ ['my_sheet', 'blank sheet']
38
+ end
39
+ end
40
+ end
41
+
42
+ let(:spreadsheet_data) do
43
+ {
44
+ [5, 1] => Date.civil(1961, 11, 21),
45
+
46
+ [8, 3] => 'thisisc8',
47
+ [8, 7] => 'thisisg8',
48
+
49
+ [12, 1] => 41.0,
50
+ [12, 2] => 42.0,
51
+ [12, 3] => 43.0,
52
+ [12, 4] => 44.0,
53
+ [12, 5] => 45.0,
54
+
55
+ [15, 3] => 43.0,
56
+ [15, 4] => 44.0,
57
+ [15, 5] => 45.0,
58
+
59
+ [16, 2] => '"Hello world!"',
60
+ [16, 3] => 'forty-three',
61
+ [16, 4] => 'forty-four',
62
+ [16, 5] => 'forty-five'
63
+ }
64
+ end
65
+
66
+ let(:spreadsheet) { klass.new('some_file', spreadsheet_data) }
67
+
68
+ describe '#uri?' do
69
+ it 'should return true when passed a filename starting with http(s)://' do
70
+ expect(spreadsheet.send(:uri?, 'http://example.com/')).to be_truthy
71
+ expect(spreadsheet.send(:uri?, 'https://example.com/')).to be_truthy
72
+ end
73
+
74
+ it 'should return false when passed a filename which does not start with http(s)://' do
75
+ expect(spreadsheet.send(:uri?, 'example.com')).to be_falsy
76
+ end
77
+
78
+ it 'should return false when passed non-String object such as Tempfile' do
79
+ expect(spreadsheet.send(:uri?, Tempfile.new('test'))).to be_falsy
80
+ end
81
+ end
82
+
83
+ describe '#set' do
84
+ it 'should not update cell when setting an invalid type' do
85
+ spreadsheet.set(1, 1, 1)
86
+ expect { spreadsheet.set(1, 1, :invalid_type) }.to raise_error(ArgumentError)
87
+ expect(spreadsheet.cell(1, 1)).to eq(1)
88
+ expect(spreadsheet.celltype(1, 1)).to eq(:float)
89
+ end
90
+ end
91
+
92
+ describe '#first_row' do
93
+ it 'should return the first row' do
94
+ expect(spreadsheet.first_row).to eq(5)
95
+ end
96
+ end
97
+
98
+ describe '#last_row' do
99
+ it 'should return the last row' do
100
+ expect(spreadsheet.last_row).to eq(16)
101
+ end
102
+ end
103
+
104
+ describe '#first_column' do
105
+ it 'should return the first column' do
106
+ expect(spreadsheet.first_column).to eq(1)
107
+ end
108
+ end
109
+
110
+ describe '#first_column_as_letter' do
111
+ it 'should return the first column as a letter' do
112
+ expect(spreadsheet.first_column_as_letter).to eq('A')
113
+ end
114
+ end
115
+
116
+ describe '#last_column' do
117
+ it 'should return the last column' do
118
+ expect(spreadsheet.last_column).to eq(7)
119
+ end
120
+ end
121
+
122
+ describe '#last_column_as_letter' do
123
+ it 'should return the last column as a letter' do
124
+ expect(spreadsheet.last_column_as_letter).to eq('G')
125
+ end
126
+ end
127
+
128
+ describe '#row' do
129
+ it 'should return the specified row' do
130
+ expect(spreadsheet.row(12)).to eq([41.0, 42.0, 43.0, 44.0, 45.0, nil, nil])
131
+ expect(spreadsheet.row(16)).to eq([nil, '"Hello world!"', 'forty-three', 'forty-four', 'forty-five', nil, nil])
132
+ end
133
+ end
134
+
135
+ describe '#empty?' do
136
+ it 'should return true when empty' do
137
+ expect(spreadsheet.empty?(1, 1)).to be_truthy
138
+ expect(spreadsheet.empty?(8, 3)).to be_falsy
139
+ expect(spreadsheet.empty?('A', 11)).to be_truthy
140
+ expect(spreadsheet.empty?('A', 12)).to be_falsy
141
+ end
142
+ end
143
+
144
+ describe '#reload' do
145
+ it 'should return reinitialize the spreadsheet' do
146
+ spreadsheet.reload
147
+ expect(spreadsheet.instance_variable_get(:@cell).empty?).to be_truthy
148
+ end
149
+ end
150
+
151
+ describe '#each' do
152
+ it 'should return an enumerator with all the rows' do
153
+ each = spreadsheet.each
154
+ expect(each).to be_a(Enumerator)
155
+ expect(each.to_a.last).to eq([nil, '"Hello world!"', 'forty-three', 'forty-four', 'forty-five', nil, nil])
156
+ end
157
+ end
158
+
159
+ describe '#to_yaml' do
160
+ it 'should convert the spreadsheet to yaml' do
161
+ expect(spreadsheet.to_yaml({}, 5, 1, 5, 1)).to eq("--- \n" + yaml_entry(5, 1, 'date', '1961-11-21'))
162
+ expect(spreadsheet.to_yaml({}, 8, 3, 8, 3)).to eq("--- \n" + yaml_entry(8, 3, 'string', 'thisisc8'))
163
+
164
+ expect(spreadsheet.to_yaml({}, 12, 3, 12, 3)).to eq("--- \n" + yaml_entry(12, 3, 'float', 43.0))
165
+
166
+ expect(spreadsheet.to_yaml({}, 12, 3, 12)).to eq(
167
+ "--- \n" + yaml_entry(12, 3, 'float', 43.0) +
168
+ yaml_entry(12, 4, 'float', 44.0) +
169
+ yaml_entry(12, 5, 'float', 45.0))
170
+
171
+ expect(spreadsheet.to_yaml({}, 12, 3)).to eq(
172
+ "--- \n" + yaml_entry(12, 3, 'float', 43.0) +
173
+ yaml_entry(12, 4, 'float', 44.0) +
174
+ yaml_entry(12, 5, 'float', 45.0) +
175
+ yaml_entry(15, 3, 'float', 43.0) +
176
+ yaml_entry(15, 4, 'float', 44.0) +
177
+ yaml_entry(15, 5, 'float', 45.0) +
178
+ yaml_entry(16, 3, 'string', 'forty-three') +
179
+ yaml_entry(16, 4, 'string', 'forty-four') +
180
+ yaml_entry(16, 5, 'string', 'forty-five'))
181
+ end
182
+ end
183
+
184
+ let(:expected_csv) do
185
+ <<EOS
186
+ ,,,,,,
187
+ ,,,,,,
188
+ ,,,,,,
189
+ ,,,,,,
190
+ 1961-11-21,,,,,,
191
+ ,,,,,,
192
+ ,,,,,,
193
+ ,,"thisisc8",,,,"thisisg8"
194
+ ,,,,,,
195
+ ,,,,,,
196
+ ,,,,,,
197
+ 41,42,43,44,45,,
198
+ ,,,,,,
199
+ ,,,,,,
200
+ ,,43,44,45,,
201
+ ,"""Hello world!""","forty-three","forty-four","forty-five",,
202
+ EOS
203
+ end
204
+
205
+ let(:expected_csv_with_semicolons) { expected_csv.gsub(/\,/, ';') }
206
+
207
+ describe '#to_csv' do
208
+ it 'should convert the spreadsheet to csv' do
209
+ expect(spreadsheet.to_csv).to eq(expected_csv)
210
+ end
211
+
212
+ it 'should convert the spreadsheet to csv using the separator when is passed on the parameter' do
213
+ expect(spreadsheet.to_csv(nil, ';')).to eq(expected_csv_with_semicolons)
214
+ end
215
+ end
4
216
  end
@@ -454,4 +454,11 @@ describe Roo::Excelx do
454
454
  end
455
455
  end
456
456
  end
457
+
458
+ describe '_x000D_' do
459
+ let(:path) { 'test/files/x000D.xlsx' }
460
+ it 'does not contain _x000D_' do
461
+ expect(subject.cell(2, 9)).not_to include('_x000D_')
462
+ end
463
+ end
457
464
  end
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,13 @@
1
1
  require 'simplecov'
2
2
  require 'roo'
3
-
4
3
  require 'vcr'
5
4
 
5
+ require 'helpers'
6
+
7
+ RSpec.configure do |c|
8
+ c.include Helpers
9
+ end
10
+
6
11
  VCR.configure do |c|
7
12
  c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
8
13
  c.hook_into :webmock # or :fakeweb
data/test/test_helper.rb CHANGED
@@ -45,10 +45,6 @@ def file_diff(fn1,fn2)
45
45
  result
46
46
  end
47
47
 
48
- def yaml_entry(row,col,type,value)
49
- "cell_#{row}_#{col}: \n row: #{row} \n col: #{col} \n celltype: #{type} \n value: #{value} \n"
50
- end
51
-
52
48
  class File
53
49
  def File.delete_if_exist(filename)
54
50
  if File.exist?(filename)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roo
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Preymesser
@@ -11,17 +11,17 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2015-07-20 00:00:00.000000000 Z
14
+ date: 2015-08-01 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: nokogiri
18
- prerelease: false
19
18
  requirement: !ruby/object:Gem::Requirement
20
19
  requirements:
21
20
  - - "~>"
22
21
  - !ruby/object:Gem::Version
23
22
  version: '1'
24
23
  type: :runtime
24
+ prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - "~>"
@@ -29,7 +29,6 @@ dependencies:
29
29
  version: '1'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: rubyzip
32
- prerelease: false
33
32
  requirement: !ruby/object:Gem::Requirement
34
33
  requirements:
35
34
  - - "~>"
@@ -39,6 +38,7 @@ dependencies:
39
38
  - !ruby/object:Gem::Version
40
39
  version: 2.0.0
41
40
  type: :runtime
41
+ prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
@@ -49,13 +49,13 @@ dependencies:
49
49
  version: 2.0.0
50
50
  - !ruby/object:Gem::Dependency
51
51
  name: rake
52
- prerelease: false
53
52
  requirement: !ruby/object:Gem::Requirement
54
53
  requirements:
55
54
  - - "~>"
56
55
  - !ruby/object:Gem::Version
57
56
  version: '10.1'
58
57
  type: :development
58
+ prerelease: false
59
59
  version_requirements: !ruby/object:Gem::Requirement
60
60
  requirements:
61
61
  - - "~>"
@@ -63,7 +63,6 @@ dependencies:
63
63
  version: '10.1'
64
64
  - !ruby/object:Gem::Dependency
65
65
  name: minitest
66
- prerelease: false
67
66
  requirement: !ruby/object:Gem::Requirement
68
67
  requirements:
69
68
  - - "~>"
@@ -73,6 +72,7 @@ dependencies:
73
72
  - !ruby/object:Gem::Version
74
73
  version: 5.4.3
75
74
  type: :development
75
+ prerelease: false
76
76
  version_requirements: !ruby/object:Gem::Requirement
77
77
  requirements:
78
78
  - - "~>"
@@ -131,6 +131,7 @@ files:
131
131
  - spec/fixtures/vcr_cassettes/google_drive.yml
132
132
  - spec/fixtures/vcr_cassettes/google_drive_access_token.yml
133
133
  - spec/fixtures/vcr_cassettes/google_drive_set.yml
134
+ - spec/helpers.rb
134
135
  - spec/lib/roo/base_spec.rb
135
136
  - spec/lib/roo/csv_spec.rb
136
137
  - spec/lib/roo/excelx/format_spec.rb
@@ -141,7 +142,6 @@ files:
141
142
  - spec/lib/roo/utils_spec.rb
142
143
  - spec/spec_helper.rb
143
144
  - test/all_ss.rb
144
- - test/test_generic_spreadsheet.rb
145
145
  - test/test_helper.rb
146
146
  - test/test_roo.rb
147
147
  homepage: http://github.com/roo-rb/roo
@@ -164,8 +164,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
164
  version: '0'
165
165
  requirements: []
166
166
  rubyforge_project:
167
- rubygems_version: 2.4.8
167
+ rubygems_version: 2.4.5
168
168
  signing_key:
169
169
  specification_version: 4
170
170
  summary: Roo can access the contents of various spreadsheet files.
171
171
  test_files: []
172
+ has_rdoc:
@@ -1,237 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.dirname(__FILE__) + '/test_helper'
3
-
4
- class TestBase < Minitest::Test
5
- def setup
6
- @klass = Class.new(Roo::Base) do
7
- def initialize(filename = 'some_file')
8
- super
9
- @filename = filename
10
- end
11
-
12
- def read_cells(sheet = nil)
13
- @cells_read[sheet] = true
14
- end
15
-
16
- def cell(row, col, sheet = nil)
17
- sheet ||= default_sheet
18
- @cell[sheet][[row, col]]
19
- end
20
-
21
- def celltype(row, col, sheet = nil)
22
- sheet ||= default_sheet
23
- @cell_type[sheet][[row, col]]
24
- end
25
-
26
- def sheets
27
- ['my_sheet', 'blank sheet']
28
- end
29
- end
30
- @oo = @klass.new
31
- setup_test_sheet(@oo)
32
- end
33
-
34
- context 'private method Roo::Base.uri?(filename)' do
35
- should 'return true when passed a filename starts with http(s)://' do
36
- assert_equal true, @oo.send(:uri?, 'http://example.com/')
37
- assert_equal true, @oo.send(:uri?, 'https://example.com/')
38
- end
39
-
40
- should 'return false when passed a filename which does not start with http(s)://' do
41
- assert_equal false, @oo.send(:uri?, 'example.com')
42
- end
43
-
44
- should 'return false when passed non-String object such as Tempfile' do
45
- assert_equal false, @oo.send(:uri?, Tempfile.new('test'))
46
- end
47
- end
48
-
49
- def test_setting_invalid_type_does_not_update_cell
50
- @oo.set(1, 1, 1)
51
- assert_raises(ArgumentError) { @oo.set(1, 1, :invalid_type) }
52
- assert_equal 1, @oo.cell(1, 1)
53
- assert_equal :float, @oo.celltype(1, 1)
54
- end
55
-
56
- def test_first_row
57
- assert_equal 5, @oo.first_row
58
- end
59
-
60
- def test_last_row
61
- assert_equal 16, @oo.last_row
62
- end
63
-
64
- def test_first_column
65
- assert_equal 1, @oo.first_column
66
- end
67
-
68
- def test_first_column_as_letter
69
- assert_equal 'A', @oo.first_column_as_letter
70
- end
71
-
72
- def test_last_column
73
- assert_equal 7, @oo.last_column
74
- end
75
-
76
- def test_last_column_as_letter
77
- assert_equal 'G', @oo.last_column_as_letter
78
- end
79
-
80
- def test_rows
81
- assert_equal [41.0, 42.0, 43.0, 44.0, 45.0, nil, nil], @oo.row(12)
82
- assert_equal [nil, '"Hello world!"', 'dreiundvierzig', 'vierundvierzig', 'fuenfundvierzig', nil, nil], @oo.row(16)
83
- end
84
-
85
- def test_empty_eh
86
- assert @oo.empty?(1, 1)
87
- assert !@oo.empty?(8, 3)
88
- assert @oo.empty?('A', 11)
89
- assert !@oo.empty?('A', 12)
90
- end
91
-
92
- def test_reload
93
- @oo.reload
94
- assert @oo.instance_variable_get(:@cell).empty?
95
- end
96
-
97
- def test_each
98
- oo_each = @oo.each
99
- assert_instance_of Enumerator, oo_each
100
- assert_equal [nil, '"Hello world!"', 'dreiundvierzig', 'vierundvierzig', 'fuenfundvierzig', nil, nil], oo_each.to_a.last
101
- end
102
-
103
- def test_to_yaml
104
- assert_equal "--- \n" + yaml_entry(5, 1, 'date', '1961-11-21'), @oo.to_yaml({}, 5, 1, 5, 1)
105
- assert_equal "--- \n" + yaml_entry(8, 3, 'string', 'thisisc8'), @oo.to_yaml({}, 8, 3, 8, 3)
106
- assert_equal "--- \n" + yaml_entry(12, 3, 'float', 43.0), @oo.to_yaml({}, 12, 3, 12, 3)
107
- assert_equal \
108
- "--- \n" + yaml_entry(12, 3, 'float', 43.0) +
109
- yaml_entry(12, 4, 'float', 44.0) +
110
- yaml_entry(12, 5, 'float', 45.0), @oo.to_yaml({}, 12, 3, 12)
111
- assert_equal \
112
- "--- \n" + yaml_entry(12, 3, 'float', 43.0) +
113
- yaml_entry(12, 4, 'float', 44.0) +
114
- yaml_entry(12, 5, 'float', 45.0) +
115
- yaml_entry(15, 3, 'float', 43.0) +
116
- yaml_entry(15, 4, 'float', 44.0) +
117
- yaml_entry(15, 5, 'float', 45.0) +
118
- yaml_entry(16, 3, 'string', 'dreiundvierzig') +
119
- yaml_entry(16, 4, 'string', 'vierundvierzig') +
120
- yaml_entry(16, 5, 'string', 'fuenfundvierzig'), @oo.to_yaml({}, 12, 3)
121
- end
122
-
123
- def test_to_csv
124
- assert_equal expected_csv, @oo.to_csv
125
- end
126
-
127
- def test_to_csv_with_separator
128
- assert_equal expected_csv_with_semicolons, @oo.to_csv(nil, ';')
129
- end
130
-
131
- protected
132
-
133
- def setup_test_sheet(workbook = nil)
134
- workbook ||= @oo
135
- set_sheet_values(workbook)
136
- set_sheet_types(workbook)
137
- set_cells_read(workbook)
138
- end
139
-
140
- def set_sheet_values(workbook)
141
- workbook.instance_variable_get(:@cell)[workbook.default_sheet] = {
142
- [5, 1] => Date.civil(1961, 11, 21).to_s,
143
-
144
- [8, 3] => 'thisisc8',
145
- [8, 7] => 'thisisg8',
146
-
147
- [12, 1] => 41.0,
148
- [12, 2] => 42.0,
149
- [12, 3] => 43.0,
150
- [12, 4] => 44.0,
151
- [12, 5] => 45.0,
152
-
153
- [15, 3] => 43.0,
154
- [15, 4] => 44.0,
155
- [15, 5] => 45.0,
156
-
157
- [16, 2] => '"Hello world!"',
158
- [16, 3] => 'dreiundvierzig',
159
- [16, 4] => 'vierundvierzig',
160
- [16, 5] => 'fuenfundvierzig'
161
- }
162
- end
163
-
164
- def set_sheet_types(workbook)
165
- workbook.instance_variable_get(:@cell_type)[workbook.default_sheet] = {
166
- [5, 1] => :date,
167
-
168
- [8, 3] => :string,
169
- [8, 7] => :string,
170
-
171
- [12, 1] => :float,
172
- [12, 2] => :float,
173
- [12, 3] => :float,
174
- [12, 4] => :float,
175
- [12, 5] => :float,
176
-
177
- [15, 3] => :float,
178
- [15, 4] => :float,
179
- [15, 5] => :float,
180
-
181
- [16, 2] => :string,
182
- [16, 3] => :string,
183
- [16, 4] => :string,
184
- [16, 5] => :string
185
- }
186
- end
187
-
188
- def set_first_row(workbook)
189
- row_hash = workbook.instance_variable_get(:@first_row)
190
- row_hash[workbook.default_sheet] = workbook.instance_variable_get(:@cell)[workbook.default_sheet].map { |k, _v| k[0] }.min
191
- end
192
-
193
- def set_last_row(workbook)
194
- row_hash = workbook.instance_variable_get(:@last_row)
195
- row_hash[workbook.default_sheet] = workbook.instance_variable_get(:@cell)[workbook.default_sheet].map { |k, _v| k[0] }.max
196
- end
197
-
198
- def set_first_col(workbook)
199
- col_hash = workbook.instance_variable_get(:@first_column)
200
- col_hash[workbook.default_sheet] = workbook.instance_variable_get(:@cell)[workbook.default_sheet].map { |k, _v| k[1] }.min
201
- end
202
-
203
- def set_last_col(workbook)
204
- col_hash = workbook.instance_variable_get(:@last_column)
205
- col_hash[workbook.default_sheet] = workbook.instance_variable_get(:@cell)[workbook.default_sheet].map { |k, _v| k[1] }.max
206
- end
207
-
208
- def set_cells_read(workbook)
209
- read_hash = workbook.instance_variable_get(:@cells_read)
210
- read_hash[workbook.default_sheet] = true
211
- end
212
-
213
- def expected_csv
214
- <<EOS
215
- ,,,,,,
216
- ,,,,,,
217
- ,,,,,,
218
- ,,,,,,
219
- 1961-11-21,,,,,,
220
- ,,,,,,
221
- ,,,,,,
222
- ,,"thisisc8",,,,"thisisg8"
223
- ,,,,,,
224
- ,,,,,,
225
- ,,,,,,
226
- 41,42,43,44,45,,
227
- ,,,,,,
228
- ,,,,,,
229
- ,,43,44,45,,
230
- ,"""Hello world!""","dreiundvierzig","vierundvierzig","fuenfundvierzig",,
231
- EOS
232
- end
233
-
234
- def expected_csv_with_semicolons
235
- expected_csv.gsub(/\,/, ';')
236
- end
237
- end