forked from AgileVentures/shf-project
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: timing calculations into own class
- Loading branch information
1 parent
fc82c8c
commit a93dd69
Showing
3 changed files
with
212 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#-------------------------- | ||
# | ||
# @class ConditionScheduleCalculator | ||
# | ||
# @desc Responsibility: calculates time between two dates, giving a :timing_direction: | ||
# The :timing_direction is whether we are calculating the number of days | ||
# _before_, _after_, or _on_ this day, starting from today. | ||
# | ||
# @author Ashley Engelund (ashley.engelund@gmail.com weedySeaDragon @ github) | ||
# @date 2019-08-14 | ||
# | ||
#-------------------------- | ||
# | ||
class TimingCalculator | ||
|
||
|
||
# Determine the number of days today is _away_from_ this date. | ||
# | ||
# @param this_date [Date] - the date to compare to today | ||
# @param timing_direction [Symbol] - which 'direction' (before, after, on) to compare to today | ||
# @return [Integer] - the number of days away from today, based on our :timing_direction | ||
def self.days_today_is_away_from(this_date, timing_direction) | ||
days_1st_date_is_from_2nd(Date.current, this_date, timing_direction) | ||
end | ||
|
||
|
||
# Determine the number of days :a_date is _away_from_ :second_date. | ||
# The :timing_direction is whether we are calculating the number of days | ||
# _before_, _after_, or _on_ this day, starting from :a_date. | ||
# | ||
# @param a_date [Date] - the starting date | ||
# @param second_date [Date] - the date to compare to :a_date | ||
# @param timing_direction [Symbol] - which 'direction' (before, after, on) to compare to :a_date | ||
# @return [Integer] - the number of days separating the two dates, based on the :timing_direction | ||
def self.days_1st_date_is_from_2nd(a_date, second_date, timing_direction) | ||
|
||
day_num_to_check = 0 # default value | ||
|
||
# We use .to_date to ensure that we're comparing and working with Dates, not Times, etc. | ||
# If calling .to_date throws an exception, that's an exception that should be raised. | ||
|
||
if timing_direction == ConditionSchedule.timing_before | ||
# number of days that a_date is _before_ second_date | ||
day_num_to_check = second_date.to_date - a_date.to_date | ||
|
||
elsif timing_direction == ConditionSchedule.timing_after | ||
# number of days that a_date is _after_ second_date | ||
day_num_to_check = a_date.to_date - second_date.to_date | ||
end | ||
|
||
day_num_to_check.to_i | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
FactoryBot.define do | ||
|
||
factory :condition_schedule do | ||
timing { :on } | ||
end | ||
|
||
|
||
trait :after do | ||
timing { :after } | ||
end | ||
|
||
trait :before do | ||
timing { :before } | ||
end | ||
|
||
trait :on do | ||
timing { :on } | ||
end | ||
|
||
trait :every_day do | ||
timing { :every_day } | ||
end | ||
|
||
trait :monthly do | ||
timing { :on_month_day } | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
require 'rails_helper' | ||
|
||
RSpec.describe TimingCalculator do | ||
|
||
|
||
let(:timing_before) { ConditionSchedule.timing_before } | ||
let(:timing_after) { ConditionSchedule.timing_after } | ||
let(:timing_on) { ConditionSchedule.timing_on } | ||
|
||
|
||
let(:nov_30) { Date.new(2018, 11, 30) } | ||
let(:dec_1) { Date.new(2018, 12, 1) } | ||
let(:dec_2) { Date.new(2018, 12, 2) } | ||
|
||
|
||
around(:each) do |example| | ||
Timecop.freeze(dec_1) | ||
example.run | ||
Timecop.return | ||
end | ||
|
||
|
||
describe '.days_a_date_is_away_from is the number of days today is _away_from_ this date.' do | ||
|
||
describe 'timing_direction is before' do | ||
|
||
it '1st is 1 day before 2nd date = 1' do | ||
expect(described_class.days_1st_date_is_from_2nd(nov_30, dec_1, timing_before)).to eq 1 | ||
end | ||
|
||
it '1st = 2nd date == 0' do | ||
expect(described_class.days_1st_date_is_from_2nd(dec_1, dec_1, timing_before)).to eq 0 | ||
end | ||
|
||
it '1st date is 1 day after 2nd date = -1' do | ||
expect(described_class.days_1st_date_is_from_2nd(dec_2, dec_1, timing_before)).to eq -1 | ||
end | ||
|
||
end | ||
|
||
context 'timing_direction is after' do | ||
|
||
it '1st is 1 day before 2nd date = -1' do | ||
expect(described_class.days_1st_date_is_from_2nd(nov_30, dec_1, timing_after)).to eq -1 | ||
end | ||
|
||
it '1st = 2nd date == 0' do | ||
expect(described_class.days_1st_date_is_from_2nd(dec_1, dec_1, timing_after)).to eq 0 | ||
end | ||
|
||
it '1st date is 1 day after 2nd date = 1' do | ||
expect(described_class.days_1st_date_is_from_2nd(dec_2, dec_1, timing_after)).to eq 1 | ||
end | ||
|
||
end | ||
|
||
|
||
context 'timing_direction is on (always returns 0 days away; this means always check on the 2nd date no matter how many days away)' do | ||
|
||
it '2nd date is 1 day before the date = 0' do | ||
expect(described_class.days_1st_date_is_from_2nd(dec_1, nov_30, timing_on)).to eq 0 | ||
end | ||
|
||
it '2nd date is == the date = 0' do | ||
expect(described_class.days_1st_date_is_from_2nd(dec_1, dec_1, timing_on)).to eq 0 | ||
end | ||
|
||
it '2nd date is 1 day after the date = 0' do | ||
expect(described_class.days_1st_date_is_from_2nd(dec_1, dec_2, timing_on)).to eq 0 | ||
end | ||
|
||
end | ||
|
||
end | ||
|
||
|
||
describe '.days_today_is_away_from(timing, some_date)' do | ||
|
||
context 'timing_direction is before' do | ||
|
||
it 'today is 1 day before the date = described_class.days_1st_date_is_from_2nd(Date.current, nov_30, timing_before)' do | ||
expect(described_class.days_today_is_away_from(nov_30, timing_before)).to eq described_class.days_1st_date_is_from_2nd(dec_1, nov_30, timing_before) | ||
end | ||
|
||
it 'today = the date = described_class.days_1st_date_is_from_2nd(Date.current, dec_1, timing_before)' do | ||
expect(described_class.days_today_is_away_from(dec_1, timing_before)).to eq described_class.days_1st_date_is_from_2nd(Date.current, dec_1, timing_before) | ||
end | ||
|
||
it 'today is 1 day after the date = described_class.days_1st_date_is_from_2nd(Date.current, dec_2, timing_before)' do | ||
expect(described_class.days_today_is_away_from(dec_2, timing_before)).to eq described_class.days_1st_date_is_from_2nd(Date.current, dec_2, timing_before) | ||
end | ||
|
||
end | ||
|
||
context 'timing_direction is after' do | ||
|
||
it 'today is 1 day after the date = described_class.days_1st_date_is_from_2nd(Date.current, dec_2, timing_after)' do | ||
expect(described_class.days_today_is_away_from(dec_2, timing_after)).to eq described_class.days_1st_date_is_from_2nd(Date.current, dec_2, timing_after) | ||
end | ||
|
||
it 'date is on today = described_class.days_1st_date_is_from_2nd(Date.current, dec_1, timing_after)' do | ||
expect(described_class.days_today_is_away_from(dec_1, timing_after)).to eq described_class.days_1st_date_is_from_2nd(Date.current, dec_1, timing_after) | ||
end | ||
|
||
it 'today is 1 day before the date = described_class.days_1st_date_is_from_2nd(Date.current, nov_30, timing_after)' do | ||
expect(described_class.days_today_is_away_from(nov_30, timing_after)).to eq described_class.days_1st_date_is_from_2nd(Date.current, nov_30, timing_after) | ||
end | ||
|
||
end | ||
|
||
|
||
context 'timing_direction is on (always returns 0 days away; this means always check on today)' do | ||
|
||
it 'date is 1 day before today = described_class.days_1st_date_is_from_2nd(Date.current, nov_30, timing_on)' do | ||
expect(described_class.days_today_is_away_from(nov_30, timing_on)).to eq described_class.days_1st_date_is_from_2nd(Date.current, nov_30, timing_on) | ||
end | ||
|
||
it 'date is on today = described_class.days_1st_date_is_from_2nd(Date.current, dec_1, timing_on)' do | ||
expect(described_class.days_today_is_away_from(dec_1, timing_on)).to eq described_class.days_1st_date_is_from_2nd(Date.current, dec_1, timing_on) | ||
end | ||
|
||
it 'date is 1 day after today = described_class.days_1st_date_is_from_2nd(Date.current, dec_2, timing_on)' do | ||
expect(described_class.days_today_is_away_from(dec_2, timing_on)).to eq described_class.days_1st_date_is_from_2nd(Date.current, dec_2, timing_on) | ||
end | ||
|
||
end | ||
|
||
end | ||
|
||
end |