1 package test.net.sourceforge.pmd;
2
3 import junit.framework.TestCase;
4 import net.sourceforge.pmd.Rule;
5 import net.sourceforge.pmd.RuleProperties;
6 import net.sourceforge.pmd.RuleSet;
7 import net.sourceforge.pmd.RuleSetWriter;
8 import net.sourceforge.pmd.cpd.CPD;
9
10 import java.io.ByteArrayInputStream;
11 import java.io.ByteArrayOutputStream;
12 import java.io.InputStream;
13 import java.io.StringBufferInputStream;
14 import java.util.Enumeration;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 import java.util.Map;
18 import java.util.Set;
19
20
21 /***
22 * A test for reading and writing a rule set file. The registered rule sets
23 *
24 * @author Donald A. Leckie
25 * @since August 30, 2002
26 * @version $Revision: 1.17 $, $Date: 2003/05/12 16:57:39 $
27 */
28 public class RuleSetReadWriteTest extends TestCase {
29 private InputStream m_inputStream;
30 private RuleSet m_ruleSetIn;
31 private RuleSet m_ruleSetOut;
32
33 /***
34 ********************************************************************************
35 *
36 */
37 public RuleSetReadWriteTest() {
38 super("Rule Set Read/Write Test");
39 }
40
41 /***
42 ********************************************************************************
43 *
44 */
45 public void testReadWrite() {
46 /*
47 try {
48 loadTestFile();
49 m_ruleSetIn = (new RuleSetReader()).read(m_inputStream, "foo");
50 write();
51 m_ruleSetOut = (new RuleSetReader()).read(m_inputStream, "foo");
52 compare();
53 } catch (PMDException pmdException) {
54 pmdException.printStackTrace();
55 }
56 */
57 }
58
59 /***
60 ********************************************************************************
61 *
62 */
63 private void loadTestFile() {
64 m_inputStream = new StringBufferInputStream(TEST1);
65 }
66
67 /***
68 ********************************************************************************
69 *
70 */
71 private void write() {
72 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
73
74 (new RuleSetWriter(outputStream)).write(m_ruleSetIn);
75
76 m_inputStream = new ByteArrayInputStream(outputStream.toByteArray());
77 }
78
79 /***
80 ********************************************************************************
81 *
82 */
83 private void compare() {
84 assertEquals("Rule set names are equal.", m_ruleSetIn.getName(), m_ruleSetOut.getName());
85 //assertEquals("Rule set descriptions are equal.", m_ruleSetIn.getDescription(), m_ruleSetOut.getDescription());
86
87 Set rulesIn = m_ruleSetIn.getRules();
88 Set rulesOut = m_ruleSetOut.getRules();
89 int rulesInCount = rulesIn.size();
90 int rulesOutCount = rulesOut.size();
91
92 assertEquals("Rule counts are equal.", rulesInCount, rulesOutCount);
93
94 Rule[] rulesOutArray = new Rule[rulesOutCount];
95
96 rulesOut.toArray(rulesOutArray);
97
98 Map rulesOutMap = new HashMap((int) (rulesInCount / 0.75));
99
100 for (int n = 0; n < rulesOutCount; n++) {
101 String key = rulesOutArray[n].getName();
102
103 rulesOutMap.put(key, rulesOutArray[n]);
104 }
105
106 Iterator iterator = rulesIn.iterator();
107
108 while (iterator.hasNext()) {
109 Rule ruleIn = (Rule) iterator.next();
110 String key = ruleIn.getName();
111 Rule ruleOut = (Rule) rulesOutMap.get(key);
112
113 assertNotNull("\"" + key + "\" exists in output rules.", ruleOut);
114
115 if (ruleOut != null) {
116 assertEquals("Rule messages are equal.", ruleIn.getMessage(), ruleOut.getMessage());
117 assertEquals("Rule class are equal.", ruleIn.getClass().getName(), ruleOut.getClass().getName());
118 assertEquals("Rule includes are equal.", ruleIn.include(), ruleOut.include());
119 // assertEquals("Rule descriptions are equal.", ruleIn.getDescription(), ruleOut.getDescription());
120 assertEquals("Rule examples are equal.", ruleIn.getExample(), ruleOut.getExample());
121
122 RuleProperties propertiesIn = ruleIn.getProperties();
123 RuleProperties propertiesOut = ruleOut.getProperties();
124
125 assertEquals("Properties counts are equal.", propertiesIn.size(), propertiesOut.size());
126
127 Enumeration property = propertiesIn.keys();
128
129 while (property.hasMoreElements()) {
130 String propertyName = (String) property.nextElement();
131 String propertyInValue = propertiesIn.getValue(propertyName);
132 String propertyOutValue = propertiesOut.getValue(propertyName);
133
134 assertNotNull("\"" + propertyName + "\" exists in output rule properties.", propertyOutValue);
135
136 String msg = "Rule property \"" + propertyName + "\" values are equal.";
137
138 assertEquals(msg, propertyInValue, propertyOutValue);
139
140 String propertyInValueType = propertiesIn.getValueType(propertyName);
141 String propertyOutValueType = propertiesOut.getValueType(propertyName);
142
143 assertNotNull("\"" + propertyName + "\" exists in output rule properties.", propertyOutValueType);
144
145 msg = "Rule property \"" + propertyName + "\" value types are equal.";
146
147 assertEquals(msg, propertyInValueType, propertyOutValueType);
148 }
149 }
150 }
151 }
152
153 /***
154 ********************************************************************************
155 *
156 * @param args
157 */
158 public static void main(String[] args) {
159 (new RuleSetReadWriteTest()).testReadWrite();
160 }
161
162 private static final String TEST1 =
163 "<?xml version=\"1.0\"?>" + CPD.EOL +
164 "<ruleset name=\"Basic Rules\">" + CPD.EOL +
165 " <description>" + CPD.EOL +
166 "The Basic Ruleset contains a collection of good practice rules which everyone should follow." + CPD.EOL +
167 " </description>" + CPD.EOL +
168 " <rule name=\"EmptyCatchBlock\"" + CPD.EOL +
169 " message=\"Avoid empty catch blocks\"" + CPD.EOL +
170 " class=\"net.sourceforge.pmd.rules.EmptyCatchBlockRule\">" + CPD.EOL +
171 " <description>" + CPD.EOL +
172 "Empty Catch Block finds instances where an exception is caught," + CPD.EOL +
173 "but nothing is done. In most circumstances, this swallows an exception" + CPD.EOL +
174 "which should either be acted on or reported." + CPD.EOL +
175 " </description>" + CPD.EOL +
176 " <example>" + CPD.EOL +
177 "<![CDATA[" + CPD.EOL +
178 " public void doSomething() {" + CPD.EOL +
179 " try {" + CPD.EOL +
180 " FileInputStream fis = new FileInputStream(\"/tmp/bugger\");" + CPD.EOL +
181 " } catch (IOException ioe) {" + CPD.EOL +
182 " // not good" + CPD.EOL +
183 " }" + CPD.EOL +
184 " }" + CPD.EOL +
185 "]]>" + CPD.EOL +
186 " </example>" + CPD.EOL +
187 " </rule>" + CPD.EOL +
188 " <rule name=\"EmptyIfStmt\"" + CPD.EOL +
189 " message=\"Avoid empty 'if' statements\"" + CPD.EOL +
190 " class=\"net.sourceforge.pmd.rules.EmptyIfStmtRule\">" + CPD.EOL +
191 " <description>" + CPD.EOL +
192 "Empty If Statement finds instances where a condition is checked but nothing is done about it." + CPD.EOL +
193 " </description>" + CPD.EOL +
194 " <example>" + CPD.EOL +
195 "<![CDATA[" + CPD.EOL +
196 " if (absValue < 1) {" + CPD.EOL +
197 " // not good" + CPD.EOL +
198 " }" + CPD.EOL +
199 "]]>" + CPD.EOL +
200 " </example>" + CPD.EOL +
201 " </rule>" + CPD.EOL +
202 " <rule name=\"EmptyWhileStmt\"" + CPD.EOL +
203 " message=\"Avoid empty 'while' statements\"" + CPD.EOL +
204 " class=\"net.sourceforge.pmd.rules.EmptyWhileStmtRule\">" + CPD.EOL +
205 " <description>" + CPD.EOL +
206 "Empty While Statement finds all instances where a while statement" + CPD.EOL +
207 "does nothing. If it is a timing loop, then you should use Thread.sleep() for it; if" + CPD.EOL +
208 "it's a while loop that does a lot in the exit expression, rewrite it to make it clearer." + CPD.EOL +
209 " </description>" + CPD.EOL +
210 " <example>" + CPD.EOL +
211 "<![CDATA[" + CPD.EOL +
212 "while (a == b) {" + CPD.EOL +
213 " // not good" + CPD.EOL +
214 "}" + CPD.EOL +
215 "]]>" + CPD.EOL +
216 " </example>" + CPD.EOL +
217 " </rule>" + CPD.EOL +
218 " <rule name=\"IfElseStmtsMustUseBracesRule\"" + CPD.EOL +
219 " message=\"Avoid using 'if...else' statements without curly braces\"" + CPD.EOL +
220 " class=\"net.sourceforge.pmd.rules.IfElseStmtsMustUseBracesRule\">" + CPD.EOL +
221 " <description>" + CPD.EOL +
222 " Avoid using if..else statements without using curly braces" + CPD.EOL +
223 " </description>" + CPD.EOL +
224 " <example>" + CPD.EOL +
225 "<![CDATA[" + CPD.EOL +
226 " public void doSomething() {" + CPD.EOL +
227 " // this is OK" + CPD.EOL +
228 " if (foo) x++;" + CPD.EOL +
229 "" + CPD.EOL +
230 " // but this is not" + CPD.EOL +
231 " if (foo)" + CPD.EOL +
232 " x=x+1;" + CPD.EOL +
233 " else" + CPD.EOL +
234 " x=x-1;" + CPD.EOL +
235 " }" + CPD.EOL +
236 "]]>" + CPD.EOL +
237 " </example>" + CPD.EOL +
238 " </rule>" + CPD.EOL +
239 " <rule name=\"UnnecessaryConversionTemporaryRule\"" + CPD.EOL +
240 " message=\"Avoid unnecessary temporaries when converting primitives to Strings\"" + CPD.EOL +
241 " class=\"net.sourceforge.pmd.rules.UnnecessaryConversionTemporaryRule\">" + CPD.EOL +
242 " <description>" + CPD.EOL +
243 " Avoid unnecessary temporaries when converting primitives to Strings" + CPD.EOL +
244 " </description>" + CPD.EOL +
245 " <example>" + CPD.EOL +
246 "<![CDATA[" + CPD.EOL +
247 " public String convert(int x) {" + CPD.EOL +
248 " // this wastes an object" + CPD.EOL +
249 " String foo = new Integer(x).toString();" + CPD.EOL +
250 " // this is better" + CPD.EOL +
251 " return Integer.toString(x);" + CPD.EOL +
252 " }" + CPD.EOL +
253 "]]>" + CPD.EOL +
254 " </example>" + CPD.EOL +
255 " </rule>" + CPD.EOL +
256 " <rule name=\"OverrideBothEqualsAndHashcodeRule\"" + CPD.EOL +
257 " message=\"Ensure you override both equals() and hashCode()\"" + CPD.EOL +
258 " class=\"net.sourceforge.pmd.rules.OverrideBothEqualsAndHashcodeRule\">" + CPD.EOL +
259 " <description>" + CPD.EOL +
260 "Override both public boolean Object.equals(Object other), and public int Object.hashCode(), or override neither. Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly delegating to your superclass." + CPD.EOL +
261 " </description>" + CPD.EOL +
262 " <example>" + CPD.EOL +
263 "<![CDATA[" + CPD.EOL +
264 "// this is bad" + CPD.EOL +
265 "public class Bar {" + CPD.EOL +
266 " public boolean equals(Object o) {" + CPD.EOL +
267 " // do some comparison" + CPD.EOL +
268 " }" + CPD.EOL +
269 "}" + CPD.EOL +
270 "// and so is this" + CPD.EOL +
271 "public class Baz {" + CPD.EOL +
272 " public int hashCode() {" + CPD.EOL +
273 " // return some hash value" + CPD.EOL +
274 " }" + CPD.EOL +
275 "}" + CPD.EOL +
276 "// this is OK" + CPD.EOL +
277 "public class Foo {" + CPD.EOL +
278 " public boolean equals(Object other) {" + CPD.EOL +
279 " // do some comparison" + CPD.EOL +
280 " }" + CPD.EOL +
281 " public int hashCode() {" + CPD.EOL +
282 " // return some hash value" + CPD.EOL +
283 " }" + CPD.EOL +
284 "}" + CPD.EOL +
285 "]]>" + CPD.EOL +
286 " </example>" + CPD.EOL +
287 " </rule>" + CPD.EOL +
288 " <rule name=\"EmptyTryBlock\"" + CPD.EOL +
289 " message=\"Avoid empty try blocks\"" + CPD.EOL +
290 " class=\"net.sourceforge.pmd.rules.EmptyTryBlockRule\">" + CPD.EOL +
291 " <description>" + CPD.EOL +
292 "Avoid empty try blocks - what's the point?" + CPD.EOL +
293 " </description>" + CPD.EOL +
294 " <example>" + CPD.EOL +
295 "<![CDATA[" + CPD.EOL +
296 "// this is bad" + CPD.EOL +
297 "public void bar() {" + CPD.EOL +
298 " try {" + CPD.EOL +
299 " } catch (Exception e) {" + CPD.EOL +
300 " e.printStackTrace();" + CPD.EOL +
301 " }" + CPD.EOL +
302 "}" + CPD.EOL +
303 "]]>" + CPD.EOL +
304 " </example>" + CPD.EOL +
305 " </rule>" + CPD.EOL +
306 " <rule name=\"EmptyFinallyBlock\"" + CPD.EOL +
307 " message=\"Avoid empty finally blocks\"" + CPD.EOL +
308 " class=\"net.sourceforge.pmd.rules.EmptyFinallyBlockRule\">" + CPD.EOL +
309 " <description>" + CPD.EOL +
310 "Avoid empty finally blocks - these can be deleted." + CPD.EOL +
311 " </description>" + CPD.EOL +
312 "" + CPD.EOL +
313 " <example>" + CPD.EOL +
314 "<![CDATA[" + CPD.EOL +
315 "// this is bad" + CPD.EOL +
316 "public void bar() {" + CPD.EOL +
317 " try {" + CPD.EOL +
318 " int x=2;" + CPD.EOL +
319 " } finally {" + CPD.EOL +
320 " }" + CPD.EOL +
321 "}" + CPD.EOL +
322 "]]>" + CPD.EOL +
323 " </example>" + CPD.EOL +
324 " </rule>" + CPD.EOL +
325 " <rule name=\"WhileLoopsMustUseBracesRule\"" + CPD.EOL +
326 " message=\"Avoid using 'while' statements without curly braces\"" + CPD.EOL +
327 " class=\"net.sourceforge.pmd.rules.WhileLoopsMustUseBracesRule\">" + CPD.EOL +
328 " <description>" + CPD.EOL +
329 " Avoid using 'while' statements without using curly braces" + CPD.EOL +
330 " </description>" + CPD.EOL +
331 "" + CPD.EOL +
332 " <example>" + CPD.EOL +
333 "<![CDATA[" + CPD.EOL +
334 " public void doSomething() {" + CPD.EOL +
335 " while (true)" + CPD.EOL +
336 " x++;" + CPD.EOL +
337 " }" + CPD.EOL +
338 "]]>" + CPD.EOL +
339 " </example>" + CPD.EOL +
340 " </rule>" + CPD.EOL +
341 " <rule name=\"ForLoopsMustUseBracesRule\"" + CPD.EOL +
342 " message=\"Avoid using 'for' statements without curly braces\"" + CPD.EOL +
343 " class=\"net.sourceforge.pmd.rules.ForLoopsMustUseBracesRule\">" + CPD.EOL +
344 " <description>" + CPD.EOL +
345 " Avoid using 'for' statements without using curly braces" + CPD.EOL +
346 " </description>" + CPD.EOL +
347 " <example>" + CPD.EOL +
348 "<![CDATA[" + CPD.EOL +
349 " public void foo() {" + CPD.EOL +
350 " for (int i=0; i<42;i++)" + CPD.EOL +
351 " foo();" + CPD.EOL +
352 " }" + CPD.EOL +
353 "]]>" + CPD.EOL +
354 " </example>" + CPD.EOL +
355 " </rule>" + CPD.EOL +
356 " </ruleset>" + CPD.EOL +
357 "";
358
359 }
This page was automatically generated by Maven