Skip to content

Commit

Permalink
Transfers: result includes also winning solemnities
Browse files Browse the repository at this point in the history
This makes the transfer logic completely encapsulated in Transfers and
celebration precedence logic in Calendar#celebrations_for doesn't
interfere with it anymore.
This is the ultimate fix to the solemnity loss and duplication bug (#80).
  • Loading branch information
igneus committed Mar 6, 2021
1 parent 3b8fa22 commit 5e04c10
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 61 deletions.
19 changes: 15 additions & 4 deletions lib/calendarium-romanum/transfers.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module CalendariumRomanum

# Internal {Calendar} component.
# {Calendar} component.
# Resolves transfers of conflicting solemnities.
#
# For any day {Temporale} has a {Celebration}.
Expand All @@ -12,22 +12,31 @@ module CalendariumRomanum
# one is celebrated on the given day and the less lucky one
# must be transferred to another day.
# However, not all days are valid as targets of solemnity transfer.
#
# @api private
# This class handles the logic of transferring impeded solemnities
# to suitable dates.
class Transfers
# @param temporale [Temporale]
# @param sanctorale [Sanctorale]
# @api private
def initialize(temporale, sanctorale)
@temporale = temporale
@sanctorale = sanctorale
end

# Resolves any conflict between temporale and sanctorale solemnities
# by deciding which of the conflicting solemnities is to take the original
# date, which is to be transferred, and specifying a date for both of them
# in the resulting Hash.
#
# @param temporale [Temporale]
# @param sanctorale [Sanctorale]
# @return [Hash<Date=>Celebration>]
def self.call(temporale, sanctorale)
new(temporale, sanctorale).call
end

# @return [Hash<Date=>Celebration>]
# @api private
def call
@transferred = {}

Expand All @@ -42,7 +51,7 @@ def call
sc = @sanctorale[date].first
next unless sc && sc.solemnity?

loser = [sc, tc].sort_by(&:rank).first
loser, winner = [sc, tc].sort_by(&:rank)

transfer_to =
if loser.symbol == :annunciation && in_holy_week?(date)
Expand All @@ -52,6 +61,8 @@ def call
free_day_closest_to(date)
end
@transferred[transfer_to] = loser
# primary celebrations have noone to be beaten by, no need to harden their dates
@transferred[date] = winner unless winner.rank == Ranks::PRIMARY
end

@transferred
Expand Down
53 changes: 0 additions & 53 deletions spec/calendar_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -500,59 +500,6 @@
end
end

describe 'effect of transfers' do
let(:year) { 2032 } # year with an interesting solemnity collision
let(:temporale) { CR::Temporale.new year }
let(:sanctorale) { CR::Data::GENERAL_ROMAN_ENGLISH.load }
let(:calendar) { described_class.new(temporale, sanctorale, transfers: transfers) }
let(:date) { Date.new 2033, 6, 24 }

before :each do
# make sure
all_celebrations = sanctorale[date] + [temporale[date]]

expect(all_celebrations)
.to all(be_solemnity)
expect(all_celebrations.collect(&:rank).uniq.size).to eq 1 # same rank
end

describe 'collision not resolved' do
let(:transfers) { proc { {} } } # no solution, just an empty Hash

it 'temporale solemnity wins, sanctorale one is lost' do
expect(calendar[date].celebrations)
.to eq [temporale[date]]

expect(calendar[date + 1].celebrations)
.not_to eq sanctorale[date]
expect(calendar[date - 1].celebrations)
.not_to eq sanctorale[date]
end
end

describe 'sanctorale solemnity transferred' do
let(:transfers) { proc { {(date + 1) => sanctorale[date].first} } }

it 'works as expected' do
expect(calendar[date].celebrations)
.to eq [temporale[date]]
expect(calendar[date + 1].celebrations)
.to eq sanctorale[date]
end
end

describe 'temporale solemnity transferred' do
let(:transfers) { proc { {(date + 1) => temporale[date]} } }

it 'works as expected' do
expect(calendar[date].celebrations)
.to eq sanctorale[date]
expect(calendar[date + 1].celebrations)
.to eq [temporale[date]]
end
end
end

it 'transfer of suppressed Annunciation (real world example)' do
c = described_class.new 2015, s

Expand Down
8 changes: 4 additions & 4 deletions spec/transfers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def date_set_temporale_impeded(date)
let(:sanctorale_solemnity) { lower_solemnity }

it 'wins' do
expect(transfers.call).to eq({(date + 1) => sanctorale_solemnity})
expect(transfers.call).to eq({date => temporale_solemnity, (date + 1) => sanctorale_solemnity})
end
end

Expand All @@ -121,7 +121,7 @@ def date_set_temporale_impeded(date)
let(:sanctorale_solemnity) { higher_solemnity }

it 'wins' do
expect(transfers.call).to eq({(date + 1) => temporale_solemnity})
expect(transfers.call).to eq({date => sanctorale_solemnity, (date + 1) => temporale_solemnity})
end
end

Expand All @@ -130,7 +130,7 @@ def date_set_temporale_impeded(date)
let(:sanctorale_solemnity) { CR::Celebration.new('s', rank: CR::Ranks::SOLEMNITY_GENERAL) }

it 'temporale wins' do
expect(transfers.call).to eq({(date + 1) => sanctorale_solemnity})
expect(transfers.call).to eq({date => temporale_solemnity, (date + 1) => sanctorale_solemnity})
end
end
end
Expand All @@ -150,7 +150,7 @@ def date_set_temporale_impeded(date)
date_set(date + 1, sanctorale_cel: celebration_in_the_way)
date_set_free(date - 1)

# date+1 was impeded by celebration_in_the_way
# date+1 was impeded by celebration_in_the_way, transferring backwards
expect(transfers.call).to eq({(date - 1) => solemnity})
end
end
Expand Down

0 comments on commit 5e04c10

Please sign in to comment.