From 332f4bae6f7110ec76cb9b14da81cbba8a0abca0 Mon Sep 17 00:00:00 2001 From: Craig Little Date: Fri, 17 Feb 2023 13:13:10 -0800 Subject: [PATCH] Raise an exception when timestamp is malformed Previously, when a provided timestamp didn't match the regex format, it would be configured as `nil`. This was nonsensical since a `nil` timestamp is unusable, which allowed for subtle bugs to creep in. Instead, we should alert the user as soon as an improper timestamp is encountered by raising an informative exception. The documentation has also been updated to reflect the expectations for tiemstamp format. Fixes #140. --- README.md | 2 ++ lib/biz/day_time.rb | 5 +++- spec/day_time_spec.rb | 66 +++++++++++++++++++++++++++++++------------ 3 files changed, 54 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 570f11a..38e6aef 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,8 @@ Biz.configure do |config| end ``` +Configured timestamps must be in either `HH:MM` or `HH:MM:SS` format. + Shifts act as exceptions to the hours configured for a particular date; that is, if a date is configured with both hours-based intervals and shifts, the shifts are in force and the intervals are disregarded. diff --git a/lib/biz/day_time.rb b/lib/biz/day_time.rb index 9916f95..4dd44e7 100644 --- a/lib/biz/day_time.rb +++ b/lib/biz/day_time.rb @@ -38,7 +38,10 @@ def from_timestamp(timestamp) match[:minute].to_i * Time.minute_seconds + match[:second].to_i ) - } + } or fail( + Error::Configuration, + 'invalid timestamp: must be in `HH:MM` or `HH:MM:SS` format' + ) end def midnight diff --git a/spec/day_time_spec.rb b/spec/day_time_spec.rb index fa974d2..4378e21 100644 --- a/spec/day_time_spec.rb +++ b/spec/day_time_spec.rb @@ -78,33 +78,63 @@ end describe '.from_timestamp' do - context 'when the timestamp is malformed' do + context 'when the timestamp is not a timestamp' do let(:timestamp) { 'timestamp' } - it 'returns nil' do - expect(described_class.from_timestamp(timestamp)).to eq nil + it 'raises a configuration error' do + expect { + described_class.from_timestamp(timestamp) + }.to raise_error Biz::Error::Configuration + end + end + + context 'when the timestamp is in `H:MM` format' do + let(:timestamp) { '5:35' } + + it 'raises a configuration error' do + expect { + described_class.from_timestamp(timestamp) + }.to raise_error Biz::Error::Configuration end end - context 'when the timestamp is well formed' do - context 'without seconds' do - let(:timestamp) { '21:43' } + context 'when the timestamp is in `HH:M` format' do + let(:timestamp) { '12:3' } - it 'returns the appropriate day time' do - expect(described_class.from_timestamp(timestamp)).to eq( - described_class.new(day_second(hour: 21, min: 43)) - ) - end + it 'raises a configuration error' do + expect { + described_class.from_timestamp(timestamp) + }.to raise_error Biz::Error::Configuration end + end - context 'with seconds' do - let(:timestamp) { '10:55:23' } + context 'when the timestamp is in `HH:MM:S` format' do + let(:timestamp) { '11:35:3' } - it 'returns the appropriate day time' do - expect(described_class.from_timestamp(timestamp)).to eq( - described_class.new(day_second(hour: 10, min: 55, sec: 23)) - ) - end + it 'raises a configuration error' do + expect { + described_class.from_timestamp(timestamp) + }.to raise_error Biz::Error::Configuration + end + end + + context 'when the timestamp is in `HH:MM` format' do + let(:timestamp) { '21:43' } + + it 'returns the appropriate day time' do + expect(described_class.from_timestamp(timestamp)).to eq( + described_class.new(day_second(hour: 21, min: 43)) + ) + end + end + + context 'when the timestamp is in `HH:MM:SS` format' do + let(:timestamp) { '10:55:23' } + + it 'returns the appropriate day time' do + expect(described_class.from_timestamp(timestamp)).to eq( + described_class.new(day_second(hour: 10, min: 55, sec: 23)) + ) end end end