Outstand (Outstanding v0.2.0)

View Source

Provides utilities to implement and work with Outstanding types

Summary

Functions

Enables infix ---, >>> shortcuts, defoutstanding, gen_nothing_outstanding_test, gen_something_outstanding_test gen_result_outstanding_test macro

Function which expects all elements in expected list to be resolved by an element from actual list

Function which expects any atom (nil is an atom)

Function which expects any bitstring

Function which expects any boolean

Function which expects any date

Function which expects any date time

Function which expects any duration

Function which expects any float

Function which expects any integer

Function which expects any list, including []

Function which expects any map

Function which expects any map set

Function which expects any naive date time

Function which expects any number

Function which expects at least one element in expected list to be resolved by actual

Function which expects at least one element from actual list to resolve expected

Function which expects any range

Function which expects any naive date time

Function which expects any tuple

Function which expects actual to be bounded by the listed min and max values

Function which expects current date

Function which expects current date time (+/- 1 min from now)

Function which expects current naive date time (+/- 1 min from now)

Function which expects current time (+/- 1 min from now)

Helper to define whether the expected side (expected) is realised by actual side (actual), returns nil if so, otherwise return what is not realised (outstanding) accepts two term :: type pairs and block of code where relation is described.

Function which expects empty list

Function which expects empty map

Function which expects empty map set

Function which expects explicit nil

Function which expects future date

Function which expects future date time

Function which expects future naive date time

Function which expects future time

Function which expects actual to be greater than the value

Function which expects actual to be less than the value

Converts term to struct if a map

Checks whether a result has nothing outstanding

Is nothing outstanding given expected and actual term?

Function which expects non empty keyword

Function which expects non empty list

Function which expects non empty map

Function which expects non empty map set

Function which expects any not nil atom

Function which expects no element in expected list to be resolved by actual

Function which expects exactly one element in expected list to be resolved by actual

Checks whether a result has anything outstanding

Function which expects past date

Function which expects past date time

Function which expects past naive date time

Function which expects past time

Suppress outstanding result when empty list, map, map set or tuple

Types the argument, similar to Typable

Function which expects actual not to be bounded by the listed min and max values

Functions

expected --- actual

(macro)

Infix shortcut --- for Outstanding.outstanding/2

Examples

iex> use Outstand
Outstand
iex> 1 --- 1
nil
iex> 1 --- :hello
1

__using__(_)

(macro)

Enables infix ---, >>> shortcuts, defoutstanding, gen_nothing_outstanding_test, gen_something_outstanding_test gen_result_outstanding_test macro

expected >>> actual

(macro)

Infix shortcut >>> for Outstanding.outstanding?/2

Examples

iex> use Outstand
Outstand
iex> 1 >>> 1
false
iex> 1 >>> :hello
true

all_of(expected, actual)

@spec all_of(maybe_improper_list(), any()) :: nil | :all_of

Function which expects all elements in expected list to be resolved by an element from actual list

Examples

iex> Outstand.all_of([1, 2, 3], [3, 1, 2])
nil
iex> Outstand.all_of([1, 2, 3], [1])
:all_of
iex> Outstand.all_of([1, 2, 3], nil)
:all_of

any_atom(actual)

@spec any_atom(any()) :: :any_atom | nil

Function which expects any atom (nil is an atom)

Examples

iex> Outstand.any_atom(:a)
nil
iex> Outstand.any_atom(nil)
nil
iex> Outstand.any_atom("a")
:any_atom

any_bitstring(actual)

@spec any_bitstring(any()) :: :any_bitstring | nil

Function which expects any bitstring

Examples

iex> Outstand.any_bitstring("a")
nil
iex> Outstand.any_bitstring(:a)
:any_bitstring
iex> Outstand.any_bitstring(nil)
:any_bitstring

any_boolean(actual)

@spec any_boolean(any()) :: :any_boolean | nil

Function which expects any boolean

Examples

iex> Outstand.any_boolean(true)
nil
iex> Outstand.any_boolean("a")
:any_boolean
iex> Outstand.any_boolean(nil)
:any_boolean

any_date(actual)

@spec any_date(any()) :: :any_date | nil

Function which expects any date

Examples

iex> Outstand.any_date(~D[2025-02-25])
nil
iex> Outstand.any_date("2025-02-25")
:any_date
iex> Outstand.any_date(nil)
:any_date

any_date_time(actual)

@spec any_date_time(any()) :: :any_date_time | nil

Function which expects any date time

Examples

iex> Outstand.any_date_time(~U[2025-02-25 11:59:00.00Z])
nil
iex> Outstand.any_date_time("2025-02-25")
:any_date_time
iex> Outstand.any_date_time(nil)
:any_date_time

any_duration(actual)

@spec any_duration(any()) :: :any_duration | nil

Function which expects any duration

Examples

iex> Outstand.any_duration(%Duration{month: 1})
nil
iex> Outstand.any_duration(%{month: 1})
:any_duration
iex> Outstand.any_duration(nil)
:any_duration

any_float(actual)

@spec any_float(any()) :: :any_float | nil

Function which expects any float

Examples

iex> Outstand.any_float(1.1)
nil
iex> Outstand.any_float(1)
:any_float
iex> Outstand.any_float(nil)
:any_float

any_integer(actual)

@spec any_integer(any()) :: :any_integer | nil

Function which expects any integer

Examples

iex> Outstand.any_integer(1)
nil
iex> Outstand.any_integer(1.1)
:any_integer
iex> Outstand.any_integer(nil)
:any_integer

any_list(actual)

@spec any_list(any()) :: :any_list | nil

Function which expects any list, including []

Examples

iex> Outstand.any_list([:a])
nil
iex> Outstand.any_list([])
nil
iex> Outstand.any_list({:a, :b, :c})
:any_list
iex> Outstand.any_list(nil)
:any_list

any_map(actual)

@spec any_map(any()) :: :any_map | nil

Function which expects any map

Examples

iex> Outstand.any_map(%{a: :a})
nil
iex> Outstand.any_map([:a])
:any_map
iex> Outstand.any_map(nil)
:any_map

any_map_set(actual)

@spec any_map_set(any()) :: :any_map_set | nil

Function which expects any map set

Examples

iex> Outstand.any_map_set(MapSet.new())
nil
iex> Outstand.any_map_set(MapSet.new([:a]))
nil
iex> Outstand.any_map_set([:a])
:any_map_set
iex> Outstand.any_map_set(nil)
:any_map_set

any_naive_date_time(actual)

@spec any_naive_date_time(any()) :: :any_naive_date_time | nil

Function which expects any naive date time

Examples

iex> Outstand.any_naive_date_time(~N[2025-02-25 11:59:00])
nil
iex> Outstand.any_naive_date_time("2025-02-25")
:any_naive_date_time
iex> Outstand.any_naive_date_time(nil)
:any_naive_date_time

any_number(actual)

@spec any_number(any()) :: :any_number | nil

Function which expects any number

Examples

iex> Outstand.any_number(1)
nil
iex> Outstand.any_number(1.1)
nil
iex> Outstand.any_number(nil)
:any_number

any_of(expected, actual)

@spec any_of(maybe_improper_list(), any()) :: nil | :any_of

Function which expects at least one element in expected list to be resolved by actual

Examples

iex> Outstand.any_of([1, 2, 3], 1)
nil
iex> Outstand.any_of([1, 2, 3], 0)
:any_of
iex> Outstand.any_of([1, 2, 3], nil)
:any_of

any_of_actual_list(expected, actual)

@spec any_of_actual_list(any(), any()) :: any()

Function which expects at least one element from actual list to resolve expected

Examples

iex> Outstand.any_of_actual_list(1, [1,2,3])
nil
iex> Outstand.any_of_actual_list(1, [2, 3])
1
iex> Outstand.any_of_actual_list(1, nil)
1

any_range(actual)

@spec any_range(any()) :: :any_range | nil

Function which expects any range

Examples

iex> Outstand.any_range(0..25//5)
nil
iex> Outstand.any_range(5)
:any_range
iex> Outstand.any_range(nil)
:any_range

any_time(actual)

@spec any_time(any()) :: :any_time | nil

Function which expects any naive date time

Examples

iex> Outstand.any_time(~T[11:59:00.000])
nil
iex> Outstand.any_time("11:59:00.000")
:any_time
iex> Outstand.any_time(nil)
:any_time

any_tuple(actual)

@spec any_tuple(any()) :: :any_tuple | nil

Function which expects any tuple

Examples

iex> Outstand.any_tuple({:a, :b, :c})
nil
iex> Outstand.any_tuple([:a])
:any_tuple
iex> Outstand.any_tuple(nil)
:any_tuple

bounded_by(expected, actual)

@spec bounded_by(maybe_improper_list(), any()) :: nil | :bounded_by | :error

Function which expects actual to be bounded by the listed min and max values

Examples

iex> Outstand.bounded_by([%Duration{hour: 1}, %Duration{minute: 90}], %Duration{minute: 70})
nil
iex> Outstand.bounded_by([%Duration{hour: 1}, %Duration{minute: 90}], %Duration{minute: 50})
:bounded_by
iex> Outstand.bounded_by([%Duration{hour: 1}, %Duration{minute: 90}], %Duration{hour: 2})
:bounded_by
iex> Outstand.bounded_by([%Duration{hour: 1}, %Duration{minute: 90}], nil)
:bounded_by

current_date(actual)

@spec current_date(any()) :: :current_date | nil

Function which expects current date

Examples

iex> today = DateTime.utc_now() |> DateTime.to_date()
iex> Outstand.current_date(today)
nil
iex> Outstand.current_date(today |> Date.add(1))
:current_date
iex> Outstand.current_date(today |> Date.add(-1))
:current_date
iex> Outstand.current_date(nil)
:current_date

current_date_time(actual)

@spec current_date_time(any()) :: :current_date_time | nil

Function which expects current date time (+/- 1 min from now)

Examples

iex> now = DateTime.utc_now()
iex> Outstand.current_date_time(now)
nil
iex> Outstand.current_date_time(now |> DateTime.add(2, :minute))
:current_date_time
iex> Outstand.current_date_time(now |> DateTime.add(-2, :minute))
:current_date_time
iex> Outstand.current_date_time(nil)
:current_date_time

current_naive_date_time(actual)

@spec current_naive_date_time(any()) :: :current_naive_date_time | nil

Function which expects current naive date time (+/- 1 min from now)

Examples

iex> now = DateTime.utc_now() |> DateTime.to_naive()
iex> Outstand.current_naive_date_time(now)
nil
iex> Outstand.current_naive_date_time(now |> NaiveDateTime.add(2, :minute))
:current_naive_date_time
iex> Outstand.current_naive_date_time(now |> NaiveDateTime.add(-2, :minute))
:current_naive_date_time
iex> Outstand.current_naive_date_time(nil)
:current_naive_date_time

current_time(actual)

@spec current_time(any()) :: :current_time | nil

Function which expects current time (+/- 1 min from now)

Examples

iex> now = DateTime.utc_now() |> DateTime.to_time()
iex> Outstand.current_time(now)
nil
iex> Outstand.current_time(now |> Time.add(2, :minute))
:current_time
iex> Outstand.current_time(now |> Time.add(-2, :minute))
:current_time
iex> Outstand.current_time(nil)
:current_time

defoutstanding(arg1, arg2, list)

(macro)

Helper to define whether the expected side (expected) is realised by actual side (actual), returns nil if so, otherwise return what is not realised (outstanding) accepts two term :: type pairs and block of code where relation is described.

Examples

iex> quote do
...>   use Outstand
...>   defmodule Foo do
...>     defstruct [:value, :meta]
...>   end
...>   defmodule Bar do
...>     defstruct [:value, :meta]
...>   end
...>   defoutstanding expected :: Foo, actual :: Any do
...>     case Outstand.type_of(actual) do
...>       Foo -> Outstanding.outstanding(expected.value, actual.value)
...>       Bar -> Outstanding.outstanding(expected.value, actual.value)
...>       Integer -> Outstanding.outstanding(expected.value, actual)
...>       _ -> expected
...>     end
...>   end
...> end
...> |> Code.compile_quoted
iex> quote do
...>   expected = %Foo{value: 1, meta: 1}
...>   actual = %Foo{value: 1, meta: 2}
...>   Outstanding.outstanding(expected, actual)
...> end
...> |> Code.eval_quoted
...> |> elem(0)
nil
iex> quote do
...>   expected = %Foo{value: 1, meta: 1}
...>   actual = %Bar{value: 1, meta: 2}
...>   Outstanding.outstanding(expected, actual)
...> end
...> |> Code.eval_quoted
...> |> elem(0)
nil
iex> quote do
...>   expected = %Foo{value: 1, meta: 1}
...>   actual = 1
...>   Outstanding.outstanding(expected, actual)
...> end
...> |> Code.eval_quoted
...> |> elem(0)
nil

empty_list(actual)

@spec empty_list(any()) :: :empty_list | nil

Function which expects empty list

Examples

iex> Outstand.empty_list([])
nil
iex> Outstand.empty_list([:a])
:empty_list
iex> Outstand.empty_list(nil)
:empty_list

empty_map(actual)

@spec empty_map(any()) :: :empty_map | nil

Function which expects empty map

Examples

iex> Outstand.empty_map(%{})
nil
iex> Outstand.empty_map(%{a: :a})
:empty_map
iex> Outstand.empty_map(nil)
:empty_map

empty_map_set(actual)

@spec empty_map_set(any()) :: :empty_map_set | nil

Function which expects empty map set

Examples

iex> Outstand.empty_map_set(MapSet.new())
nil
iex> Outstand.empty_map_set(MapSet.new([:a]))
:empty_map_set
iex> Outstand.empty_map_set(nil)
:empty_map_set

explicit_nil(actual)

@spec explicit_nil(any()) :: :explicit_nil | nil

Function which expects explicit nil

Examples

iex> Outstand.explicit_nil(:explicit_nil)
nil
iex> Outstand.explicit_nil(nil)
:explicit_nil
iex> Outstand.explicit_nil(:a)
:explicit_nil

future_date(actual)

@spec future_date(any()) :: :future_date | nil

Function which expects future date

Examples

iex> today = DateTime.utc_now() |> DateTime.to_date()
iex> Outstand.future_date(today |> Date.add(1))
nil
iex> Outstand.future_date(today)
:future_date
iex> Outstand.future_date(nil)
:future_date

future_date_time(actual)

@spec future_date_time(any()) :: :future_date_time | nil

Function which expects future date time

Examples

iex> now = DateTime.utc_now()
iex> Outstand.future_date_time(now |> DateTime.add(1, :minute))
nil
iex> Outstand.future_date_time(now)
:future_date_time
iex> Outstand.future_date_time(nil)
:future_date_time

future_naive_date_time(actual)

@spec future_naive_date_time(any()) :: :future_naive_date_time | nil

Function which expects future naive date time

Examples

iex> now = DateTime.utc_now() |> DateTime.to_naive()
iex> Outstand.future_naive_date_time(now |> NaiveDateTime.add(1, :minute))
nil
iex> Outstand.future_naive_date_time(now)
:future_naive_date_time
iex> Outstand.future_naive_date_time(nil)
:future_naive_date_time

future_time(actual)

@spec future_time(any()) :: :future_time | nil

Function which expects future time

Examples

iex> now = DateTime.utc_now() |> DateTime.to_time()
iex> Outstand.future_time(now |> Time.add(1, :minute))
nil
iex> Outstand.future_time(now)
:future_time
iex> Outstand.future_time(nil)
:future_time

gen_nothing_outstanding_test(name, expected, actual)

(macro)

gen_result_outstanding_test(name, expected, actual, outstanding)

(macro)

gen_something_outstanding_test(name, expected, actual)

(macro)

greater_than(expected, actual)

@spec greater_than(Duration.t(), any()) :: nil | :longer_than

Function which expects actual to be greater than the value

Examples

iex> Outstand.greater_than(%Duration{hour: 1}, %Duration{hour: 2})
nil
iex> Outstand.greater_than(%Duration{hour: 1}, %Duration{hour: 1})
:greater_than
iex> Outstand.greater_than(%Duration{hour: 1}, nil)
:greater_than

less_than(expected, actual)

@spec less_than(Duration.t(), any()) :: nil | :less_than

Function which expects actual to be less than the value

Examples

iex> Outstand.less_than(%Duration{hour: 2}, %Duration{hour: 1})
nil
iex> Outstand.less_than(%Duration{hour: 1}, %Duration{hour: 1})
:less_than
iex> Outstand.less_than(%Duration{hour: 1}, nil)
:less_than

map_to_struct(term, name)

@spec map_to_struct(any() | nil, bitstring()) :: any()

Converts term to struct if a map

Examples

iex> today = DateTime.utc_now() |> DateTime.to_date()
iex> today_map = Map.delete(today, :__struct__)
iex> assert today == Outstand.map_to_struct(today_map, Date)
iex> Outstand.map_to_struct(nil, Date)
nil

nil_outstanding?(outstanding)

Checks whether a result has nothing outstanding

Examples

iex> Outstand.nil_outstanding?(1)
false
iex> Outstand.nil_outstanding?(nil)
true
iex> Outstand.nil_outstanding?(%{})
false
iex> Outstand.nil_outstanding?([])
false

nil_outstanding?(expected, actual)

@spec nil_outstanding?(Outstanding.t(), any()) :: boolean()

Is nothing outstanding given expected and actual term?

Examples

iex> Outstand.nil_outstanding?(1, 1)
true
iex> Outstand.nil_outstanding?(1, nil)
false
iex> Outstand.nil_outstanding?(1, 2)
false

non_empty_keyword(actual)

@spec non_empty_keyword(any()) :: :non_empty_keyword | nil

Function which expects non empty keyword

Examples

iex> Outstand.non_empty_keyword([a: :a])
nil
iex> Outstand.non_empty_keyword([])
:non_empty_keyword
iex> Outstand.non_empty_keyword(nil)
:non_empty_keyword

non_empty_list(actual)

@spec non_empty_list(any()) :: :non_empty_list | nil

Function which expects non empty list

Examples

iex> Outstand.non_empty_list([:a])
nil
iex> Outstand.non_empty_list([])
:non_empty_list
iex> Outstand.non_empty_list(nil)
:non_empty_list

non_empty_map(actual)

@spec non_empty_map(any()) :: :non_empty_map | nil

Function which expects non empty map

Examples

iex> Outstand.non_empty_map(%{a: :a})
nil
iex> Outstand.non_empty_map(%{})
:non_empty_map
iex> Outstand.non_empty_map(nil)
:non_empty_map

non_empty_map_set(actual)

@spec non_empty_map_set(any()) :: :non_empty_map_set | nil

Function which expects non empty map set

Examples

iex> Outstand.non_empty_map_set(MapSet.new([:a]))
nil
iex> Outstand.non_empty_map_set(MapSet.new())
:non_empty_map_set
iex> Outstand.non_empty_map_set(nil)
:non_empty_map_set

non_nil_atom(actual)

@spec non_nil_atom(any()) :: :non_nil_atom | nil

Function which expects any not nil atom

Examples

iex> Outstand.non_nil_atom(:a)
nil
iex> Outstand.non_nil_atom(nil)
:non_nil_atom
iex> Outstand.non_nil_atom("a")
:non_nil_atom

none_of(expected, actual)

@spec none_of(maybe_improper_list(), any()) :: nil | :none_of

Function which expects no element in expected list to be resolved by actual

Examples

iex> Outstand.none_of([1, 2, 3], 0)
nil
iex> Outstand.none_of([1, 2, 3], 1)
:none_of
iex> Outstand.none_of([1, 2, 3], nil)
nil

one_of(expected, actual)

@spec one_of(maybe_improper_list(), any()) :: nil | :one_of

Function which expects exactly one element in expected list to be resolved by actual

Examples

iex> Outstand.one_of([1, 2, 3], 1)
nil
iex> Outstand.one_of([1, 1, 3], 1)
:one_of
iex> Outstand.one_of([1, 2, 3], nil)
:one_of

outstanding?(outstanding)

Checks whether a result has anything outstanding

Examples

iex> Outstand.outstanding?(1)
true
iex> Outstand.outstanding?(nil)
false
iex> Outstand.outstanding?(%{})
true
iex> Outstand.outstanding?([])
true

past_date(actual)

@spec past_date(any()) :: :past_date | nil

Function which expects past date

Examples

iex> Outstand.past_date(~D[2002-02-25])
nil
iex> Outstand.past_date(~D[2102-02-25])
:past_date
iex> Outstand.past_date(nil)
:past_date

past_date_time(actual)

@spec past_date_time(any()) :: :past_date_time | nil

Function which expects past date time

Examples

iex> Outstand.past_date_time(~U[2002-02-25 11:59:00.00Z])
nil
iex> Outstand.past_date_time(~U[2102-02-25 11:59:00.00Z])
:past_date_time
iex> Outstand.past_date_time(nil)
:past_date_time

past_naive_date_time(actual)

@spec past_naive_date_time(any()) :: :past_naive_date_time | nil

Function which expects past naive date time

Examples

iex> Outstand.past_naive_date_time(~N[2002-02-25 11:59:00])
nil
iex> Outstand.past_naive_date_time(~N[2102-02-25 11:59:00])
:past_naive_date_time
iex> Outstand.past_naive_date_time(nil)
:past_naive_date_time

past_time(actual)

@spec past_time(any()) :: :past_time | nil

Function which expects past time

Examples

iex> Outstand.past_time(~T[00:00:00.000])
nil
iex> Outstand.past_time(~T[23:59:59.999])
:past_time
iex> Outstand.past_time(nil)
:past_time

suppress(enum)

Suppress outstanding result when empty list, map, map set or tuple

Examples

iex> Outstand.suppress([])
nil
iex> Outstand.suppress([:a])
[:a]
iex> Outstand.suppress(%{})
nil
iex> Outstand.suppress(%{x: :a})
%{x: :a}
iex> Outstand.suppress(MapSet.new())
nil
iex> Outstand.suppress(MapSet.new([:a]))
MapSet.new([:a])
iex> Outstand.suppress({})
nil
iex> Outstand.suppress({:a})
{:a}

type_of(term)

@spec type_of(any()) :: module()

Types the argument, similar to Typable

Examples

iex> Outstand.type_of(nil)
Atom
iex> Outstand.type_of(:a)
Atom
iex> Outstand.type_of(true)
Boolean
iex> Outstand.type_of("a")
BitString
iex> Outstand.type_of(1.1)
Float
iex> Outstand.type_of(&Outstand.any_atom/1)
Function
iex> Outstand.type_of(1)
Integer
iex> Outstand.type_of([:a])
List
iex> Outstand.type_of([a: %{a: "a", b: "b"}])
List
iex> Outstand.type_of(%{a: :a})
Map
iex> Outstand.type_of(MapSet.new([:a]))
MapSet
iex> Outstand.type_of(0..25//5)
Range
iex> Outstand.type_of({:a, :b, :c})
Tuple
iex> Outstand.type_of({:a, %{a: "a", b: "b"}})
Tuple
iex> Outstand.type_of(~U[2025-02-25 11:59:00.00Z])
DateTime
iex> Outstand.type_of(~D[2025-02-25])
Date
iex> Outstand.type_of(self())
Other

unbounded_by(expected, actual)

@spec unbounded_by(maybe_improper_list(), any()) :: nil | :bounded_by | :error

Function which expects actual not to be bounded by the listed min and max values

Examples

iex> Outstand.unbounded_by([%Duration{hour: 1}, %Duration{minute: 90}], %Duration{minute: 30})
nil
iex> Outstand.unbounded_by([%Duration{hour: 1}, %Duration{minute: 90}], %Duration{hour: 2})
nil
iex> Outstand.unbounded_by([%Duration{hour: 1}, %Duration{minute: 90}], %Duration{minute: 70})
:unbounded_by
iex> Outstand.unbounded_by([%Duration{hour: 1}, %Duration{minute: 90}], nil)
:unbounded_by