package de.codescape.bitvunit.rule;

import org.junit.Test;
import org.reflections.Reflections;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Set;

import static org.junit.Assert.*;

public class RuleImplementationTest {

    private static final String RULE_NAME_PROPERTY = "RULE_NAME";

    @Test
    public void everyNonAbstractRuleImplementationMustProvideAPublicStaticStringWithTheNameOfTheRule() throws Exception {
        Reflections reflections = new Reflections("de.codescape.bitvunit.rule");
        Set<Class<? extends Rule>> rules = reflections.getSubTypesOf(Rule.class);
        for (Class<? extends Rule> rule : rules) {
            if (!Modifier.isAbstract(rule.getModifiers()))
                checkRule(rule);
        }
    }

    private void checkRule(Class<? extends Rule> rule) {
        try {
            Field field = rule.getDeclaredField(RULE_NAME_PROPERTY);
            assertEquals(RULE_NAME_PROPERTY + " is not of type java.lang.String in rule" + rule.getSimpleName(), String.class, field.getType());
            assertTrue(RULE_NAME_PROPERTY + " is not static in rule " + rule.getSimpleName(), Modifier.isStatic(field.getModifiers()));
            assertTrue(RULE_NAME_PROPERTY + " is not public in rule " + rule.getSimpleName(), Modifier.isPublic(field.getModifiers()));
        } catch (NoSuchFieldException e) {
            fail("Rule " + rule.getSimpleName() + " does not provide a public static field called " + RULE_NAME_PROPERTY);
        }
    }

}

@@ -160,30 +160,8 @@
 ier;
-%0Aimport java.util.Set;
 %0A%0Aim
@@ -297,16 +297,98 @@
 E_NAME%22;
+%0A    private static final String PACKAGE_FOR_RULES = %22de.codescape.bitvunit.rule%22;
 %0A%0A    @T
@@ -525,93 +525,13 @@
     
-Reflections reflections = new Reflections(%22de.codescape.bitvunit.rule%22);%0A        Set%3C
+for (
 Clas
@@ -551,19 +551,21 @@
 ule%3E
-%3E
  rule
-s = r
+ : new R
 efle
@@ -570,16 +570,35 @@
 lections
+(PACKAGE_FOR_RULES)
 .getSubT
@@ -615,17 +615,19 @@
 e.class)
-;
+) %7B
 %0A       
@@ -619,36 +619,190 @@
 ass)) %7B%0A        
-for 
+    if (ruleIsNotAbstract(rule)) %7B%0A                verifyRuleProvidesRequiredField(rule);%0A            %7D%0A        %7D%0A    %7D%0A%0A    private boolean ruleIsNotAbstract
 (Class%3C? extends
@@ -816,16 +816,8 @@
 rule
- : rules
 ) %7B%0A
@@ -824,24 +824,23 @@
         
-    if (
+return 
 !Modifie
@@ -876,86 +876,65 @@
 s())
-)%0A                checkRule(rule);%0A        %7D%0A    %7D%0A%0A    private void checkRule
+;%0A    %7D%0A%0A    private void verifyRuleProvidesRequiredField
 (Cla
@@ -952,32 +952,60 @@
 s Rule%3E rule) %7B%0A
+        Field field = null;%0A
         try %7B%0A  
@@ -1006,38 +1006,32 @@
 y %7B%0A            
-Field 
 field = rule.get
@@ -1065,24 +1065,196 @@
 PERTY);%0A    
+    %7D catch (NoSuchFieldException e) %7B%0A            fail(%22Rule %22 + rule.getSimpleName() + %22 does not provide a public static field called %22 + RULE_NAME_PROPERTY);%0A        %7D%0A
         asse
@@ -1382,36 +1382,32 @@
 ype());%0A        
-   
- 
 assertTrue(RULE_
@@ -1518,28 +1518,24 @@
 ));%0A        
-    
 assertTrue(R
@@ -1650,184 +1650,8 @@
 ));%0A
-        %7D catch (NoSuchFieldException e) %7B%0A            fail(%22Rule %22 + rule.getSimpleName() + %22 does not provide a public static field called %22 + RULE_NAME_PROPERTY);%0A        %7D%0A
     

make test more readable