001    /*
002     *  Copyright 2001-2005 Stephen Colebourne
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     */
016    package org.joda.time;
017    
018    import java.io.ByteArrayInputStream;
019    import java.io.ByteArrayOutputStream;
020    import java.io.ObjectInputStream;
021    import java.io.ObjectOutputStream;
022    import java.util.Locale;
023    import java.util.TimeZone;
024    
025    import junit.framework.TestCase;
026    import junit.framework.TestSuite;
027    
028    /**
029     * This class is a JUnit test for PeriodType.
030     *
031     * @author Stephen Colebourne
032     */
033    public class TestPeriodType extends TestCase {
034        // Test in 2002/03 as time zones are more well known
035        // (before the late 90's they were all over the place)
036    
037        private static final DateTimeZone PARIS = DateTimeZone.forID("Europe/Paris");
038        private static final DateTimeZone LONDON = DateTimeZone.forID("Europe/London");
039        
040        long y2002days = 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 + 
041                         366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 
042                         365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 +
043                         366 + 365;
044        long y2003days = 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 + 
045                         366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 
046                         365 + 365 + 366 + 365 + 365 + 365 + 366 + 365 + 365 + 365 +
047                         366 + 365 + 365;
048        
049        // 2002-06-09
050        private long TEST_TIME_NOW =
051                (y2002days + 31L + 28L + 31L + 30L + 31L + 9L -1L) * DateTimeConstants.MILLIS_PER_DAY;
052                
053        // 2002-04-05
054        private long TEST_TIME1 =
055                (y2002days + 31L + 28L + 31L + 5L -1L) * DateTimeConstants.MILLIS_PER_DAY
056                + 12L * DateTimeConstants.MILLIS_PER_HOUR
057                + 24L * DateTimeConstants.MILLIS_PER_MINUTE;
058            
059        // 2003-05-06
060        private long TEST_TIME2 =
061                (y2003days + 31L + 28L + 31L + 30L + 6L -1L) * DateTimeConstants.MILLIS_PER_DAY
062                + 14L * DateTimeConstants.MILLIS_PER_HOUR
063                + 28L * DateTimeConstants.MILLIS_PER_MINUTE;
064        
065        private DateTimeZone originalDateTimeZone = null;
066        private TimeZone originalTimeZone = null;
067        private Locale originalLocale = null;
068    
069        public static void main(String[] args) {
070            junit.textui.TestRunner.run(suite());
071        }
072    
073        public static TestSuite suite() {
074            return new TestSuite(TestPeriodType.class);
075        }
076    
077        public TestPeriodType(String name) {
078            super(name);
079        }
080    
081        protected void setUp() throws Exception {
082            DateTimeUtils.setCurrentMillisFixed(TEST_TIME_NOW);
083            originalDateTimeZone = DateTimeZone.getDefault();
084            originalTimeZone = TimeZone.getDefault();
085            originalLocale = Locale.getDefault();
086            DateTimeZone.setDefault(LONDON);
087            TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
088            Locale.setDefault(Locale.UK);
089        }
090    
091        protected void tearDown() throws Exception {
092            DateTimeUtils.setCurrentMillisSystem();
093            DateTimeZone.setDefault(originalDateTimeZone);
094            TimeZone.setDefault(originalTimeZone);
095            Locale.setDefault(originalLocale);
096            originalDateTimeZone = null;
097            originalTimeZone = null;
098            originalLocale = null;
099        }
100    
101        //-----------------------------------------------------------------------
102        public void testTest() {
103            assertEquals("2002-06-09T00:00:00.000Z", new Instant(TEST_TIME_NOW).toString());
104            assertEquals("2002-04-05T12:24:00.000Z", new Instant(TEST_TIME1).toString());
105            assertEquals("2003-05-06T14:28:00.000Z", new Instant(TEST_TIME2).toString());
106        }
107    
108        //-----------------------------------------------------------------------
109        private void assertEqualsAfterSerialization(PeriodType type) throws Exception {
110            ByteArrayOutputStream baos = new ByteArrayOutputStream();
111            ObjectOutputStream oos = new ObjectOutputStream(baos);
112            oos.writeObject(type);
113            byte[] bytes = baos.toByteArray();
114            oos.close();
115            
116            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
117            ObjectInputStream ois = new ObjectInputStream(bais);
118            PeriodType result = (PeriodType) ois.readObject();
119            ois.close();
120            
121            assertEquals(type, result);
122        }
123    
124        private void assertSameAfterSerialization(PeriodType type) throws Exception {
125            ByteArrayOutputStream baos = new ByteArrayOutputStream();
126            ObjectOutputStream oos = new ObjectOutputStream(baos);
127            oos.writeObject(type);
128            byte[] bytes = baos.toByteArray();
129            oos.close();
130            
131            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
132            ObjectInputStream ois = new ObjectInputStream(bais);
133            PeriodType result = (PeriodType) ois.readObject();
134            ois.close();
135            
136            assertEquals(type, result);
137        }
138    
139        //-----------------------------------------------------------------------
140        public void testStandard() throws Exception {
141            PeriodType type = PeriodType.standard();
142            assertEquals(8, type.size());
143            assertEquals(DurationFieldType.years(), type.getFieldType(0));
144            assertEquals(DurationFieldType.months(), type.getFieldType(1));
145            assertEquals(DurationFieldType.weeks(), type.getFieldType(2));
146            assertEquals(DurationFieldType.days(), type.getFieldType(3));
147            assertEquals(DurationFieldType.hours(), type.getFieldType(4));
148            assertEquals(DurationFieldType.minutes(), type.getFieldType(5));
149            assertEquals(DurationFieldType.seconds(), type.getFieldType(6));
150            assertEquals(DurationFieldType.millis(), type.getFieldType(7));
151            assertEquals("Standard", type.getName());
152            assertEquals("PeriodType[Standard]", type.toString());
153            assertEquals(true, type.equals(type));
154            assertEquals(true, type == PeriodType.standard());
155            assertEquals(false, type.equals(PeriodType.millis()));
156            assertEquals(true, type.hashCode() == type.hashCode());
157            assertEquals(true, type.hashCode() == PeriodType.standard().hashCode());
158            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
159            assertSameAfterSerialization(type);
160        }
161    
162        //-----------------------------------------------------------------------
163        public void testYearMonthDayTime() throws Exception {
164            PeriodType type = PeriodType.yearMonthDayTime();
165            assertEquals(7, type.size());
166            assertEquals(DurationFieldType.years(), type.getFieldType(0));
167            assertEquals(DurationFieldType.months(), type.getFieldType(1));
168            assertEquals(DurationFieldType.days(), type.getFieldType(2));
169            assertEquals(DurationFieldType.hours(), type.getFieldType(3));
170            assertEquals(DurationFieldType.minutes(), type.getFieldType(4));
171            assertEquals(DurationFieldType.seconds(), type.getFieldType(5));
172            assertEquals(DurationFieldType.millis(), type.getFieldType(6));
173            assertEquals("YearMonthDayTime", type.getName());
174            assertEquals("PeriodType[YearMonthDayTime]", type.toString());
175            assertEquals(true, type.equals(type));
176            assertEquals(true, type == PeriodType.yearMonthDayTime());
177            assertEquals(false, type.equals(PeriodType.millis()));
178            assertEquals(true, type.hashCode() == type.hashCode());
179            assertEquals(true, type.hashCode() == PeriodType.yearMonthDayTime().hashCode());
180            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
181            assertSameAfterSerialization(type);
182        }
183    
184        //-----------------------------------------------------------------------
185        public void testYearMonthDay() throws Exception {
186            PeriodType type = PeriodType.yearMonthDay();
187            assertEquals(3, type.size());
188            assertEquals(DurationFieldType.years(), type.getFieldType(0));
189            assertEquals(DurationFieldType.months(), type.getFieldType(1));
190            assertEquals(DurationFieldType.days(), type.getFieldType(2));
191            assertEquals("YearMonthDay", type.getName());
192            assertEquals("PeriodType[YearMonthDay]", type.toString());
193            assertEquals(true, type.equals(type));
194            assertEquals(true, type == PeriodType.yearMonthDay());
195            assertEquals(false, type.equals(PeriodType.millis()));
196            assertEquals(true, type.hashCode() == type.hashCode());
197            assertEquals(true, type.hashCode() == PeriodType.yearMonthDay().hashCode());
198            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
199            assertSameAfterSerialization(type);
200        }
201    
202        //-----------------------------------------------------------------------
203        public void testYearWeekDayTime() throws Exception {
204            PeriodType type = PeriodType.yearWeekDayTime();
205            assertEquals(7, type.size());
206            assertEquals(DurationFieldType.years(), type.getFieldType(0));
207            assertEquals(DurationFieldType.weeks(), type.getFieldType(1));
208            assertEquals(DurationFieldType.days(), type.getFieldType(2));
209            assertEquals(DurationFieldType.hours(), type.getFieldType(3));
210            assertEquals(DurationFieldType.minutes(), type.getFieldType(4));
211            assertEquals(DurationFieldType.seconds(), type.getFieldType(5));
212            assertEquals(DurationFieldType.millis(), type.getFieldType(6));
213            assertEquals("YearWeekDayTime", type.getName());
214            assertEquals("PeriodType[YearWeekDayTime]", type.toString());
215            assertEquals(true, type.equals(type));
216            assertEquals(true, type == PeriodType.yearWeekDayTime());
217            assertEquals(false, type.equals(PeriodType.millis()));
218            assertEquals(true, type.hashCode() == type.hashCode());
219            assertEquals(true, type.hashCode() == PeriodType.yearWeekDayTime().hashCode());
220            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
221            assertSameAfterSerialization(type);
222        }
223    
224        //-----------------------------------------------------------------------
225        public void testYearWeekDay() throws Exception {
226            PeriodType type = PeriodType.yearWeekDay();
227            assertEquals(3, type.size());
228            assertEquals(DurationFieldType.years(), type.getFieldType(0));
229            assertEquals(DurationFieldType.weeks(), type.getFieldType(1));
230            assertEquals(DurationFieldType.days(), type.getFieldType(2));
231            assertEquals("YearWeekDay", type.getName());
232            assertEquals("PeriodType[YearWeekDay]", type.toString());
233            assertEquals(true, type.equals(type));
234            assertEquals(true, type == PeriodType.yearWeekDay());
235            assertEquals(false, type.equals(PeriodType.millis()));
236            assertEquals(true, type.hashCode() == type.hashCode());
237            assertEquals(true, type.hashCode() == PeriodType.yearWeekDay().hashCode());
238            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
239            assertSameAfterSerialization(type);
240        }
241    
242        //-----------------------------------------------------------------------
243        public void testYearDayTime() throws Exception {
244            PeriodType type = PeriodType.yearDayTime();
245            assertEquals(6, type.size());
246            assertEquals(DurationFieldType.years(), type.getFieldType(0));
247            assertEquals(DurationFieldType.days(), type.getFieldType(1));
248            assertEquals(DurationFieldType.hours(), type.getFieldType(2));
249            assertEquals(DurationFieldType.minutes(), type.getFieldType(3));
250            assertEquals(DurationFieldType.seconds(), type.getFieldType(4));
251            assertEquals(DurationFieldType.millis(), type.getFieldType(5));
252            assertEquals("YearDayTime", type.getName());
253            assertEquals("PeriodType[YearDayTime]", type.toString());
254            assertEquals(true, type.equals(type));
255            assertEquals(true, type == PeriodType.yearDayTime());
256            assertEquals(false, type.equals(PeriodType.millis()));
257            assertEquals(true, type.hashCode() == type.hashCode());
258            assertEquals(true, type.hashCode() == PeriodType.yearDayTime().hashCode());
259            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
260            assertSameAfterSerialization(type);
261        }
262    
263        //-----------------------------------------------------------------------
264        public void testYearDay() throws Exception {
265            PeriodType type = PeriodType.yearDay();
266            assertEquals(2, type.size());
267            assertEquals(DurationFieldType.years(), type.getFieldType(0));
268            assertEquals(DurationFieldType.days(), type.getFieldType(1));
269            assertEquals("YearDay", type.getName());
270            assertEquals("PeriodType[YearDay]", type.toString());
271            assertEquals(true, type.equals(type));
272            assertEquals(true, type == PeriodType.yearDay());
273            assertEquals(false, type.equals(PeriodType.millis()));
274            assertEquals(true, type.hashCode() == type.hashCode());
275            assertEquals(true, type.hashCode() == PeriodType.yearDay().hashCode());
276            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
277            assertSameAfterSerialization(type);
278        }
279    
280        //-----------------------------------------------------------------------
281        public void testDayTime() throws Exception {
282            PeriodType type = PeriodType.dayTime();
283            assertEquals(5, type.size());
284            assertEquals(DurationFieldType.days(), type.getFieldType(0));
285            assertEquals(DurationFieldType.hours(), type.getFieldType(1));
286            assertEquals(DurationFieldType.minutes(), type.getFieldType(2));
287            assertEquals(DurationFieldType.seconds(), type.getFieldType(3));
288            assertEquals(DurationFieldType.millis(), type.getFieldType(4));
289            assertEquals("DayTime", type.getName());
290            assertEquals("PeriodType[DayTime]", type.toString());
291            assertEquals(true, type.equals(type));
292            assertEquals(true, type == PeriodType.dayTime());
293            assertEquals(false, type.equals(PeriodType.millis()));
294            assertEquals(true, type.hashCode() == type.hashCode());
295            assertEquals(true, type.hashCode() == PeriodType.dayTime().hashCode());
296            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
297            assertSameAfterSerialization(type);
298        }
299    
300        //-----------------------------------------------------------------------
301        public void testTime() throws Exception {
302            PeriodType type = PeriodType.time();
303            assertEquals(4, type.size());
304            assertEquals(DurationFieldType.hours(), type.getFieldType(0));
305            assertEquals(DurationFieldType.minutes(), type.getFieldType(1));
306            assertEquals(DurationFieldType.seconds(), type.getFieldType(2));
307            assertEquals(DurationFieldType.millis(), type.getFieldType(3));
308            assertEquals("Time", type.getName());
309            assertEquals("PeriodType[Time]", type.toString());
310            assertEquals(true, type.equals(type));
311            assertEquals(true, type == PeriodType.time());
312            assertEquals(false, type.equals(PeriodType.millis()));
313            assertEquals(true, type.hashCode() == type.hashCode());
314            assertEquals(true, type.hashCode() == PeriodType.time().hashCode());
315            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
316            assertSameAfterSerialization(type);
317        }
318    
319        //-----------------------------------------------------------------------
320        public void testYears() throws Exception {
321            PeriodType type = PeriodType.years();
322            assertEquals(1, type.size());
323            assertEquals(DurationFieldType.years(), type.getFieldType(0));
324            assertEquals("Years", type.getName());
325            assertEquals("PeriodType[Years]", type.toString());
326            assertEquals(true, type.equals(type));
327            assertEquals(true, type == PeriodType.years());
328            assertEquals(false, type.equals(PeriodType.standard()));
329            assertEquals(true, type.hashCode() == type.hashCode());
330            assertEquals(true, type.hashCode() == PeriodType.years().hashCode());
331            assertEquals(false, type.hashCode() == PeriodType.standard().hashCode());
332            assertSameAfterSerialization(type);
333        }
334    
335        //-----------------------------------------------------------------------
336        public void testMonths() throws Exception {
337            PeriodType type = PeriodType.months();
338            assertEquals(1, type.size());
339            assertEquals(DurationFieldType.months(), type.getFieldType(0));
340            assertEquals("Months", type.getName());
341            assertEquals("PeriodType[Months]", type.toString());
342            assertEquals(true, type.equals(type));
343            assertEquals(true, type == PeriodType.months());
344            assertEquals(false, type.equals(PeriodType.standard()));
345            assertEquals(true, type.hashCode() == type.hashCode());
346            assertEquals(true, type.hashCode() == PeriodType.months().hashCode());
347            assertEquals(false, type.hashCode() == PeriodType.standard().hashCode());
348            assertSameAfterSerialization(type);
349        }
350    
351        //-----------------------------------------------------------------------
352        public void testWeeks() throws Exception {
353            PeriodType type = PeriodType.weeks();
354            assertEquals(1, type.size());
355            assertEquals(DurationFieldType.weeks(), type.getFieldType(0));
356            assertEquals("Weeks", type.getName());
357            assertEquals("PeriodType[Weeks]", type.toString());
358            assertEquals(true, type.equals(type));
359            assertEquals(true, type == PeriodType.weeks());
360            assertEquals(false, type.equals(PeriodType.standard()));
361            assertEquals(true, type.hashCode() == type.hashCode());
362            assertEquals(true, type.hashCode() == PeriodType.weeks().hashCode());
363            assertEquals(false, type.hashCode() == PeriodType.standard().hashCode());
364            assertSameAfterSerialization(type);
365        }
366    
367        //-----------------------------------------------------------------------
368        public void testDays() throws Exception {
369            PeriodType type = PeriodType.days();
370            assertEquals(1, type.size());
371            assertEquals(DurationFieldType.days(), type.getFieldType(0));
372            assertEquals("Days", type.getName());
373            assertEquals("PeriodType[Days]", type.toString());
374            assertEquals(true, type.equals(type));
375            assertEquals(true, type == PeriodType.days());
376            assertEquals(false, type.equals(PeriodType.standard()));
377            assertEquals(true, type.hashCode() == type.hashCode());
378            assertEquals(true, type.hashCode() == PeriodType.days().hashCode());
379            assertEquals(false, type.hashCode() == PeriodType.standard().hashCode());
380            assertSameAfterSerialization(type);
381        }
382    
383        //-----------------------------------------------------------------------
384        public void testHours() throws Exception {
385            PeriodType type = PeriodType.hours();
386            assertEquals(1, type.size());
387            assertEquals(DurationFieldType.hours(), type.getFieldType(0));
388            assertEquals("Hours", type.getName());
389            assertEquals("PeriodType[Hours]", type.toString());
390            assertEquals(true, type.equals(type));
391            assertEquals(true, type == PeriodType.hours());
392            assertEquals(false, type.equals(PeriodType.standard()));
393            assertEquals(true, type.hashCode() == type.hashCode());
394            assertEquals(true, type.hashCode() == PeriodType.hours().hashCode());
395            assertEquals(false, type.hashCode() == PeriodType.standard().hashCode());
396            assertSameAfterSerialization(type);
397        }
398    
399        //-----------------------------------------------------------------------
400        public void testMinutes() throws Exception {
401            PeriodType type = PeriodType.minutes();
402            assertEquals(1, type.size());
403            assertEquals(DurationFieldType.minutes(), type.getFieldType(0));
404            assertEquals("Minutes", type.getName());
405            assertEquals("PeriodType[Minutes]", type.toString());
406            assertEquals(true, type.equals(type));
407            assertEquals(true, type == PeriodType.minutes());
408            assertEquals(false, type.equals(PeriodType.standard()));
409            assertEquals(true, type.hashCode() == type.hashCode());
410            assertEquals(true, type.hashCode() == PeriodType.minutes().hashCode());
411            assertEquals(false, type.hashCode() == PeriodType.standard().hashCode());
412            assertSameAfterSerialization(type);
413        }
414    
415        //-----------------------------------------------------------------------
416        public void testSeconds() throws Exception {
417            PeriodType type = PeriodType.seconds();
418            assertEquals(1, type.size());
419            assertEquals(DurationFieldType.seconds(), type.getFieldType(0));
420            assertEquals("Seconds", type.getName());
421            assertEquals("PeriodType[Seconds]", type.toString());
422            assertEquals(true, type.equals(type));
423            assertEquals(true, type == PeriodType.seconds());
424            assertEquals(false, type.equals(PeriodType.standard()));
425            assertEquals(true, type.hashCode() == type.hashCode());
426            assertEquals(true, type.hashCode() == PeriodType.seconds().hashCode());
427            assertEquals(false, type.hashCode() == PeriodType.standard().hashCode());
428            assertSameAfterSerialization(type);
429        }
430    
431        //-----------------------------------------------------------------------
432        public void testMillis() throws Exception {
433            PeriodType type = PeriodType.millis();
434            assertEquals(1, type.size());
435            assertEquals(DurationFieldType.millis(), type.getFieldType(0));
436            assertEquals("Millis", type.getName());
437            assertEquals("PeriodType[Millis]", type.toString());
438            assertEquals(true, type.equals(type));
439            assertEquals(true, type == PeriodType.millis());
440            assertEquals(false, type.equals(PeriodType.standard()));
441            assertEquals(true, type.hashCode() == type.hashCode());
442            assertEquals(true, type.hashCode() == PeriodType.millis().hashCode());
443            assertEquals(false, type.hashCode() == PeriodType.standard().hashCode());
444            assertSameAfterSerialization(type);
445        }
446    
447        //-----------------------------------------------------------------------
448        public void testForFields1() throws Exception {
449            PeriodType type = PeriodType.forFields(new DurationFieldType[] {
450                DurationFieldType.years(),
451            });
452            assertSame(PeriodType.years(), type);
453            type = PeriodType.forFields(new DurationFieldType[] {
454                DurationFieldType.months(),
455            });
456            assertSame(PeriodType.months(), type);
457            type = PeriodType.forFields(new DurationFieldType[] {
458                    DurationFieldType.weeks(),
459            });
460            assertSame(PeriodType.weeks(), type);
461            type = PeriodType.forFields(new DurationFieldType[] {
462                    DurationFieldType.days(),
463            });
464            assertSame(PeriodType.days(), type);
465            type = PeriodType.forFields(new DurationFieldType[] {
466                    DurationFieldType.hours(),
467            });
468            assertSame(PeriodType.hours(), type);
469            type = PeriodType.forFields(new DurationFieldType[] {
470                    DurationFieldType.minutes(),
471            });
472            assertSame(PeriodType.minutes(), type);
473            type = PeriodType.forFields(new DurationFieldType[] {
474                    DurationFieldType.seconds(),
475            });
476            assertSame(PeriodType.seconds(), type);
477            type = PeriodType.forFields(new DurationFieldType[] {
478                    DurationFieldType.millis(),
479            });
480            assertSame(PeriodType.millis(), type);
481        }
482    
483        public void testForFields2() throws Exception {
484            DurationFieldType[] types = new DurationFieldType[] {
485                DurationFieldType.years(),
486                DurationFieldType.hours(),
487            };
488            PeriodType type = PeriodType.forFields(types);
489            assertEquals(2, type.size());
490            assertEquals(DurationFieldType.years(), type.getFieldType(0));
491            assertEquals(DurationFieldType.hours(), type.getFieldType(1));
492            assertEquals("StandardNoMonthsNoWeeksNoDaysNoMinutesNoSecondsNoMillis", type.getName());
493            assertEquals("PeriodType[StandardNoMonthsNoWeeksNoDaysNoMinutesNoSecondsNoMillis]", type.toString());
494            assertEquals(true, type.equals(type));
495            assertEquals(true, type == PeriodType.forFields(types));
496            assertEquals(false, type.equals(PeriodType.millis()));
497            assertEquals(true, type.hashCode() == type.hashCode());
498            assertEquals(true, type.hashCode() == PeriodType.forFields(types).hashCode());
499            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
500            assertSameAfterSerialization(type);
501        }
502    
503        public void testForFields3() throws Exception {
504            DurationFieldType[] types = new DurationFieldType[] {
505                DurationFieldType.months(),
506                DurationFieldType.weeks(),
507            };
508            PeriodType type = PeriodType.forFields(types);
509            assertEquals(2, type.size());
510            assertEquals(DurationFieldType.months(), type.getFieldType(0));
511            assertEquals(DurationFieldType.weeks(), type.getFieldType(1));
512            assertEquals("StandardNoYearsNoDaysNoHoursNoMinutesNoSecondsNoMillis", type.getName());
513            assertEquals("PeriodType[StandardNoYearsNoDaysNoHoursNoMinutesNoSecondsNoMillis]", type.toString());
514            assertEquals(true, type.equals(type));
515            assertEquals(true, type == PeriodType.forFields(types));
516            assertEquals(false, type.equals(PeriodType.millis()));
517            assertEquals(true, type.hashCode() == type.hashCode());
518            assertEquals(true, type.hashCode() == PeriodType.forFields(types).hashCode());
519            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
520            assertSameAfterSerialization(type);
521        }
522    
523        public void testForFields4() throws Exception {
524            DurationFieldType[] types = new DurationFieldType[] {
525                DurationFieldType.weeks(),
526                DurationFieldType.days(),  // adding this makes this test unique, so cache is not pre-populated
527                DurationFieldType.months(),
528            };
529            DurationFieldType[] types2 = new DurationFieldType[] {
530                DurationFieldType.months(),
531                DurationFieldType.days(),
532                DurationFieldType.weeks(),
533            };
534            PeriodType type = PeriodType.forFields(types);
535            PeriodType type2 = PeriodType.forFields(types2);
536            assertEquals(true, type == type2);
537        }
538    
539        public void testForFields5() throws Exception {
540            DurationFieldType[] types = new DurationFieldType[] {
541                DurationFieldType.centuries(),
542                DurationFieldType.months(),
543            };
544            try {
545                PeriodType.forFields(types);
546                fail();
547            } catch (IllegalArgumentException ex) {
548                // expected
549            }
550            try {
551                PeriodType.forFields(types);  // repeated for test coverage of cache
552                fail();
553            } catch (IllegalArgumentException ex) {
554                // expected
555            }
556        }
557    
558        public void testForFields6() throws Exception {
559            DurationFieldType[] types = null;
560            try {
561                PeriodType.forFields(types);
562                fail();
563            } catch (IllegalArgumentException ex) {
564                // expected
565            }
566            
567            types = new DurationFieldType[0];
568            try {
569                PeriodType.forFields(types);
570                fail();
571            } catch (IllegalArgumentException ex) {
572                // expected
573            }
574            
575            types = new DurationFieldType[] {
576                null,
577                DurationFieldType.months(),
578            };
579            try {
580                PeriodType.forFields(types);
581                fail();
582            } catch (IllegalArgumentException ex) {
583                // expected
584            }
585            
586            types = new DurationFieldType[] {
587                DurationFieldType.months(),
588                null,
589            };
590            try {
591                PeriodType.forFields(types);
592                fail();
593            } catch (IllegalArgumentException ex) {
594                // expected
595            }
596        }
597    
598        // ensure hash key distribution
599        public void testForFields7() throws Exception {
600            DurationFieldType[] types = new DurationFieldType[] {
601                DurationFieldType.weeks(),
602                DurationFieldType.months(),
603            };
604            DurationFieldType[] types2 = new DurationFieldType[] {
605                DurationFieldType.seconds(),
606            };
607            PeriodType type = PeriodType.forFields(types);
608            PeriodType type2 = PeriodType.forFields(types2);
609            assertEquals(false, type == type2);
610            assertEquals(false, type.equals(type2));
611            assertEquals(false, type.hashCode() == type2.hashCode());
612        }
613    
614        //-----------------------------------------------------------------------
615        public void testMaskYears() throws Exception {
616            PeriodType type = PeriodType.standard().withYearsRemoved();
617            assertEquals(7, type.size());
618            assertEquals(DurationFieldType.months(), type.getFieldType(0));
619            assertEquals(DurationFieldType.weeks(), type.getFieldType(1));
620            assertEquals(DurationFieldType.days(), type.getFieldType(2));
621            assertEquals(DurationFieldType.hours(), type.getFieldType(3));
622            assertEquals(DurationFieldType.minutes(), type.getFieldType(4));
623            assertEquals(DurationFieldType.seconds(), type.getFieldType(5));
624            assertEquals(DurationFieldType.millis(), type.getFieldType(6));
625            assertEquals(true, type.equals(type));
626            assertEquals(true, type.equals(PeriodType.standard().withYearsRemoved()));
627            assertEquals(false, type.equals(PeriodType.millis()));
628            assertEquals(true, type.hashCode() == type.hashCode());
629            assertEquals(true, type.hashCode() == PeriodType.standard().withYearsRemoved().hashCode());
630            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
631            assertEquals("StandardNoYears", type.getName());
632            assertEquals("PeriodType[StandardNoYears]", type.toString());
633            assertEqualsAfterSerialization(type);
634        }
635    
636        //-----------------------------------------------------------------------
637        public void testMaskMonths() throws Exception {
638            PeriodType type = PeriodType.standard().withMonthsRemoved();
639            assertEquals(7, type.size());
640            assertEquals(DurationFieldType.years(), type.getFieldType(0));
641            assertEquals(DurationFieldType.weeks(), type.getFieldType(1));
642            assertEquals(DurationFieldType.days(), type.getFieldType(2));
643            assertEquals(DurationFieldType.hours(), type.getFieldType(3));
644            assertEquals(DurationFieldType.minutes(), type.getFieldType(4));
645            assertEquals(DurationFieldType.seconds(), type.getFieldType(5));
646            assertEquals(DurationFieldType.millis(), type.getFieldType(6));
647            assertEquals(true, type.equals(type));
648            assertEquals(true, type.equals(PeriodType.standard().withMonthsRemoved()));
649            assertEquals(false, type.equals(PeriodType.millis()));
650            assertEquals(true, type.hashCode() == type.hashCode());
651            assertEquals(true, type.hashCode() == PeriodType.standard().withMonthsRemoved().hashCode());
652            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
653            assertEquals("StandardNoMonths", type.getName());
654            assertEquals("PeriodType[StandardNoMonths]", type.toString());
655            assertEqualsAfterSerialization(type);
656        }
657    
658        //-----------------------------------------------------------------------
659        public void testMaskWeeks() throws Exception {
660            PeriodType type = PeriodType.standard().withWeeksRemoved();
661            assertEquals(7, type.size());
662            assertEquals(DurationFieldType.years(), type.getFieldType(0));
663            assertEquals(DurationFieldType.months(), type.getFieldType(1));
664            assertEquals(DurationFieldType.days(), type.getFieldType(2));
665            assertEquals(DurationFieldType.hours(), type.getFieldType(3));
666            assertEquals(DurationFieldType.minutes(), type.getFieldType(4));
667            assertEquals(DurationFieldType.seconds(), type.getFieldType(5));
668            assertEquals(DurationFieldType.millis(), type.getFieldType(6));
669            assertEquals(true, type.equals(type));
670            assertEquals(true, type.equals(PeriodType.standard().withWeeksRemoved()));
671            assertEquals(false, type.equals(PeriodType.millis()));
672            assertEquals(true, type.hashCode() == type.hashCode());
673            assertEquals(true, type.hashCode() == PeriodType.standard().withWeeksRemoved().hashCode());
674            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
675            assertEquals("StandardNoWeeks", type.getName());
676            assertEquals("PeriodType[StandardNoWeeks]", type.toString());
677            assertEqualsAfterSerialization(type);
678        }
679    
680        //-----------------------------------------------------------------------
681        public void testMaskDays() throws Exception {
682            PeriodType type = PeriodType.standard().withDaysRemoved();
683            assertEquals(7, type.size());
684            assertEquals(DurationFieldType.years(), type.getFieldType(0));
685            assertEquals(DurationFieldType.months(), type.getFieldType(1));
686            assertEquals(DurationFieldType.weeks(), type.getFieldType(2));
687            assertEquals(DurationFieldType.hours(), type.getFieldType(3));
688            assertEquals(DurationFieldType.minutes(), type.getFieldType(4));
689            assertEquals(DurationFieldType.seconds(), type.getFieldType(5));
690            assertEquals(DurationFieldType.millis(), type.getFieldType(6));
691            assertEquals(true, type.equals(type));
692            assertEquals(true, type.equals(PeriodType.standard().withDaysRemoved()));
693            assertEquals(false, type.equals(PeriodType.millis()));
694            assertEquals(true, type.hashCode() == type.hashCode());
695            assertEquals(true, type.hashCode() == PeriodType.standard().withDaysRemoved().hashCode());
696            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
697            assertEquals("StandardNoDays", type.getName());
698            assertEquals("PeriodType[StandardNoDays]", type.toString());
699            assertEqualsAfterSerialization(type);
700        }
701    
702        //-----------------------------------------------------------------------
703        public void testMaskHours() throws Exception {
704            PeriodType type = PeriodType.standard().withHoursRemoved();
705            assertEquals(7, type.size());
706            assertEquals(DurationFieldType.years(), type.getFieldType(0));
707            assertEquals(DurationFieldType.months(), type.getFieldType(1));
708            assertEquals(DurationFieldType.weeks(), type.getFieldType(2));
709            assertEquals(DurationFieldType.days(), type.getFieldType(3));
710            assertEquals(DurationFieldType.minutes(), type.getFieldType(4));
711            assertEquals(DurationFieldType.seconds(), type.getFieldType(5));
712            assertEquals(DurationFieldType.millis(), type.getFieldType(6));
713            assertEquals(true, type.equals(type));
714            assertEquals(true, type.equals(PeriodType.standard().withHoursRemoved()));
715            assertEquals(false, type.equals(PeriodType.millis()));
716            assertEquals(true, type.hashCode() == type.hashCode());
717            assertEquals(true, type.hashCode() == PeriodType.standard().withHoursRemoved().hashCode());
718            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
719            assertEquals("StandardNoHours", type.getName());
720            assertEquals("PeriodType[StandardNoHours]", type.toString());
721            assertEqualsAfterSerialization(type);
722        }
723    
724        //-----------------------------------------------------------------------
725        public void testMaskMinutes() throws Exception {
726            PeriodType type = PeriodType.standard().withMinutesRemoved();
727            assertEquals(7, type.size());
728            assertEquals(DurationFieldType.years(), type.getFieldType(0));
729            assertEquals(DurationFieldType.months(), type.getFieldType(1));
730            assertEquals(DurationFieldType.weeks(), type.getFieldType(2));
731            assertEquals(DurationFieldType.days(), type.getFieldType(3));
732            assertEquals(DurationFieldType.hours(), type.getFieldType(4));
733            assertEquals(DurationFieldType.seconds(), type.getFieldType(5));
734            assertEquals(DurationFieldType.millis(), type.getFieldType(6));
735            assertEquals(true, type.equals(type));
736            assertEquals(true, type.equals(PeriodType.standard().withMinutesRemoved()));
737            assertEquals(false, type.equals(PeriodType.millis()));
738            assertEquals(true, type.hashCode() == type.hashCode());
739            assertEquals(true, type.hashCode() == PeriodType.standard().withMinutesRemoved().hashCode());
740            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
741            assertEquals("StandardNoMinutes", type.getName());
742            assertEquals("PeriodType[StandardNoMinutes]", type.toString());
743            assertEqualsAfterSerialization(type);
744        }
745    
746        //-----------------------------------------------------------------------
747        public void testMaskSeconds() throws Exception {
748            PeriodType type = PeriodType.standard().withSecondsRemoved();
749            assertEquals(7, type.size());
750            assertEquals(DurationFieldType.years(), type.getFieldType(0));
751            assertEquals(DurationFieldType.months(), type.getFieldType(1));
752            assertEquals(DurationFieldType.weeks(), type.getFieldType(2));
753            assertEquals(DurationFieldType.days(), type.getFieldType(3));
754            assertEquals(DurationFieldType.hours(), type.getFieldType(4));
755            assertEquals(DurationFieldType.minutes(), type.getFieldType(5));
756            assertEquals(DurationFieldType.millis(), type.getFieldType(6));
757            assertEquals(true, type.equals(type));
758            assertEquals(true, type.equals(PeriodType.standard().withSecondsRemoved()));
759            assertEquals(false, type.equals(PeriodType.millis()));
760            assertEquals(true, type.hashCode() == type.hashCode());
761            assertEquals(true, type.hashCode() == PeriodType.standard().withSecondsRemoved().hashCode());
762            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
763            assertEquals("StandardNoSeconds", type.getName());
764            assertEquals("PeriodType[StandardNoSeconds]", type.toString());
765            assertEqualsAfterSerialization(type);
766        }
767    
768        //-----------------------------------------------------------------------
769        public void testMaskMillis() throws Exception {
770            PeriodType type = PeriodType.standard().withMillisRemoved();
771            assertEquals(7, type.size());
772            assertEquals(DurationFieldType.years(), type.getFieldType(0));
773            assertEquals(DurationFieldType.months(), type.getFieldType(1));
774            assertEquals(DurationFieldType.weeks(), type.getFieldType(2));
775            assertEquals(DurationFieldType.days(), type.getFieldType(3));
776            assertEquals(DurationFieldType.hours(), type.getFieldType(4));
777            assertEquals(DurationFieldType.minutes(), type.getFieldType(5));
778            assertEquals(DurationFieldType.seconds(), type.getFieldType(6));
779            assertEquals(true, type.equals(type));
780            assertEquals(true, type.equals(PeriodType.standard().withMillisRemoved()));
781            assertEquals(false, type.equals(PeriodType.millis()));
782            assertEquals(true, type.hashCode() == type.hashCode());
783            assertEquals(true, type.hashCode() == PeriodType.standard().withMillisRemoved().hashCode());
784            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
785            assertEquals("StandardNoMillis", type.getName());
786            assertEquals("PeriodType[StandardNoMillis]", type.toString());
787            assertEqualsAfterSerialization(type);
788        }
789    
790        //-----------------------------------------------------------------------
791        public void testMaskHoursMinutesSeconds() throws Exception {
792            PeriodType type = PeriodType.standard().withHoursRemoved().withMinutesRemoved().withSecondsRemoved();
793            assertEquals(5, type.size());
794            assertEquals(DurationFieldType.years(), type.getFieldType(0));
795            assertEquals(DurationFieldType.months(), type.getFieldType(1));
796            assertEquals(DurationFieldType.weeks(), type.getFieldType(2));
797            assertEquals(DurationFieldType.days(), type.getFieldType(3));
798            assertEquals(DurationFieldType.millis(), type.getFieldType(4));
799            assertEquals(true, type.equals(type));
800            assertEquals(true, type.equals(PeriodType.standard().withHoursRemoved().withMinutesRemoved().withSecondsRemoved()));
801            assertEquals(false, type.equals(PeriodType.millis()));
802            assertEquals(true, type.hashCode() == type.hashCode());
803            assertEquals(true, type.hashCode() == PeriodType.standard().withHoursRemoved().withMinutesRemoved().withSecondsRemoved().hashCode());
804            assertEquals(false, type.hashCode() == PeriodType.millis().hashCode());
805            assertEquals("StandardNoHoursNoMinutesNoSeconds", type.getName());
806            assertEquals("PeriodType[StandardNoHoursNoMinutesNoSeconds]", type.toString());
807            assertEqualsAfterSerialization(type);
808        }
809    
810        //-----------------------------------------------------------------------
811        public void testMaskTwice1() throws Exception {
812            PeriodType type = PeriodType.standard().withYearsRemoved();
813            PeriodType type2 = type.withYearsRemoved();
814            assertEquals(true, type == type2);
815            
816            type = PeriodType.standard().withMonthsRemoved();
817            type2 = type.withMonthsRemoved();
818            assertEquals(true, type == type2);
819            
820            type = PeriodType.standard().withWeeksRemoved();
821            type2 = type.withWeeksRemoved();
822            assertEquals(true, type == type2);
823            
824            type = PeriodType.standard().withDaysRemoved();
825            type2 = type.withDaysRemoved();
826            assertEquals(true, type == type2);
827            
828            type = PeriodType.standard().withHoursRemoved();
829            type2 = type.withHoursRemoved();
830            assertEquals(true, type == type2);
831            
832            type = PeriodType.standard().withMinutesRemoved();
833            type2 = type.withMinutesRemoved();
834            assertEquals(true, type == type2);
835            
836            type = PeriodType.standard().withSecondsRemoved();
837            type2 = type.withSecondsRemoved();
838            assertEquals(true, type == type2);
839            
840            type = PeriodType.standard().withMillisRemoved();
841            type2 = type.withMillisRemoved();
842            assertEquals(true, type == type2);
843        }
844    
845        //-----------------------------------------------------------------------
846        public void testMaskTwice2() throws Exception {
847            PeriodType type = PeriodType.dayTime();
848            PeriodType type2 = type.withYearsRemoved();
849            assertEquals(true, type == type2);
850            
851            type = PeriodType.dayTime();
852            type2 = type.withMonthsRemoved();
853            assertEquals(true, type == type2);
854            
855            type = PeriodType.dayTime();
856            type2 = type.withWeeksRemoved();
857            assertEquals(true, type == type2);
858            
859            type = PeriodType.millis();
860            type2 = type.withDaysRemoved();
861            assertEquals(true, type == type2);
862            
863            type = PeriodType.millis();
864            type2 = type.withHoursRemoved();
865            assertEquals(true, type == type2);
866            
867            type = PeriodType.millis();
868            type2 = type.withMinutesRemoved();
869            assertEquals(true, type == type2);
870            
871            type = PeriodType.millis();
872            type2 = type.withSecondsRemoved();
873            assertEquals(true, type == type2);
874        }
875    
876        //-----------------------------------------------------------------------
877        public void testEquals() throws Exception {
878            PeriodType type = PeriodType.dayTime().withMillisRemoved();
879            assertEquals(true, type.equals(type));
880            assertEquals(true, type.equals(PeriodType.dayTime().withMillisRemoved()));
881            assertEquals(false, type.equals(null));
882            assertEquals(false, type.equals(""));
883        }
884    
885        public void testHashCode() throws Exception {
886            PeriodType type = PeriodType.dayTime().withMillisRemoved();
887            assertEquals(type.hashCode(), type.hashCode());
888        }
889    
890        //-----------------------------------------------------------------------
891        public void testIsSupported() throws Exception {
892            PeriodType type = PeriodType.dayTime().withMillisRemoved();
893            assertEquals(false, type.isSupported(DurationFieldType.years()));
894            assertEquals(false, type.isSupported(DurationFieldType.months()));
895            assertEquals(false, type.isSupported(DurationFieldType.weeks()));
896            assertEquals(true, type.isSupported(DurationFieldType.days()));
897            assertEquals(true, type.isSupported(DurationFieldType.hours()));
898            assertEquals(true, type.isSupported(DurationFieldType.minutes()));
899            assertEquals(true, type.isSupported(DurationFieldType.seconds()));
900            assertEquals(false, type.isSupported(DurationFieldType.millis()));
901        }
902    
903        //-----------------------------------------------------------------------
904        public void testIndexOf() throws Exception {
905            PeriodType type = PeriodType.dayTime().withMillisRemoved();
906            assertEquals(-1, type.indexOf(DurationFieldType.years()));
907            assertEquals(-1, type.indexOf(DurationFieldType.months()));
908            assertEquals(-1, type.indexOf(DurationFieldType.weeks()));
909            assertEquals(0, type.indexOf(DurationFieldType.days()));
910            assertEquals(1, type.indexOf(DurationFieldType.hours()));
911            assertEquals(2, type.indexOf(DurationFieldType.minutes()));
912            assertEquals(3, type.indexOf(DurationFieldType.seconds()));
913            assertEquals(-1, type.indexOf(DurationFieldType.millis()));
914        }
915    
916    }