View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.java.rule;
5    
6   import static org.junit.Assert.assertEquals;
7   
8   import java.io.StringReader;
9   import java.util.HashMap;
10  import java.util.List;
11  
12  import net.sourceforge.pmd.PMD;
13  import net.sourceforge.pmd.PropertyDescriptor;
14  import net.sourceforge.pmd.Report;
15  import net.sourceforge.pmd.RuleContext;
16  import net.sourceforge.pmd.RuleSet;
17  import net.sourceforge.pmd.RuleSets;
18  import net.sourceforge.pmd.RuleViolation;
19  import net.sourceforge.pmd.lang.Language;
20  import net.sourceforge.pmd.lang.LanguageVersion;
21  import net.sourceforge.pmd.lang.Parser;
22  import net.sourceforge.pmd.lang.ParserOptions;
23  import net.sourceforge.pmd.lang.ast.Node;
24  import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
25  import net.sourceforge.pmd.lang.rule.XPathRule;
26  import net.sourceforge.pmd.lang.rule.properties.StringProperty;
27  import net.sourceforge.pmd.lang.rule.xpath.JaxenXPathRuleQuery;
28  import net.sourceforge.pmd.lang.rule.xpath.SaxonXPathRuleQuery;
29  import net.sourceforge.pmd.lang.rule.xpath.XPathRuleQuery;
30  import net.sourceforge.pmd.testframework.RuleTst;
31  
32  import org.junit.Before;
33  import org.junit.Test;
34  
35   /**
36    * @author daniels
37    */
38   public class XPathRuleTest extends RuleTst {
39   
40       XPathRule rule;
41   
42       @Before
43       public void setUp() {
44           rule = new XPathRule();
45           rule.setLanguage(Language.JAVA);
46           rule.setMessage("XPath Rule Failed");
47       }
48   
49       @Test
50       public void testPluginname() throws Throwable {
51           rule.setXPath("//VariableDeclaratorId[string-length(@Image) < 3]");
52           rule.setMessage("{0}");
53           PMD p = new PMD();
54           RuleContext ctx = new RuleContext();
55           Report report = new Report();
56           ctx.setReport(report);
57           ctx.setSourceCodeFilename("n/a");
58           RuleSet rules = new RuleSet();
59           rules.addRule(rule);
60           p.getSourceCodeProcessor().processSourceCode(new StringReader(TEST1), new RuleSets(rules), ctx);
61           RuleViolation rv = report.iterator().next();
62           assertEquals("a", rv.getDescription());
63       }
64   
65       @Test
66       public void testVariables() throws Throwable {
67           rule.setXPath("//VariableDeclaratorId[@Image=$var]");
68           rule.setMessage("Avoid vars");
69           StringProperty varDescriptor = new StringProperty("var", "Test var", null, 1.0f);
70           rule.definePropertyDescriptor(varDescriptor);
71           rule.setProperty(varDescriptor, "fiddle");
72           PMD p = new PMD();
73           RuleContext ctx = new RuleContext();
74           Report report = new Report();
75           ctx.setReport(report);
76           ctx.setSourceCodeFilename("n/a");
77           RuleSet rules = new RuleSet();
78           rules.addRule(rule);
79           p.getSourceCodeProcessor().processSourceCode(new StringReader(TEST2), new RuleSets(rules), ctx);
80           RuleViolation rv = report.iterator().next();
81           assertEquals(3, rv.getBeginLine());
82       }
83  
84       /**
85        * Test for problem reported in bug #1219 PrimarySuffix/@Image does not work in some cases in xpath 2.0
86        * @throws Exception any error
87        */
88       @Test
89       public void testImageOfPrimarySuffix() throws Exception {
90           String SUFFIX = "import java.io.File;\n" + 
91                   "\n" + 
92                   "public class TestSuffix {\n" + 
93                   "    public static void main(String args[]) {\n" + 
94                   "        new File(\"subdirectory\").list();\n" + 
95                   "    }\n" + 
96                   "}";
97           LanguageVersion language = Language.JAVA.getDefaultVersion();
98           ParserOptions parserOptions = language.getLanguageVersionHandler().getDefaultParserOptions();
99           Parser parser = language.getLanguageVersionHandler().getParser(parserOptions);
100          ASTCompilationUnit cu = (ASTCompilationUnit)parser.parse("test", new StringReader(SUFFIX));
101          RuleContext ruleContext = new RuleContext();
102          ruleContext.setLanguageVersion(language);
103 
104          String xpath = "//PrimarySuffix[@Image='list']";
105 
106          // XPATH version 1.0
107          XPathRuleQuery xpathRuleQuery = new JaxenXPathRuleQuery();
108          xpathRuleQuery.setXPath(xpath);
109          xpathRuleQuery.setProperties(new HashMap<PropertyDescriptor<?>, Object>());
110          xpathRuleQuery.setVersion(XPathRuleQuery.XPATH_1_0);
111          List<Node> nodes = xpathRuleQuery.evaluate(cu, ruleContext);
112          assertEquals(1, nodes.size());
113 
114          // XPATH version 1.0 Compatibility
115          xpathRuleQuery = new SaxonXPathRuleQuery();
116          xpathRuleQuery.setXPath(xpath);
117          xpathRuleQuery.setProperties(new HashMap<PropertyDescriptor<?>, Object>());
118          xpathRuleQuery.setVersion(XPathRuleQuery.XPATH_1_0_COMPATIBILITY);
119          nodes = xpathRuleQuery.evaluate(cu, ruleContext);
120          assertEquals(1, nodes.size());
121 
122          // XPATH version 2.0
123          xpathRuleQuery = new SaxonXPathRuleQuery();
124          xpathRuleQuery.setXPath(xpath);
125          xpathRuleQuery.setProperties(new HashMap<PropertyDescriptor<?>, Object>());
126          xpathRuleQuery.setVersion(XPathRuleQuery.XPATH_2_0);
127          nodes = xpathRuleQuery.evaluate(cu, ruleContext);
128          assertEquals(1, nodes.size());
129      }
130 
131      /**
132       * Following sibling check: See https://sourceforge.net/p/pmd/bugs/1209/
133       * @throws Exception any error
134       */
135      @Test
136      public void testFollowingSibling() throws Exception {
137          String SOURCE = "public class dummy {\n" +
138                  "  public String toString() {\n" +
139                  "    String test = \"bad example\";\n" +
140                  "    test = \"a\";\n" +
141                  "    return test;\n" +
142                  "  }\n" +
143                  "}";
144          LanguageVersion language = Language.JAVA.getDefaultVersion();
145          ParserOptions parserOptions = language.getLanguageVersionHandler().getDefaultParserOptions();
146          Parser parser = language.getLanguageVersionHandler().getParser(parserOptions);
147          ASTCompilationUnit cu = (ASTCompilationUnit)parser.parse("test", new StringReader(SOURCE));
148          RuleContext ruleContext = new RuleContext();
149          ruleContext.setLanguageVersion(language);
150 
151          String xpath = "//Block/BlockStatement/following-sibling::BlockStatement";
152 
153          // XPATH version 1.0
154          XPathRuleQuery xpathRuleQuery = new JaxenXPathRuleQuery();
155          xpathRuleQuery.setXPath(xpath);
156          xpathRuleQuery.setProperties(new HashMap<PropertyDescriptor<?>, Object>());
157          xpathRuleQuery.setVersion(XPathRuleQuery.XPATH_1_0);
158          List<Node> nodes = xpathRuleQuery.evaluate(cu, ruleContext);
159          assertEquals(2, nodes.size());
160          assertEquals(4, nodes.get(0).getBeginLine());
161          assertEquals(5, nodes.get(1).getBeginLine());
162 
163          // XPATH version 2.0
164          xpathRuleQuery = new SaxonXPathRuleQuery();
165          xpathRuleQuery.setXPath(xpath);
166          xpathRuleQuery.setProperties(new HashMap<PropertyDescriptor<?>, Object>());
167          xpathRuleQuery.setVersion(XPathRuleQuery.XPATH_2_0);
168          nodes = xpathRuleQuery.evaluate(cu, ruleContext);
169          assertEquals(2, nodes.size());
170          assertEquals(4, nodes.get(0).getBeginLine());
171          assertEquals(5, nodes.get(1).getBeginLine());
172      }
173 
174      private static final String TEST1 =
175              "public class Foo {" + PMD.EOL +
176              " int a;" + PMD.EOL +
177              "}";
178  
179      private static final String TEST2 =
180              "public class Foo {" + PMD.EOL +
181              " int faddle;" + PMD.EOL +
182              " int fiddle;" + PMD.EOL +
183              "}";
184 
185      public static junit.framework.Test suite() {
186          return new junit.framework.JUnit4TestAdapter(XPathRuleTest.class);
187      }
188  }