1 package test.net.sourceforge.pmd.stat;
2
3 import junit.framework.AssertionFailedError;
4 import junit.framework.TestCase;
5 import net.sourceforge.pmd.Report;
6 import net.sourceforge.pmd.Rule;
7 import net.sourceforge.pmd.RuleContext;
8 import net.sourceforge.pmd.stat.DataPoint;
9 import net.sourceforge.pmd.stat.Metric;
10 import net.sourceforge.pmd.stat.StatisticalRule;
11
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Random;
17
18 /***
19 * This class tests the Statistical Rules in PMD.
20 *
21 * The idea is, that we fill up 999 datapoints into
22 * the Stat Rule, and then throw random parameters
23 * at it.
24 *
25 * The three parameters which are checked are:
26 * sigma - # Sigmas over the mean.
27 * topscore - Only the top 5 or so items.
28 * minimum - Only things of score 10 or better
29 *
30 * When more than one parameter is lumped together, then
31 * we expect the one which would return the fewest to
32 * determine what gets sent back.
33 *
34 * So, we throw each collection of parameters, where each
35 * one is a different order into the system. We check the
36 * results off of what the smallest value should be.
37 *
38 * If you are going to work with StatisticalRule any, please
39 * bump the "NUM_TESTS" number up to something like 128. That
40 * way you are more likely to identify problems. It is set low
41 * now to make building and running tests easier (when we aren't
42 * touching the file.)
43 *
44 * Note also, that when verifying the Sigma, I wasn't quite able
45 * to determine how many results it would return (it would vary
46 * from -2 to 2 of what I expected.) That is what the delta
47 * parameter on the verify method takes. If you can figure it
48 * out exactly, (without stealing code from the StatRule) then
49 * feel free to change it and tighten the deltas.
50 */
51 public class StatisticalRuleTest extends TestCase {
52
53 private static final int POINTS = 100;
54
55 private DataPoint points[] = new DataPoint[POINTS];
56 private MockStatisticalRule IUT = null;
57 private String testName = null;
58 private Random random = new Random();
59
60 public static final double MAX_MINIMUM = POINTS;
61 public static final double NO_MINIMUM = -1.0;
62 public static final double MAX_SIGMA = 5.0;
63 public static final double NO_SIGMA = -1.0;
64 public static final int MIN_TOPSCORE = 0;
65 public static final int NO_TOPSCORE = -1;
66
67
68 public static final double MEAN = 49.5;
69 public static final double SIGMA = 29.0115;
70 public static final int NUM_TESTS = 1;
71
72 public static final double DELTA = 0.005;
73
74 public StatisticalRuleTest(String name) {
75 super(name);
76 this.testName = name;
77 }
78
79 public void setUp() {
80 IUT = new MockStatisticalRule();
81 if (testName.endsWith("0")) {
82 for (int i = 0; i < POINTS; i++) {
83 points[i] = new DataPoint();
84 points[i].setScore(1.0 * i);
85 points[i].setLineNumber(i);
86 points[i].setMessage("DataPoint[" + Integer.toString(i) + "]");
87
88 IUT.addDataPoint(points[i]);
89 }
90 } else if (testName.endsWith("1")) {
91 for (int i = POINTS-1; i >= 0; i--) {
92 points[i] = new DataPoint();
93 points[i].setScore(1.0 * i);
94 points[i].setLineNumber(i);
95 points[i].setMessage("DataPoint[" + Integer.toString(i) + "]");
96
97 IUT.addDataPoint(points[i]);
98 }
99 } else {
100 List lPoints = new ArrayList();
101 for (int i = 0; i < POINTS; i++) {
102 DataPoint point = new DataPoint();
103 point.setScore(1.0 * i);
104 point.setLineNumber(i);
105 point.setMessage("DataPoint[" + Integer.toString(i) + "]");
106
107 lPoints.add(point);
108 }
109
110 Collections.shuffle(lPoints);
111 for (int i = 0; i < POINTS; i++) {
112 IUT.addDataPoint((DataPoint) lPoints.get(i));
113 }
114 }
115
116 }
117
118 /***
119 * This test verifies that the Stat rule creates a Metric,
120 * with the proper values.
121 */
122 public void testMetrics() throws Throwable {
123 Report report = makeReport(IUT);
124 Iterator metrics = report.metrics();
125
126 assertTrue(metrics.hasNext());
127 Object o = metrics.next();
128
129 assertTrue(o instanceof Metric);
130 Metric m = (Metric) o;
131
132 assertEquals("test.net.sourceforge.pmd.stat.MockStatisticalRule", m.getMetricName());
133
134 assertEquals(0.0, m.getLowValue(), 0.05);
135 assertEquals(POINTS -1.0, m.getHighValue(), 0.05);
136 assertEquals(MEAN, m.getAverage(), 0.05);
137 assertEquals(SIGMA, m.getStandardDeviation(), 0.05);
138 }
139
140 /***
141 * This returns a Random value for Sigma which will
142 * return some values.
143 */
144 public double randomSigma() {
145 return random.nextDouble() * 1.0;
146 }
147
148 /***
149 * This returns a Random value for Sigma which value
150 * is greater than the parameter.
151 */
152 public double randomSigma(int minimum) {
153 double minSigma = ((POINTS -1 - minimum) - MEAN) / SIGMA;
154
155 if ((minSigma <= 0) || (minSigma > 2))
156 return randomSigma();
157
158 return minSigma + (random.nextDouble() * (2 - minSigma));
159 }
160
161 /***
162 * This returns the expected number of results when
163 * the Sigma rating is the smallest.
164 */
165 public int expectedSigma(double sigma) {
166 long expectedMin = Math.round(MEAN + (sigma * SIGMA));
167
168 if (((POINTS -1) - expectedMin) < 0)
169 return 0;
170 return (POINTS -1) - (int) expectedMin;
171 }
172
173 /***
174 * This generates a random minimum value for testing.
175 */
176 public double randomMinimum() {
177 return random.nextDouble() * (POINTS -1);
178 }
179
180 /***
181 * This generates a random minimum value for which fewer
182 * results would be returned.
183 */
184 public double randomMinimum(int minimum) {
185 double diffTarget = 1.0 * (POINTS -1 - minimum);
186 return (random.nextDouble() * minimum) + diffTarget;
187 }
188
189 /***
190 * This returns the expected number of reports.
191 *
192 * If the Minimum comes in at 521.569 then we expect
193 * 522, 523, ... 999 will pass.
194 */
195 public int expectedMinimum(double minimum) {
196 Double d = new Double(minimum);
197 return POINTS -1 - d.intValue();
198 }
199
200 public void testExpectedMinimum() {
201 for (int i = 0; i < POINTS -1; i++) {
202 assertEquals("Integer Min", POINTS -1 - i, expectedMinimum(i * 1.0));
203 assertEquals("Double Min", POINTS -1 - i, expectedMinimum((i * 1.0) + 0.5));
204 }
205 }
206
207 /***
208 * This returns a random value for Top Score.
209 */
210 public int randomTopScore() {
211 return random.nextInt(POINTS -1);
212 }
213
214 /***
215 * This will return a random value for the Top Score
216 * which will return more than the minimum provided.
217 */
218 public int randomTopScore(double target) {
219 if (target < 0)
220 return 0;
221
222 return random.nextInt((new Double(target)).intValue());
223 }
224
225 /***
226 * This will return the expected number of results
227 * with the given Top Score.
228 */
229 public int expectedTopScore(int target) {
230 return target;
231 }
232
233 // Test Single Datapoint
234 public void testSingleDatapoint() {
235 StatisticalRule IUT = new MockStatisticalRule();
236
237 DataPoint point = new DataPoint();
238 point.setScore(POINTS + 1.0);
239 point.setLineNumber(POINTS + 1);
240 point.setMessage("SingleDataPoint");
241
242 IUT.addProperty("minimum", Integer.toString(POINTS));
243
244 IUT.addDataPoint(point);
245
246 Report report = makeReport(IUT);
247
248 assertEquals("Expecting only one result.", 1, report.size());
249 }
250
251 // Okay, we have three properties we need to
252 // test in Combination:
253 // S = Sigma
254 // T = Top Score
255 // M = Minimum
256 //
257 // They are listed in decreasing order of what
258 // to expect.
259 //
260 // Thus testSM() should have the Sigma less than
261 // the minimum, so we expect the Minimum # of results.
262 //
263
264 public void testS() throws Throwable {
265 verifyResults(MAX_SIGMA, NO_MINIMUM, NO_TOPSCORE, 0, 2);
266
267 for (int i = 0; i < NUM_TESTS; i++) {
268 double sigma = randomSigma();
269 verifyResults(sigma, -1.0, -1, expectedSigma(sigma), 2);
270 }
271 }
272
273 public void testS1() throws Throwable {
274 testS();
275 }
276
277 public void testS2() throws Throwable {
278 testS();
279 }
280
281 public void testS3() throws Throwable {
282 testS();
283 }
284
285 public void testS4() throws Throwable {
286 testS();
287 }
288
289 public void testS5() throws Throwable {
290 testS();
291 }
292
293
294 public void testT() throws Throwable {
295 verifyResults(NO_SIGMA, NO_MINIMUM, MIN_TOPSCORE, 0, 0);
296
297 for (int i = 0; i < NUM_TESTS; i++) {
298 int topScore = randomTopScore();
299 verifyResults(-1.0, -1.0, topScore, expectedTopScore(topScore), 0);
300 }
301 }
302
303 public void testT1() throws Throwable {
304 testT();
305 }
306
307 public void testT2() throws Throwable {
308 testT();
309 }
310
311 public void testT3() throws Throwable {
312 testT();
313 }
314
315 public void testT4() throws Throwable {
316 testT();
317 }
318
319 public void testT5() throws Throwable {
320 testT();
321 }
322
323 public void testM() throws Throwable {
324 verifyResults(NO_SIGMA, MAX_MINIMUM, NO_TOPSCORE, 0, 0);
325
326 for (int i = 0; i < NUM_TESTS; i++) {
327 double minimum = randomMinimum();
328 verifyResults(-1.0, minimum, -1, expectedMinimum(minimum), 0);
329 }
330 }
331
332 public void testM1() throws Throwable {
333 testM();
334 }
335
336 public void testM2() throws Throwable {
337 testM();
338 }
339
340 public void testM3() throws Throwable {
341 testM();
342 }
343
344 public void testM4() throws Throwable {
345 testM();
346 }
347
348 public void testM5() throws Throwable {
349 testM();
350 }
351
352 public void testST() throws Throwable {
353 verifyResults(randomSigma(), NO_MINIMUM, MIN_TOPSCORE, 0, 0);
354
355 for (int i = 0; i < NUM_TESTS; i++) {
356 double sigma = randomSigma();
357 int topScore = randomTopScore(expectedSigma(sigma));
358
359 verifyResults(sigma, NO_MINIMUM, topScore, expectedTopScore(topScore), 0);
360 }
361 }
362
363 public void testST1() throws Throwable {
364 testST();
365 }
366
367 public void testST2() throws Throwable {
368 testST();
369 }
370
371 public void testST3() throws Throwable {
372 testST();
373 }
374
375 public void testST4() throws Throwable {
376 testST();
377 }
378
379 public void testST5() throws Throwable {
380 testST();
381 }
382
383 public void testTS() throws Throwable {
384 verifyResults(MAX_SIGMA, NO_MINIMUM, randomTopScore(), 0, 0);
385
386 for (int i = 0; i < NUM_TESTS; i++) {
387 int topScore = randomTopScore();
388 double sigma = randomSigma(expectedTopScore(topScore));
389
390 verifyResults(sigma, -1.0, topScore, expectedSigma(sigma), 2);
391 }
392 }
393
394 public void testTS1() throws Throwable {
395 testTS();
396 }
397
398 public void testTS2() throws Throwable {
399 testTS();
400 }
401
402 public void testTS3() throws Throwable {
403 testTS();
404 }
405
406 public void testTS4() throws Throwable {
407 testTS();
408 }
409
410 public void testTS5() throws Throwable {
411 testTS();
412 }
413
414 public void testSM() throws Throwable {
415 verifyResults(randomSigma(), MAX_MINIMUM, NO_TOPSCORE, 0, 0);
416 for (int i = 0; i < NUM_TESTS; i++) {
417 double sigma = randomSigma();
418 double minimum = randomMinimum(expectedSigma(sigma));
419
420 verifyResults(sigma, minimum, -1, expectedMinimum(minimum), 0);
421 }
422
423 }
424
425 public void testSM1() throws Throwable {
426 testSM();
427 }
428
429 public void testSM2() throws Throwable {
430 testSM();
431 }
432
433 public void testSM3() throws Throwable {
434 testSM();
435 }
436
437 public void testSM4() throws Throwable {
438 testSM();
439 }
440
441 public void testSM5() throws Throwable {
442 testSM();
443 }
444
445
446 public void testMS() throws Throwable {
447 verifyResults(MAX_SIGMA, randomMinimum(), NO_TOPSCORE, 0, 0);
448 for (int i = 0; i < NUM_TESTS; i++) {
449 double minimum = randomMinimum();
450 double sigma = randomSigma(expectedMinimum(minimum));
451
452 verifyResults(sigma, minimum, -1, expectedSigma(sigma), 2);
453 }
454 }
455
456 public void testMS1() throws Throwable {
457 testMS();
458 }
459
460 public void testMS2() throws Throwable {
461 testMS();
462 }
463
464 public void testMS3() throws Throwable {
465 testMS();
466 }
467
468 public void testMS4() throws Throwable {
469 testMS();
470 }
471
472 public void testMS5() throws Throwable {
473 testMS();
474 }
475
476
477 public void testTM() throws Throwable {
478 verifyResults(NO_SIGMA, MAX_MINIMUM, randomTopScore(), 0, 0);
479 for (int i = 0; i < NUM_TESTS; i++) {
480 int topScore = randomTopScore();
481 double minimum = randomMinimum(expectedTopScore(topScore));
482
483 verifyResults(NO_SIGMA, minimum, topScore, expectedMinimum(minimum), 0);
484 }
485 }
486
487 public void testTM1() throws Throwable {
488 testTM();
489 }
490
491 public void testTM2() throws Throwable {
492 testTM();
493 }
494
495 public void testTM3() throws Throwable {
496 testTM();
497 }
498
499 public void testTM4() throws Throwable {
500 testTM();
501 }
502
503 public void testTM5() throws Throwable {
504 testTM();
505 }
506
507
508 public void testMT() throws Throwable {
509 verifyResults(NO_SIGMA, randomMinimum(), MIN_TOPSCORE, 0, 0);
510 for (int i = 0; i < NUM_TESTS; i++) {
511 double minimum = randomMinimum();
512 int topScore = randomTopScore(expectedMinimum(minimum));
513
514 verifyResults(NO_SIGMA, minimum, topScore, expectedTopScore(topScore), 0);
515 }
516 }
517
518 public void testMT1() throws Throwable {
519 testMT();
520 }
521
522 public void testMT2() throws Throwable {
523 testMT();
524 }
525
526 public void testMT3() throws Throwable {
527 testMT();
528 }
529
530 public void testMT4() throws Throwable {
531 testMT();
532 }
533
534 public void testMT5() throws Throwable {
535 testMT();
536 }
537
538
539 public void testSTM() throws Throwable {
540 double sigma = randomSigma();
541 verifyResults(sigma, MAX_MINIMUM, randomTopScore(expectedSigma(sigma)), 0, 0);
542
543 for (int i = 0; i < NUM_TESTS; i++) {
544 sigma = randomSigma();
545 int topScore = randomTopScore(expectedSigma(sigma));
546 double minimum = randomMinimum(expectedTopScore(topScore));
547
548 verifyResults(sigma, minimum, topScore, expectedMinimum(minimum), 0);
549 }
550 }
551
552 public void testSTM1() throws Throwable {
553 testSTM();
554 }
555
556 public void testSTM2() throws Throwable {
557 testSTM();
558 }
559
560 public void testSTM3() throws Throwable {
561 testSTM();
562 }
563
564 public void testSTM4() throws Throwable {
565 testSTM();
566 }
567
568 public void testSTM5() throws Throwable {
569 testSTM();
570 }
571
572 public void testSMT() throws Throwable {
573 double sigma = randomSigma();
574 verifyResults(sigma, randomMinimum(expectedSigma(sigma)), MIN_TOPSCORE, 0, 0);
575
576 for (int i = 0; i < NUM_TESTS; i++) {
577 sigma = randomSigma();
578 double minimum = randomMinimum(expectedSigma(sigma));
579 int topScore = randomTopScore(expectedMinimum(minimum));
580
581 verifyResults(sigma, minimum, topScore, expectedTopScore(topScore), 0);
582 }
583 }
584
585 public void testSMT1() throws Throwable {
586 testSMT();
587 }
588
589 public void testSMT2() throws Throwable {
590 testSMT();
591 }
592
593 public void testSMT3() throws Throwable {
594 testSMT();
595 }
596
597 public void testSMT4() throws Throwable {
598 testSMT();
599 }
600
601 public void testSMT5() throws Throwable {
602 testSMT();
603 }
604
605 public void testTSM() throws Throwable {
606 int topScore = randomTopScore();
607 verifyResults(randomSigma(expectedTopScore(topScore)), MAX_MINIMUM, topScore, 0, 0);
608
609 for (int i = 0; i < NUM_TESTS; i++) {
610 topScore = randomTopScore();
611 double sigma = randomSigma(expectedTopScore(topScore));
612 double minimum = randomMinimum(expectedSigma(sigma));
613
614 verifyResults(sigma, minimum, topScore, expectedMinimum(minimum), 0);
615 }
616 }
617
618 public void testTSM1() throws Throwable {
619 testTSM();
620 }
621
622 public void testTSM2() throws Throwable {
623 testTSM();
624 }
625
626 public void testTSM3() throws Throwable {
627 testTSM();
628 }
629
630 public void testTSM4() throws Throwable {
631 testTSM();
632 }
633
634 public void testTSM5() throws Throwable {
635 testTSM();
636 }
637
638 public void testTMS() throws Throwable {
639 int topScore = randomTopScore();
640 verifyResults(MAX_SIGMA, randomMinimum(expectedTopScore(topScore)), topScore, 0, 0);
641
642 for (int i = 0; i < NUM_TESTS; i++) {
643 topScore = randomTopScore();
644 double minimum = randomMinimum(expectedTopScore(topScore));
645 double sigma = randomSigma(expectedMinimum(minimum));
646
647 verifyResults(sigma, minimum, topScore, expectedSigma(sigma), 2);
648 }
649 }
650
651 public void testTMS1() throws Throwable {
652 testTMS();
653 }
654
655 public void testTMS2() throws Throwable {
656 testTMS();
657 }
658
659 public void testTMS3() throws Throwable {
660 testTMS();
661 }
662
663 public void testTMS4() throws Throwable {
664 testTMS();
665 }
666
667 public void testTMS5() throws Throwable {
668 testTMS();
669 }
670
671 /***
672 * Verifies what happens when you pass these parameters
673 * into the thing. DELTA is the amount of error allowed.
674 * Usually DELTA is only used for Sigma, as we really can't
675 * calculate it exactly.
676 */
677
678 public void verifyResults(double sigma, double minimum, int topScore, int expected, int delta) {
679 try {
680 setUp();
681 if (sigma >= 0) {
682 IUT.addProperty("sigma", Double.toString(sigma));
683 }
684
685 if (minimum >= 0) {
686 IUT.addProperty("minimum", Double.toString(minimum));
687 }
688
689 if (topScore >= 0) {
690 IUT.addProperty("topscore", Integer.toString(topScore));
691 }
692
693 Report report = makeReport(IUT);
694 if (delta == 0) {
695 assertEquals("Unexpected number of results: sigma= " + Double.toString(sigma) + " min= " + Double.toString(minimum) + " topscore= " + Integer.toString(topScore), expected, report.size());
696 } else {
697 String assertStr = "Unexpected number of results: sigma= " + Double.toString(sigma) + " min= " + Double.toString(minimum) + " topscore= " + Integer.toString(topScore) + " expected= " + Integer.toString(expected) + " +/- " + Integer.toString(delta) + " actual-result= " + report.size();
698
699 assertTrue(assertStr, report.size() >= (expected - delta));
700 assertTrue(assertStr, report.size() <= (expected + delta));
701 }
702 } catch (AssertionFailedError afe) {
703 System.err.println("******** " + testName + " ***********");
704 if (sigma != NO_SIGMA) {
705 System.err.println("SIGMA: " + Double.toString(sigma) + " EXPECT: " + Integer.toString(expectedSigma(sigma)));
706 }
707
708 if (minimum != NO_MINIMUM) {
709 System.err.println("MIN: " + Double.toString(minimum) + " EXPECT: " + Integer.toString(expectedMinimum(minimum)));
710 }
711
712 if (topScore != NO_TOPSCORE) {
713 System.err.println("TOP: " + Integer.toString(topScore) + " EXPECT: " + Integer.toString(expectedTopScore(topScore)));
714 }
715
716 throw afe;
717
718 }
719 }
720
721 public Report makeReport(Rule IUT) {
722 List list = new ArrayList();
723 Report report = new Report();
724
725 RuleContext ctx = new RuleContext();
726 ctx.setReport(report);
727 ctx.setSourceCodeFilename(testName);
728
729 IUT.apply(list, ctx);
730
731 return report;
732 }
733 }
This page was automatically generated by Maven