001    /*
002     *  Copyright 2001-2006 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.field;
017    
018    import java.util.Locale;
019    
020    import junit.framework.TestCase;
021    import junit.framework.TestSuite;
022    
023    import org.joda.time.DateTimeField;
024    import org.joda.time.DateTimeFieldType;
025    import org.joda.time.DurationFieldType;
026    import org.joda.time.LocalTime;
027    import org.joda.time.ReadablePartial;
028    
029    /**
030     * This class is a JUnit test to test only the UnsupportedDateTimeField class.
031     * This set of test cases exercises everything described in the Javadoc for this
032     * class.
033     * 
034     * @author Jeremy R. Rickard
035     */
036    public class TestUnsupportedDateTimeField extends TestCase {
037    
038        private DurationFieldType weeks;
039        private DurationFieldType months;
040        private DateTimeFieldType dateTimeFieldTypeOne;
041        private ReadablePartial localTime;
042    
043        public static TestSuite suite() {
044            return new TestSuite(TestUnsupportedDateTimeField.class);
045        }
046    
047        protected void setUp() throws Exception {
048            weeks = DurationFieldType.weeks();
049            months = DurationFieldType.months();
050            dateTimeFieldTypeOne = DateTimeFieldType.centuryOfEra();
051            localTime = new LocalTime();
052        }
053    
054        /**
055         * Passing null values into UnsupportedDateTimeField.getInstance() should
056         * throw an IllegalArguementsException
057         */
058        public void testNullValuesToGetInstanceThrowsException() {
059    
060            try {
061                UnsupportedDateTimeField.getInstance(null, null);
062                assertTrue(false);
063            } catch (IllegalArgumentException e) {
064                assertTrue(true);
065            }
066        }
067    
068        /**
069         * 
070         * This test exercises the logic in UnsupportedDateTimeField.getInstance. If
071         * getInstance() is invoked twice with: - the same DateTimeFieldType -
072         * different duration fields
073         * 
074         * Then the field returned in the first invocation should not be equal to
075         * the field returned by the second invocation. In otherwords, the generated
076         * instance should be the same for a unique pairing of
077         * DateTimeFieldType/DurationField
078         */
079        public void testDifferentDurationReturnDifferentObjects() {
080    
081            /**
082             * The fields returned by getInstance should be the same when the
083             * duration is the same for both method calls.
084             */
085            DateTimeField fieldOne = UnsupportedDateTimeField.getInstance(
086                    dateTimeFieldTypeOne, UnsupportedDurationField
087                            .getInstance(weeks));
088            DateTimeField fieldTwo = UnsupportedDateTimeField.getInstance(
089                    dateTimeFieldTypeOne, UnsupportedDurationField
090                            .getInstance(weeks));
091            assertSame(fieldOne, fieldTwo);
092    
093            /**
094             * The fields returned by getInstance should NOT be the same when the
095             * duration is the same for both method calls.
096             */
097            DateTimeField fieldThree = UnsupportedDateTimeField.getInstance(
098                    dateTimeFieldTypeOne, UnsupportedDurationField
099                            .getInstance(months));
100            assertNotSame(fieldOne, fieldThree);
101        }
102    
103        /**
104         * The getName() method should return the same value as the getName() method
105         * of the DateTimeFieldType that was used to create the instance.
106         * 
107         */
108        public void testPublicGetNameMethod() {
109            DateTimeField fieldOne = UnsupportedDateTimeField.getInstance(
110                    dateTimeFieldTypeOne, UnsupportedDurationField
111                            .getInstance(weeks));
112    
113            assertSame(fieldOne.getName(), dateTimeFieldTypeOne.getName());
114        }
115    
116        /**
117         * As this is an unsupported date/time field, some normal methods will
118         * always return false, as they are not supported. Verify that each method
119         * correctly returns null.
120         */
121        public void testAlwaysFalseReturnTypes() {
122            DateTimeField fieldOne = UnsupportedDateTimeField.getInstance(
123                    dateTimeFieldTypeOne, UnsupportedDurationField
124                            .getInstance(weeks));
125            assertFalse(fieldOne.isLenient());
126            assertFalse(fieldOne.isSupported());
127        }
128    
129        /**
130         * According to the JavaDocs, there are two methods that should always
131         * return null. * getRangeDurationField() * getLeapDurationField()
132         * 
133         * Ensure that these are in fact null.
134         */
135    
136        public void testMethodsThatShouldAlwaysReturnNull() {
137            DateTimeField fieldOne = UnsupportedDateTimeField.getInstance(
138                    dateTimeFieldTypeOne, UnsupportedDurationField
139                            .getInstance(weeks));
140    
141            assertNull(fieldOne.getLeapDurationField());
142            assertNull(fieldOne.getRangeDurationField());
143        }
144    
145        /**
146         * As this is an unsupported date/time field, many normal methods are
147         * unsupported and throw an UnsupportedOperationException. Verify that each
148         * method correctly throws this exception. * add(ReadablePartial instant,
149         * int fieldIndex, int[] values, int valueToAdd) * addWrapField(long
150         * instant, int value) * addWrapField(ReadablePartial instant, int
151         * fieldIndex, int[] values, int valueToAdd) *
152         * addWrapPartial(ReadablePartial instant, int fieldIndex, int[] values, int
153         * valueToAdd) * get(long instant) * getAsShortText(int fieldValue, Locale
154         * locale) * getAsShortText(long instant) * getAsShortText(long instant,
155         * Locale locale) * getAsShortText(ReadablePartial partial, int fieldValue,
156         * Locale locale) * getAsShortText(ReadablePartial partial, Locale locale) *
157         * getAsText(int fieldValue, Locale locale) * getAsText(long instant) *
158         * getAsText(long instant, Locale locale) * getAsText(ReadablePartial
159         * partial, int fieldValue, Locale locale) * getAsText(ReadablePartial
160         * partial, Locale locale) * getLeapAmount(long instant) *
161         * getMaximumShortTextLength(Locale locale) * getMaximumTextLength(Locale
162         * locale) * getMaximumValue() * getMaximumValue(long instant) *
163         * getMaximumValue(ReadablePartial instant) *
164         * getMaximumValue(ReadablePartial instant, int[] values) *
165         * getMinimumValue() * getMinimumValue(long instant) *
166         * getMinimumValue(ReadablePartial instant) *
167         * getMinimumValue(ReadablePartial instant, int[] values) * isLeap(long
168         * instant) * remainder(long instant) * roundCeiling(long instant) *
169         * roundFloor(long instant) * roundHalfCeiling(long instant) *
170         * roundHalfEven(long instant) * roundHalfFloor(long instant) * set(long
171         * instant, int value) * set(long instant, String text) * set(long instant,
172         * String text, Locale locale) * set(ReadablePartial instant, int
173         * fieldIndex, int[] values, int newValue) * set(ReadablePartial instant,
174         * int fieldIndex, int[] values, String text, Locale locale)
175         */
176        public void testUnsupportedMethods() {
177            DateTimeField fieldOne = UnsupportedDateTimeField.getInstance(
178                    dateTimeFieldTypeOne, UnsupportedDurationField
179                            .getInstance(weeks));
180    
181            // add(ReadablePartial instant, int fieldIndex, int[] values, int
182            // valueToAdd)
183            try {
184                fieldOne.add(localTime, 0, new int[] { 0, 100 }, 100);
185                assertTrue(false);
186            } catch (UnsupportedOperationException e) {
187                assertTrue(true);
188            }
189            // addWrapField(long instant, int value)
190            try {
191                fieldOne.addWrapField(100000L, 250);
192                assertTrue(false);
193            } catch (UnsupportedOperationException e) {
194                assertTrue(true);
195            }
196            // addWrapField(ReadablePartial instant, int fieldIndex, int[] values,
197            // int valueToAdd)
198            try {
199                fieldOne.addWrapField(localTime, 0, new int[] { 0, 100 }, 100);
200                assertTrue(false);
201            } catch (UnsupportedOperationException e) {
202                assertTrue(true);
203            }
204            // addWrapPartial(ReadablePartial instant, int fieldIndex, int[] values,
205            // int valueToAdd)
206            try {
207                fieldOne.addWrapPartial(localTime, 0, new int[] { 0, 100 }, 100);
208                assertTrue(false);
209            } catch (UnsupportedOperationException e) {
210                assertTrue(true);
211            }
212            // UnsupportedDateTimeField.get(long instant)
213            try {
214                fieldOne.get(1000L);
215                assertTrue(false);
216            } catch (UnsupportedOperationException e) {
217                assertTrue(true);
218            }
219    
220            // UnsupportedDateTimeField.getAsShortText(int fieldValue,
221            // Locale locale)
222            try {
223                fieldOne.getAsShortText(0, Locale.getDefault());
224                assertTrue(false);
225            } catch (UnsupportedOperationException e) {
226                assertTrue(true);
227            }
228    
229            // UnsupportedDateTimeField.getAsShortText(long instant)
230            try {
231                fieldOne.getAsShortText(100000L);
232                assertTrue(false);
233            } catch (UnsupportedOperationException e) {
234                assertTrue(true);
235            }
236    
237            // UnsupportedDateTimeField.getAsShortText(long instant, Locale locale)
238            try {
239                fieldOne.getAsShortText(100000L, Locale.getDefault());
240                assertTrue(false);
241            } catch (UnsupportedOperationException e) {
242                assertTrue(true);
243            }
244    
245            // UnsupportedDateTimeField.getAsShortText(ReadablePartial partial,
246            // int fieldValue,
247            // Locale locale)
248            try {
249                fieldOne.getAsShortText(localTime, 0, Locale.getDefault());
250                assertTrue(false);
251            } catch (UnsupportedOperationException e) {
252                assertTrue(true);
253            }
254    
255            // UnsupportedDateTimeField.getAsShortText(ReadablePartial partial,
256            // Locale locale)
257            try {
258                fieldOne.getAsShortText(localTime, Locale.getDefault());
259                assertTrue(false);
260            } catch (UnsupportedOperationException e) {
261                assertTrue(true);
262            }
263    
264            // UnsupportedDateTimeField.getAsText(int fieldValue,
265            // Locale locale)
266            try {
267                fieldOne.getAsText(0, Locale.getDefault());
268                assertTrue(false);
269            } catch (UnsupportedOperationException e) {
270                assertTrue(true);
271            }
272    
273            // UnsupportedDateTimeField.getAsText(long instant)
274            try {
275                fieldOne.getAsText(1000L);
276                assertTrue(false);
277            } catch (UnsupportedOperationException e) {
278                assertTrue(true);
279            }
280    
281            // UnsupportedDateTimeField.getAsText(long instant, Locale locale)
282            try {
283                fieldOne.getAsText(1000L, Locale.getDefault());
284                assertTrue(false);
285            } catch (UnsupportedOperationException e) {
286                assertTrue(true);
287            }
288    
289            // UnsupportedDateTimeField.getAsText(ReadablePartial partial,
290            // int fieldValue,
291            // Locale locale)
292            try {
293                fieldOne.getAsText(localTime, 0, Locale.getDefault());
294                assertTrue(false);
295            } catch (UnsupportedOperationException e) {
296                assertTrue(true);
297            }
298    
299            // UnsupportedDateTimeField.getAsText(ReadablePartial partial,
300            // Locale locale)
301            try {
302                fieldOne.getAsText(localTime, Locale.getDefault());
303                assertTrue(false);
304            } catch (UnsupportedOperationException e) {
305                assertTrue(true);
306            }
307    
308            // UnsupportedDateTimeField.getLeapAmount(long instant) is unsupported
309            // and should always thrown an UnsupportedOperationException
310            try {
311                fieldOne.getLeapAmount(System.currentTimeMillis());
312                assertTrue(false);
313            } catch (UnsupportedOperationException e) {
314                assertTrue(true);
315            }
316    
317            // UnsupportedDateTimeField.getMaximumShortTextLength(Locale locale)
318            // is unsupported and should always thrown an
319            // UnsupportedOperationException
320            try {
321                fieldOne.getMaximumShortTextLength(Locale.getDefault());
322                assertTrue(false);
323            } catch (UnsupportedOperationException e) {
324                assertTrue(true);
325            }
326    
327            // UnsupportedDateTimeField.getMaximumTextLength(Locale locale)
328            // is unsupported and should always thrown an
329            // UnsupportedOperationException
330            try {
331                fieldOne.getMaximumTextLength(Locale.getDefault());
332                assertTrue(false);
333            } catch (UnsupportedOperationException e) {
334                assertTrue(true);
335            }
336    
337            // UnsupportedDateTimeField.getMaximumValue() is unsupported
338            // and should always thrown an UnsupportedOperationException
339            try {
340                fieldOne.getMaximumValue();
341                assertTrue(false);
342            } catch (UnsupportedOperationException e) {
343                assertTrue(true);
344            }
345    
346            // UnsupportedDateTimeField.getMaximumValue(long instant)
347            // is unsupported and should always thrown an
348            // UnsupportedOperationException
349            try {
350                fieldOne.getMaximumValue(1000000L);
351                assertTrue(false);
352            } catch (UnsupportedOperationException e) {
353                assertTrue(true);
354            }
355    
356            // UnsupportedDateTimeField.getMaximumValue(ReadablePartial instant)
357            // is unsupported and should always thrown an
358            // UnsupportedOperationException
359            try {
360                fieldOne.getMaximumValue(localTime);
361                assertTrue(false);
362            } catch (UnsupportedOperationException e) {
363                assertTrue(true);
364            }
365    
366            // UnsupportedDateTimeField.getMaximumValue(ReadablePartial instant,
367            // int[] values)
368            // is unsupported and should always thrown an
369            // UnsupportedOperationException
370            try {
371                fieldOne.getMaximumValue(localTime, new int[] { 0 });
372                assertTrue(false);
373            } catch (UnsupportedOperationException e) {
374                assertTrue(true);
375            }
376    
377            // UnsupportedDateTimeField.getMinumumValue() is unsupported
378            // and should always thrown an UnsupportedOperationException
379            try {
380                fieldOne.getMinimumValue();
381                assertTrue(false);
382            } catch (UnsupportedOperationException e) {
383                assertTrue(true);
384            }
385    
386            // UnsupportedDateTimeField.getMinumumValue(long instant) is unsupported
387            // and should always thrown an UnsupportedOperationException
388            try {
389                fieldOne.getMinimumValue(10000000L);
390                assertTrue(false);
391            } catch (UnsupportedOperationException e) {
392                assertTrue(true);
393            }
394    
395            // UnsupportedDateTimeField.getMinumumValue(ReadablePartial instant)
396            // is unsupported and should always thrown an
397            // UnsupportedOperationException
398            try {
399                fieldOne.getMinimumValue(localTime);
400                assertTrue(false);
401            } catch (UnsupportedOperationException e) {
402                assertTrue(true);
403            }
404    
405            // UnsupportedDateTimeField.getMinumumValue(ReadablePartial instant,
406            // int[] values) is unsupported
407            // and should always thrown an UnsupportedOperationException
408            try {
409                fieldOne.getMinimumValue(localTime, new int[] { 0 });
410                assertTrue(false);
411            } catch (UnsupportedOperationException e) {
412                assertTrue(true);
413            }
414    
415            // UnsupportedDateTimeField.isLeap(long instant) is unsupported and
416            // should always thrown an UnsupportedOperationException
417            try {
418                fieldOne.isLeap(System.currentTimeMillis());
419                assertTrue(false);
420            } catch (UnsupportedOperationException e) {
421                assertTrue(true);
422            }
423    
424            // UnsupportedDateTimeField.remainder(long instant) is unsupported and
425            // should always thrown an UnsupportedOperationException
426            try {
427                fieldOne.remainder(1000000L);
428                assertTrue(false);
429            } catch (UnsupportedOperationException e) {
430                assertTrue(true);
431            }
432    
433            // UnsupportedDateTimeField.roundCeiling(long instant) is unsupported
434            // and
435            // should always thrown an UnsupportedOperationException
436            try {
437                fieldOne.roundCeiling(1000000L);
438                assertTrue(false);
439            } catch (UnsupportedOperationException e) {
440                assertTrue(true);
441            }
442    
443            // UnsupportedDateTimeField.roundFloor(long instant) is unsupported and
444            // should always thrown an UnsupportedOperationException
445            try {
446                fieldOne.roundFloor(1000000L);
447                assertTrue(false);
448            } catch (UnsupportedOperationException e) {
449                assertTrue(true);
450            }
451    
452            // UnsupportedDateTimeField.roundHalfCeiling(long instant) is
453            // unsupported and
454            // should always thrown an UnsupportedOperationException
455            try {
456                fieldOne.roundHalfCeiling(1000000L);
457                assertTrue(false);
458            } catch (UnsupportedOperationException e) {
459                assertTrue(true);
460            }
461    
462            // UnsupportedDateTimeField.roundHalfEven(long instant) is unsupported
463            // and
464            // should always thrown an UnsupportedOperationException
465            try {
466                fieldOne.roundHalfEven(1000000L);
467                assertTrue(false);
468            } catch (UnsupportedOperationException e) {
469                assertTrue(true);
470            }
471    
472            // UnsupportedDateTimeField.roundHalfFloor(long instant) is unsupported
473            // and
474            // should always thrown an UnsupportedOperationException
475            try {
476                fieldOne.roundHalfFloor(1000000L);
477                assertTrue(false);
478            } catch (UnsupportedOperationException e) {
479                assertTrue(true);
480            }
481    
482            // UnsupportedDateTimeField.set(long instant, int value) is unsupported
483            // and
484            // should always thrown an UnsupportedOperationException
485            try {
486                fieldOne.set(1000000L, 1000);
487                assertTrue(false);
488            } catch (UnsupportedOperationException e) {
489                assertTrue(true);
490            }
491    
492            // UnsupportedDateTimeField.set(long instant, String test) is
493            // unsupported and
494            // should always thrown an UnsupportedOperationException
495            try {
496                fieldOne.set(1000000L, "Unsupported Operation");
497                assertTrue(false);
498            } catch (UnsupportedOperationException e) {
499                assertTrue(true);
500            }
501    
502            // UnsupportedDateTimeField.set(long instant, String text, Locale
503            // locale)
504            // is unsupported and should always thrown an
505            // UnsupportedOperationException
506            try {
507                fieldOne
508                        .set(1000000L, "Unsupported Operation", Locale.getDefault());
509                assertTrue(false);
510            } catch (UnsupportedOperationException e) {
511                assertTrue(true);
512            }
513    
514            // UnsupportedDateTimeField.set(ReadablePartial instant,
515            // int fieldIndex,
516            // int[] values,
517            // int newValue) is unsupported and
518            // should always thrown an UnsupportedOperationException
519            try {
520                fieldOne.set(localTime, 0, new int[] { 0 }, 10000);
521                assertTrue(false);
522            } catch (UnsupportedOperationException e) {
523                assertTrue(true);
524            }
525    
526            // UnsupportedDateTimeField.set(ReadablePartial instant,
527            // int fieldIndex,
528            // int[] values,
529            // String text,
530            // Locale locale) is unsupported and
531            // should always thrown an UnsupportedOperationException
532            try {
533                fieldOne.set(localTime, 0, new int[] { 0 },
534                        "Unsupported Operation", Locale.getDefault());
535                assertTrue(false);
536            } catch (UnsupportedOperationException e) {
537                assertTrue(true);
538            }
539        }
540    
541        /**
542         * As this is an unsupported date/time field, many normal methods are
543         * unsupported. Some delegate and can possibly throw an
544         * UnsupportedOperationException or have a valid return. Verify that each
545         * method correctly throws this exception when appropriate and delegates
546         * correctly based on the Duration used to get the instance.
547         */
548        public void testDelegatedMethods() {
549            DateTimeField fieldOne = UnsupportedDateTimeField.getInstance(
550                    dateTimeFieldTypeOne, UnsupportedDurationField
551                            .getInstance(weeks));
552            PreciseDurationField hoursDuration = new PreciseDurationField(
553                    DurationFieldType.hours(), 10L);
554            DateTimeField fieldTwo = UnsupportedDateTimeField.getInstance(
555                    dateTimeFieldTypeOne, hoursDuration);
556    
557            // UnsupportedDateTimeField.add(long instant, int value) should
558            // throw an UnsupportedOperationException when the duration does
559            // not support the operation, otherwise it delegates to the duration.
560            // First
561            // try it with an UnsupportedDurationField, then a PreciseDurationField.
562            try {
563                fieldOne.add(System.currentTimeMillis(), 100);
564                assertTrue(false);
565            } catch (UnsupportedOperationException e) {
566                assertTrue(true);
567            }
568            try {
569                long currentTime = System.currentTimeMillis();
570                long firstComputation = hoursDuration.add(currentTime, 100);
571                long secondComputation = fieldTwo.add(currentTime,
572                        100);
573                assertEquals(firstComputation,secondComputation);
574            } catch (UnsupportedOperationException e) {
575                assertTrue(false);
576            }
577    
578            // UnsupportedDateTimeField.add(long instant, long value) should
579            // throw an UnsupportedOperationException when the duration does
580            // not support the operation, otherwise it delegates to the duration.
581            // First
582            // try it with an UnsupportedDurationField, then a PreciseDurationField.
583            try {
584                fieldOne.add(System.currentTimeMillis(), 1000L);
585                assertTrue(false);
586            } catch (UnsupportedOperationException e) {
587                assertTrue(true);
588            }
589    
590            try {
591                long currentTime = System.currentTimeMillis();
592                long firstComputation = hoursDuration.add(currentTime, 1000L);
593                long secondComputation = fieldTwo.add(currentTime,
594                        1000L);
595                assertTrue(firstComputation == secondComputation);
596                assertEquals(firstComputation,secondComputation);
597            } catch (UnsupportedOperationException e) {
598                assertTrue(false);
599            }
600    
601            // UnsupportedDateTimeField.getDifference(long minuendInstant,
602            // long subtrahendInstant)
603            // should throw an UnsupportedOperationException when the duration does
604            // not support the operation, otherwise return the result from the
605            // delegated call.
606            try {
607                fieldOne.getDifference(100000L, 1000L);
608                assertTrue(false);
609            } catch (UnsupportedOperationException e) {
610                assertTrue(true);
611            }
612    
613            try {
614                int firstDifference = hoursDuration.getDifference(100000L, 1000L);
615                int secondDifference = fieldTwo.getDifference(100000L, 1000L);
616                assertEquals(firstDifference,secondDifference);
617            } catch (UnsupportedOperationException e) {
618                assertTrue(false);
619            }
620    
621            // UnsupportedDateTimeField.getDifferenceAsLong(long minuendInstant,
622            // long subtrahendInstant)
623            // should throw an UnsupportedOperationException when the duration does
624            // not support the operation, otherwise return the result from the
625            // delegated call.
626            try {
627                fieldOne.getDifferenceAsLong(100000L, 1000L);
628                assertTrue(false);
629            } catch (UnsupportedOperationException e) {
630                assertTrue(true);
631            }
632    
633            try {
634                long firstDifference = hoursDuration.getDifference(100000L, 1000L);
635                long secondDifference = fieldTwo.getDifference(100000L, 1000L);
636                assertEquals(firstDifference,secondDifference);
637            } catch (UnsupportedOperationException e) {
638                assertTrue(false);
639            }
640        }
641    
642        /**
643        * The toString method should return a suitable debug message (not null).
644        * Ensure that the toString method returns a string with length greater than
645        * 0 (and not null)
646        * 
647        */
648        public void testToString() {
649            DateTimeField fieldOne = UnsupportedDateTimeField.getInstance(
650                    dateTimeFieldTypeOne, UnsupportedDurationField
651                            .getInstance(weeks));
652    
653            String debugMessage = fieldOne.toString();
654            assertNotNull(debugMessage);
655            assertTrue(debugMessage.length() > 0);
656        }
657    }