Skip to content

Commit 230963f

Browse files
authored
Fix test failures because of times with microseconds (#299)
1 parent 988bd3d commit 230963f

8 files changed

Lines changed: 40 additions & 15 deletions

File tree

.tool-versions

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
elixir 1.12.1-otp-24
2-
erlang 24.0.2
1+
elixir 1.14.5-otp-25
2+
erlang 25.3.2

lib/cocktail/builder/i_calendar.ex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ defmodule Cocktail.Builder.ICalendar do
55
TODO: write long description
66
"""
77

8+
import Cocktail.Util
9+
810
alias Cocktail.{Rule, Schedule, Validation}
911
alias Cocktail.Validation.{Day, DayOfMonth, HourOfDay, Interval, MinuteOfHour, SecondOfMinute, TimeOfDay, TimeRange}
1012

@@ -106,7 +108,7 @@ defmodule Cocktail.Builder.ICalendar do
106108

107109
defp build_end_time(%Schedule{start_time: start_time, duration: duration}) do
108110
start_time
109-
|> Timex.shift(seconds: duration)
111+
|> shift_time(seconds: duration)
110112
|> build_time("DTEND")
111113
end
112114

lib/cocktail/schedule_state.ex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ defmodule Cocktail.ScheduleState do
22
@moduledoc false
33

44
alias Cocktail.{RuleState, Schedule, Span}
5+
import Cocktail.Util
56

67
@type t :: %__MODULE__{
78
recurrence_rules: [RuleState.t()],
@@ -114,15 +115,15 @@ defmodule Cocktail.ScheduleState do
114115
| recurrence_rules: rules,
115116
recurrence_times: times,
116117
exception_times: exceptions,
117-
current_time: Timex.shift(time, seconds: 1)
118+
current_time: shift_time(time, seconds: 1)
118119
}
119120

120121
{occurrence, new_state}
121122
end
122123

123124
@spec span_or_time(Cocktail.time() | nil, pos_integer | nil) :: Cocktail.occurrence()
124125
defp span_or_time(time, nil), do: time
125-
defp span_or_time(time, duration), do: Span.new(time, Timex.shift(time, seconds: duration))
126+
defp span_or_time(time, duration), do: Span.new(time, shift_time(time, seconds: duration))
126127

127128
@spec min_time_for_rules([RuleState.t()]) :: Cocktail.time() | nil
128129
defp min_time_for_rules([]), do: nil

lib/cocktail/util.ex

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,26 @@ defmodule Cocktail.Util do
33

44
def next_gte([], _), do: nil
55
def next_gte([x | rest], search), do: if(x >= search, do: x, else: next_gte(rest, search))
6+
7+
def beginning_of_day(time) do
8+
time
9+
|> Timex.beginning_of_day()
10+
|> no_ms()
11+
end
12+
13+
def beginning_of_month(time) do
14+
time
15+
|> Timex.beginning_of_month()
16+
|> no_ms()
17+
end
18+
19+
def shift_time(datetime, opts) do
20+
datetime
21+
|> Timex.shift(opts)
22+
|> no_ms()
23+
end
24+
25+
def no_ms(time) do
26+
Map.put(time, :microsecond, {0, 0})
27+
end
628
end

lib/cocktail/validation/day_of_month.ex

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule Cocktail.Validation.DayOfMonth do
22
@moduledoc false
33

44
import Cocktail.Validation.Shift
5-
import Cocktail.Util, only: [next_gte: 2]
5+
import Cocktail.Util
66

77
# assumed that DST can not "take" more than 4 hours between any 2 consecutive days
88
@min_dst_resultant_hours 20
@@ -28,9 +28,7 @@ defmodule Cocktail.Validation.DayOfMonth do
2828
case next_gte(normalized_days, current_day_of_month) do
2929
# go to next month
3030
nil ->
31-
next_month_time =
32-
time
33-
|> Timex.shift(months: 1)
31+
next_month_time = shift_time(time, months: 1)
3432

3533
next_month_normalized_days = Enum.map(days, &normalize_day_of_month(&1, next_month_time))
3634
next_month_earliest_day = Timex.set(next_month_time, day: hd(Enum.sort(next_month_normalized_days)))

lib/cocktail/validation/interval.ex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ defmodule Cocktail.Validation.Interval do
33

44
import Integer, only: [mod: 2, floor_div: 2]
55
import Cocktail.Validation.Shift
6+
import Cocktail.Util
67

78
@typep iso_week :: {Timex.Types.year(), Timex.Types.weeknum()}
89

@@ -20,8 +21,8 @@ defmodule Cocktail.Validation.Interval do
2021

2122
def next_time(%__MODULE__{type: :monthly, interval: interval}, time, start_time) do
2223
start_time
23-
|> Timex.beginning_of_month()
24-
|> Timex.diff(Timex.beginning_of_month(time), :months)
24+
|> beginning_of_month()
25+
|> Timex.diff(beginning_of_month(time), :months)
2526
|> mod(interval)
2627
|> shift_by(:months, time)
2728
end

lib/cocktail/validation/schedule_lock.ex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ defmodule Cocktail.Validation.ScheduleLock do
33

44
import Integer, only: [mod: 2]
55
import Cocktail.Validation.Shift
6+
import Cocktail.Util
67

78
@type lock :: :second | :minute | :hour | :wday | :mday
89

@@ -34,7 +35,7 @@ defmodule Cocktail.Validation.ScheduleLock do
3435

3536
def next_time(%__MODULE__{type: :mday}, time, start_time) do
3637
if start_time.day > Calendar.ISO.days_in_month(time.year, time.month) do
37-
next_time(%__MODULE__{type: :mday}, Timex.shift(time, months: 1), start_time)
38+
next_time(%__MODULE__{type: :mday}, shift_time(time, months: 1), start_time)
3839
else
3940
next_mday_time(%__MODULE__{type: :mday}, time, start_time)
4041
end
@@ -56,7 +57,7 @@ defmodule Cocktail.Validation.ScheduleLock do
5657
|> Timex.diff(time, :days)
5758

5859
start_time_day_of_month ->
59-
next_month_date = Timex.shift(time, months: 1)
60+
next_month_date = shift_time(time, months: 1)
6061
# Timex.set already handle the marginal case like setting a day of month more than the month contains
6162
next_month_date
6263
|> Timex.set(day: start_time_day_of_month)

lib/cocktail/validation/shift.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ defmodule Cocktail.Validation.Shift do
99

1010
@typep option :: nil | :beginning_of_day | :beginning_of_hour | :beginning_of_minute
1111

12-
import Timex, only: [shift: 2, beginning_of_day: 1]
12+
import Cocktail.Util
1313

1414
@spec shift_by(integer, shift_type, Cocktail.time(), option) :: result
1515
def shift_by(amount, type, time, option \\ nil)
@@ -18,7 +18,7 @@ defmodule Cocktail.Validation.Shift do
1818
def shift_by(amount, type, time, option) do
1919
new_time =
2020
time
21-
|> shift("#{type}": amount)
21+
|> shift_time("#{type}": amount)
2222
|> apply_option(option)
2323

2424
{:change, new_time}

0 commit comments

Comments
 (0)