This page showcases some examples for commonly useful invariants that are either included in Invariants.jl or simple to construct.
hasmethod_invariant
is an invariant that lets us check that a method exists and can be called with the given arguments. We construct it with argument names and optional default values, and check it by providing a
NamedTuple
input with values for the arguments.
Checking that the input has a
length
method:
inv_length
=
Invariants
.
hasmethod_invariant
(
Base
.
length
,
:
xs
)
check
(
inv_length
,
(
;
xs
=
1
:
10
)
)
✔ Invariant satisfied: Method Base.length(xs) implemented
check
(
inv_length
,
(
;
xs
=
nothing
)
)
⨯ Invariant not satisfied: Method Base.length(xs) implemented
When calling length, got a MethodError. This means that there is no method implemented for the given arguments. To fix this, please implement the following method:
Base.length(xs::Nothing)
To be sure that a working method exists,
hasmethod_invariant
runs the functions on the given arguments. This means that you should not use it to check functions with side effects or long-running computations.
We can also construct an invariant that expects multiple arguments and provides default values. Here, we check that the
getindex
method exists and we can load the element at index 1:
inv_index
=
Invariants
.
hasmethod_invariant
(
Base
.
getindex
,
:
xs
,
:
idx
=>
1
)
check
(
inv_index
,
(
;
xs
=
[
1
,
2
,
3
]
)
)
✔ Invariant satisfied: Method Base.getindex(xs, idx) implemented
If violated, the invariant will output
contextual
error messages based on the error encountered. If no
getindex
method is defined, we are told that a method is missing:
check
(
inv_index
,
(
;
xs
=
nothing
)
)
⨯ Invariant not satisfied: Method Base.getindex(xs, idx) implemented
When calling getindex, got a MethodError. This means that there is no method implemented for the given arguments. To fix this, please implement the following method:
Base.getindex(xs::Nothing, idx::Int64)
If there is a method, but it throws an error, we get a different error message:
check
(
inv_index
,
(
;
xs
=
[
]
)
)
⨯ Invariant not satisfied: Method Base.getindex(xs, idx) implemented
When calling getindex, got an unexpected error:
BoundsError: attempt to access 0-element Vector{Any} at index [1]
This means that there is a method matching the given arguments, but calling it throws an error. To fix this, please debug the following method:
Base.getindex(xs::Array, idx::Int64)
The following page links back here: