package org.junit.runner.manipulation;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import org.junit.runner.Description;
import org.junit.runner.OrderWith;

Reorders tests. An Ordering can reverse the order of tests, sort the order or even shuffle the order.

In general you will not need to use a Ordering directly. Instead, use Request.orderWith(Ordering).

Since:4.13
/** * Reorders tests. An {@code Ordering} can reverse the order of tests, sort the * order or even shuffle the order. * * <p>In general you will not need to use a <code>Ordering</code> directly. * Instead, use {@link org.junit.runner.Request#orderWith(Ordering)}. * * @since 4.13 */
public abstract class Ordering { private static final String CONSTRUCTOR_ERROR_FORMAT = "Ordering class %s should have a public constructor with signature " + "%s(Ordering.Context context)";
Creates an Ordering that shuffles the items using the given Random instance.
/** * Creates an {@link Ordering} that shuffles the items using the given * {@link Random} instance. */
public static Ordering shuffledBy(final Random random) { return new Ordering() { @Override boolean validateOrderingIsCorrect() { return false; } @Override protected List<Description> orderItems(Collection<Description> descriptions) { List<Description> shuffled = new ArrayList<Description>(descriptions); Collections.shuffle(shuffled, random); return shuffled; } }; }
Creates an Ordering from the given factory class. The class must have a public no-arg constructor.
Params:
  • factoryClass – class to use to create the ordering
  • annotatedTestClass – test class that is annotated with OrderWith.
Throws:
/** * Creates an {@link Ordering} from the given factory class. The class must have a public no-arg * constructor. * * @param factoryClass class to use to create the ordering * @param annotatedTestClass test class that is annotated with {@link OrderWith}. * @throws InvalidOrderingException if the instance could not be created */
public static Ordering definedBy( Class<? extends Ordering.Factory> factoryClass, Description annotatedTestClass) throws InvalidOrderingException { if (factoryClass == null) { throw new NullPointerException("factoryClass cannot be null"); } if (annotatedTestClass == null) { throw new NullPointerException("annotatedTestClass cannot be null"); } Ordering.Factory factory; try { Constructor<? extends Ordering.Factory> constructor = factoryClass.getConstructor(); factory = constructor.newInstance(); } catch (NoSuchMethodException e) { throw new InvalidOrderingException(String.format( CONSTRUCTOR_ERROR_FORMAT, getClassName(factoryClass), factoryClass.getSimpleName())); } catch (Exception e) { throw new InvalidOrderingException( "Could not create ordering for " + annotatedTestClass, e); } return definedBy(factory, annotatedTestClass); }
Creates an Ordering from the given factory.
Params:
  • factory – factory to use to create the ordering
  • annotatedTestClass – test class that is annotated with OrderWith.
Throws:
/** * Creates an {@link Ordering} from the given factory. * * @param factory factory to use to create the ordering * @param annotatedTestClass test class that is annotated with {@link OrderWith}. * @throws InvalidOrderingException if the instance could not be created */
public static Ordering definedBy( Ordering.Factory factory, Description annotatedTestClass) throws InvalidOrderingException { if (factory == null) { throw new NullPointerException("factory cannot be null"); } if (annotatedTestClass == null) { throw new NullPointerException("annotatedTestClass cannot be null"); } return factory.create(new Ordering.Context(annotatedTestClass)); } private static String getClassName(Class<?> clazz) { String name = clazz.getCanonicalName(); if (name == null) { return clazz.getName(); } return name; }
Order the tests in target using this ordering.
Throws:
  • InvalidOrderingException – if ordering does something invalid (like remove or add children)
/** * Order the tests in <code>target</code> using this ordering. * * @throws InvalidOrderingException if ordering does something invalid (like remove or add * children) */
public void apply(Object target) throws InvalidOrderingException { /* * Note that some subclasses of Ordering override apply(). The Sorter * subclass of Ordering overrides apply() to apply the sort (this is * done because sorting is more efficient than ordering). */ if (target instanceof Orderable) { Orderable orderable = (Orderable) target; orderable.order(new Orderer(this)); } }
Returns true if this ordering could produce invalid results (i.e. if it could add or remove values).
/** * Returns {@code true} if this ordering could produce invalid results (i.e. * if it could add or remove values). */
boolean validateOrderingIsCorrect() { return true; }
Implemented by sub-classes to order the descriptions.
Returns:descriptions in order
/** * Implemented by sub-classes to order the descriptions. * * @return descriptions in order */
protected abstract List<Description> orderItems(Collection<Description> descriptions);
Context about the ordering being applied.
/** Context about the ordering being applied. */
public static class Context { private final Description description;
Gets the description for the top-level target being ordered.
/** * Gets the description for the top-level target being ordered. */
public Description getTarget() { return description; } private Context(Description description) { this.description = description; } }
Factory for creating Ordering instances.

For a factory to be used with @OrderWith it needs to have a public no-arg constructor.

/** * Factory for creating {@link Ordering} instances. * * <p>For a factory to be used with {@code @OrderWith} it needs to have a public no-arg * constructor. */
public interface Factory {
Creates an Ordering instance using the given context. Implementations of this method that do not need to use the context can return the same instance every time.
/** * Creates an Ordering instance using the given context. Implementations * of this method that do not need to use the context can return the * same instance every time. */
Ordering create(Context context); } }