1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2013, by Object Refinery Limited and Contributors.
6  *
7  * Project Info:  http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
22  * USA.
23  *
24  * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
25  * Other names may be trademarks of their respective owners.]
26  *
27  * -------------------
28  * TimeSeriesTest.java
29  * -------------------
30  * (C) Copyright 2001-2013, by Object Refinery Limited.
31  *
32  * Original Author:  David Gilbert (for Object Refinery Limited);
33  * Contributor(s):   -;
34  *
35  * Changes
36  * -------
37  * 16-Nov-2001 : Version 1 (DG);
38  * 17-Oct-2002 : Fixed errors reported by Checkstyle (DG);
39  * 13-Mar-2003 : Added serialization test (DG);
40  * 15-Oct-2003 : Added test for setMaximumItemCount method (DG);
41  * 23-Aug-2004 : Added test that highlights a bug where the addOrUpdate()
42  *               method can lead to more than maximumItemCount items in the
43  *               dataset (DG);
44  * 24-May-2006 : Added new tests (DG);
45  * 31-Oct-2007 : New hashCode() test (DG);
46  * 21-Nov-2007 : Added testBug1832432() and testClone2() (DG);
47  * 10-Jan-2008 : Added testBug1864222() (DG);
48  * 13-Jan-2009 : Added testEquals3() and testRemoveAgedItems3() (DG);
49  * 26-May-2009 : Added various tests for min/maxY values (DG);
50  * 09-Jun-2009 : Added testAdd_TimeSeriesDataItem (DG);
51  * 31-Aug-2009 : Added new test for createCopy() method (DG);
52  * 03-Dec-2011 : Added testBug3446965() (DG);
53  *
54  */
55 
56 package org.jfree.data.time;
57 
58 import static org.junit.Assert.assertTrue;
59 import static org.junit.Assert.assertEquals;
60 import static org.junit.Assert.assertFalse;
61 import static org.junit.Assert.assertNull;
62 import static org.junit.Assert.fail;
63 
64 import org.jfree.chart.TestUtilities;
65 
66 import org.jfree.data.general.SeriesChangeEvent;
67 import org.jfree.data.general.SeriesChangeListener;
68 import org.jfree.data.general.SeriesException;
69 import org.jfree.date.MonthConstants;
70 import org.junit.Before;
71 import org.junit.Test;
72 
73 /**
74  * A collection of test cases for the {@link TimeSeries} class.
75  */
76 public class TimeSeriesTest implements SeriesChangeListener {
77 
78     /** A time series. */
79     private TimeSeries seriesA;
80 
81     /** A time series. */
82     private TimeSeries seriesB;
83 
84     /** A time series. */
85     private TimeSeries seriesC;
86 
87     /** A flag that indicates whether or not a change event was fired. */
88     private boolean gotSeriesChangeEvent = false;
89 
90     /**
91      * Common test setup.
92      */
93     @Before
setUp()94     public void setUp() {
95         this.seriesA = new TimeSeries("Series A");
96         this.seriesA.add(new Year(2000), new Integer(102000));
97         this.seriesA.add(new Year(2001), new Integer(102001));
98         this.seriesA.add(new Year(2002), new Integer(102002));
99         this.seriesA.add(new Year(2003), new Integer(102003));
100         this.seriesA.add(new Year(2004), new Integer(102004));
101         this.seriesA.add(new Year(2005), new Integer(102005));
102 
103         this.seriesB = new TimeSeries("Series B");
104         this.seriesB.add(new Year(2006), new Integer(202006));
105         this.seriesB.add(new Year(2007), new Integer(202007));
106         this.seriesB.add(new Year(2008), new Integer(202008));
107 
108         this.seriesC = new TimeSeries("Series C");
109         this.seriesC.add(new Year(1999), new Integer(301999));
110         this.seriesC.add(new Year(2000), new Integer(302000));
111         this.seriesC.add(new Year(2002), new Integer(302002));
112     }
113 
114     /**
115      * Sets the flag to indicate that a {@link SeriesChangeEvent} has been
116      * received.
117      *
118      * @param event  the event.
119      */
120     @Override
seriesChanged(SeriesChangeEvent event)121     public void seriesChanged(SeriesChangeEvent event) {
122         this.gotSeriesChangeEvent = true;
123     }
124 
125     /**
126      * Check that cloning works.
127      */
128     @Test
testClone()129     public void testClone() throws CloneNotSupportedException {
130 
131         TimeSeries series = new TimeSeries("Test Series");
132         RegularTimePeriod jan1st2002 = new Day(1, MonthConstants.JANUARY, 2002);
133         series.add(jan1st2002, new Integer(42));
134 
135         TimeSeries clone;
136         clone = (TimeSeries) series.clone();
137         clone.setKey("Clone Series");
138         clone.update(jan1st2002, new Integer(10));
139 
140         int seriesValue = series.getValue(jan1st2002).intValue();
141         int cloneValue = clone.getValue(jan1st2002).intValue();
142 
143         assertEquals(42, seriesValue);
144         assertEquals(10, cloneValue);
145         assertEquals("Test Series", series.getKey());
146         assertEquals("Clone Series", clone.getKey());
147     }
148 
149     /**
150      * Another test of the clone() method.
151      */
152     @Test
testClone2()153     public void testClone2() throws CloneNotSupportedException {
154         TimeSeries s1 = new TimeSeries("S1", Year.class);
155         s1.add(new Year(2007), 100.0);
156         s1.add(new Year(2008), null);
157         s1.add(new Year(2009), 200.0);
158         TimeSeries s2 = (TimeSeries) s1.clone();
159         assertTrue(s1.equals(s2));
160 
161         // check independence
162         s2.addOrUpdate(new Year(2009), 300.0);
163         assertFalse(s1.equals(s2));
164         s1.addOrUpdate(new Year(2009), 300.0);
165         assertTrue(s1.equals(s2));
166     }
167 
168     /**
169      * Add a value to series A for 1999.  It should be added at index 0.
170      */
171     @Test
testAddValue()172     public void testAddValue() {
173         this.seriesA.add(new Year(1999), new Integer(1));
174         int value = this.seriesA.getValue(0).intValue();
175         assertEquals(1, value);
176     }
177 
178     /**
179      * Tests the retrieval of values.
180      */
181     @Test
testGetValue()182     public void testGetValue() {
183         Number value1 = this.seriesA.getValue(new Year(1999));
184         assertNull(value1);
185         int value2 = this.seriesA.getValue(new Year(2000)).intValue();
186         assertEquals(102000, value2);
187     }
188 
189     /**
190      * Tests the deletion of values.
191      */
192     @Test
testDelete()193     public void testDelete() {
194         this.seriesA.delete(0, 0);
195         assertEquals(5, this.seriesA.getItemCount());
196         Number value = this.seriesA.getValue(new Year(2000));
197         assertNull(value);
198     }
199 
200     /**
201      * Basic tests for the delete() method.
202      */
203     @Test
testDelete2()204     public void testDelete2() {
205         TimeSeries s1 = new TimeSeries("Series", Year.class);
206         s1.add(new Year(2000), 13.75);
207         s1.add(new Year(2001), 11.90);
208         s1.add(new Year(2002), null);
209         s1.addChangeListener(this);
210         this.gotSeriesChangeEvent = false;
211         s1.delete(new Year(2001));
212         assertTrue(this.gotSeriesChangeEvent);
213         assertEquals(2, s1.getItemCount());
214         assertEquals(null, s1.getValue(new Year(2001)));
215 
216         // try deleting a time period that doesn't exist...
217         this.gotSeriesChangeEvent = false;
218         s1.delete(new Year(2006));
219         assertFalse(this.gotSeriesChangeEvent);
220 
221         // try deleting null
222         try {
223             s1.delete(null);
224             fail("Expected IllegalArgumentException.");
225         }
226         catch (IllegalArgumentException e) {
227             // expected
228         }
229     }
230 
231     /**
232      * Some checks for the delete(int, int) method.
233      */
234     @Test
testDelete3()235     public void testDelete3() {
236         TimeSeries s1 = new TimeSeries("S1");
237         s1.add(new Year(2011), 1.1);
238         s1.add(new Year(2012), 2.2);
239         s1.add(new Year(2013), 3.3);
240         s1.add(new Year(2014), 4.4);
241         s1.add(new Year(2015), 5.5);
242         s1.add(new Year(2016), 6.6);
243         s1.delete(2, 5);
244         assertEquals(2, s1.getItemCount());
245         assertEquals(new Year(2011), s1.getTimePeriod(0));
246         assertEquals(new Year(2012), s1.getTimePeriod(1));
247         assertEquals(1.1, s1.getMinY(), EPSILON);
248         assertEquals(2.2, s1.getMaxY(), EPSILON);
249     }
250 
251     /**
252      * Check that the item bounds are determined correctly when there is a
253      * maximum item count and a new value is added.
254      */
255     @Test
testDelete_RegularTimePeriod()256     public void testDelete_RegularTimePeriod() {
257         TimeSeries s1 = new TimeSeries("S1");
258         s1.add(new Year(2010), 1.1);
259         s1.add(new Year(2011), 2.2);
260         s1.add(new Year(2012), 3.3);
261         s1.add(new Year(2013), 4.4);
262         s1.delete(new Year(2010));
263         s1.delete(new Year(2013));
264         assertEquals(2.2, s1.getMinY(), EPSILON);
265         assertEquals(3.3, s1.getMaxY(), EPSILON);
266     }
267 
268     /**
269      * Serialize an instance, restore it, and check for equality.
270      */
271     @Test
testSerialization()272     public void testSerialization() {
273         TimeSeries s1 = new TimeSeries("A test");
274         s1.add(new Year(2000), 13.75);
275         s1.add(new Year(2001), 11.90);
276         s1.add(new Year(2002), null);
277         s1.add(new Year(2005), 19.32);
278         s1.add(new Year(2007), 16.89);
279         TimeSeries s2 = (TimeSeries) TestUtilities.serialised(s1);
280         assertTrue(s1.equals(s2));
281     }
282 
283     /**
284      * Tests the equals method.
285      */
286     @Test
testEquals()287     public void testEquals() {
288         TimeSeries s1 = new TimeSeries("Time Series 1");
289         TimeSeries s2 = new TimeSeries("Time Series 2");
290         boolean b1 = s1.equals(s2);
291         assertFalse("b1", b1);
292 
293         s2.setKey("Time Series 1");
294         boolean b2 = s1.equals(s2);
295         assertTrue("b2", b2);
296 
297         RegularTimePeriod p1 = new Day();
298         RegularTimePeriod p2 = p1.next();
299         s1.add(p1, 100.0);
300         s1.add(p2, 200.0);
301         boolean b3 = s1.equals(s2);
302         assertFalse("b3", b3);
303 
304         s2.add(p1, 100.0);
305         s2.add(p2, 200.0);
306         boolean b4 = s1.equals(s2);
307         assertTrue("b4", b4);
308 
309         s1.setMaximumItemCount(100);
310         boolean b5 = s1.equals(s2);
311         assertFalse("b5", b5);
312 
313         s2.setMaximumItemCount(100);
314         boolean b6 = s1.equals(s2);
315         assertTrue("b6", b6);
316 
317         s1.setMaximumItemAge(100);
318         boolean b7 = s1.equals(s2);
319         assertFalse("b7", b7);
320 
321         s2.setMaximumItemAge(100);
322         boolean b8 = s1.equals(s2);
323         assertTrue("b8", b8);
324     }
325 
326     /**
327      * Tests a specific bug report where null arguments in the constructor
328      * cause the equals() method to fail.  Fixed for 0.9.21.
329      */
330     @Test
testEquals2()331     public void testEquals2() {
332         TimeSeries s1 = new TimeSeries("Series", null, null, Day.class);
333         TimeSeries s2 = new TimeSeries("Series", null, null, Day.class);
334         assertTrue(s1.equals(s2));
335     }
336 
337     /**
338      * Two classes with different period classes are NOT the same.
339      */
340     @Test
testEquals3()341     public void testEquals3() {
342         TimeSeries s1 = new TimeSeries("Series", Day.class);
343         TimeSeries s2 = new TimeSeries("Series", Month.class);
344         assertFalse(s1.equals(s2));
345     }
346 
347     /**
348      * Some tests to ensure that the createCopy(RegularTimePeriod,
349      * RegularTimePeriod) method is functioning correctly.
350      */
351     @Test
testCreateCopy1()352     public void testCreateCopy1() {
353 
354         TimeSeries series = new TimeSeries("Series", Month.class);
355         series.add(new Month(MonthConstants.JANUARY, 2003), 45.0);
356         series.add(new Month(MonthConstants.FEBRUARY, 2003), 55.0);
357         series.add(new Month(MonthConstants.JUNE, 2003), 35.0);
358         series.add(new Month(MonthConstants.NOVEMBER, 2003), 85.0);
359         series.add(new Month(MonthConstants.DECEMBER, 2003), 75.0);
360 
361         try {
362             // copy a range before the start of the series data...
363             TimeSeries result1 = series.createCopy(
364                     new Month(MonthConstants.NOVEMBER, 2002),
365                     new Month(MonthConstants.DECEMBER, 2002));
366             assertEquals(0, result1.getItemCount());
367 
368             // copy a range that includes only the first item in the series...
369             TimeSeries result2 = series.createCopy(
370                     new Month(MonthConstants.NOVEMBER, 2002),
371                     new Month(MonthConstants.JANUARY, 2003));
372             assertEquals(1, result2.getItemCount());
373 
374             // copy a range that begins before and ends in the middle of the
375             // series...
376             TimeSeries result3 = series.createCopy(
377                     new Month(MonthConstants.NOVEMBER, 2002),
378                     new Month(MonthConstants.APRIL, 2003));
379             assertEquals(2, result3.getItemCount());
380 
381             TimeSeries result4 = series.createCopy(
382                     new Month(MonthConstants.NOVEMBER, 2002),
383                     new Month(MonthConstants.DECEMBER, 2003));
384             assertEquals(5, result4.getItemCount());
385 
386             TimeSeries result5 = series.createCopy(
387                     new Month(MonthConstants.NOVEMBER, 2002),
388                     new Month(MonthConstants.MARCH, 2004));
389             assertEquals(5, result5.getItemCount());
390 
391             TimeSeries result6 = series.createCopy(
392                     new Month(MonthConstants.JANUARY, 2003),
393                     new Month(MonthConstants.JANUARY, 2003));
394             assertEquals(1, result6.getItemCount());
395 
396             TimeSeries result7 = series.createCopy(
397                     new Month(MonthConstants.JANUARY, 2003),
398                     new Month(MonthConstants.APRIL, 2003));
399             assertEquals(2, result7.getItemCount());
400 
401             TimeSeries result8 = series.createCopy(
402                     new Month(MonthConstants.JANUARY, 2003),
403                     new Month(MonthConstants.DECEMBER, 2003));
404             assertEquals(5, result8.getItemCount());
405 
406             TimeSeries result9 = series.createCopy(
407                     new Month(MonthConstants.JANUARY, 2003),
408                     new Month(MonthConstants.MARCH, 2004));
409             assertEquals(5, result9.getItemCount());
410 
411             TimeSeries result10 = series.createCopy(
412                     new Month(MonthConstants.MAY, 2003),
413                     new Month(MonthConstants.DECEMBER, 2003));
414             assertEquals(3, result10.getItemCount());
415 
416             TimeSeries result11 = series.createCopy(
417                     new Month(MonthConstants.MAY, 2003),
418                     new Month(MonthConstants.MARCH, 2004));
419             assertEquals(3, result11.getItemCount());
420 
421             TimeSeries result12 = series.createCopy(
422                     new Month(MonthConstants.DECEMBER, 2003),
423                     new Month(MonthConstants.DECEMBER, 2003));
424             assertEquals(1, result12.getItemCount());
425 
426             TimeSeries result13 = series.createCopy(
427                     new Month(MonthConstants.DECEMBER, 2003),
428                     new Month(MonthConstants.MARCH, 2004));
429             assertEquals(1, result13.getItemCount());
430 
431             TimeSeries result14 = series.createCopy(
432                     new Month(MonthConstants.JANUARY, 2004),
433                     new Month(MonthConstants.MARCH, 2004));
434             assertEquals(0, result14.getItemCount());
435         }
436         catch (CloneNotSupportedException e) {
437             assertTrue(false);
438         }
439 
440     }
441 
442     /**
443      * Some tests to ensure that the createCopy(int, int) method is
444      * functioning correctly.
445      */
446     @Test
testCreateCopy2()447     public void testCreateCopy2() {
448 
449         TimeSeries series = new TimeSeries("Series", Month.class);
450         series.add(new Month(MonthConstants.JANUARY, 2003), 45.0);
451         series.add(new Month(MonthConstants.FEBRUARY, 2003), 55.0);
452         series.add(new Month(MonthConstants.JUNE, 2003), 35.0);
453         series.add(new Month(MonthConstants.NOVEMBER, 2003), 85.0);
454         series.add(new Month(MonthConstants.DECEMBER, 2003), 75.0);
455 
456         try {
457             // copy just the first item...
458             TimeSeries result1 = series.createCopy(0, 0);
459             assertEquals(new Month(1, 2003), result1.getTimePeriod(0));
460 
461             // copy the first two items...
462             result1 = series.createCopy(0, 1);
463             assertEquals(new Month(2, 2003), result1.getTimePeriod(1));
464 
465             // copy the middle three items...
466             result1 = series.createCopy(1, 3);
467             assertEquals(new Month(2, 2003), result1.getTimePeriod(0));
468             assertEquals(new Month(11, 2003), result1.getTimePeriod(2));
469 
470             // copy the last two items...
471             result1 = series.createCopy(3, 4);
472             assertEquals(new Month(11, 2003), result1.getTimePeriod(0));
473             assertEquals(new Month(12, 2003), result1.getTimePeriod(1));
474 
475             // copy the last item...
476             result1 = series.createCopy(4, 4);
477             assertEquals(new Month(12, 2003), result1.getTimePeriod(0));
478         }
479         catch (CloneNotSupportedException e) {
480             assertTrue(false);
481         }
482 
483         // check negative first argument
484         boolean pass = false;
485         try {
486             /* TimeSeries result = */ series.createCopy(-1, 1);
487         }
488         catch (IllegalArgumentException e) {
489             pass = true;
490         }
491         catch (CloneNotSupportedException e) {
492             pass = false;
493         }
494         assertTrue(pass);
495 
496         // check second argument less than first argument
497         pass = false;
498         try {
499             /* TimeSeries result = */ series.createCopy(1, 0);
500         }
501         catch (IllegalArgumentException e) {
502             pass = true;
503         }
504         catch (CloneNotSupportedException e) {
505             pass = false;
506         }
507         assertTrue(pass);
508 
509         TimeSeries series2 = new TimeSeries("Series 2");
510         try {
511             TimeSeries series3 = series2.createCopy(99, 999);
512             assertEquals(0, series3.getItemCount());
513         }
514         catch (CloneNotSupportedException e) {
515             assertTrue(false);
516         }
517     }
518 
519     /**
520      * Checks that the min and max y values are updated correctly when copying
521      * a subset.
522      *
523      * @throws java.lang.CloneNotSupportedException
524      */
525     @Test
testCreateCopy3()526     public void testCreateCopy3() throws CloneNotSupportedException {
527         TimeSeries s1 = new TimeSeries("S1");
528         s1.add(new Year(2009), 100.0);
529         s1.add(new Year(2010), 101.0);
530         s1.add(new Year(2011), 102.0);
531         assertEquals(100.0, s1.getMinY(), EPSILON);
532         assertEquals(102.0, s1.getMaxY(), EPSILON);
533 
534         TimeSeries s2 = s1.createCopy(0, 1);
535         assertEquals(100.0, s2.getMinY(), EPSILON);
536         assertEquals(101.0, s2.getMaxY(), EPSILON);
537 
538         TimeSeries s3 = s1.createCopy(1, 2);
539         assertEquals(101.0, s3.getMinY(), EPSILON);
540         assertEquals(102.0, s3.getMaxY(), EPSILON);
541     }
542 
543     /**
544      * Test the setMaximumItemCount() method to ensure that it removes items
545      * from the series if necessary.
546      */
547     @Test
testSetMaximumItemCount()548     public void testSetMaximumItemCount() {
549         TimeSeries s1 = new TimeSeries("S1", Year.class);
550         s1.add(new Year(2000), 13.75);
551         s1.add(new Year(2001), 11.90);
552         s1.add(new Year(2002), null);
553         s1.add(new Year(2005), 19.32);
554         s1.add(new Year(2007), 16.89);
555         assertTrue(s1.getItemCount() == 5);
556 
557         s1.setMaximumItemCount(3);
558         assertTrue(s1.getItemCount() == 3);
559         TimeSeriesDataItem item = s1.getDataItem(0);
560         assertTrue(item.getPeriod().equals(new Year(2002)));
561         assertEquals(16.89, s1.getMinY(), EPSILON);
562         assertEquals(19.32, s1.getMaxY(), EPSILON);
563     }
564 
565     /**
566      * Some checks for the addOrUpdate() method.
567      */
568     @Test
testAddOrUpdate()569     public void testAddOrUpdate() {
570         TimeSeries s1 = new TimeSeries("S1", Year.class);
571         s1.setMaximumItemCount(2);
572         s1.addOrUpdate(new Year(2000), 100.0);
573         assertEquals(1, s1.getItemCount());
574         s1.addOrUpdate(new Year(2001), 101.0);
575         assertEquals(2, s1.getItemCount());
576         s1.addOrUpdate(new Year(2001), 102.0);
577         assertEquals(2, s1.getItemCount());
578         s1.addOrUpdate(new Year(2002), 103.0);
579         assertEquals(2, s1.getItemCount());
580     }
581 
582     /**
583      * Test the add branch of the addOrUpdate() method.
584      */
585     @Test
testAddOrUpdate2()586     public void testAddOrUpdate2() {
587         TimeSeries s1 = new TimeSeries("S1");
588         s1.setMaximumItemCount(2);
589         s1.addOrUpdate(new Year(2010), 1.1);
590         s1.addOrUpdate(new Year(2011), 2.2);
591         s1.addOrUpdate(new Year(2012), 3.3);
592         assertEquals(2, s1.getItemCount());
593         assertEquals(2.2, s1.getMinY(), EPSILON);
594         assertEquals(3.3, s1.getMaxY(), EPSILON);
595     }
596 
597     /**
598      * Test that the addOrUpdate() method won't allow multiple time period
599      * classes.
600      */
601     @Test
testAddOrUpdate3()602     public void testAddOrUpdate3() {
603         TimeSeries s1 = new TimeSeries("S1");
604         s1.addOrUpdate(new Year(2010), 1.1);
605         assertEquals(Year.class, s1.getTimePeriodClass());
606 
607         boolean pass = false;
608         try {
609             s1.addOrUpdate(new Month(1, 2009), 0.0);
610         }
611         catch (SeriesException e) {
612             pass = true;
613         }
614         assertTrue(pass);
615     }
616 
617     /**
618      * Some more checks for the addOrUpdate() method.
619      */
620     @Test
testAddOrUpdate4()621     public void testAddOrUpdate4() {
622         TimeSeries ts = new TimeSeries("S");
623         TimeSeriesDataItem overwritten = ts.addOrUpdate(new Year(2009), 20.09);
624         assertNull(overwritten);
625         overwritten = ts.addOrUpdate(new Year(2009), 1.0);
626         assertEquals(new Double(20.09), overwritten.getValue());
627         assertEquals(new Double(1.0), ts.getValue(new Year(2009)));
628 
629         // changing the overwritten record shouldn't affect the series
630         overwritten.setValue(null);
631         assertEquals(new Double(1.0), ts.getValue(new Year(2009)));
632 
633         TimeSeriesDataItem item = new TimeSeriesDataItem(new Year(2010), 20.10);
634         overwritten = ts.addOrUpdate(item);
635         assertNull(overwritten);
636         assertEquals(new Double(20.10), ts.getValue(new Year(2010)));
637         // changing the item that was added should not change the series
638         item.setValue(null);
639         assertEquals(new Double(20.10), ts.getValue(new Year(2010)));
640     }
641 
642     /**
643      * A test for the bug report 1075255.
644      */
645     @Test
testBug1075255()646     public void testBug1075255() {
647         TimeSeries ts = new TimeSeries("dummy");
648         ts.add(new FixedMillisecond(0L), 0.0);
649         TimeSeries ts2 = new TimeSeries("dummy2");
650         ts2.add(new FixedMillisecond(0L), 1.0);
651         try {
652             ts.addAndOrUpdate(ts2);
653         }
654         catch (Exception e) {
655             fail("No exceptions should be thrown.");
656         }
657         assertEquals(1, ts.getItemCount());
658     }
659 
660     /**
661      * A test for bug 1832432.
662      */
663     @Test
testBug1832432()664     public void testBug1832432() throws CloneNotSupportedException {
665         TimeSeries s1 = new TimeSeries("Series");
666         TimeSeries s2 = (TimeSeries) s1.clone();
667         assertTrue(s1 != s2);
668         assertTrue(s1.getClass() == s2.getClass());
669         assertTrue(s1.equals(s2));
670 
671         // test independence
672         s1.add(new Day(1, 1, 2007), 100.0);
673         assertFalse(s1.equals(s2));
674     }
675 
676     /**
677      * Some checks for the getIndex() method.
678      */
679     @Test
testGetIndex()680     public void testGetIndex() {
681         TimeSeries series = new TimeSeries("Series", Month.class);
682         assertEquals(-1, series.getIndex(new Month(1, 2003)));
683 
684         series.add(new Month(1, 2003), 45.0);
685         assertEquals(0, series.getIndex(new Month(1, 2003)));
686         assertEquals(-1, series.getIndex(new Month(12, 2002)));
687         assertEquals(-2, series.getIndex(new Month(2, 2003)));
688 
689         series.add(new Month(3, 2003), 55.0);
690         assertEquals(-1, series.getIndex(new Month(12, 2002)));
691         assertEquals(0, series.getIndex(new Month(1, 2003)));
692         assertEquals(-2, series.getIndex(new Month(2, 2003)));
693         assertEquals(1, series.getIndex(new Month(3, 2003)));
694         assertEquals(-3, series.getIndex(new Month(4, 2003)));
695     }
696 
697     /**
698      * Some checks for the getDataItem(int) method.
699      */
700     @Test
testGetDataItem1()701     public void testGetDataItem1() {
702         TimeSeries series = new TimeSeries("S", Year.class);
703 
704         // can't get anything yet...just an exception
705         boolean pass = false;
706         try {
707             /*TimeSeriesDataItem item =*/ series.getDataItem(0);
708         }
709         catch (IndexOutOfBoundsException e) {
710             pass = true;
711         }
712         assertTrue(pass);
713 
714         series.add(new Year(2006), 100.0);
715         TimeSeriesDataItem item = series.getDataItem(0);
716         assertEquals(new Year(2006), item.getPeriod());
717         pass = false;
718         try {
719             /*item = */series.getDataItem(-1);
720         }
721         catch (IndexOutOfBoundsException e) {
722             pass = true;
723         }
724         assertTrue(pass);
725 
726         pass = false;
727         try {
728             /*item = */series.getDataItem(1);
729         }
730         catch (IndexOutOfBoundsException e) {
731             pass = true;
732         }
733         assertTrue(pass);
734     }
735 
736     /**
737      * Some checks for the getDataItem(RegularTimePeriod) method.
738      */
739     @Test
testGetDataItem2()740     public void testGetDataItem2() {
741         TimeSeries series = new TimeSeries("S", Year.class);
742         assertNull(series.getDataItem(new Year(2006)));
743 
744         // try a null argument
745         boolean pass = false;
746         try {
747             /* TimeSeriesDataItem item = */ series.getDataItem(null);
748         }
749         catch (IllegalArgumentException e) {
750             pass = true;
751         }
752         assertTrue(pass);
753     }
754 
755     /**
756      * Some checks for the removeAgedItems() method.
757      */
758     @Test
testRemoveAgedItems()759     public void testRemoveAgedItems() {
760         TimeSeries series = new TimeSeries("Test Series", Year.class);
761         series.addChangeListener(this);
762         assertEquals(Long.MAX_VALUE, series.getMaximumItemAge());
763         assertEquals(Integer.MAX_VALUE, series.getMaximumItemCount());
764         this.gotSeriesChangeEvent = false;
765 
766         // test empty series
767         series.removeAgedItems(true);
768         assertEquals(0, series.getItemCount());
769         assertFalse(this.gotSeriesChangeEvent);
770 
771         // test series with one item
772         series.add(new Year(1999), 1.0);
773         series.setMaximumItemAge(0);
774         this.gotSeriesChangeEvent = false;
775         series.removeAgedItems(true);
776         assertEquals(1, series.getItemCount());
777         assertFalse(this.gotSeriesChangeEvent);
778 
779         // test series with two items
780         series.setMaximumItemAge(10);
781         series.add(new Year(2001), 2.0);
782         this.gotSeriesChangeEvent = false;
783         series.setMaximumItemAge(2);
784         assertEquals(2, series.getItemCount());
785         assertEquals(0, series.getIndex(new Year(1999)));
786         assertFalse(this.gotSeriesChangeEvent);
787         series.setMaximumItemAge(1);
788         assertEquals(1, series.getItemCount());
789         assertEquals(0, series.getIndex(new Year(2001)));
790         assertTrue(this.gotSeriesChangeEvent);
791     }
792 
793     /**
794      * Some checks for the removeAgedItems(long, boolean) method.
795      */
796     @Test
testRemoveAgedItems2()797     public void testRemoveAgedItems2() {
798         long y2006 = 1157087372534L;  // milliseconds somewhere in 2006
799         TimeSeries series = new TimeSeries("Test Series", Year.class);
800         series.addChangeListener(this);
801         assertEquals(Long.MAX_VALUE, series.getMaximumItemAge());
802         assertEquals(Integer.MAX_VALUE, series.getMaximumItemCount());
803         this.gotSeriesChangeEvent = false;
804 
805         // test empty series
806         series.removeAgedItems(y2006, true);
807         assertEquals(0, series.getItemCount());
808         assertFalse(this.gotSeriesChangeEvent);
809 
810         // test a series with 1 item
811         series.add(new Year(2004), 1.0);
812         series.setMaximumItemAge(1);
813         this.gotSeriesChangeEvent = false;
814         series.removeAgedItems(new Year(2005).getMiddleMillisecond(), true);
815         assertEquals(1, series.getItemCount());
816         assertFalse(this.gotSeriesChangeEvent);
817         series.removeAgedItems(y2006, true);
818         assertEquals(0, series.getItemCount());
819         assertTrue(this.gotSeriesChangeEvent);
820 
821         // test a series with two items
822         series.setMaximumItemAge(2);
823         series.add(new Year(2003), 1.0);
824         series.add(new Year(2005), 2.0);
825         assertEquals(2, series.getItemCount());
826         this.gotSeriesChangeEvent = false;
827         assertEquals(2, series.getItemCount());
828 
829         series.removeAgedItems(new Year(2005).getMiddleMillisecond(), true);
830         assertEquals(2, series.getItemCount());
831         assertFalse(this.gotSeriesChangeEvent);
832         series.removeAgedItems(y2006, true);
833         assertEquals(1, series.getItemCount());
834         assertTrue(this.gotSeriesChangeEvent);
835     }
836 
837     /**
838      * Calling removeAgedItems() on an empty series should not throw any
839      * exception.
840      */
841     @Test
testRemoveAgedItems3()842     public void testRemoveAgedItems3() {
843         TimeSeries s = new TimeSeries("Test");
844         boolean pass = true;
845         try {
846             s.removeAgedItems(0L, true);
847         }
848         catch (Exception e) {
849             pass = false;
850         }
851         assertTrue(pass);
852     }
853 
854     /**
855      * Check that the item bounds are determined correctly when there is a
856      * maximum item count.
857      */
858     @Test
testRemoveAgedItems4()859     public void testRemoveAgedItems4() {
860         TimeSeries s1 = new TimeSeries("S1");
861         s1.setMaximumItemAge(2);
862         s1.add(new Year(2010), 1.1);
863         s1.add(new Year(2011), 2.2);
864         s1.add(new Year(2012), 3.3);
865         s1.add(new Year(2013), 2.5);
866         assertEquals(3, s1.getItemCount());
867         assertEquals(2.2, s1.getMinY(), EPSILON);
868         assertEquals(3.3, s1.getMaxY(), EPSILON);
869     }
870 
871     /**
872      * Check that the item bounds are determined correctly after a call to
873      * removeAgedItems().
874      */
875     @Test
testRemoveAgedItems5()876     public void testRemoveAgedItems5() {
877         TimeSeries s1 = new TimeSeries("S1");
878         s1.setMaximumItemAge(4);
879         s1.add(new Year(2010), 1.1);
880         s1.add(new Year(2011), 2.2);
881         s1.add(new Year(2012), 3.3);
882         s1.add(new Year(2013), 2.5);
883         s1.removeAgedItems(new Year(2015).getMiddleMillisecond(), true);
884         assertEquals(3, s1.getItemCount());
885         assertEquals(2.2, s1.getMinY(), EPSILON);
886         assertEquals(3.3, s1.getMaxY(), EPSILON);
887     }
888 
889     /**
890      * Some simple checks for the hashCode() method.
891      */
892     @Test
testHashCode()893     public void testHashCode() {
894         TimeSeries s1 = new TimeSeries("Test");
895         TimeSeries s2 = new TimeSeries("Test");
896         assertEquals(s1, s2);
897         assertEquals(s1.hashCode(), s2.hashCode());
898 
899         s1.add(new Day(1, 1, 2007), 500.0);
900         s2.add(new Day(1, 1, 2007), 500.0);
901         assertEquals(s1, s2);
902         assertEquals(s1.hashCode(), s2.hashCode());
903 
904         s1.add(new Day(2, 1, 2007), null);
905         s2.add(new Day(2, 1, 2007), null);
906         assertEquals(s1, s2);
907         assertEquals(s1.hashCode(), s2.hashCode());
908 
909         s1.add(new Day(5, 1, 2007), 111.0);
910         s2.add(new Day(5, 1, 2007), 111.0);
911         assertEquals(s1, s2);
912         assertEquals(s1.hashCode(), s2.hashCode());
913 
914         s1.add(new Day(9, 1, 2007), 1.0);
915         s2.add(new Day(9, 1, 2007), 1.0);
916         assertEquals(s1, s2);
917         assertEquals(s1.hashCode(), s2.hashCode());
918     }
919 
920     /**
921      * Test for bug report 1864222.
922      */
923     @Test
testBug1864222()924     public void testBug1864222() {
925         TimeSeries s = new TimeSeries("S");
926         s.add(new Day(19, 8, 2005), 1);
927         s.add(new Day(31, 1, 2006), 1);
928         boolean pass = true;
929         try {
930             s.createCopy(new Day(1, 12, 2005), new Day(18, 1, 2006));
931         }
932         catch (CloneNotSupportedException e) {
933             pass = false;
934         }
935         assertTrue(pass);
936     }
937 
938     /**
939      * Test for bug report 3446965.
940      */
941     @Test
testBug3446965()942     public void testBug3446965() {
943         TimeSeries s = new TimeSeries("s");
944         s.addOrUpdate(new Year(2011), 100.0);
945         s.addOrUpdate(new Year(2012), 150.0);
946         s.addOrUpdate(new Year(2013), 200.0);
947         s.addOrUpdate(new Year(2012), 250.0);  // this line triggers the defect
948         assertEquals(100.0, s.getMinY(), EPSILON);
949         assertEquals(250.0, s.getMaxY(), EPSILON);
950     }
951 
952     private static final double EPSILON = 0.0000000001;
953 
954     /**
955      * Some checks for the getMinY() method.
956      */
957     @Test
testGetMinY()958     public void testGetMinY() {
959         TimeSeries s1 = new TimeSeries("S1");
960         assertTrue(Double.isNaN(s1.getMinY()));
961 
962         s1.add(new Year(2008), 1.1);
963         assertEquals(1.1, s1.getMinY(), EPSILON);
964 
965         s1.add(new Year(2009), 2.2);
966         assertEquals(1.1, s1.getMinY(), EPSILON);
967 
968         s1.add(new Year(2000), 99.9);
969         assertEquals(1.1, s1.getMinY(), EPSILON);
970 
971         s1.add(new Year(2002), -1.1);
972         assertEquals(-1.1, s1.getMinY(), EPSILON);
973 
974         s1.add(new Year(2003), null);
975         assertEquals(-1.1, s1.getMinY(), EPSILON);
976 
977         s1.addOrUpdate(new Year(2002), null);
978         assertEquals(1.1, s1.getMinY(), EPSILON);
979    }
980 
981     /**
982      * Some checks for the getMaxY() method.
983      */
984     @Test
testGetMaxY()985     public void testGetMaxY() {
986         TimeSeries s1 = new TimeSeries("S1");
987         assertTrue(Double.isNaN(s1.getMaxY()));
988 
989         s1.add(new Year(2008), 1.1);
990         assertEquals(1.1, s1.getMaxY(), EPSILON);
991 
992         s1.add(new Year(2009), 2.2);
993         assertEquals(2.2, s1.getMaxY(), EPSILON);
994 
995         s1.add(new Year(2000), 99.9);
996         assertEquals(99.9, s1.getMaxY(), EPSILON);
997 
998         s1.add(new Year(2002), -1.1);
999         assertEquals(99.9, s1.getMaxY(), EPSILON);
1000 
1001         s1.add(new Year(2003), null);
1002         assertEquals(99.9, s1.getMaxY(), EPSILON);
1003 
1004         s1.addOrUpdate(new Year(2000), null);
1005         assertEquals(2.2, s1.getMaxY(), EPSILON);
1006     }
1007 
1008     /**
1009      * A test for the clear method.
1010      */
1011     @Test
testClear()1012     public void testClear() {
1013         TimeSeries s1 = new TimeSeries("S1");
1014         s1.add(new Year(2009), 1.1);
1015         s1.add(new Year(2010), 2.2);
1016 
1017         assertEquals(2, s1.getItemCount());
1018 
1019         s1.clear();
1020         assertEquals(0, s1.getItemCount());
1021         assertTrue(Double.isNaN(s1.getMinY()));
1022         assertTrue(Double.isNaN(s1.getMaxY()));
1023     }
1024 
1025     /**
1026      * Check that the item bounds are determined correctly when there is a
1027      * maximum item count and a new value is added.
1028      */
1029     @Test
testAdd()1030     public void testAdd() {
1031         TimeSeries s1 = new TimeSeries("S1");
1032         s1.setMaximumItemCount(2);
1033         s1.add(new Year(2010), 1.1);
1034         s1.add(new Year(2011), 2.2);
1035         s1.add(new Year(2012), 3.3);
1036         assertEquals(2, s1.getItemCount());
1037         assertEquals(2.2, s1.getMinY(), EPSILON);
1038         assertEquals(3.3, s1.getMaxY(), EPSILON);
1039     }
1040 
1041     /**
1042      * Some checks for the update(RegularTimePeriod...method).
1043      */
1044     @Test
testUpdate_RegularTimePeriod()1045     public void testUpdate_RegularTimePeriod() {
1046         TimeSeries s1 = new TimeSeries("S1");
1047         s1.add(new Year(2010), 1.1);
1048         s1.add(new Year(2011), 2.2);
1049         s1.add(new Year(2012), 3.3);
1050         s1.update(new Year(2012), 4.4);
1051         assertEquals(4.4, s1.getMaxY(), EPSILON);
1052         s1.update(new Year(2010), 0.5);
1053         assertEquals(0.5, s1.getMinY(), EPSILON);
1054         s1.update(new Year(2012), null);
1055         assertEquals(2.2, s1.getMaxY(), EPSILON);
1056         s1.update(new Year(2010), null);
1057         assertEquals(2.2, s1.getMinY(), EPSILON);
1058     }
1059 
1060     /**
1061      * Create a TimeSeriesDataItem, add it to a TimeSeries.  Now, modifying
1062      * the original TimeSeriesDataItem should NOT affect the TimeSeries.
1063      */
1064     @Test
testAdd_TimeSeriesDataItem()1065     public void testAdd_TimeSeriesDataItem() {
1066         TimeSeriesDataItem item = new TimeSeriesDataItem(new Year(2009), 1.0);
1067         TimeSeries series = new TimeSeries("S1");
1068         series.add(item);
1069         assertTrue(item.equals(series.getDataItem(0)));
1070         item.setValue(new Double(99.9));
1071         assertFalse(item.equals(series.getDataItem(0)));
1072     }
1073 
1074     @Test
testSetKey()1075     public void testSetKey() {
1076         TimeSeries s1 = new TimeSeries("S");
1077         s1.setKey("S1");
1078         assertEquals("S1", s1.getKey());
1079 
1080         TimeSeriesCollection c = new TimeSeriesCollection();
1081         c.addSeries(s1);
1082         TimeSeries s2 = new TimeSeries("S2");
1083         c.addSeries(s2);
1084 
1085         // now we should be allowed to change s1's key to anything but "S2"
1086         s1.setKey("OK");
1087         assertEquals("OK", s1.getKey());
1088 
1089         try {
1090             s1.setKey("S2");
1091             fail("Expect an exception here.");
1092         } catch (IllegalArgumentException e) {
1093             // OK
1094         }
1095 
1096         // after s1 is removed from the collection, we should be able to set
1097         // the key to anything we want...
1098         c.removeSeries(s1);
1099         s1.setKey("S2");
1100 
1101         // check that removing by index also works
1102         s1.setKey("S1");
1103         c.addSeries(s1);
1104         c.removeSeries(1);
1105         s1.setKey("S2");
1106     }
1107 
1108 }
1109