Skip to content

Commit

Permalink
Merge pull request #241 from maxx-coffee/main
Browse files Browse the repository at this point in the history
Excludes times when they fall out of range
  • Loading branch information
dimakula authored Jan 3, 2024
2 parents e497f58 + fed4619 commit 565654b
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 8 deletions.
36 changes: 28 additions & 8 deletions lib/cocktail/schedule_state.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ defmodule Cocktail.ScheduleState do
%__MODULE__{
recurrence_rules: schedule.recurrence_rules |> Enum.map(&RuleState.new/1),
recurrence_times: recurrence_times_after_current_time,
exception_times: schedule.exception_times |> Enum.sort(&(Timex.compare(&1, &2) <= 0)),
exception_times: schedule.exception_times |> Enum.uniq() |> Enum.sort(&(Timex.compare(&1, &2) <= 0)),
start_time: schedule.start_time,
current_time: current_time,
duration: schedule.duration
Expand All @@ -51,7 +51,15 @@ defmodule Cocktail.ScheduleState do
{time, remaining_rules} = next_time_from_recurrence_rules(state)
{time, remaining_times} = next_time_from_recurrence_times(state.recurrence_times, time)
{is_exception, remaining_exceptions} = apply_exception_time(state.exception_times, time)
result = next_occurrence_and_state(time, remaining_rules, remaining_times, remaining_exceptions, state)

result =
next_occurrence_and_state(
time,
remaining_rules,
remaining_times,
remaining_exceptions,
state
)

case result do
{occurrence, state} ->
Expand Down Expand Up @@ -91,19 +99,31 @@ defmodule Cocktail.ScheduleState do
end
end

@spec apply_exception_time([Cocktail.time()], Cocktail.time() | nil) :: {boolean, [Cocktail.time()]}
@spec apply_exception_time([Cocktail.time()], Cocktail.time() | nil) ::
{boolean, [Cocktail.time()]}
defp apply_exception_time([], _), do: {false, []}
defp apply_exception_time(exceptions, nil), do: {false, exceptions}

defp apply_exception_time([next_exception | rest] = exceptions, current_time) do
if Timex.compare(next_exception, current_time) == 0 do
{true, rest}
else
{false, exceptions}
case Timex.compare(next_exception, current_time) do
0 ->
{true, rest}

-1 ->
apply_exception_time(rest, current_time)

_ ->
{false, exceptions}
end
end

@spec next_occurrence_and_state(Cocktail.time(), [RuleState.t()], [Cocktail.time()], [Cocktail.time()], t) ::
@spec next_occurrence_and_state(
Cocktail.time(),
[RuleState.t()],
[Cocktail.time()],
[Cocktail.time()],
t
) ::
{Cocktail.occurrence(), t} | nil
defp next_occurrence_and_state(nil, _, _, _, _), do: nil

Expand Down
30 changes: 30 additions & 0 deletions test/cocktail/schedule_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,36 @@ defmodule Cocktail.ScheduleTest do
assert times == [~N[2017-09-09 09:00:00], ~N[2017-09-11 09:00:00]]
end

test "exception times outside of schedule" do
schedule =
~N[2017-09-09 09:00:00]
|> Cocktail.Schedule.new(duration: 1800)
|> Cocktail.Schedule.add_recurrence_rule(:secondly,
interval: 1800,
hours: [9, 10, 11, 12, 13, 14, 15],
until: ~N[2017-09-10 23:59:00]
)
|> Schedule.add_exception_time(~N[2017-09-09 13:00:00])
|> Schedule.add_exception_time(~N[2017-09-09 13:00:00])
|> Schedule.add_exception_time(~N[2017-09-09 13:30:00])
|> Schedule.add_exception_time(~N[2017-09-09 17:00:00])
|> Schedule.add_exception_time(~N[2017-09-10 10:00:00])

times = schedule |> Schedule.occurrences() |> Enum.to_list()

refute times
|> Enum.member?(%Cocktail.Span{
from: ~N[2017-09-10 10:00:00],
until: ~N[2017-09-10 10:30:00]
})

refute times
|> Enum.member?(%Cocktail.Span{
from: ~N[2017-09-09 13:30:00],
until: ~N[2017-09-09 14:00:00]
})
end

test "exception times with no schedule or recurrence time" do
schedule =
~N[2017-09-09 09:00:00]
Expand Down

0 comments on commit 565654b

Please sign in to comment.