Skip to content

Instantly share code, notes, and snippets.

@stevenharman
Created March 4, 2022 15:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevenharman/1081d2cab9b893f9832fe1e276a83474 to your computer and use it in GitHub Desktop.
Save stevenharman/1081d2cab9b893f9832fe1e276a83474 to your computer and use it in GitHub Desktop.
A DateRange value object, for those times you need to work with a range (or span) of dates (or really... datetimes)!
# frozen_string_literal: true
require 'active_support'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/time'
class DateRange
attr_reader :start, :stop
def initialize(start: nil, stop: nil)
@start = extract_date(start)
@stop = extract_date(stop)
end
alias begin start
alias :end stop
def empty?
start.blank? && stop.blank?
end
def present?
!blank?
end
def start?
start.present?
end
alias begin? start?
def stop?
stop.present?
end
alias :end? stop?
private
def extract_date(date)
return nil if date.blank?
Time.zone.parse(String(date)).to_date
end
end
# frozen_string_literal: true
require 'date_range'
RSpec.describe DateRange do
describe 'with no start nor stop' do
subject(:range) { described_class.new }
it 'is empty, blank' do
expect(range).to be_empty
expect(range).to be_blank
end
it 'is not present' do
expect(range).not_to be_present
end
end
describe 'converting strings to dates' do
subject(:range) { described_class.new(start: '2017-04-20', stop: '2018-04-28') }
it 'turns a valid date string into a date' do
expect(range.start).to eq(Date.parse('2017-04-20'))
expect(range.begin).to eq(Date.parse('2017-04-20'))
expect(range.stop).to eq(Date.parse('2018-04-28'))
expect(range.end).to eq(Date.parse('2018-04-28'))
end
it 'allows nil or empty dates' do
nil_dates = described_class.new(start: nil, stop: nil)
expect(nil_dates.start).to be_nil
expect(nil_dates.stop).to be_nil
empty_dates = described_class.new(start: '', stop: '')
expect(empty_dates.start).to be_nil
expect(empty_dates.stop).to be_nil
end
it 'blows up on a bad date' do
expect { described_class.new(start: '2018-01') }.to raise_error(ArgumentError)
expect { described_class.new(stop: '2018-01') }.to raise_error(ArgumentError)
end
end
describe 'with date objects' do
subject(:range) { described_class.new(start: Date.parse('2017-04-20'), stop: Date.parse('2018-04-28')) }
it 'turns a valid date string into a date' do
expect(range.start).to eq(Date.parse('2017-04-20'))
expect(range.begin).to eq(Date.parse('2017-04-20'))
expect(range.stop).to eq(Date.parse('2018-04-28'))
expect(range.end).to eq(Date.parse('2018-04-28'))
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment