/*
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira.junit
 */
package net.ranides.assira.junit;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Annotation used to mark methods as usable by {@link TestContractRunner}.
 * Object which contains one or more annotated methods is called tester.
 *
 * Tester can declare methods for tests and fields for injection.
 * To read about injection, lets look at {@link TestResource}.
 *
 * Annotated method must be non-static, public, and has one compatible argument.
 * Type of argument is critical, because runner checks if currently tested object
 * is sublcass of this argument and executes method only if it is designed for this type.
 *
 * Tester methods can take 3 types of arguments:
 * 1) just an object of type T:
 *    runner will create it using supplier and send this object in default state to the tester
 *
 * 2) supplier of object of type {@code Supplier<T>}:
 *    runner will pass supplier, tester can call supplier to create many objects with default state
 *
 * 3) {@code function<X,T>}:
 *    runner will pass function; tester can call this function with different "X" arguments
 *    to create objects in different state. there is no exact definition of "different state":
 *    only guaranteed effect is, they won't be equal.
 *
 *    Some functions takes int[] and use convention, that first int defines hashcode, and second defines equality.
 *    Some functions takes int[] and use convention, to create collection filled by "some objects" created from int[] elements.
 *
 * You have to correctly configure runner to be able to pass those arguments to testers.
 * For example: runner which does not have function<int[],T> won't be able to execute tests which expect this function.
 *
 * Every tester method must take argument, even if it does not use it,
 * because we want to match tested type and decide if method should be executed.
 *
 * Some contract testers do not use passed arguments too much, but use injected factories.
 * To use them, you must configure TestContractRunner, using {@link TestContractRunner#param}.
 *
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface TestContract {
    
}
