Skip to content

Commit

Permalink
[bug] catch RangeError when trying to parse dates
Browse files Browse the repository at this point in the history
And refactor date_column_spec.rb
  • Loading branch information
benprew committed Nov 24, 2023
1 parent a19e8c8 commit 42eba87
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 48 deletions.
9 changes: 6 additions & 3 deletions lib/reckon/date_column.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,15 @@ def self.likelihood(entry)
date_score += 30 if entry =~ /^\d+[:\/\.-]\d+[:\/\.-]\d+([ :]\d+[:\/\.]\d+)?$/
date_score += 10 if entry =~ /^\d+\[\d+:GMT\]$/i

# ruby 2.6.0 doesn't have Date::Error, but Date::Error is a subclass of
# ArgumentError
#
# Sometimes DateTime.parse can throw a RangeError
# See https://github.com/cantino/reckon/issues/126
begin
DateTime.parse(entry)
date_score += 20
# ruby 2.6.0 doesn't have Date::Error, but Date::Error is a subclass of
# ArgumentError
rescue ArgumentError
rescue StandardError
# we don't need do anything here since the column didn't parse as a date
nil
end
Expand Down
103 changes: 58 additions & 45 deletions spec/reckon/date_column_spec.rb
Original file line number Diff line number Diff line change
@@ -1,59 +1,72 @@
#!/usr/bin/env ruby
# encoding: utf-8
# frozen_string_literal: true

require "spec_helper"
require 'rubygems'
require 'reckon'

describe Reckon::DateColumn do
describe "initialize" do
it "should detect us and world time" do
Reckon::DateColumn.new( ["01/02/2013", "01/14/2013"] ).endian_precedence.should == [:middle]
Reckon::DateColumn.new( ["01/02/2013", "14/01/2013"] ).endian_precedence.should == [:little]
end
it "should set endian_precedence to default when date format cannot be misinterpreted" do
Reckon::DateColumn.new( ["2013/01/02"] ).endian_precedence.should == [:middle,:little]
end
it "should raise an error when in doubt" do
expect{ Reckon::DateColumn.new( ["01/02/2013", "01/03/2013"] )}.to raise_error( StandardError )
end
end
describe "for" do
it "should detect the date" do
expect(Reckon::DateColumn.new(%w[13/12/2013]).for(0))
.to eq(Date.new(2013, 12, 13))
expect(Reckon::DateColumn.new(%w[01/14/2013]).for(0))
.to eq(Date.new(2013, 1, 14))
expect(Reckon::DateColumn.new(%w[13/12/2013 21/11/2013]).for(1))
.to eq(Date.new(2013, 11, 21))
expect(Reckon::DateColumn.new( ["2013-11-21"] ).for( 0 ))
.to eq(Date.new(2013, 11, 21))
require "rubygems"
require "reckon"

# datecolumn specs
module Reckon
describe DateColumn do
describe "#initialize" do
it "should detect us and world time" do
expect(DateColumn.new(%w[01/02/2013 01/14/2013]).endian_precedence)
.to eq [:middle]
expect(DateColumn.new(%w[01/02/2013 14/01/2013]).endian_precedence)
.to eq [:little]
end
it "should set endian_precedence to default when date format cannot be misinterpreted" do
expect(DateColumn.new(["2013/01/02"]).endian_precedence)
.to eq %i[middle little]
end
it "should raise an error when in doubt" do
expect { DateColumn.new(["01/02/2013", "01/03/2013"]) }
.to raise_error(StandardError)
end
end

it "should correctly use endian_precedence" do
expect(Reckon::DateColumn.new(%w[01/02/2013 01/14/2013]).for(0))
.to eq(Date.new(2013, 1, 2))
expect(Reckon::DateColumn.new(%w[01/02/2013 14/01/2013]).for(0))
.to eq(Date.new(2013, 2, 1))
end
end
describe "#for" do
it "should detect the date" do
expect(DateColumn.new(%w[13/12/2013]).for(0)).to eq(Date.new(2013, 12, 13))
expect(DateColumn.new(%w[01/14/2013]).for(0)).to eq(Date.new(2013, 1, 14))
expect(DateColumn.new(%w[13/12/2013 21/11/2013]).for(1))
.to eq(Date.new(2013, 11, 21))
expect(DateColumn.new(["2013-11-21"]).for(0)).to eq(Date.new(2013, 11, 21))
end

describe "#pretty_for" do
it 'should use ledger_date_format' do
expect(Reckon::DateColumn.new(%w[13/02/2013], {ledger_date_format: '%d/%m/%Y'}).pretty_for(0))
.to eq('13/02/2013')
it "should correctly use endian_precedence" do
expect(DateColumn.new(%w[01/02/2013 01/14/2013]).for(0))
.to eq(Date.new(2013, 1, 2))
expect(DateColumn.new(%w[01/02/2013 14/01/2013]).for(0))
.to eq(Date.new(2013, 2, 1))
end
end

it 'should default to is' do
expect(Reckon::DateColumn.new(%w[13/12/2013]).pretty_for(0))
.to eq('2013-12-13')
describe "#pretty_for" do
it "should use ledger_date_format" do
expect(
DateColumn.new(["13/02/2013"],
{ ledger_date_format: "%d/%m/%Y" }).pretty_for(0)
)
.to eq("13/02/2013")
end

it "should default to is" do
expect(DateColumn.new(["13/12/2013"]).pretty_for(0))
.to eq("2013-12-13")
end
end
end

describe "#likelihood" do
it "should prefer numbers that looks like dates" do
expect(Reckon::DateColumn.likelihood("123456789")).to be < Reckon::DateColumn.likelihood("20160102")
describe "#likelihood" do
it "should prefer numbers that looks like dates" do
expect(DateColumn.likelihood("123456789"))
.to be < DateColumn.likelihood("20160102")
end

# See https://github.com/cantino/reckon/issues/126
it "Issue #126 - it shouldn't fail on invalid dates" do
expect(DateColumn.likelihood("303909302970-07-2023")).to be > 0
end
end
end
end

0 comments on commit 42eba87

Please sign in to comment.