Examples

This page showcases some examples for commonly useful invariants that are either included in Invariants.jl or simple to construct.

Checking for method implementations

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)
Functions with side effects

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)
Backlinks