From d622bb278705b5c5184a4fc5a84fe310d8ccaa28 Mon Sep 17 00:00:00 2001 From: Matt Beanland Date: Fri, 14 Aug 2026 14:56:49 +0930 Subject: [PATCH] chore: add tests for the Duration form of the datetime expressions Covers `ago/1`, `from_now/1`, `datetime_add/2` and `date_add/2` with a `Duration`, including a multi-unit duration and a negative one, and checks that `date_add` still compares as a date. These pass only with the corresponding ash_sql change; against released ash_sql all six fail with `Unsupported expression`. Part of #553. --- test/duration_expr_test.exs | 89 +++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 test/duration_expr_test.exs diff --git a/test/duration_expr_test.exs b/test/duration_expr_test.exs new file mode 100644 index 00000000..85ba43ea --- /dev/null +++ b/test/duration_expr_test.exs @@ -0,0 +1,89 @@ +# SPDX-FileCopyrightText: 2019 ash_postgres contributors +# +# SPDX-License-Identifier: MIT + +defmodule AshPostgres.DurationExprTest do + use AshPostgres.RepoCase, async: false + alias AshPostgres.Test.Post + + require Ash.Query + + defp post!(title, created_at) do + Post + |> Ash.Changeset.for_create(:create, %{title: title, created_at: created_at}) + |> Ash.create!() + end + + describe "ago/1" do + test "filters on a duration" do + post!("old", DateTime.add(DateTime.utc_now(), -60, :day)) + post!("recent", DateTime.utc_now()) + + assert [%Post{title: "recent"}] = + Post + |> Ash.Query.filter(created_at > ago(^Duration.new!(day: 30))) + |> Ash.read!() + end + + test "filters on a multi-unit duration" do + post!("old", DateTime.add(DateTime.utc_now(), -60, :day)) + post!("recent", DateTime.add(DateTime.utc_now(), -20, :day)) + + assert [%Post{title: "recent"}] = + Post + |> Ash.Query.filter(created_at > ago(^Duration.new!(month: 1, day: 2))) + |> Ash.read!() + end + end + + describe "from_now/1" do + test "filters on a duration" do + post!("soon", DateTime.add(DateTime.utc_now(), 10, :day)) + post!("later", DateTime.add(DateTime.utc_now(), 60, :day)) + + assert [%Post{title: "soon"}] = + Post + |> Ash.Query.filter(created_at < from_now(^Duration.new!(day: 30))) + |> Ash.read!() + end + end + + describe "datetime_add/2" do + test "adds a duration to a datetime" do + now = DateTime.utc_now() + post!("before", DateTime.add(now, 3, :day)) + post!("after", DateTime.add(now, 30, :day)) + + assert [%Post{title: "before"}] = + Post + |> Ash.Query.filter(created_at < datetime_add(^now, ^Duration.new!(day: 7))) + |> Ash.read!() + end + + test "a negative duration subtracts" do + now = DateTime.utc_now() + post!("old", DateTime.add(now, -30, :day)) + post!("recent", now) + + assert [%Post{title: "recent"}] = + Post + |> Ash.Query.filter(created_at > datetime_add(^now, ^Duration.new!(day: -7))) + |> Ash.read!() + end + end + + describe "date_add/2" do + test "adds a duration to a date, and stays a date" do + today = Date.utc_today() + post!("old", DateTime.add(DateTime.utc_now(), -60, :day)) + post!("recent", DateTime.utc_now()) + + assert [%Post{title: "recent"}] = + Post + |> Ash.Query.filter( + type(created_at, :date) >= date_add(^today, ^Duration.new!(day: -30)) + ) + |> Ash.read!() + end + end +end