001/*
002 * ModeShape (http://www.modeshape.org)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *       http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.modeshape.common.statistic;
017
018import static org.hamcrest.core.Is.is;
019import static org.junit.Assert.assertEquals;
020import static org.junit.Assert.assertThat;
021import static org.junit.Assert.assertTrue;
022import org.modeshape.common.math.FloatOperations;
023import org.modeshape.common.math.IntegerOperations;
024import org.modeshape.common.logging.Logger;
025import org.junit.Test;
026
027public class DetailedStatisticsTest {
028
029    private DetailedStatistics<Integer> intStats = new DetailedStatistics<Integer>(new IntegerOperations());
030    private DetailedStatistics<Float> floatStats = new DetailedStatistics<Float>(new FloatOperations());
031    private Logger logger = Logger.getLogger(DetailedStatisticsTest.class);
032
033    @Test
034    public void shouldHaveValidValuesWhenUnused() {
035        assertThat(this.intStats.getCount(), is(0));
036        assertThat(this.intStats.getMinimum(), is(0));
037        assertThat(this.intStats.getMaximum(), is(0));
038        assertThat(this.intStats.getMean(), is(0));
039        assertThat(this.intStats.getMedian(), is(0));
040        assertThat(this.intStats.getStandardDeviation(), is(0.0d));
041    }
042
043    @Test
044    public void shouldCorrectStatisitcValuesWhenUnusedOnce() {
045        this.intStats.add(10);
046        assertThat(this.intStats.getCount(), is(1));
047        assertThat(this.intStats.getMinimum(), is(10));
048        assertThat(this.intStats.getMaximum(), is(10));
049        assertThat(this.intStats.getMean(), is(10));
050        assertThat(this.intStats.getMedian(), is(10));
051        assertThat(this.intStats.getStandardDeviation(), is(0.0d));
052    }
053
054    @Test
055    public void shouldCorrectStatisitcValuesWhenUsedAnOddNumberOfTimesButMoreThanOnce() {
056        this.intStats.add(1);
057        this.intStats.add(2);
058        this.intStats.add(3);
059        assertThat(this.intStats.getCount(), is(3));
060        assertThat(this.intStats.getMinimum(), is(1));
061        assertThat(this.intStats.getMaximum(), is(3));
062        assertThat(this.intStats.getMean(), is(2));
063        assertThat(this.intStats.getMeanValue(), is(2.0d));
064        assertThat(this.intStats.getMedian(), is(2));
065        assertThat(this.intStats.getMedianValue(), is(2.0d));
066        assertEquals(0.816496d, this.intStats.getStandardDeviation(), 0.001d);
067    }
068
069    @Test
070    public void shouldCorrectStatisitcValuesWhenUsedAnEvenNumberOfTimes() {
071        this.intStats.add(2);
072        this.intStats.add(4);
073        this.intStats.add(1);
074        this.intStats.add(3);
075        assertThat(this.intStats.getCount(), is(4));
076        assertThat(this.intStats.getMinimum(), is(1));
077        assertThat(this.intStats.getMaximum(), is(4));
078        assertThat(this.intStats.getMeanValue(), is(2.5d));
079        assertThat(this.intStats.getMedianValue(), is(2.5d));
080        assertEquals(1.0d, this.intStats.getStandardDeviation(), 0.2d);
081    }
082
083    @Test
084    public void shouldCorrectStatisitcValuesWhenAllValuesAreTheSame() {
085        this.intStats.add(2);
086        this.intStats.add(2);
087        this.intStats.add(2);
088        this.intStats.add(2);
089        assertThat(this.intStats.getCount(), is(4));
090        assertThat(this.intStats.getMinimum(), is(2));
091        assertThat(this.intStats.getMaximum(), is(2));
092        assertThat(this.intStats.getMean(), is(2));
093        assertThat(this.intStats.getMeanValue(), is(2.0d));
094        assertThat(this.intStats.getMedian(), is(2));
095        assertThat(this.intStats.getMedianValue(), is(2.0d));
096        assertThat(this.intStats.getStandardDeviation(), is(0.0d));
097    }
098
099    @Test
100    public void shouldCorrectStatisitcValuesForComplexIntegerData() {
101        this.intStats.add(19);
102        this.intStats.add(10);
103        this.intStats.add(20);
104        this.intStats.add(7);
105        this.intStats.add(73);
106        this.intStats.add(72);
107        this.intStats.add(42);
108        this.intStats.add(9);
109        this.intStats.add(47);
110        this.intStats.add(24);
111        System.out.println(this.intStats);
112        assertThat(this.intStats.getCount(), is(10));
113        assertThat(this.intStats.getMinimum(), is(7));
114        assertThat(this.intStats.getMaximum(), is(73));
115        assertThat(this.intStats.getMeanValue(), is(32.3d));
116        assertEquals(32.3d, this.intStats.getMeanValue(), 0.0001d);
117        assertEquals(22.0d, this.intStats.getMedianValue(), 0.0001d);
118        assertEquals(23.70675d, this.intStats.getStandardDeviation(), 0.0001d);
119
120        HistogramTest.writeHistogramToLog(this.logger, this.intStats.getHistogram(), 20, "Histogram of 10 integer values: ");
121        HistogramTest.writeHistogramToLog(this.logger,
122                                          this.intStats.getHistogram().setBucketCount(7),
123                                          20,
124                                          "Histogram of 10 integer values: ");
125    }
126
127    @Test
128    public void shouldCorrectStatisitcValuesForComplexFloatData() {
129        this.floatStats.add(1.9f);
130        this.floatStats.add(1.0f);
131        this.floatStats.add(2.0f);
132        this.floatStats.add(0.7f);
133        this.floatStats.add(7.3f);
134        this.floatStats.add(7.2f);
135        this.floatStats.add(4.2f);
136        this.floatStats.add(0.9f);
137        this.floatStats.add(4.7f);
138        this.floatStats.add(2.4f);
139        System.out.println(this.floatStats);
140        assertThat(this.floatStats.getCount(), is(10));
141        assertThat(this.floatStats.getMinimum(), is(0.7f));
142        assertThat(this.floatStats.getMaximum(), is(7.3f));
143        assertEquals(3.23f, this.floatStats.getMeanValue(), 0.0001f);
144        assertEquals(2.20f, this.floatStats.getMedianValue(), 0.0001f);
145        assertEquals(2.370675f, this.floatStats.getStandardDeviation(), 0.0001f);
146
147        HistogramTest.writeHistogramToLog(this.logger, this.floatStats.getHistogram(), 20, "Histogram of 10 float values: ");
148        HistogramTest.writeHistogramToLog(this.logger,
149                                          this.floatStats.getHistogram().setBucketCount(7),
150                                          20,
151                                          "Histogram of 10 float values: ");
152    }
153
154    @Test
155    public void shouldHaveNoStatisticValuesAfterUnusedAndReset() {
156        this.intStats.add(19);
157        this.intStats.add(10);
158        this.intStats.add(20);
159        assertEquals(3, this.intStats.getCount());
160        this.intStats.reset();
161        assertThat(this.intStats.getCount(), is(0));
162        assertThat(this.intStats.getMinimum(), is(0));
163        assertThat(this.intStats.getMaximum(), is(0));
164        assertThat(this.intStats.getMean(), is(0));
165        assertThat(this.intStats.getMedian(), is(0));
166        assertThat(this.intStats.getStandardDeviation(), is(0.0d));
167    }
168
169    @Test
170    public void shouldHaveStringRepresentationWithoutStatisticsForSingleSample() {
171        this.intStats.add(19);
172        String str = this.intStats.toString();
173        System.out.println(str);
174        assertTrue(str.matches("1 sample.*"));
175        assertTrue(str.matches(".*min=\\d{1,5}.*"));
176        assertTrue(str.matches(".*max=\\d{1,5}.*"));
177        assertTrue(str.matches(".*avg=\\d{1,5}.*"));
178        assertTrue(str.matches(".*stddev=\\d{1,5}.*"));
179        assertTrue(str.matches(".*median=\\d{1,5}.*"));
180    }
181
182    @Test
183    public void shouldHaveStringRepresentationWithStatisticsForMultipleSample() {
184        this.intStats.add(19);
185        this.intStats.add(10);
186        this.intStats.add(20);
187        String str = this.intStats.toString();
188        System.out.println(str);
189        assertTrue(str.matches("^\\d{1,5}.*"));
190        assertTrue(str.matches(".*3 samples.*"));
191        assertTrue(str.matches(".*min=\\d{1,5}.*"));
192        assertTrue(str.matches(".*max=\\d{1,5}.*"));
193        assertTrue(str.matches(".*avg=\\d{1,5}.*"));
194        assertTrue(str.matches(".*stddev=\\d{1,5}.*"));
195        assertTrue(str.matches(".*median=\\d{1,5}.*"));
196    }
197
198}