roo 2.1.0 → 2.1.1

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