hedgehog.state.Command.scala Maven / Gradle / Ivy
The newest version!
package hedgehog.state
import hedgehog.core._
/**
* The specification for the expected behaviour of an `Action`.
*/
trait Command[S, I, O] extends CommandIO[S] {
type Input = I
type Output = O
/**
* Return a list of _all_ `Var` instances referenced by `Input`
*
* Failure to do this correctly will result in missing variable errors during shrinking.
*/
def vars(i: Input): List[Var[_]] =
Nil
/**
* A generator which provides random arguments for a command.
* If the command cannot be executed in the current state, it should return `None`.
*/
def gen(s: S): Option[GenT[Input]]
/**
* Executes a command using the arguments generated by [[gen]].
*/
def execute(env: Environment, s: Input): Either[String, Output]
/**
* A pre-condition for a command that must be verified before the command can be executed.
* This is mainly used during shrinking to ensure that it is still OK to run a command
* despite the fact that some previously executed commands may have been removed from the sequence.
*/
def require(s: S, i: Input): Boolean =
true
/**
* Updates the model state, given the input and output of the command.
*/
def update(s0: S, i: Input, o: Var[Output]): S
/**
* A post-condition for a command that must be verified for the command to be considered a success.
*/
def ensure(env: Environment, before: S, after: S, i: Input, o: Output): Result
/**
* Render the input for displaying in test output.
*
* The default is to use `toString`, but optionally can support being overridden.
*/
def renderInput(i: Input): String =
String.valueOf(i)
final override def command: Command[S, Input, Output] =
this
}
/**
* Capture the `Input` and `Output` variables from `Command` existentially.
*
* FIXME If we can make the rest of the code play nicely with path-dependent types then we can remove this.
*/
trait CommandIO[S] {
type Input
type Output
def command: Command[S, Input, Output]
}