carbidecpp22devenv/plugins/org.eclipse.test.source_3.5.0.r20080925/src/org.junit4_4.5.0.v20090423/junitsrc/org/junit/experimental/theories/Theories.java
author cawthron
Fri, 04 Dec 2009 11:49:54 -0600
changeset 636 3ef299ba838f
permissions -rw-r--r--
add files for RCL_2_2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
636
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
     1
/**
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
     2
 * 
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
     3
 */
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
     4
package org.junit.experimental.theories;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
     5
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
     6
import java.lang.reflect.Field;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
     7
import java.lang.reflect.InvocationTargetException;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
     8
import java.lang.reflect.Modifier;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
     9
import java.util.ArrayList;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    10
import java.util.List;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    11
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    12
import org.junit.Assert;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    13
import org.junit.experimental.theories.PotentialAssignment.CouldNotGenerateValueException;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    14
import org.junit.experimental.theories.internal.Assignments;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    15
import org.junit.experimental.theories.internal.ParameterizedAssertionError;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    16
import org.junit.internal.AssumptionViolatedException;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    17
import org.junit.runners.BlockJUnit4ClassRunner;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    18
import org.junit.runners.model.FrameworkMethod;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    19
import org.junit.runners.model.InitializationError;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    20
import org.junit.runners.model.Statement;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    21
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    22
public class Theories extends BlockJUnit4ClassRunner {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    23
	public Theories(Class<?> klass) throws InitializationError {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    24
		super(klass);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    25
	}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    26
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    27
	@Override
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    28
	protected void collectInitializationErrors(List<Throwable> errors) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    29
		super.collectInitializationErrors(errors);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    30
		validateDataPointFields(errors);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    31
	}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    32
	
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    33
	private void validateDataPointFields(List<Throwable> errors) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    34
		Field[] fields= getTestClass().getJavaClass().getDeclaredFields();
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    35
		
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    36
		for (Field each : fields)
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    37
			if (each.getAnnotation(DataPoint.class) != null && !Modifier.isStatic(each.getModifiers()))
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    38
				errors.add(new Error("DataPoint field " + each.getName() + " must be static"));
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    39
	}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    40
	
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    41
	@Override
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    42
	protected void validateZeroArgConstructor(List<Throwable> errors) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    43
		// constructor can have args
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    44
	}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    45
	
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    46
	@Override
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    47
	protected void validateTestMethods(List<Throwable> errors) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    48
		for (FrameworkMethod each : computeTestMethods())
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    49
			each.validatePublicVoid(false, errors);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    50
	}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    51
	
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    52
	@Override
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    53
	protected List<FrameworkMethod> computeTestMethods() {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    54
		List<FrameworkMethod> testMethods= super.computeTestMethods();
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    55
		List<FrameworkMethod> theoryMethods= getTestClass().getAnnotatedMethods(Theory.class);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    56
		testMethods.removeAll(theoryMethods);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    57
		testMethods.addAll(theoryMethods);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    58
		return testMethods;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    59
	}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    60
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    61
	@Override
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    62
	public Statement methodBlock(final FrameworkMethod method) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    63
		return new TheoryAnchor(method);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    64
	}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    65
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    66
	public class TheoryAnchor extends Statement {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    67
		private int successes= 0;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    68
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    69
		private FrameworkMethod fTestMethod;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    70
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    71
		private List<AssumptionViolatedException> fInvalidParameters= new ArrayList<AssumptionViolatedException>();
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    72
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    73
		public TheoryAnchor(FrameworkMethod method) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    74
			fTestMethod= method;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    75
		}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    76
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    77
		@Override
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    78
		public void evaluate() throws Throwable {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    79
			runWithAssignment(Assignments.allUnassigned(
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    80
					fTestMethod.getMethod(), getTestClass()));
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    81
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    82
			if (successes == 0)
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    83
				Assert
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    84
						.fail("Never found parameters that satisfied method assumptions.  Violated assumptions: "
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    85
								+ fInvalidParameters);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    86
		}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    87
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    88
		protected void runWithAssignment(Assignments parameterAssignment)
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    89
				throws Throwable {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    90
			if (!parameterAssignment.isComplete()) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    91
				runWithIncompleteAssignment(parameterAssignment);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    92
			} else {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    93
				runWithCompleteAssignment(parameterAssignment);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    94
			}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    95
		}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    96
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    97
		protected void runWithIncompleteAssignment(Assignments incomplete)
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    98
				throws InstantiationException, IllegalAccessException,
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
    99
				Throwable {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   100
			for (PotentialAssignment source : incomplete
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   101
					.potentialsForNextUnassigned()) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   102
				runWithAssignment(incomplete.assignNext(source));
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   103
			}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   104
		}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   105
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   106
		protected void runWithCompleteAssignment(final Assignments complete)
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   107
				throws InstantiationException, IllegalAccessException,
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   108
				InvocationTargetException, NoSuchMethodException, Throwable {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   109
			new BlockJUnit4ClassRunner(getTestClass().getJavaClass()) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   110
				@Override
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   111
				protected void collectInitializationErrors(
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   112
						List<Throwable> errors) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   113
					// do nothing
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   114
				}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   115
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   116
				@Override
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   117
				public Statement methodBlock(FrameworkMethod method) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   118
					final Statement statement= super.methodBlock(method);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   119
					return new Statement() {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   120
						@Override
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   121
						public void evaluate() throws Throwable {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   122
							try {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   123
								statement.evaluate();
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   124
								handleDataPointSuccess();
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   125
							} catch (AssumptionViolatedException e) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   126
								handleAssumptionViolation(e);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   127
							} catch (Throwable e) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   128
								reportParameterizedError(e, complete
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   129
										.getArgumentStrings(nullsOk()));
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   130
							}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   131
						}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   132
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   133
					};
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   134
				}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   135
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   136
				@Override
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   137
				protected Statement methodInvoker(FrameworkMethod method, Object test) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   138
					return methodCompletesWithParameters(method, complete, test);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   139
				}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   140
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   141
				@Override
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   142
				public Object createTest() throws Exception {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   143
					return getTestClass().getOnlyConstructor().newInstance(
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   144
							complete.getConstructorArguments(nullsOk()));
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   145
				}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   146
			}.methodBlock(fTestMethod).evaluate();
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   147
		}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   148
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   149
		private Statement methodCompletesWithParameters(
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   150
				final FrameworkMethod method, final Assignments complete, final Object freshInstance) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   151
			return new Statement() {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   152
				@Override
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   153
				public void evaluate() throws Throwable {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   154
					try {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   155
						final Object[] values= complete.getMethodArguments(
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   156
								nullsOk());
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   157
						method.invokeExplosively(freshInstance, values);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   158
					} catch (CouldNotGenerateValueException e) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   159
						// ignore
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   160
					}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   161
				}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   162
			};
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   163
		}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   164
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   165
		protected void handleAssumptionViolation(AssumptionViolatedException e) {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   166
			fInvalidParameters.add(e);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   167
		}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   168
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   169
		protected void reportParameterizedError(Throwable e, Object... params)
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   170
				throws Throwable {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   171
			if (params.length == 0)
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   172
				throw e;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   173
			throw new ParameterizedAssertionError(e, fTestMethod.getName(),
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   174
					params);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   175
		}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   176
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   177
		private boolean nullsOk() {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   178
			Theory annotation= fTestMethod.getMethod().getAnnotation(
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   179
					Theory.class);
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   180
			if (annotation == null)
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   181
				return false;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   182
			return annotation.nullsAccepted();
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   183
		}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   184
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   185
		protected void handleDataPointSuccess() {
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   186
			successes++;
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   187
		}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   188
	}
3ef299ba838f add files for RCL_2_2
cawthron
parents:
diff changeset
   189
}