Skip to content

Commit

Permalink
Fixes #1019 by adding validtion that @ClassRule should only be implem…
Browse files Browse the repository at this point in the history
…entation of TestRule
  • Loading branch information
npathai committed Nov 2, 2014
1 parent 26f9eba commit 4ee480d
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class RuleMemberValidator {
.withValidator(new DeclaringClassMustBePublic())
.withValidator(new MemberMustBeStatic())
.withValidator(new MemberMustBePublic())
.withValidator(new FieldMustBeARule())
.withValidator(new FieldMustBeATestRule())
.build();
/**
* Validates fields with a {@link Rule} annotation.
Expand All @@ -54,7 +54,7 @@ public class RuleMemberValidator {
.withValidator(new DeclaringClassMustBePublic())
.withValidator(new MemberMustBeStatic())
.withValidator(new MemberMustBePublic())
.withValidator(new MethodMustBeARule())
.withValidator(new MethodMustBeATestRule())
.build();

/**
Expand Down Expand Up @@ -164,6 +164,7 @@ interface RuleValidator {
* Requires the validated member to be non-static
*/
private static final class MemberMustBeNonStaticOrAlsoClassRule implements RuleValidator {
@Override
public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
boolean isMethodRuleMember = isMethodRule(member);
boolean isClassRuleAnnotated = (member.getAnnotation(ClassRule.class) != null);
Expand All @@ -189,6 +190,7 @@ public void validate(FrameworkMember<?> member, Class<? extends Annotation> anno
* Requires the member to be static
*/
private static final class MemberMustBeStatic implements RuleValidator {
@Override
public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
if (!member.isStatic()) {
errors.add(new ValidationError(member, annotation,
Expand All @@ -201,6 +203,7 @@ public void validate(FrameworkMember<?> member, Class<? extends Annotation> anno
* Requires the member's declaring class to be public
*/
private static final class DeclaringClassMustBePublic implements RuleValidator {
@Override
public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
if (!isDeclaringClassPublic(member)) {
errors.add(new ValidationError(member, annotation,
Expand All @@ -217,6 +220,7 @@ private boolean isDeclaringClassPublic(FrameworkMember<?> member) {
* Requires the member to be public
*/
private static final class MemberMustBePublic implements RuleValidator {
@Override
public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
if (!member.isPublic()) {
errors.add(new ValidationError(member, annotation,
Expand All @@ -229,6 +233,7 @@ public void validate(FrameworkMember<?> member, Class<? extends Annotation> anno
* Requires the member is a field implementing {@link org.junit.rules.MethodRule} or {@link org.junit.rules.TestRule}
*/
private static final class FieldMustBeARule implements RuleValidator {
@Override
public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
if (!isRuleType(member)) {
errors.add(new ValidationError(member, annotation,
Expand All @@ -242,11 +247,42 @@ public void validate(FrameworkMember<?> member, Class<? extends Annotation> anno
* {@link org.junit.rules.TestRule}
*/
private static final class MethodMustBeARule implements RuleValidator {
@Override
public void validate(FrameworkMember<?> member, Class<? extends Annotation> annotation, List<Throwable> errors) {
if (!isRuleType(member)) {
errors.add(new ValidationError(member, annotation,
"must return an implementation of MethodRule or TestRule."));
}
}
}

/**
* Require the member to return an implementation of {@link org.junit.rules.TestRule}
*/
private static final class MethodMustBeATestRule implements RuleValidator {

@Override
public void validate(FrameworkMember<?> member,
Class<? extends Annotation> annotation, List<Throwable> errors) {
if (!isTestRule(member)) {
errors.add(new ValidationError(member, annotation,
"must return an implementation of TestRule."));
}
}
}

/**
* Requires the member is a field implementing {@link org.junit.rules.TestRule}
*/
private static final class FieldMustBeATestRule implements RuleValidator {

@Override
public void validate(FrameworkMember<?> member,
Class<? extends Annotation> annotation, List<Throwable> errors) {
if (!isTestRule(member)) {
errors.add(new ValidationError(member, annotation,
"must implement TestRule."));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,99 @@ static class NonPublicTestWithClassRule {
@ClassRule
public static TestRule temporaryFolder = new TemporaryFolder();
}

/**
* If there is any property annotated with @ClassRule then it must implement
* {@link TestRule}
*
* <p>This case has been added with
* <a href="https://github.com/junit-team/junit/issues/1019">Issue #1019</a>
*/
@Test
public void rejectClassRuleThatIsImplemetationOfMethodRule() {
TestClass target = new TestClass(TestWithClassRuleIsImplementationOfMethodRule.class);
CLASS_RULE_VALIDATOR.validate(target, errors);
assertOneErrorWithMessage("The @ClassRule 'classRule' must implement TestRule.");
}

public static class TestWithClassRuleIsImplementationOfMethodRule {
@ClassRule
public static MethodRule classRule = new MethodRule() {

@Override
public Statement apply(Statement base, FrameworkMethod method, Object target) {
return base;
}
};
}

/**
* If there is any method annotated with @ClassRule then it must return an
* implementation of {@link TestRule}
*
* <p>This case has been added with
* <a href="https://github.com/junit-team/junit/issues/1019">Issue #1019</a>
*/
@Test
public void rejectClassRuleThatReturnsImplementationOfMethodRule() {
TestClass target = new TestClass(TestWithClassRuleMethodThatReturnsMethodRule.class);
CLASS_RULE_METHOD_VALIDATOR.validate(target, errors);
assertOneErrorWithMessage("The @ClassRule 'methodRule' must return an implementation of TestRule.");
}

public static class TestWithClassRuleMethodThatReturnsMethodRule {
@ClassRule
public static MethodRule methodRule() {
return new MethodRule() {

@Override
public Statement apply(Statement base, FrameworkMethod method, Object target) {
return base;
}
};
}
}

/**
* If there is any property annotated with @ClassRule then it must implement
* {@link TestRule}
*
* <p>This case has been added with
* <a href="https://github.com/junit-team/junit/issues/1019">Issue #1019</a>
*/
@Test
public void rejectClassRuleIsAnArbitraryObject() throws Exception {
TestClass target = new TestClass(TestWithClassRuleIsAnArbitraryObject.class);
CLASS_RULE_VALIDATOR.validate(target, errors);
assertOneErrorWithMessage("The @ClassRule 'arbitraryObject' must implement TestRule.");
}

public static class TestWithClassRuleIsAnArbitraryObject {
@ClassRule
public static Object arbitraryObject = 1;
}

/**
* If there is any method annotated with @ClassRule then it must return an
* implementation of {@link TestRule}
*
* <p>This case has been added with
* <a href="https://github.com/junit-team/junit/issues/1019">Issue #1019</a>
*/
@Test
public void rejectClassRuleMethodReturnsAnArbitraryObject() throws Exception {
TestClass target = new TestClass(TestWithClassRuleMethodReturnsAnArbitraryObject.class);
CLASS_RULE_METHOD_VALIDATOR.validate(target, errors);
assertOneErrorWithMessage("The @ClassRule 'arbitraryObject' must return an implementation of TestRule.");
}

public static class TestWithClassRuleMethodReturnsAnArbitraryObject {
@ClassRule
public static Object arbitraryObject() {
return 1;
}
}

@Test
public void acceptNonStaticTestRule() {
TestClass target = new TestClass(TestWithNonStaticTestRule.class);
Expand Down Expand Up @@ -119,6 +211,7 @@ public void acceptMethodRule() throws Exception {
public static class TestWithMethodRule {
@Rule
public MethodRule temporaryFolder = new MethodRule() {
@Override
public Statement apply(Statement base, FrameworkMethod method,
Object target) {
return null;
Expand Down Expand Up @@ -233,6 +326,7 @@ public static class MethodTestWithMethodRule {
@Rule
public MethodRule getTemporaryFolder() {
return new MethodRule() {
@Override
public Statement apply(Statement base, FrameworkMethod method,
Object target) {
return null;
Expand Down

0 comments on commit 4ee480d

Please sign in to comment.