package org.junit.tests.experimental.rules;
import static org.junit.Assert.assertEquals;
import static org.junit.internal.runners.rules.RuleFieldValidator.CLASS_RULE_METHOD_VALIDATOR;
import static org.junit.internal.runners.rules.RuleFieldValidator.CLASS_RULE_VALIDATOR;
import static org.junit.internal.runners.rules.RuleFieldValidator.RULE_METHOD_VALIDATOR;
import static org.junit.internal.runners.rules.RuleFieldValidator.RULE_VALIDATOR;
import java.util.ArrayList;
import java.util.List;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestRule;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
import org.junit.runners.model.TestClass;
public class RuleFieldValidatorTest {
private final List<Throwable> errors = new ArrayList<Throwable>();
@Test
public void rejectProtectedClassRule() {
TestClass target = new TestClass(TestWithProtectedClassRule.class);
CLASS_RULE_VALIDATOR.validate(target, errors);
assertOneErrorWithMessage("The @ClassRule 'temporaryFolder' must be public.");
}
public static class TestWithProtectedClassRule {
@ClassRule
protected static TestRule temporaryFolder = new TemporaryFolder();
}
@Test
public void rejectNonStaticClassRule() {
TestClass target = new TestClass(TestWithNonStaticClassRule.class);
CLASS_RULE_VALIDATOR.validate(target, errors);
assertOneErrorWithMessage("The @ClassRule 'temporaryFolder' must be static.");
}
public static class TestWithNonStaticClassRule {
@ClassRule
public TestRule temporaryFolder = new TemporaryFolder();
}
@Test
public void rejectClassRuleInNonPublicClass() {
TestClass target = new TestClass(NonPublicTestWithClassRule.class);
CLASS_RULE_VALIDATOR.validate(target, errors);
assertOneErrorWithMessage("The @ClassRule 'temporaryFolder' must be declared in a public class.");
}
static class NonPublicTestWithClassRule {
@ClassRule
public static TestRule temporaryFolder = new TemporaryFolder();
}
@Test
public void acceptNonStaticTestRule() {
TestClass target = new TestClass(TestWithNonStaticTestRule.class);
RULE_VALIDATOR.validate(target, errors);
assertNumberOfErrors(0);
}
public static class TestWithNonStaticTestRule {
@Rule
public TestRule temporaryFolder = new TemporaryFolder();
}
@Test
public void rejectStaticTestRule() {
TestClass target = new TestClass(TestWithStaticTestRule.class);
RULE_VALIDATOR.validate(target, errors);
assertOneErrorWithMessage("The @Rule 'temporaryFolder' must not be static or it has to be annotated with @ClassRule.");
}
public static class TestWithStaticTestRule {
@Rule
public static TestRule temporaryFolder = new TemporaryFolder();
}
@Test
public void acceptMethodRule() throws Exception {
TestClass target = new TestClass(TestWithMethodRule.class);
RULE_VALIDATOR.validate(target, errors);
assertNumberOfErrors(0);
}
public static class TestWithMethodRule {
@Rule
public MethodRule temporaryFolder = new MethodRule() {
public Statement apply(Statement base, FrameworkMethod method,
Object target) {
return null;
}
};
}
@Test
public void rejectArbitraryObjectWithRuleAnnotation() throws Exception {
TestClass target = new TestClass(TestWithArbitraryObjectWithRuleAnnotation.class);
RULE_VALIDATOR.validate(target, errors);
assertOneErrorWithMessage("The @Rule 'arbitraryObject' must implement MethodRule or TestRule.");
}
public static class TestWithArbitraryObjectWithRuleAnnotation {
@Rule
public Object arbitraryObject = 1;
}
@Test
public void methodRejectProtectedClassRule() {
TestClass target = new TestClass(MethodTestWithProtectedClassRule.class);
CLASS_RULE_METHOD_VALIDATOR.validate(target, errors);
assertOneErrorWithMessage("The @ClassRule 'getTemporaryFolder' must be public.");
}
public static class MethodTestWithProtectedClassRule {
@ClassRule
protected static TestRule getTemporaryFolder() {
return new TemporaryFolder();
}
}
@Test
public void methodRejectNonStaticClassRule() {
TestClass target = new TestClass(MethodTestWithNonStaticClassRule.class);
CLASS_RULE_METHOD_VALIDATOR.validate(target, errors);
assertOneErrorWithMessage("The @ClassRule 'getTemporaryFolder' must be static.");
}
public static class MethodTestWithNonStaticClassRule {
@ClassRule
public TestRule getTemporaryFolder() {
return new TemporaryFolder();
}
}
@Test
public void acceptMethodNonStaticTestRule() {
TestClass target = new TestClass(TestMethodWithNonStaticTestRule.class);
RULE_METHOD_VALIDATOR.validate(target, errors);
assertNumberOfErrors(0);
}
public static class TestMethodWithNonStaticTestRule {
@Rule
public TestRule getTemporaryFolder() {
return new TemporaryFolder();
}
}
@Test
public void rejectMethodStaticTestRule() {
TestClass target = new TestClass(TestMethodWithStaticTestRule.class);
RULE_METHOD_VALIDATOR.validate(target, errors);
assertOneErrorWithMessage("The @Rule 'getTemporaryFolder' must not be static or it has to be annotated with @ClassRule.");
}
public static class TestMethodWithStaticTestRule {
@Rule
public static TestRule getTemporaryFolder() {
return new TemporaryFolder();
}
}
@Test
public void methodAcceptMethodRuleMethod() throws Exception {
TestClass target = new TestClass(MethodTestWithMethodRule.class);
RULE_METHOD_VALIDATOR.validate(target, errors);
assertNumberOfErrors(0);
}
public static class MethodTestWithMethodRule {
@Rule
public MethodRule getTemporaryFolder() {
return new MethodRule() {
public Statement apply(Statement base, FrameworkMethod method,
Object target) {
return null;
}
};
}
}
@Test
public void methodRejectArbitraryObjectWithRuleAnnotation() throws Exception {
TestClass target = new TestClass(MethodTestWithArbitraryObjectWithRuleAnnotation.class);
RULE_METHOD_VALIDATOR.validate(target, errors);
assertOneErrorWithMessage("The @Rule 'getArbitraryObject' must return an implementation of MethodRule or TestRule.");
}
public static class MethodTestWithArbitraryObjectWithRuleAnnotation {
@Rule
public Object getArbitraryObject() {
return 1;
}
}
private void assertOneErrorWithMessage(String message) {
assertNumberOfErrors(1);
assertEquals("Wrong error message:", message, errors.get(0).getMessage());
}
private void assertNumberOfErrors(int numberOfErrors) {
assertEquals("Wrong number of errors:", numberOfErrors, errors.size());
}
}