Moar.Assertions (Moar v4.1.0)
View SourceExUnit assertions.
See also: siiibo/assert_match which is similar to this module's
assert_eq function but with pattern matching.
Summary
Functions
Asserts that the left list or map contains all of the items in the right list or map,
or contains the single right element if it's not a list or map. Returns left or raises ExUnit.AssertionError.
Asserts that the left and right values are equal. It returns the left value unless the assertion fails,
or unless the :returning option is used. As a special case, if the first argument is a string and the second
is a Regex, the comparison is done with the =~ operator instead of the == operator.
Asserts that datetime is within recency of now (in UTC), returning datetime if the assertion succeeeds.
Asserts that a pre-condition and a post-condition are true after performing an action, returning the result of the action.
Refute that a condition is changed after performing an action, returning the result of the action.
Types
@type assert_eq_opt_shortcut() :: :downcase | :sort | :squish | :to_string | :trim
@type assert_eq_opts() :: (any() -> any()) | {:apply, (any() -> any()) | assert_eq_opt_shortcut()} | assert_eq_opt_shortcut() | {:except, list()} | :ignore_order | {:ignore_order, boolean()} | {:ignore_whitespace, :leading_and_trailing} | {:map, (any() -> any()) | assert_eq_opt_shortcut()} | {:only, list()} | {:returning, any()} | {:whitespace, :squish | :trim} | {:within, number() | {number(), Moar.Duration.time_unit()}}
Functions
@spec assert_contains(map(), map()) :: map()
@spec assert_contains(list(), list() | any()) :: list()
Asserts that the left list or map contains all of the items in the right list or map,
or contains the single right element if it's not a list or map. Returns left or raises ExUnit.AssertionError.
iex> assert_contains([1, 2, 3], [1, 3])
[1, 2, 3]
iex> assert_contains(%{a: 1, b: 2, c: 3}, %{a: 1, c: 3})
%{a: 1, b: 2, c: 3}
iex> assert_contains([1, 2, 3], 2)
[1, 2, 3]
@spec assert_eq( left :: any(), right :: any(), opts :: assert_eq_opts() | [assert_eq_opts()] ) :: any()
Asserts that the left and right values are equal. It returns the left value unless the assertion fails,
or unless the :returning option is used. As a special case, if the first argument is a string and the second
is a Regex, the comparison is done with the =~ operator instead of the == operator.
Style note: the authors prefer to use assert in most cases, using assert_eq only when the extra options
are helpful or when they want to make assertions in a pipeline.
iex> import Moar.Assertions
# prefer regular `assert` when `assert_eq` is not necessary
iex> assert Map.put(%{a: 1}, :b, 2) == %{a: 1, b: 2}
true
# works nicely with pipes
iex> %{a: 1} |> Map.put(:b, 2) |> assert_eq(%{a: 1, b: 2})
%{a: 1, b: 2}
# returns an arbitrary value instead of the left value
iex> map = %{a: 1, b: 2}
iex> map |> Map.get(:a) |> assert_eq(1, returning: map)
%{a: 1, b: 2}
# compares using a regex if `left` is a string and `right` is a Regex
iex> assert_eq "the length is 10cm", ~r/.*length is \d{2}cm/left and right can be transformed by passing in one or more functions (optionally using the apply: keyword).
If left and right are lists, all their values can be transformed using the map: option.
iex> import Moar.Assertions
# apply a function
iex> assert_eq("hello", "heLLo", &String.downcase/1)
"hello"
# apply multiple functions (left to right)
iex> assert_eq("hello", "heLLo", [&String.downcase/1, &String.reverse/1])
"olleh"
# apply a function explicitly
iex> assert_eq("hello", "heLLo", apply: &String.downcase/1)
"hello"
# map all elements with a function
iex> assert_eq(["a", "B"], ["A", "b"], map: &String.downcase/1)
["a", "b"]
# combine apply and map (left to right)
iex> assert_eq(["a", "B", "C"], ["A", "b", "Z"], apply: &Enum.drop(&1, -1), map: &String.downcase/1)
["a", "b"]If left and right are maps, only: <list> will only consider the given keys, and except: <list> will ignore
certain keys.
iex> import Moar.Assertions
# ignore one or more keys of a map
iex> assert_eq(%{a: 1, b: 2, c: 3}, %{a: 1, b: 100, c: 3}, except: [:b])
%{a: 1, b: 2, c: 3}
# only assert on one or more keys of a map
iex> assert_eq(%{a: 1, b: 2, c: 3}, %{a: 1, b: 100, c: 3}, only: [:a, :c])
%{a: 1, b: 2, c: 3}If left and right are lists, their order can be ignored using :ignore_order.
iex> import Moar.Assertions
# ignoring order when comparing lists
iex> assert_eq(["a", "b"], ["b", "a"], :ignore_order)
["a", "b"]For inexact numerical assertions, within: <delta> works like ExUnit.Assertions.assert_in_delta/4, and
for inexact date and datetime assertions, within: {<delta>, <time-unit>} asserts that left and right
are within some duration of each other. See Moar.Duration for more about time units, and also see
Moar.Assertions.assert_recent/2. If left and right are strings, they are parsed as ISO8601 dates.
iex> import Moar.Assertions
# assert within a delta (this particular case could use ExUnit.Assertions.assert_in_delta/4).
iex> assert_eq(4/28, 0.14, within: 0.01)
0.14285714285714285
# assert within a time delta
iex> inserted_at = ~U[2022-01-02 03:00:00Z]
iex> updated_at = ~U[2022-01-02 03:04:00Z]
iex> assert_eq(inserted_at, updated_at, within: {10, :minute})
~U[2022-01-02 03:00:00Z]
# assert within a time delta when inputs are time strings
iex> inserted_at = "2022-01-02T03:00:00Z"
iex> updated_at = "2022-01-02T03:04:00Z"
iex> assert_eq(inserted_at, updated_at, within: {10, :minute})
"2022-01-02T03:00:00Z"The following transformation shortcuts are supported:
:downcase- ifleftandrightare strings, converts them to lowercase before comparing:sort- the same as:ignore_order:squish- ifleftandrightare strings, trims the strings and replaces consecutive whitespace characters with a single space usingMoar.String.squish/1before comparing:to_string- callsString.Chars.to_stringonleftandrightbefore comparing:trim- ifleftandrightare strings, trims the strings usingString.trim/1before comparing
iex> import Moar.Assertions
iex> assert_eq("FOO bar", "foo bar", :downcase)
"foo bar"
iex> assert_eq(" FOO bar ", "foo bar", [:downcase, :squish])
"foo bar"The following options are deprecated:
ignore_order: <boolean>- use:ignore_orderinstead ofignore_order: trueignore_whitespace: :leading_and_trailing- use:squishor:triminsteadwhitespace: :squish- use:squishinsteadwhitespace: :trim- use:triminstead
@spec assert_recent(DateTime.t() | NaiveDateTime.t() | binary(), Moar.Duration.t()) :: DateTime.t() | NaiveDateTime.t() | binary()
Asserts that datetime is within recency of now (in UTC), returning datetime if the assertion succeeeds.
Uses assert_eq(datetime, now, within: recency) under the hood.
datetimecan be aDateTime, aNaiveDateTime, or an ISO8601-formatted UTC datetime string.recencyis aMoar.Durationand defaults to{10, :second}.
iex> five_seconds_ago = Moar.DateTime.add(DateTime.utc_now(), {-5, :second})
iex> assert_recent five_seconds_ago
iex> twenty_seconds_ago = Moar.DateTime.add(DateTime.utc_now(), {-20, :second})
iex> assert_recent twenty_seconds_ago, {25, :second}
Asserts that a pre-condition and a post-condition are true after performing an action, returning the result of the action.
To use an anonymous function as the action, wrap it in parentheses and call it with .().
Examples
iex> {:ok, agent} = Agent.start(fn -> 0 end)
...>
iex> assert_that Agent.update(agent, fn s -> s + 1 end),
...> changes: Agent.get(agent, fn s -> s end),
...> from: 0,
...> to: 1
:ok
...>
iex> assert_that Agent.update(agent, fn s -> s + 1 end),
...> changes: Agent.get(agent, fn s -> s end),
...> to: 2
:ok
...>
iex> assert_that (fn -> Agent.update(agent, fn s -> s + 1 end) end).(),
...> changes: Agent.get(agent, fn s -> s end),
...> to: 3
:ok
Refute that a condition is changed after performing an action, returning the result of the action.
Examples
iex> {:ok, agent} = Agent.start(fn -> 0 end)
...>
iex> refute_that Function.identity(1),
...> changes: Agent.get(agent, fn s -> s end)
1
iex> refute_that Function.identity(5),
...> changes: %{a: 1}
5