Skip to content

Commit

Permalink
Fix property tests and improve generators
Browse files Browse the repository at this point in the history
  • Loading branch information
bitwalker committed Jun 27, 2019
1 parent 32018e5 commit 28096f1
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 15 deletions.
12 changes: 10 additions & 2 deletions lib/datetime/datetime.ex
Original file line number Diff line number Diff line change
Expand Up @@ -245,14 +245,22 @@ defimpl Timex.Protocol, for: DateTime do
shifted_us = us + shift
shifted_secs = div(shifted_us, 1_000*1_000) + (applied_offset_ms * -1)
rem_us = rem(shifted_us, 1_000*1_000)
new_precision =
case Timex.DateTime.Helpers.precision(rem_us) do
np when np < precision ->
precision

np ->
np
end

# Convert back to original timezone
case raw_convert(shifted_secs, {rem_us, precision}, tz, :wall) do
case raw_convert(shifted_secs, {rem_us, new_precision}, tz, :wall) do
{:error, {:could_not_resolve_timezone, _, _, _}} ->
# This occurs when the shifted date/time doesn't exist because of a leap forward
# This doesn't mean the shift is invalid, simply that we need to ask for the right wall time
# Which in these cases means asking for the time + 1h
raw_convert(shifted_secs + 3600, {rem_us, precision}, tz, :wall)
raw_convert(shifted_secs + 3600, {rem_us, new_precision}, tz, :wall)
result ->
result
end
Expand Down
4 changes: 2 additions & 2 deletions lib/datetime/helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ defmodule Timex.DateTime.Helpers do
end
end

defp precision(0), do: 0
defp precision(n) when is_integer(n) do
def precision(0), do: 0
def precision(n) when is_integer(n) do
ns = Integer.to_string(n)
n_width = byte_size(ns)
trimmed = byte_size(String.trim_trailing(ns, "0"))
Expand Down
29 changes: 25 additions & 4 deletions test/helpers/property_helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@ defmodule PropertyHelpers do
"""

def date_time_generator(:struct) do
date_time_generator(:tupple)
|> StreamData.map(&Timex.to_datetime/1)
[
date_time_generator(:tuple),
microsecond_generator()
]
|> StreamData.fixed_list()
|> StreamData.map(fn [{{y, m, d}, {h, mm, s}}, {us, p}] ->
{:ok, nd} = NaiveDateTime.new(y, m, d, h, mm, s, {us, p})
DateTime.from_naive!(nd, "Etc/UTC")
end)
end

def date_time_generator(:tupple) do
def date_time_generator(:tuple) do
[
StreamData.integer(2000..2030),
StreamData.integer(1..12),
Expand All @@ -18,6 +25,9 @@ defmodule PropertyHelpers do
StreamData.integer(0..59)
]
|> StreamData.fixed_list()
|> StreamData.filter(fn [year, month, day, _hour, _minute, _second] ->
:calendar.valid_date(year, month, day)
end)
|> StreamData.map(fn [year, month, day, hour, minute, second] ->
{{year, month, day}, {hour, minute, second}}
end)
Expand All @@ -27,4 +37,15 @@ defmodule PropertyHelpers do
Timex.timezones()
|> StreamData.member_of()
end
end

def microsecond_generator() do
[
StreamData.integer(0..999_999),
StreamData.integer(1..6)
]
|> StreamData.fixed_list()
|> StreamData.map(fn [us, precision] ->
{us, precision}
end)
end
end
8 changes: 4 additions & 4 deletions test/set_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ defmodule SetTests do

property "setting all the properties from the target date should become a target date for a DateTime" do
check all input_date <- PropertyHelpers.date_time_generator(:struct),
{{year, month, day}, {hour, minute, second}} = target_date <- PropertyHelpers.date_time_generator(:tupple) do
{{year, month, day}, {hour, minute, second}} = target_date <- PropertyHelpers.date_time_generator(:tuple) do

date = Timex.set(input_date, [year: year, month: month, day: day, hour: hour, minute: minute, second: second])
assert Timex.to_erl(date) == target_date
end
end

property "setting all the properties from the target date should become a target date for a tupple" do
check all input_date <- PropertyHelpers.date_time_generator(:tupple),
{{year, month, day}, {hour, minute, second}} = target_date <- PropertyHelpers.date_time_generator(:tupple) do
property "setting all the properties from the target date should become a target date for a tuple" do
check all input_date <- PropertyHelpers.date_time_generator(:tuple),
{{year, month, day}, {hour, minute, second}} = target_date <- PropertyHelpers.date_time_generator(:tuple) do

date = Timex.set(input_date, [year: year, month: month, day: day, hour: hour, minute: minute, second: second])
assert Timex.to_erl(date) == target_date
Expand Down
4 changes: 2 additions & 2 deletions test/timex_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ defmodule TimexTests do

test "subtract milliseconds" do
time = Timex.to_datetime({{2015, 6, 24}, {14, 27, 52}})
time = %{time | microsecond: {910_000, 6}}
time = %{time | microsecond: {910_000, 2}}
subtracted = Timex.subtract(time, Duration.from_milliseconds(10))
assert subtracted.microsecond === {900_000, 6}
assert subtracted.microsecond === {900_000, 2}
end

test "weekday" do
Expand Down
2 changes: 1 addition & 1 deletion test/timezone_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ defmodule TimezoneTests do
end

property "convert always returns DateTime or AmbiguousDateTime" do
check all input_date <- PropertyHelpers.date_time_generator(:tupple),
check all input_date <- PropertyHelpers.date_time_generator(:tuple),
timezone <- PropertyHelpers.timezone_generator() do
result = Timezone.convert(input_date, timezone)
assert match?(%DateTime{}, result) || match?(%Timex.AmbiguousDateTime{}, result)
Expand Down

0 comments on commit 28096f1

Please sign in to comment.