View Javadoc

1   /**
2    * <copyright>
3    *  Copyright 1997-2002 BBNT Solutions, LLC
4    *  under sponsorship of the Defense Advanced Research Projects Agency (DARPA).
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the Cougaar Open Source License as published by
8    *  DARPA on the Cougaar Open Source Website (www.cougaar.org).
9    *
10   *  THE COUGAAR SOFTWARE AND ANY DERIVATIVE SUPPLIED BY LICENSOR IS
11   *  PROVIDED 'AS IS' WITHOUT WARRANTIES OF ANY KIND, WHETHER EXPRESS OR
12   *  IMPLIED, INCLUDING (BUT NOT LIMITED TO) ALL IMPLIED WARRANTIES OF
13   *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND WITHOUT
14   *  ANY WARRANTIES AS TO NON-INFRINGEMENT.  IN NO EVENT SHALL COPYRIGHT
15   *  HOLDER BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT OR CONSEQUENTIAL
16   *  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE OF DATA OR PROFITS,
17   *  TORTIOUS CONDUCT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18   *  PERFORMANCE OF THE COUGAAR SOFTWARE.
19   * </copyright>
20   *
21   * Created on Aug 26, 2002
22   */
23  package net.sourceforge.pmd.stat;
24  
25  import static net.sourceforge.pmd.lang.rule.stat.StatisticalRule.MINIMUM_DESCRIPTOR;
26  import static net.sourceforge.pmd.lang.rule.stat.StatisticalRule.SIGMA_DESCRIPTOR;
27  import static net.sourceforge.pmd.lang.rule.stat.StatisticalRule.TOP_SCORE_DESCRIPTOR;
28  import static org.junit.Assert.assertEquals;
29  import static org.junit.Assert.assertTrue;
30  
31  import java.util.ArrayList;
32  import java.util.Collections;
33  import java.util.Iterator;
34  import java.util.List;
35  import java.util.Random;
36  
37  import junit.framework.AssertionFailedError;
38  import net.sourceforge.pmd.Report;
39  import net.sourceforge.pmd.Rule;
40  import net.sourceforge.pmd.RuleContext;
41  import net.sourceforge.pmd.lang.Language;
42  import net.sourceforge.pmd.lang.java.ast.DummyJavaNode;
43  import net.sourceforge.pmd.lang.java.symboltable.SourceFileScope;
44  import net.sourceforge.pmd.lang.rule.stat.StatisticalRule;
45  
46  import org.junit.Before;
47  import org.junit.Ignore;
48  import org.junit.Test;
49  
50  /**
51   * This class tests the Statistical Rules in PMD.
52   * <p/>
53   * The idea is, that we fill up 999 datapoints into
54   * the Stat Rule, and then throw random parameters
55   * at it.
56   * <p/>
57   * The three parameters which are checked are:
58   * sigma - # Sigmas over the mean.
59   * topscore - Only the top 5 or so items.
60   * minimum - Only things of score 10 or better
61   * <p/>
62   * When more than one parameter is lumped together, then
63   * we expect the one which would return the fewest to
64   * determine what gets sent back.
65   * <p/>
66   * So, we throw each collection of parameters, where each
67   * one is a different order into the system.  We check the
68   * results off of what the smallest value should be.
69   * <p/>
70   * If you are going to work with StatisticalRule any, please
71   * bump the "NUM_TESTS" number up to something like 128.  That
72   * way you are more likely to identify problems.  It is set low
73   * now to make building and running tests easier (when we aren't
74   * touching the file.)
75   * <p/>
76   * Note also, that when verifying the Sigma, I wasn't quite able
77   * to determine how many results it would return (it would vary
78   * from -2 to 2 of what I expected.)  That is what the delta
79   * parameter on the verify method takes.  If you can figure it
80   * out exactly, (without stealing code from the StatRule) then
81   * feel free to change it and tighten the deltas.
82   */
83  public class StatisticalRuleTest  {
84  
85      private static final int POINTS = 100;
86  
87      private DataPoint[] points = new DataPoint[POINTS];
88      private MockStatisticalRule IUT = null;
89      private String testName = "";//FIXME - why/when was this added. It was never set.
90      private Random random = new Random();
91  
92      public static final double MAX_MINIMUM = POINTS;
93      public static final double NO_MINIMUM = -1.0;
94      public static final double MAX_SIGMA = 5.0;
95      public static final double NO_SIGMA = -1.0;
96      public static final int MIN_TOPSCORE = 0;
97      public static final int NO_TOPSCORE = -1;
98  
99  
100     public static final double MEAN = 49.5;
101     public static final double SIGMA = 29.0115;
102     public static final int NUM_TESTS = 1;
103 
104     public static final double DELTA = 0.005;
105 
106 
107     @Before
108     public void setUp() {
109         IUT = new MockStatisticalRule();
110         if (testName.endsWith("0")) {
111             for (int i = 0; i < POINTS; i++) {
112                 points[i] = new DataPoint();
113                 points[i].setScore(1.0 * i);
114                 DummyJavaNode s = new DummyJavaNode(1);
115                 s.setScope(new SourceFileScope("foo"));
116                 s.testingOnly__setBeginLine(i);
117                 s.testingOnly__setBeginColumn(1);
118                 points[i].setNode(s);
119                 points[i].setMessage("DataPoint[" + Integer.toString(i) + "]");
120 
121                 IUT.addDataPoint(points[i]);
122             }
123         } else if (testName.endsWith("1")) {
124             for (int i = POINTS - 1; i >= 0; i--) {
125                 points[i] = new DataPoint();
126                 points[i].setScore(1.0 * i);
127                 DummyJavaNode s = new DummyJavaNode(1);
128                 s.setScope(new SourceFileScope("foo"));
129                 s.testingOnly__setBeginLine(i);
130                 s.testingOnly__setBeginColumn(1);
131                 points[i].setNode(s);
132                 points[i].setMessage("DataPoint[" + Integer.toString(i) + "]");
133 
134                 IUT.addDataPoint(points[i]);
135             }
136         } else {
137             List<DataPoint> lPoints = new ArrayList<DataPoint>();
138             for (int i = 0; i < POINTS; i++) {
139                 points[i] = new DataPoint();
140                 points[i].setScore(1.0 * i);
141                 DummyJavaNode s = new DummyJavaNode(1);
142                 s.setScope(new SourceFileScope("foo"));
143                 s.testingOnly__setBeginLine(i);
144                 s.testingOnly__setBeginColumn(1);
145                 s.testingOnly__setBeginColumn(1);
146                 points[i].setNode(s);
147                 points[i].setMessage("DataPoint[" + Integer.toString(i) + "]");
148 
149                 lPoints.add(points[i]);
150             }
151 
152             Collections.shuffle(lPoints);
153             for (int i = 0; i < POINTS; i++) {
154                 IUT.addDataPoint(lPoints.get(i));
155             }
156         }
157 
158     }
159 
160     /**
161      * This test verifies that the Stat rule creates a Metric,
162      * with the proper values.
163      */
164     @Test
165     public void testMetrics() throws Throwable {
166         Report report = makeReport(IUT);
167         Iterator metrics = report.metrics();
168 
169         assertTrue(metrics.hasNext());
170         Object o = metrics.next();
171 
172         assertTrue(o instanceof Metric);
173         Metric m = (Metric) o;
174 
175         assertEquals("net.sourceforge.pmd.stat.MockStatisticalRule", m.getMetricName());
176 
177         assertEquals(0.0, m.getLowValue(), 0.05);
178         assertEquals(POINTS - 1.0, m.getHighValue(), 0.05);
179         assertEquals(MEAN, m.getAverage(), 0.05);
180         assertEquals(SIGMA, m.getStandardDeviation(), 0.05);
181     }
182 
183     /**
184      * This returns a Random value for Sigma which will
185      * return some values.
186      */
187     public double randomSigma() {
188         return random.nextDouble() * 1.0;
189     }
190 
191     /**
192      * This returns a Random value for Sigma which value
193      * is greater than the parameter.
194      */
195     public double randomSigma(int minimum) {
196         double minSigma = ((POINTS - 1 - minimum) - MEAN) / SIGMA;
197 
198         if ((minSigma <= 0) || (minSigma > 2))
199             return randomSigma();
200 
201         return minSigma + (random.nextDouble() * (2 - minSigma));
202     }
203 
204     /**
205      * This returns the expected number of results when
206      * the Sigma rating is the smallest.
207      */
208     public int expectedSigma(double sigma) {
209         long expectedMin = Math.round(MEAN + (sigma * SIGMA));
210 
211         if (((POINTS - 1) - expectedMin) < 0)
212             return 0;
213         return (POINTS - 1) - (int) expectedMin;
214     }
215 
216     /**
217      * This generates a random minimum value for testing.
218      */
219     public double randomMinimum() {
220         return random.nextDouble() * (POINTS - 1);
221     }
222 
223     /**
224      * This generates a random minimum value for which fewer
225      * results would be returned.
226      */
227     public double randomMinimum(int minimum) {
228         double diffTarget = 1.0 * (POINTS - 1 - minimum);
229         return (random.nextDouble() * minimum) + diffTarget;
230     }
231 
232     /**
233      * This returns the expected number of reports.
234      * <p/>
235      * If the Minimum comes in at 521.569 then we expect
236      * 522, 523, ... 999 will pass.
237      */
238     public int expectedMinimum(double minimum) {
239         Double d = Double.valueOf(minimum);
240         return POINTS - 1 - d.intValue();
241     }
242 
243     @Test
244     public void testExpectedMinimum() {
245         for (int i = 0; i < POINTS - 1; i++) {
246             assertEquals("Integer Min", POINTS - 1 - i, expectedMinimum(i * 1.0));
247             assertEquals("Double Min", POINTS - 1 - i, expectedMinimum((i * 1.0) + 0.5));
248         }
249     }
250 
251     /**
252      * This returns a random value for Top Score.
253      */
254     public int randomTopScore() {
255         return random.nextInt(POINTS - 1);
256     }
257 
258     /**
259      * This will return a random value for the Top Score
260      * which will return more than the minimum provided.
261      */
262     public int randomTopScore(double target) {
263         if (target < 0)
264             return 0;
265 
266         return random.nextInt(Double.valueOf(target).intValue());
267     }
268 
269     /**
270      * This will return the expected number of results
271      * with the given Top Score.
272      */
273     public int expectedTopScore(int target) {
274         return target;
275     }
276 
277     // Test Single Datapoint
278     @Test
279     public void testSingleDatapoint() {
280         StatisticalRule IUT = new MockStatisticalRule();
281 
282         DataPoint point = new DataPoint();
283         point.setScore(POINTS + 1.0);
284         DummyJavaNode s = new DummyJavaNode(1);
285         s.setScope(new SourceFileScope("foo"));
286         s.testingOnly__setBeginLine(POINTS + 1);
287         s.testingOnly__setBeginColumn(1);
288         point.setNode(s);
289         point.setMessage("SingleDataPoint");
290 
291         IUT.setProperty(MINIMUM_DESCRIPTOR, (double)POINTS);
292 
293         IUT.addDataPoint(point);
294 
295         Report report = makeReport(IUT);
296 
297         assertEquals("Expecting only one result", 1, report.size());
298     }
299 
300     // Okay, we have three properties we need to
301     // test in Combination:
302     //  S = Sigma
303     //  T = Top Score
304     //  M = Minimum
305     //
306     // They are listed in decreasing order of what
307     // to expect.
308     //
309     // Thus testSM() should have the Sigma less than
310     // the minimum, so we expect the Minimum # of results.
311     //
312 
313     @Test
314     public void testS() throws Throwable {
315         verifyResults(MAX_SIGMA, NO_MINIMUM, NO_TOPSCORE, 0, 2);
316 
317         for (int i = 0; i < NUM_TESTS; i++) {
318             double sigma = randomSigma();
319             verifyResults(sigma, -1.0, -1, expectedSigma(sigma), 2);
320         }
321     }
322 
323     @Test
324     public void testS1() throws Throwable {
325         testS();
326     }
327 
328     @Test
329     public void testS2() throws Throwable {
330         testS();
331     }
332 
333     @Test
334     public void testS3() throws Throwable {
335         testS();
336     }
337 
338     @Test
339     public void testS4() throws Throwable {
340         testS();
341     }
342 
343     @Test
344     public void testS5() throws Throwable {
345         testS();
346     }
347 
348 
349     @Test
350     public void testT() throws Throwable {
351         verifyResults(NO_SIGMA, NO_MINIMUM, MIN_TOPSCORE, 0, 0);
352 
353         for (int i = 0; i < NUM_TESTS; i++) {
354             int topScore = randomTopScore();
355             verifyResults(-1.0, -1.0, topScore, expectedTopScore(topScore), 0);
356         }
357     }
358 
359     @Test
360     public void testT1() throws Throwable {
361         testT();
362     }
363 
364     @Test
365     public void testT2() throws Throwable {
366         testT();
367     }
368 
369     @Test
370     public void testT3() throws Throwable {
371         testT();
372     }
373 
374     @Test
375     public void testT4() throws Throwable {
376         testT();
377     }
378 
379     @Test
380     public void testT5() throws Throwable {
381         testT();
382     }
383 
384     @Test
385     public void testM() throws Throwable {
386         verifyResults(NO_SIGMA, MAX_MINIMUM, NO_TOPSCORE, 0, 0);
387 
388         for (int i = 0; i < NUM_TESTS; i++) {
389             double minimum = randomMinimum();
390             verifyResults(-1.0, minimum, -1, expectedMinimum(minimum), 0);
391         }
392     }
393 
394     @Test
395     public void testM1() throws Throwable {
396         testM();
397     }
398 
399     @Test
400     public void testM2() throws Throwable {
401         testM();
402     }
403 
404     @Test
405     public void testM3() throws Throwable {
406         testM();
407     }
408 
409     @Test
410     public void testM4() throws Throwable {
411         testM();
412     }
413 
414     @Test
415     public void testM5() throws Throwable {
416         testM();
417     }
418 
419     @Test
420     public void testST() throws Throwable {
421         verifyResults(randomSigma(), NO_MINIMUM, MIN_TOPSCORE, 0, 0);
422 
423         for (int i = 0; i < NUM_TESTS; i++) {
424             double sigma = randomSigma();
425             int topScore = randomTopScore(expectedSigma(sigma));
426 
427             verifyResults(sigma, NO_MINIMUM, topScore, expectedTopScore(topScore), 0);
428         }
429     }
430 
431     @Test
432     public void testST1() throws Throwable {
433         testST();
434     }
435 
436     @Test
437     public void testST2() throws Throwable {
438         testST();
439     }
440 
441     @Test
442     public void testST3() throws Throwable {
443         testST();
444     }
445 
446     @Test
447     public void testST4() throws Throwable {
448         testST();
449     }
450 
451     @Test
452     public void testST5() throws Throwable {
453         testST();
454     }
455 
456     @Test
457     public void testTS() throws Throwable {
458         verifyResults(MAX_SIGMA, NO_MINIMUM, randomTopScore(), 0, 0);
459 
460         for (int i = 0; i < NUM_TESTS; i++) {
461             int topScore = randomTopScore();
462             double sigma = randomSigma(expectedTopScore(topScore));
463 
464             verifyResults(sigma, -1.0, topScore, expectedSigma(sigma), 2);
465         }
466     }
467 
468     @Test
469     public void testTS1() throws Throwable {
470         testTS();
471     }
472 
473     @Test
474     public void testTS2() throws Throwable {
475         testTS();
476     }
477 
478     @Test
479     public void testTS3() throws Throwable {
480         testTS();
481     }
482 
483     @Test
484     public void testTS4() throws Throwable {
485         testTS();
486     }
487 
488     @Test
489     public void testTS5() throws Throwable {
490         testTS();
491     }
492 
493     @Test
494     public void testSM() throws Throwable {
495         verifyResults(randomSigma(), MAX_MINIMUM, NO_TOPSCORE, 0, 0);
496         for (int i = 0; i < NUM_TESTS; i++) {
497             double sigma = randomSigma();
498             double minimum = randomMinimum(expectedSigma(sigma));
499 
500             verifyResults(sigma, minimum, -1, expectedMinimum(minimum), 0);
501         }
502 
503     }
504 
505     @Test
506     public void testSM1() throws Throwable {
507         testSM();
508     }
509 
510     @Test
511     public void testSM2() throws Throwable {
512         testSM();
513     }
514 
515     @Test
516     public void testSM3() throws Throwable {
517         testSM();
518     }
519 
520     @Test
521     public void testSM4() throws Throwable {
522         testSM();
523     }
524 
525     @Test
526     public void testSM5() throws Throwable {
527         testSM();
528     }
529 
530 
531     @Test
532     public void testMS() throws Throwable {
533         verifyResults(MAX_SIGMA, randomMinimum(), NO_TOPSCORE, 0, 0);
534         for (int i = 0; i < NUM_TESTS; i++) {
535             double minimum = randomMinimum();
536             double sigma = randomSigma(expectedMinimum(minimum));
537 
538             verifyResults(sigma, minimum, -1, expectedSigma(sigma), 2);
539         }
540     }
541 
542     @Test
543     public void testMS1() throws Throwable {
544         testMS();
545     }
546 
547     @Test
548     public void testMS2() throws Throwable {
549         testMS();
550     }
551 
552     @Test
553     public void testMS3() throws Throwable {
554         testMS();
555     }
556 
557     @Test
558     public void testMS4() throws Throwable {
559         testMS();
560     }
561 
562     @Test
563     public void testMS5() throws Throwable {
564         testMS();
565     }
566 
567 
568     @Test
569     public void testTM() throws Throwable {
570         verifyResults(NO_SIGMA, MAX_MINIMUM, randomTopScore(), 0, 0);
571         for (int i = 0; i < NUM_TESTS; i++) {
572             int topScore = randomTopScore();
573             double minimum = randomMinimum(expectedTopScore(topScore));
574 
575             verifyResults(NO_SIGMA, minimum, topScore, expectedMinimum(minimum), 0);
576         }
577     }
578 
579     @Test
580     public void testTM1() throws Throwable {
581         testTM();
582     }
583 
584     @Test
585     public void testTM2() throws Throwable {
586         testTM();
587     }
588 
589     @Test
590     public void testTM3() throws Throwable {
591         testTM();
592     }
593 
594     @Test
595     public void testTM4() throws Throwable {
596         testTM();
597     }
598 
599     @Test
600     public void testTM5() throws Throwable {
601         testTM();
602     }
603 
604 
605     @Test
606     public void testMT() throws Throwable {
607         verifyResults(NO_SIGMA, randomMinimum(), MIN_TOPSCORE, 0, 0);
608         for (int i = 0; i < NUM_TESTS; i++) {
609             double minimum = randomMinimum();
610             int topScore = randomTopScore(expectedMinimum(minimum));
611 
612             verifyResults(NO_SIGMA, minimum, topScore, expectedTopScore(topScore), 0);
613         }
614     }
615 
616     @Test
617     public void testMT1() throws Throwable {
618         testMT();
619     }
620 
621     @Test
622     public void testMT2() throws Throwable {
623         testMT();
624     }
625 
626     @Test
627     public void testMT3() throws Throwable {
628         testMT();
629     }
630 
631     @Test
632     public void testMT4() throws Throwable {
633         testMT();
634     }
635 
636     @Test
637     public void testMT5() throws Throwable {
638         testMT();
639     }
640 
641 
642     @Test
643     public void testSTM() throws Throwable {
644         double sigma = randomSigma();
645         verifyResults(sigma, MAX_MINIMUM, randomTopScore(expectedSigma(sigma)), 0, 0);
646 
647         for (int i = 0; i < NUM_TESTS; i++) {
648             sigma = randomSigma();
649             int topScore = randomTopScore(expectedSigma(sigma));
650             double minimum = randomMinimum(expectedTopScore(topScore));
651 
652             verifyResults(sigma, minimum, topScore, expectedMinimum(minimum), 0);
653         }
654     }
655 
656     @Test
657     public void testSTM1() throws Throwable {
658         testSTM();
659     }
660 
661     @Test
662     public void testSTM2() throws Throwable {
663         testSTM();
664     }
665 
666     @Test
667     public void testSTM3() throws Throwable {
668         testSTM();
669     }
670 
671     @Test
672     public void testSTM4() throws Throwable {
673         testSTM();
674     }
675 
676     @Test
677     public void testSTM5() throws Throwable {
678         testSTM();
679     }
680 
681     @Test
682     public void testSMT() throws Throwable {
683         double sigma = randomSigma();
684         verifyResults(sigma, randomMinimum(expectedSigma(sigma)), MIN_TOPSCORE, 0, 0);
685 
686         for (int i = 0; i < NUM_TESTS; i++) {
687             sigma = randomSigma();
688             double minimum = randomMinimum(expectedSigma(sigma));
689             int topScore = randomTopScore(expectedMinimum(minimum));
690 
691             verifyResults(sigma, minimum, topScore, expectedTopScore(topScore), 0);
692         }
693     }
694 
695     @Test
696     public void testSMT1() throws Throwable {
697         testSMT();
698     }
699 
700     @Test
701     public void testSMT2() throws Throwable {
702         testSMT();
703     }
704 
705     @Test
706     public void testSMT3() throws Throwable {
707         testSMT();
708     }
709 
710     @Test
711     public void testSMT4() throws Throwable {
712         testSMT();
713     }
714 
715     @Test
716     public void testSMT5() throws Throwable {
717         testSMT();
718     }
719 
720     @Test
721     // because of random failures during continuous integration,
722     // tests are disabled in regress mode until somebody figures out
723     // what the tests are supposed to measure and why they sometime fail
724     @Ignore("random failures during continuous integration")
725     public void testTSM() throws Throwable {
726         int topScore = randomTopScore();
727         verifyResults(randomSigma(expectedTopScore(topScore)), MAX_MINIMUM, topScore, 0, 0);
728 
729         for (int i = 0; i < NUM_TESTS; i++) {
730             topScore = randomTopScore();
731             double sigma = randomSigma(expectedTopScore(topScore));
732             double minimum = randomMinimum(expectedSigma(sigma));
733 
734             verifyResults(sigma, minimum, topScore, expectedMinimum(minimum), 0);
735         }
736     }
737 
738     @Test
739     @Ignore("random failures during continuous integration")
740     public void testTSM1() throws Throwable {
741         testTSM();
742     }
743 
744     @Test
745     @Ignore("random failures during continuous integration")
746     public void testTSM2() throws Throwable {
747         testTSM();
748     }
749 
750     @Test
751     @Ignore("random failures during continuous integration")
752     public void testTSM3() throws Throwable {
753         testTSM();
754     }
755 
756     @Test
757     @Ignore("random failures during continuous integration")
758     public void testTSM4() throws Throwable {
759         testTSM();
760     }
761 
762     @Test
763     @Ignore("random failures during continuous integration")
764     public void testTSM5() throws Throwable {
765         testTSM();
766     }
767 
768     @Test
769     public void testTMS() throws Throwable {
770         int topScore = randomTopScore();
771         verifyResults(MAX_SIGMA, randomMinimum(expectedTopScore(topScore)), topScore, 0, 0);
772 
773         for (int i = 0; i < NUM_TESTS; i++) {
774             topScore = randomTopScore();
775             double minimum = randomMinimum(expectedTopScore(topScore));
776             double sigma = randomSigma(expectedMinimum(minimum));
777 
778             verifyResults(sigma, minimum, topScore, expectedSigma(sigma), 2);
779         }
780     }
781 
782     @Test
783     public void testTMS1() throws Throwable {
784         testTMS();
785     }
786 
787     @Test
788     public void testTMS2() throws Throwable {
789         testTMS();
790     }
791 
792     @Test
793     public void testTMS3() throws Throwable {
794         testTMS();
795     }
796 
797     @Test
798     public void testTMS4() throws Throwable {
799         testTMS();
800     }
801 
802     @Test
803     public void testTMS5() throws Throwable {
804         testTMS();
805     }
806 
807     /**
808      * Verifies what happens when you pass these parameters
809      * into the thing.  DELTA is the amount of error allowed.
810      * Usually DELTA is only used for Sigma, as we really can't
811      * calculate it exactly.
812      */
813 
814     public void verifyResults(double sigma, double minimum, int topScore, int expected, int delta) {
815         try {
816             setUp();
817             if (sigma >= 0) {
818             	IUT.setProperty(SIGMA_DESCRIPTOR, sigma);
819             }
820 
821             if (minimum >= 0) {
822             	IUT.setProperty(MINIMUM_DESCRIPTOR, minimum);
823             }
824 
825             if (topScore >= 0) {
826                 IUT.setProperty(TOP_SCORE_DESCRIPTOR, topScore);
827             }
828 
829             Report report = makeReport(IUT);
830             if (delta == 0) {
831                 assertEquals("Unexpected number of results: sigma= " + Double.toString(sigma) + " min= " + Double.toString(minimum) + " topscore= " + Integer.toString(topScore), expected, report.size());
832             } else {
833                 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();
834 
835                 assertTrue(assertStr, report.size() >= (expected - delta));
836                 assertTrue(assertStr, report.size() <= (expected + delta));
837             }
838         } catch (AssertionFailedError afe) {
839             System.err.println("******** " + testName + " ***********");
840             if (sigma != NO_SIGMA) {
841                 System.err.println("SIGMA: " + Double.toString(sigma) + " EXPECT: " + Integer.toString(expectedSigma(sigma)));
842             }
843 
844             if (minimum != NO_MINIMUM) {
845                 System.err.println("MIN: " + Double.toString(minimum) + " EXPECT: " + Integer.toString(expectedMinimum(minimum)));
846             }
847 
848             if (topScore != NO_TOPSCORE) {
849                 System.err.println("TOP: " + Integer.toString(topScore) + " EXPECT: " + Integer.toString(expectedTopScore(topScore)));
850             }
851 
852             throw afe;
853 
854         }
855     }
856 
857     public Report makeReport(Rule IUT) {
858         List list = new ArrayList();
859         Report report = new Report();
860 
861         RuleContext ctx = new RuleContext();
862         ctx.setReport(report);
863         ctx.setSourceCodeFilename(testName);
864         ctx.setLanguageVersion(Language.JAVA.getDefaultVersion());
865 
866         IUT.apply(list, ctx);
867 
868         return report;
869     }
870 
871     public static junit.framework.Test suite() {
872         return new junit.framework.JUnit4TestAdapter(StatisticalRuleTest.class);
873     }
874 }