Assertions v0.6.0 Assertions.Predicates View Source
All of the predicate functions which return boolean values.
Link to this section Summary
Functions
Tests if two lists have the same elements according to a given comparison function without asserting they are in the same order
Tests if two maps have the same values at the given keys
Tests that messages matching the given patterns, and only those messages, are received in order within the given time period, specified in milliseconds
Tests that a message matching the given pattern, and only that message, is received within the given time period, specified in milliseconds
Tests if struct
is in the given list
by checking the values of the given
keys
Tests if two structs have the same values at the given keys
Link to this section Functions
Tests if two lists have the same elements according to a given comparison function without asserting they are in the same order.
This is very similar to lists_equal?/2
, but it allows you to determine
how two elements in your list are considered equal. This is especially helpful
when comparing lists of structs, since comparing structs for equality with
==
is very error prone.
The comparison function you pass as the third argument must be a function that takes two elements (one from the left list and one from the right list) and returns a boolean if those two elements are equal.
Examples
iex> lists_equal?([1,2,3], [1,3,2], &Kernel.==/2)
true
iex> lists_equal?(["12", "23.5"], ["23", "12 "], fn left, right ->
...> {left_int, _} = Integer.parse(left)
...> {right_int, _} = Integer.parse(right)
...> left_int == right_int
...> end)
true
iex> left = [DateTime.utc_now(), Date.utc_today()]
iex> right = [Date.utc_today(), DateTime.utc_now()]
iex> lists_equal?(left, right, &structs_equal?(&1, &2, [:year, :month, :day]))
true
iex> left = [DateTime.utc_now()]
iex> right = [Date.utc_today(), DateTime.utc_now()]
iex> lists_equal?(left, right, &structs_equal?(&1, &2, [:year, :month, :day]))
false
iex> left = [Date.utc_today(), DateTime.utc_now()]
iex> right = [DateTime.utc_now()]
iex> lists_equal?(left, right, &structs_equal?(&1, &2, [:year, :month, :day]))
false
Tests if two maps have the same values at the given keys.
Examples
iex> left = %{first: :first, second: :second}
iex> right = %{first: :first, second: :second, third: :third}
iex> map_values_equal?(left, right, [:first, :second])
true
iex> left = %{first: "first", second: :second}
iex> right = %{first: :first, second: :second, third: :third}
iex> map_values_equal?(left, right, [:first, :second])
false
iex> left = %{first: :first, second: :second}
iex> right = %{first: :first, third: :third}
iex> map_values_equal?(left, right, [:first, :second])
false
By default if both maps are missing a given key, they are not considered equal.
iex> left = %{first: :first, second: :second}
iex> right = %{first: :first, second: :second, third: :third}
iex> map_values_equal?(left, right, [:first, :second, "not_there"])
false
If you would like maps to be considered equal in this case, you can pass
strict: false
as the fourth argument.
iex> left = %{first: :first, second: :second}
iex> right = %{first: :first, second: :second, third: :third}
iex> map_values_equal?(left, right, [:first, :second, "not_there"], strict: false)
true
Tests that messages matching the given patterns, and only those messages, are received in order within the given time period, specified in milliseconds.
This is an expansion of receive_only?/2
. See the documentation there for
details on the behavior of this function.
Examples
iex> send(self(), :hello)
iex> send(self(), :hello_again)
iex> send(self(), :goodbye)
iex> receive_exactly?([:hello, :hello_again, :goodbye])
true
iex> send(self(), :hello)
iex> Process.send_after(self(), :hello_again, 50)
iex> receive_exactly?([:hello, :hello_again])
true
iex> send(self(), :hello_again)
iex> send(self(), :hello)
iex> receive_exactly?([:hello, :hello_again])
false
iex> send(self(), :hello)
iex> send(self(), :goodbye)
iex> send(self(), :hello_again)
iex> receive_exactly?([:hello, :hello_again])
false
iex> send(self(), :hello)
iex> send(self(), :hello_again)
iex> send(self(), :goodbye)
iex> receive_exactly?([:hello, :hello_again])
false
iex> send(self(), :goodbye)
iex> send(self(), :hello)
iex> send(self(), :hello_again)
iex> receive_exactly?([:hello, :hello_again])
false
iex> hello = :hello
iex> send(self(), hello)
iex> send(self(), :hello_again)
iex> receive_exactly?([^hello, :hello_again])
true
iex> hello = :hello
iex> send(self(), :hello_again)
iex> send(self(), hello)
iex> receive_exactly?([^hello, _])
false
Tests that a message matching the given pattern, and only that message, is received within the given time period, specified in milliseconds.
The optional second argument is a timeout for the receive
to wait for the
expected message, and defaults to 100ms.
If you want to check that no message was received before the expected message,
and that no message is received for a given time after calling
receive_only?/2
, you can combine received_only?/2
with
ExUnit.Assertions.refute_receive/3
.
assert receive_only?(:hello)
refute_receive _, 100
Examples
iex> send(self(), :hello)
iex> receive_only?(:hello)
true
iex> send(self(), [:hello])
iex> receive_only?([_])
true
iex> a = :hello
iex> send(self(), :hello)
iex> receive_only?(^a)
true
iex> send(self(), :hello)
iex> send(self(), :hello_again)
iex> receive_only?(:hello)
false
If a message is received after the function has matched a message to the given
pattern, but the second message is received before the timeout, that second
message is ignored and the function returns true
.
This function only tests that the message that matches the given pattern was
the first message in the process inbox, and that nothing was sent between the
sending the message that matches the pattern and when receive_only?/2
was
called.
iex> Process.send_after(self(), :hello, 20)
iex> Process.send_after(self(), :hello_again, 50)
iex> receive_only?(:hello, 100)
true
iex> Process.send_after(self(), :hello, 50)
iex> Process.send_after(self(), :hello_again, 20)
iex> receive_only?(:hello, 100)
false
Tests if struct
is in the given list
by checking the values of the given
keys
.
## Examples
iex> list = [DateTime.utc_now(), Date.utc_today()]
iex> assert struct_in_list?(DateTime.utc_now(), list, [:year, :month, :day, :second])
true
Tests if two structs have the same values at the given keys.
Directly comparing structs for equality using ==
can be very tricky, which
is why you almost never want to do that. Using this assertion, you get to
determine what makes two structs equal while allowing for inconsequential
differences like relations that are preloaded in one struct but not in the
other.
If you are comparing a struct to a map with the same keys and values, the check will fail. Both structs need to be of the same type for the check to pass.
Examples
iex> left = DateTime.utc_now()
iex> right = DateTime.utc_now()
iex> structs_equal?(left, right, [:year, :month, :day])
true
iex> left = DateTime.utc_now()
iex> right = Date.utc_today()
iex> structs_equal?(left, right, [:year, :month, :day])
false
iex> left = DateTime.utc_now()
iex> right = Map.from_struct(DateTime.utc_now())
iex> structs_equal?(left, right, [:year, :month, :day])
false