View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.testframework;
5   
6   import java.util.ArrayList;
7   import java.util.LinkedList;
8   import java.util.List;
9   
10  import net.sourceforge.pmd.Rule;
11  
12  import org.junit.Test;
13  import org.junit.internal.runners.InitializationError;
14  import org.junit.internal.runners.JUnit4ClassRunner;
15  import org.junit.runner.Description;
16  import org.junit.runner.RunWith;
17  import org.junit.runner.notification.Failure;
18  import org.junit.runner.notification.RunNotifier;
19  
20  /**
21   * Standard methods for (simple) testcases.
22   */
23  @RunWith(SimpleAggregatorTst.CustomXmlTestClassMethodsRunner.class)
24  /**
25   * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
26   */
27  public abstract class SimpleAggregatorTst extends RuleTst {
28      /**
29       * Run a set of tests defined in an XML test-data file for a rule. The file
30       * should be ./xml/RuleName.xml relative to the test-class. The format is
31       * defined in test-data.xsd.
32       */
33      public void runTests(Rule rule) {
34          runTests(extractTestsFromXml(rule));
35      }
36  
37      /**
38       * Run a set of tests defined in a XML test-data file. The file should be
39       * ./xml/[testsFileName].xml relative to the test-class. The format is
40       * defined in test-data.xsd.
41       */
42      public void runTests(Rule rule, String testsFileName) {
43          runTests(extractTestsFromXml(rule, testsFileName));
44      }
45  
46      /**
47       * Run a set of tests of a certain sourceType.
48       */
49      public void runTests(TestDescriptor[] tests) {
50          for (int i = 0; i < tests.length; i++) {
51              runTest(tests[i]);
52          }
53      }
54  
55      private List<Rule> rules = new ArrayList<Rule>();
56  
57      /**
58       * Add new XML tests associated with the rule to the test suite. This should
59       * be called from the setup method.
60       */
61      protected void addRule(String ruleSet, String ruleName) {
62          rules.add(findRule(ruleSet, ruleName));
63      }
64  
65      /**
66       * Run a set of tests for all rules added in the setup method.
67       */
68      @Test
69      public void testAll() {
70          boolean regressionTestMode = TestDescriptor.inRegressionTestMode();
71          ArrayList<Failure> l = new ArrayList<Failure>();
72          List<Description> ignored = new LinkedList<Description>();
73          for (Rule r : rules) {
74              TestDescriptor[] tests = extractTestsFromXml(r);
75              for (TestDescriptor test: tests) {
76  		if (!regressionTestMode || test.isRegressionTest()) {
77  		    try {
78  			runTest(test);
79  		    } catch (Throwable t) {
80  			Failure f = CustomXmlTestClassMethodsRunner.createFailure(r, t);
81  			l.add(f);
82  		    }
83  		} else {
84  		    // the test is ignored
85  		    Description description = CustomXmlTestClassMethodsRunner.createDescription(r,
86  			    test.getDescription());
87  		    ignored.add(description);
88  		}
89              }
90          }
91          for(Failure f: l) {
92              CustomXmlTestClassMethodsRunner.addFailure(f);
93          }
94          for (Description d: ignored) {
95              CustomXmlTestClassMethodsRunner.addIgnore(d);
96          }
97      }
98  
99      public static class CustomXmlTestClassMethodsRunner extends JUnit4ClassRunner {
100         public CustomXmlTestClassMethodsRunner(Class<?> klass) throws InitializationError {
101             super(klass);
102         }
103 
104         public static Failure createFailure(Rule rule, Throwable targetException) {
105             return new Failure(createDescription(rule, null),
106                     targetException);
107         }
108         
109         public static Description createDescription(Rule rule, String testName) {
110             return Description.createTestDescription(
111                     SimpleAggregatorTst.class, "xml." + rule.getRuleSetName() + '.' + rule.getName()
112                     + (testName != null ? ":" + testName : ""));
113         }
114 
115         public static void addFailure(Failure failure) {
116             synchronized(CustomXmlTestClassMethodsRunner.class) {
117                 NOTIFIER.fireTestFailure(failure);
118             }
119         }
120         
121         public static void addIgnore(Description description) {
122             synchronized (CustomXmlTestClassMethodsRunner.class) {
123 		NOTIFIER.fireTestIgnored(description);
124 	    }
125         }
126 
127         @Override
128         public void run(RunNotifier n) {
129             synchronized(CustomXmlTestClassMethodsRunner.class) {
130                 // synchronized so that access to NOTIFIER is safe: only
131                 // one runner at a time is active
132                 NOTIFIER = n;
133                 super.run(n);
134             }
135         }
136 
137         private static RunNotifier NOTIFIER;
138     }
139 
140 }