From 42eba87add4227a9323d4313e0567dc1a27af582 Mon Sep 17 00:00:00 2001 From: Ben Prew Date: Fri, 24 Nov 2023 13:54:56 -0800 Subject: [PATCH] [bug] catch RangeError when trying to parse dates And refactor date_column_spec.rb --- lib/reckon/date_column.rb | 9 ++- spec/reckon/date_column_spec.rb | 103 ++++++++++++++++++-------------- 2 files changed, 64 insertions(+), 48 deletions(-) diff --git a/lib/reckon/date_column.rb b/lib/reckon/date_column.rb index 8ddea06..78821a4 100644 --- a/lib/reckon/date_column.rb +++ b/lib/reckon/date_column.rb @@ -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 diff --git a/spec/reckon/date_column_spec.rb b/spec/reckon/date_column_spec.rb index 24f0506..028b88a 100755 --- a/spec/reckon/date_column_spec.rb +++ b/spec/reckon/date_column_spec.rb @@ -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