All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.jqwik.api.state.ActionChain Maven / Gradle / Ivy

The newest version!
package net.jqwik.api.state;

import java.util.*;
import java.util.function.*;

import org.apiguardian.api.*;
import org.jspecify.annotations.*;

import net.jqwik.api.*;

import static org.apiguardian.api.API.Status.*;

/**
 * A chain of transforming Actions that can be run for values of type {@code S}.
 * Since the next action is usually created on demand, the current {@code runState}
 * of a chain can be queried.
 *
 * 

* By default any action chain instance is not thread safe, * i.e. you should not try to invoke {@linkplain #run()} concurrently. *

* * @param The type of the object going through state transformations */ @API(status = EXPERIMENTAL, since = "1.7.0") public interface ActionChain { @API(status = INTERNAL) abstract class ActionChainFacade { static final ActionChainFacade implementation; static { implementation = FacadeLoader.load(ActionChainFacade.class); } public abstract ActionChainArbitrary startWith(Supplier initialSupplier); } /** * Create arbitrary for a {@linkplain ActionChain chain} with a certain initial state. * * @param initialSupplier function to create the initial state object * @param The type of state to be transformed through the chain. * @return new arbitrary instance */ static ActionChainArbitrary startWith(Supplier initialSupplier) { return ActionChainFacade.implementation.startWith(initialSupplier); } enum RunningState { NOT_RUN, RUNNING, FAILED, SUCCEEDED } /** * Return list of all applied transformations. * *

* For a chain that has not been run this list is always empty. *

* * @return list of describing strings */ List transformations(); /** * Return list of all used transformer instances. * *

* Checking transformer instances - e.g. if they are of a certain implementation type - * only makes sense if the transformer's description string is NOT set explicitly, * e.g. in an Action's description() method. *

* *

* For a chain that has not been run this list is always empty. *

* * @return list of transformer instances */ @API(status = EXPERIMENTAL, since = "1.7.1") List> transformers(); /** * Run the list through all transformations provided by the actions to create it. * Stop when either the maximum number of transformations is reached or if a * {@linkplain Transformer#END_OF_CHAIN} is being applied. * * @return the last resulting state of running through transformations */ S run(); /** * Add an unlabelled invariant to a sequence. * * @param invariant will be checked after each successful action * @return the same chain instance * @see #withInvariant(String, Consumer) */ default ActionChain withInvariant(Consumer invariant) { return withInvariant(null, invariant); } /** * Add a labelled invariant to a sequence. * * @param label will show up in error messages when the invariant fails * @param invariant will be checked after each successful action * @return the same chain instance * @see #withInvariant(Consumer) */ ActionChain withInvariant(@Nullable String label, Consumer invariant); /** * The final state value after running an action chain. * * @return state or {@linkplain Optional#empty()} if chain has not been run */ Optional finalState(); /** * An action chain can be in different running states: NOT_RUN, RUNNING, FAILED, SUCEEDED * * @return a {@linkplain RunningState state} object */ RunningState running(); /** * Observe the state transformations of a running chain by adding a peeker to an action chain. * The {@code peeker} will be called after each successful transformation * but before checking invariants. * *

* There can be more than one peeker. *

* * @param peeker A consumer of a state object * @return the same chain instance */ ActionChain peek(Consumer peeker); }