1 4 package test.net.sourceforge.pmd.testframework; 5 6 import java.io.IOException ; 7 import java.io.InputStream ; 8 import java.io.StringReader ; 9 import java.util.Properties ; 10 11 import javax.xml.parsers.DocumentBuilder ; 12 import javax.xml.parsers.DocumentBuilderFactory ; 13 import javax.xml.parsers.FactoryConfigurationError ; 14 import javax.xml.parsers.ParserConfigurationException ; 15 16 import junit.framework.TestCase; 17 import net.sourceforge.pmd.PMD; 18 import net.sourceforge.pmd.PMDException; 19 import net.sourceforge.pmd.Report; 20 import net.sourceforge.pmd.Rule; 21 import net.sourceforge.pmd.RuleContext; 22 import net.sourceforge.pmd.RuleSet; 23 import net.sourceforge.pmd.RuleSetFactory; 24 import net.sourceforge.pmd.RuleSetNotFoundException; 25 import net.sourceforge.pmd.RuleSets; 26 import net.sourceforge.pmd.SimpleRuleSetNameMapper; 27 import net.sourceforge.pmd.SourceType; 28 import net.sourceforge.pmd.SourceTypeToRuleLanguageMapper; 29 30 import org.w3c.dom.Document ; 31 import org.w3c.dom.Element ; 32 import org.w3c.dom.Node ; 33 import org.w3c.dom.NodeList ; 34 import org.xml.sax.SAXException ; 35 36 39 public class RuleTst extends TestCase { 40 public static final SourceType DEFAULT_SOURCE_TYPE = SourceType.JAVA_14; 41 42 45 public Rule findRule(String ruleSet, String ruleName) { 46 try { 47 Rule rule = new RuleSetFactory().createRuleSets(new SimpleRuleSetNameMapper(ruleSet).getRuleSets()).getRuleByName(ruleName); 48 rule.setRuleSetName(ruleSet); 49 if (rule == null) { 50 fail("Rule " + ruleName + " not found in ruleset " + ruleSet); 51 } 52 return rule; 53 } catch (RuleSetNotFoundException e) { 54 e.printStackTrace(); 55 fail("Couldn't find ruleset " + ruleSet); 56 return null; 57 } 58 } 59 60 61 64 public void runTest(TestDescriptor test) { 65 Rule rule = test.getRule(); 66 67 if (test.getReinitializeRule()) { 68 rule = findRule(rule.getRuleSetName(), rule.getName()); 69 } 70 71 Properties ruleProperties = rule.getProperties(); 72 Properties oldProperties = (Properties )ruleProperties.clone(); 73 try { 74 if (test.getProperties() != null) { 75 oldProperties = (Properties )ruleProperties.clone(); 76 ruleProperties.putAll(test.getProperties()); 77 } 78 79 int res = processUsingStringReader(test.getCode(), rule, test.getSourceType()).size(); 80 assertEquals("\"" + test.getDescription() + "\" test resulted in wrong number of failures,", 81 test.getNumberOfProblemsExpected(), res); 82 } catch (Throwable t) { 83 t.printStackTrace(); 84 throw new RuntimeException ("Test \"" + test.getDescription() + "\" failed"); 85 } finally { 86 ruleProperties.clear(); 88 ruleProperties.putAll(oldProperties); 89 } 90 } 91 92 private Report processUsingStringReader(String code, Rule rule, 93 SourceType sourceType) throws PMDException { 94 Report report = new Report(); 95 runTestFromString(code, rule, report, sourceType); 96 return report; 97 } 98 99 102 public void runTestFromString(String code, Rule rule, Report report, SourceType sourceType) throws PMDException { 103 PMD p = new PMD(); 104 p.setJavaVersion(sourceType); 105 RuleContext ctx = new RuleContext(); 106 ctx.setReport(report); 107 ctx.setSourceCodeFilename("n/a"); 108 RuleSet rules = new RuleSet(); 109 rules.addRule(rule); 110 rules.setLanguage(SourceTypeToRuleLanguageMapper.getMappedLanguage(sourceType)); 111 p.processFile(new StringReader (code), new RuleSets(rules), ctx, sourceType); 112 } 113 114 118 private String getCleanRuleName(Rule rule) { 119 String fullClassName = rule.getClass().getName(); 120 if (fullClassName.equals(rule.getName())) { 121 String packageName = rule.getClass().getPackage().getName(); 123 return fullClassName.substring(packageName.length()+1); 124 } else { 125 return rule.getName(); } 127 } 128 129 134 public TestDescriptor[] extractTestsFromXml(Rule rule) { 135 String testsFileName = getCleanRuleName(rule); 136 137 return extractTestsFromXml(rule, testsFileName); 138 } 139 140 145 public TestDescriptor[] extractTestsFromXml(Rule rule, String testsFileName) { 146 String testXmlFileName = "xml/" + testsFileName + ".xml"; 147 InputStream inputStream = getClass().getResourceAsStream(testXmlFileName); 148 if (inputStream == null) { 149 throw new RuntimeException ("Couldn't find " + testXmlFileName); 150 } 151 152 Document doc; 153 try { 154 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 155 doc = builder.parse(inputStream); 156 } catch (ParserConfigurationException pce) { 157 pce.printStackTrace(); 158 throw new RuntimeException ("Couldn't parse " + testXmlFileName + ", due to: " + pce.getMessage()); 159 } catch (FactoryConfigurationError fce) { 160 fce.printStackTrace(); 161 throw new RuntimeException ("Couldn't parse " + testXmlFileName + ", due to: " + fce.getMessage()); 162 } catch (IOException ioe) { 163 ioe.printStackTrace(); 164 throw new RuntimeException ("Couldn't parse " + testXmlFileName + ", due to: " + ioe.getMessage()); 165 } catch (SAXException se) { 166 se.printStackTrace(); 167 throw new RuntimeException ("Couldn't parse " + testXmlFileName + ", due to: " + se.getMessage()); 168 } 169 170 return parseTests(rule, doc); 171 } 172 173 private TestDescriptor[] parseTests(Rule rule, Document doc) { 174 Element root = doc.getDocumentElement(); 175 NodeList testCodes = root.getElementsByTagName("test-code"); 176 177 TestDescriptor[] tests = new TestDescriptor[testCodes.getLength()]; 178 for (int i = 0; i < testCodes.getLength(); i++) { 179 Element testCode = (Element )testCodes.item(i); 180 181 boolean reinitializeRule = false; 182 Node reinitializeRuleAttribute = testCode.getAttributes().getNamedItem("reinitializeRule"); 183 if (reinitializeRuleAttribute != null) { 184 String reinitializeRuleValue = reinitializeRuleAttribute.getNodeValue(); 185 if ("true".equalsIgnoreCase(reinitializeRuleValue) || 186 "1".equalsIgnoreCase(reinitializeRuleValue)) { 187 reinitializeRule = true; 188 } 189 } 190 191 NodeList ruleProperties = testCode.getElementsByTagName("rule-property"); 192 Properties properties = new Properties (); 193 for (int j = 0; j < ruleProperties.getLength(); j++) { 194 Node ruleProperty = ruleProperties.item(j); 195 String propertyName = ruleProperty.getAttributes().getNamedItem("name").getNodeValue(); 196 properties.setProperty(propertyName, parseTextNode(ruleProperty)); 197 } 198 int expectedProblems = Integer.parseInt(getNodeValue(testCode, "expected-problems", true)); 199 String description = getNodeValue(testCode, "description", true); 200 String code = getNodeValue(testCode, "code", false); 201 if (code == null) { 202 NodeList coderefs = testCode.getElementsByTagName("code-ref"); 204 if (coderefs.getLength()==0) { 205 throw new RuntimeException ("Required tag is missing from the test-xml. Supply either a code or a code-ref tag"); 206 } 207 Node coderef = coderefs.item(0); 208 String referenceId = coderef.getAttributes().getNamedItem("id").getNodeValue(); 209 NodeList codeFragments = root.getElementsByTagName("code-fragment"); 210 for (int j = 0; j < codeFragments.getLength(); j++) { 211 String fragmentId = codeFragments.item(j).getAttributes().getNamedItem("id").getNodeValue(); 212 if (referenceId.equals(fragmentId)) { 213 code = parseTextNode(codeFragments.item(j)); 214 } 215 } 216 217 if (code==null) { 218 throw new RuntimeException ("No matching code fragment found for coderef"); 219 } 220 } 221 222 String sourceTypeString = getNodeValue(testCode, "source-type", false); 223 if (sourceTypeString == null) { 224 tests[i] = new TestDescriptor(code, description, expectedProblems, rule); 225 } else { 226 SourceType sourceType = SourceType.getSourceTypeForId(sourceTypeString); 227 if (sourceType != null) { 228 tests[i] = new TestDescriptor(code, description, expectedProblems, rule, sourceType); 229 } else { 230 throw new RuntimeException ("Unknown sourceType for test: " + sourceTypeString); 231 } 232 } 233 tests[i].setReinitializeRule(reinitializeRule); 234 tests[i].setProperties(properties); 235 } 236 return tests; 237 } 238 239 private String getNodeValue(Element parentElm, String nodeName, boolean required) { 240 NodeList nodes = parentElm.getElementsByTagName(nodeName); 241 if (nodes == null || nodes.getLength() == 0) { 242 if (required) { 243 throw new RuntimeException ("Required tag is missing from the test-xml: " + nodeName); 244 } else { 245 return null; 246 } 247 } 248 Node node = nodes.item(0); 249 return parseTextNode(node); 250 } 251 252 private static String parseTextNode(Node exampleNode) { 253 StringBuffer buffer = new StringBuffer (); 254 for (int i = 0; i < exampleNode.getChildNodes().getLength(); i++) { 255 Node node = exampleNode.getChildNodes().item(i); 256 if (node.getNodeType() == Node.CDATA_SECTION_NODE 257 || node.getNodeType() == Node.TEXT_NODE) { 258 buffer.append(node.getNodeValue()); 259 } 260 } 261 return buffer.toString().trim(); 262 } 263 264 268 public void runTestFromString(String code, Rule rule, Report report) throws PMDException { 269 runTestFromString(code, rule, report, DEFAULT_SOURCE_TYPE); 270 } 271 } 272 | Popular Tags |