Method: ConditionalIgnoreMethodRule()

1: /*
2: * #%~
3: * Test Framework for Overture
4: * %%
5: * Copyright (C) 2008 - 2014 Overture
6: * %%
7: * This program is free software: you can redistribute it and/or modify
8: * it under the terms of the GNU General Public License as
9: * published by the Free Software Foundation, either version 3 of the
10: * License, or (at your option) any later version.
11: *
12: * This program is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: * GNU General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public
18: * License along with this program. If not, see
19: * <http://www.gnu.org/licenses/gpl-3.0.html>.
20: * #~%
21: */
22: package org.overture.test.framework;
23:
24: import java.lang.annotation.ElementType;
25: import java.lang.annotation.Retention;
26: import java.lang.annotation.RetentionPolicy;
27: import java.lang.annotation.Target;
28:
29: import org.junit.Assume;
30: import org.junit.rules.MethodRule;
31: import org.junit.runners.model.FrameworkMethod;
32: import org.junit.runners.model.Statement;
33:
34: public class ConditionalIgnoreMethodRule implements MethodRule
35: {
36:         /**
37:          * Condition that decides if the current test should be ignored
38:          *
39:          * @author kel
40:          */
41:         public interface IgnoreCondition
42:         {
43:                 /**
44:                  * Gets the truth value of the condition
45:                  *
46:                  * @return true if the condition decides that the test should be skipped, otherwise false.
47:                  */
48:                 boolean isIgnored();
49:         }
50:
51:         /**
52:          * Junit annotation used to annotate the test method
53:          *
54:          * @author kel
55:          */
56:         @Retention(RetentionPolicy.RUNTIME)
57:         @Target({ ElementType.METHOD })
58:         public @interface ConditionalIgnore
59:         {
60:                 Class<? extends IgnoreCondition> condition();
61:         }
62:
63:         /**
64:          * Check the rule
65:          */
66:         @Override
67:         public Statement apply(Statement base, FrameworkMethod method, Object target)
68:         {
69:                 Statement result = base;
70:                 if (hasAnnotation(method))
71:                 {
72:                         IgnoreCondition condition = getIgnoreContition(method);
73:                         if (condition.isIgnored())
74:                         {
75:                                 result = new IgnoreStatement(condition);
76:                         }
77:                 }
78:                 return result;
79:         }
80:
81:         /**
82:          * Gets the ignore condition. This should only be called in
83:          * {@link ConditionalIgnoreMethodRule#hasAnnotation(FrameworkMethod)} return true
84:          *
85:          * @param method
86:          * @return
87:          */
88:         private IgnoreCondition getIgnoreContition(FrameworkMethod method)
89:         {
90:                 ConditionalIgnore annotation = method.getAnnotation(ConditionalIgnore.class);
91:                 return newCondition(annotation);
92:         }
93:
94:         /**
95:          * Constructs a new instance of the condition such that is can be validated
96:          *
97:          * @param annotation
98:          * @return
99:          */
100:         private IgnoreCondition newCondition(ConditionalIgnore annotation)
101:         {
102:                 try
103:                 {
104:                         return annotation.condition().newInstance();
105:                 } catch (RuntimeException re)
106:                 {
107:                         throw re;
108:                 } catch (Exception e)
109:                 {
110:                         throw new RuntimeException(e);
111:                 }
112:         }
113:
114:         /**
115:          * Checks if the annotation exists
116:          *
117:          * @param method
118:          * @return
119:          */
120:         private boolean hasAnnotation(FrameworkMethod method)
121:         {
122:                 return method.getAnnotation(ConditionalIgnore.class) != null;
123:         }
124:
125:         /**
126:          * Ignore statement returned if the test should be ignored.
127:          *
128:          * @author kel
129:          */
130:         private static class IgnoreStatement extends Statement
131:         {
132:                 private IgnoreCondition condition;
133:
134:                 IgnoreStatement(IgnoreCondition condition)
135:                 {
136:                         this.condition = condition;
137:                 }
138:
139:                 @Override
140:                 public void evaluate()
141:                 {
142:                         Assume.assumeTrue("Ignored test by "
143:                                         + condition.getClass().getSimpleName(), false);
144:                 }
145:         }
146:
147: }