Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DateTime util module and tests #2372

Merged
merged 52 commits into from
Feb 11, 2025
Merged

DateTime util module and tests #2372

merged 52 commits into from
Feb 11, 2025

Conversation

anthonyshull
Copy link
Contributor

This is just some background work to system status and planned disruptions. Most of the logic entails checking the time range of an alert against various service ranges. This elevates the concept of a service range in a similar way that Timex has functions like beginning_of_week or end_of_week. But, instead we have beginning_of_service_week and end_of_service_week.

The tests introduce a new property-based testing framework which is great for catching edge cases like daylight savings time.

@anthonyshull anthonyshull marked this pull request as ready for review February 10, 2025 16:04
@anthonyshull anthonyshull requested a review from a team as a code owner February 10, 2025 16:04

alias Dotcom.Utils

@type service_range() :: :past | :today | :this_week | :next_week | :later
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Non-blocking) This name (and the name of the function below that's also called service_range/1) feels like a potential source of confusion, since it refers to an atom, not an actual range.


The service range continuum:

<---before today---|---later this week---|---next week---|---after next week--->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooh this is nice. Love a good explanatory ASCII art.

That is because one hour does not occur--02:00:00am to 03:00:00am.
In that case, we set the time to 03:00:00am.

If we are given something tha tis not a DateTime, AmbiguousDateTime, or an error tuple, we log the input and return `now`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Non-blocking): It looks like the now fallback was removed (thank you 🙂), so unless I missed something, I think we can also drop this part of the doc comment?

Copy link
Contributor

@joshlarson joshlarson Feb 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also a small nit, but if I did miss something then here's a tiny spelling fix.

Suggested change
If we are given something tha tis not a DateTime, AmbiguousDateTime, or an error tuple, we log the input and return `now`.
If we are given something that is not a DateTime, AmbiguousDateTime, or an error tuple, we log the input and return `now`.

Copy link
Contributor

@joshlarson joshlarson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few more comments, but you'll have to address them as follow-ups if you feel they're worth addressing at all. Ha. Ha!

(Maybe I'll address them myself if I think they're worth addressing - anything can happen!)

But seriously, this is great - big improvement over the mishmash of Utils.service_* and Timex calls, and nice to have a unified place for core service and core date-time stuff.

The service range for the given date_time.
"""
@spec service_range(DateTime.t()) :: named_service_range()
def service_range(date_time) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Non-blocking) Having the word _range at the end of the function name service_range makes me think that it returns something with the type date_time_range(), much like the other service_range_day()/etc functions. (Same deal with the name of the type named_service_range() - ending it with _range() makes me think that

It's not a huge deal, especially because dialyzer will help keep callers of this function honest, but still a potential source of confusion.

Some options:

  • service_window() or named_service_window() for both the function and the type?
  • Augment the @doc here to include examples.

This is kind of what I was getting at with this comment

A behaviour for working with date_times.
"""

@callback now() :: DateTime.t()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question (non-blocking): now() is the only one of these functions that we would ever need to mock, right?

Does that mean that the other two functions could be regular functions, rather than callbacks?

(Disclaimer: I'm new to Elixir behaviours ((to the point of never being sure how to even spell it)), so there's a lot I don't know about how they work and what they're for)


test "returns :today if today is the last day of the service week" do
# Setup
expect(Dotcom.Utils.DateTime.Mock, :now, 2, fn ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Instead of mocking now twice in this test, pass Dotcom.Utils.DateTime.now() |> Timex.beginning_of_week() |> beginning_of_service_day() into service_range_later_this_week() as an argument.

I think that in order for that to work fully, we'd need to replace the expect calls with stub in this test.

# Setup
{beginning_of_service_week, end_of_service_week} = service_range_later_this_week()

stub(Dotcom.Utils.DateTime.Mock, :now, fn ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curiosity: How come we use stub sometimes in this suite, and sometimes we use expect?

@anthonyshull anthonyshull merged commit 177282b into main Feb 11, 2025
29 checks passed
@anthonyshull anthonyshull deleted the ags/datetime-utils-lib branch February 11, 2025 16:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants