Skip to content

Commit

Permalink
Merge pull request #7 from mak-it/handle-invalid-number-formats
Browse files Browse the repository at this point in the history
Fallback to string when typecasting fails
  • Loading branch information
ebeigarts authored Feb 8, 2017
2 parents fa880da + 89ec30d commit 60cfb40
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 11 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
rvm:
- 2.0
- 2.1
- 2.2
- 2.3
- 2.4.0
- ruby-head
19 changes: 11 additions & 8 deletions lib/saxlsx/rows_collection_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,33 +97,36 @@ def value_of(text)
when 's'
@shared_strings[text.to_i]
when 'inlineStr'
text
CGI.unescapeHTML(text)
when 'b'
BooleanParser.parse text
else
case @current_number_format
when :date
@base_date + text.to_i
@base_date + Integer(text)
when :date_time
# Round time to seconds
date = @base_date + Rational((text.to_f * SECONDS_IN_DAY).round, SECONDS_IN_DAY)
date = @base_date + Rational((Float(text) * SECONDS_IN_DAY).round, SECONDS_IN_DAY)
DateTime.new(date.year, date.month, date.day, date.hour, date.minute, date.second)
when :fixnum
text.to_i
Integer(text)
when :float, :percentage
text.to_f
Float(text)
when :bignum
BigDecimal.new(text)
Float(text) # raises ArgumentError if text is not a number
BigDecimal(text) # doesn't raise ArgumentError
else
if @current_type == 'n'
text.to_f
Float(text)
elsif text =~ /\A-?\d+(\.\d+(?:e[+-]\d+)?)?\Z/i # Auto convert numbers
$1 ? text.to_f : text.to_i
$1 ? Float(text) : Integer(text)
else
CGI.unescapeHTML(text)
end
end
end
rescue ArgumentError
CGI.unescapeHTML(text)
end

def detect_format_type(index)
Expand Down
2 changes: 2 additions & 0 deletions saxlsx.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
spec.test_files = spec.files.grep(%r{^spec/})
spec.require_paths = ["lib"]

spec.required_ruby_version = '>= 2.1.0'

spec.add_dependency 'rubyzip', '~> 1.0'
spec.add_dependency 'ox', '~> 2.1'

Expand Down
Binary file added spec/data/SpecNumberFormat.xlsx
Binary file not shown.
30 changes: 28 additions & 2 deletions spec/sheet_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
w.sheets[0].to_csv tmp_path

csv = File.open(csv_file, 'r') { |f| f.readlines }
csv[0].should eq %{"LevenshteinDistance","3.14","3","2013-12-13T08:00:58+00:00","1970-01-01T00:00:00+00:00","0.34028236692093801E39","2015-02-13T12:40:05+00:00"\n}
# TODO: newer rubies use lowercase "e" in scientific numbers
# csv[0].should eq %{"LevenshteinDistance","3.14","3","2013-12-13T08:00:58+00:00","1970-01-01T00:00:00+00:00","0.34028236692093801E39","2015-02-13T12:40:05+00:00"\n}
csv[1].should eq %{"Case sensitive","false","3.0","1970-01-01T01:00:00+00:00"\n}
csv[2].should eq "\"Fields\",\"Type\",\"URL Mining\"\n"
csv[3].should eq "\"autor\",\"text\",\"false\"\n"
Expand Down Expand Up @@ -119,4 +120,29 @@
end
end
end
end

context 'with number formats' do
let(:filename) { "#{File.dirname(__FILE__)}/data/SpecNumberFormat.xlsx" }

[ ["General", "Test"],
["Fixnum", 123],
["Currency", 123.0],
["Date", DateTime.new(1970, 1, 1)],
["Time", DateTime.new(2015, 2, 13, 12, 40, 5)],
["Percentage", 0.9999],
["Fraction", 0.5],
["Scientific", BigDecimal.new('3.4028236692093801E+38')],
["Custom", 123.0],
].each.with_index do |row, i|
name, value = row

it "should typecast #{name}" do
Workbook.open filename do |w|
w.sheets[0].tap do |s|
expect(s.rows[i+1]).to eq([name, value, "Test"])
end
end
end
end
end
end

0 comments on commit 60cfb40

Please sign in to comment.