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