1/*
2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * This file is available under and governed by the GNU General Public
26 * License version 2 only, as published by the Free Software Foundation.
27 * However, the following notice accompanied the original version of this
28 * file:
29 *
30 * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
31 *
32 * All rights reserved.
33 *
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions are met:
36 *
37 *  * Redistributions of source code must retain the above copyright notice,
38 *    this list of conditions and the following disclaimer.
39 *
40 *  * Redistributions in binary form must reproduce the above copyright notice,
41 *    this list of conditions and the following disclaimer in the documentation
42 *    and/or other materials provided with the distribution.
43 *
44 *  * Neither the name of JSR-310 nor the names of its contributors
45 *    may be used to endorse or promote products derived from this software
46 *    without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
51 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
52 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
53 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
54 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
55 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
56 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
57 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 */
60package tck.java.time;
61
62import static java.time.temporal.ChronoField.ERA;
63import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
64import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
65import static java.time.temporal.ChronoField.YEAR;
66import static java.time.temporal.ChronoField.YEAR_OF_ERA;
67import static java.time.temporal.ChronoUnit.CENTURIES;
68import static java.time.temporal.ChronoUnit.DAYS;
69import static java.time.temporal.ChronoUnit.DECADES;
70import static java.time.temporal.ChronoUnit.HOURS;
71import static java.time.temporal.ChronoUnit.MILLENNIA;
72import static java.time.temporal.ChronoUnit.MONTHS;
73import static java.time.temporal.ChronoUnit.YEARS;
74import static org.testng.Assert.assertEquals;
75import static org.testng.Assert.assertTrue;
76import static org.testng.Assert.fail;
77
78import java.io.ByteArrayOutputStream;
79import java.io.DataOutputStream;
80import java.io.IOException;
81import java.time.Clock;
82import java.time.DateTimeException;
83import java.time.Duration;
84import java.time.Instant;
85import java.time.LocalDate;
86import java.time.LocalDateTime;
87import java.time.LocalTime;
88import java.time.Month;
89import java.time.Period;
90import java.time.Year;
91import java.time.YearMonth;
92import java.time.ZoneId;
93import java.time.ZoneOffset;
94import java.time.chrono.IsoChronology;
95import java.time.format.DateTimeFormatter;
96import java.time.format.DateTimeParseException;
97import java.time.temporal.ChronoField;
98import java.time.temporal.ChronoUnit;
99import java.time.temporal.JulianFields;
100import java.time.temporal.TemporalAccessor;
101import java.time.temporal.TemporalAmount;
102import java.time.temporal.TemporalField;
103import java.time.temporal.TemporalQueries;
104import java.time.temporal.TemporalQuery;
105import java.time.temporal.TemporalUnit;
106import java.time.temporal.UnsupportedTemporalTypeException;
107import java.util.ArrayList;
108import java.util.Arrays;
109import java.util.HashSet;
110import java.util.List;
111import java.util.Set;
112
113import org.testng.annotations.BeforeClass;
114import org.testng.annotations.DataProvider;
115import org.testng.annotations.Test;
116
117/**
118 * Test YearMonth.
119 */
120@Test
121public class TCKYearMonth extends AbstractDateTimeTest {
122
123    // Android-changed: This was originally non-static and initialized in @BeforeMethod,
124    // but @BeforeMethod is run after @DataProvider methods are run, so it only worked by accident,
125    // since multiple test methods were run and the first one did not require this value.
126    private static YearMonth TEST_2008_06;
127
128    @BeforeClass
129    public static void setUp() {
130        TEST_2008_06 = YearMonth.of(2008, 6);
131    }
132
133    //-----------------------------------------------------------------------
134    @Override
135    protected List<TemporalAccessor> samples() {
136        TemporalAccessor[] array = {TEST_2008_06, };
137        return Arrays.asList(array);
138    }
139
140    @Override
141    protected List<TemporalField> validFields() {
142        TemporalField[] array = {
143            MONTH_OF_YEAR,
144            PROLEPTIC_MONTH,
145            YEAR_OF_ERA,
146            YEAR,
147            ERA,
148        };
149        return Arrays.asList(array);
150    }
151
152    @Override
153    protected List<TemporalField> invalidFields() {
154        List<TemporalField> list = new ArrayList<>(Arrays.<TemporalField>asList(ChronoField.values()));
155        list.removeAll(validFields());
156        list.add(JulianFields.JULIAN_DAY);
157        list.add(JulianFields.MODIFIED_JULIAN_DAY);
158        list.add(JulianFields.RATA_DIE);
159        return list;
160    }
161
162    //-----------------------------------------------------------------------
163    void check(YearMonth test, int y, int m) {
164        assertEquals(test.getYear(), y);
165        assertEquals(test.getMonth().getValue(), m);
166    }
167
168    //-----------------------------------------------------------------------
169    // now()
170    //-----------------------------------------------------------------------
171    @Test
172    public void now() {
173        YearMonth expected = YearMonth.now(Clock.systemDefaultZone());
174        YearMonth test = YearMonth.now();
175        for (int i = 0; i < 100; i++) {
176            if (expected.equals(test)) {
177                return;
178            }
179            expected = YearMonth.now(Clock.systemDefaultZone());
180            test = YearMonth.now();
181        }
182        assertEquals(test, expected);
183    }
184
185    //-----------------------------------------------------------------------
186    // now(ZoneId)
187    //-----------------------------------------------------------------------
188    @Test(expectedExceptions=NullPointerException.class)
189    public void now_ZoneId_nullZoneId() {
190        YearMonth.now((ZoneId) null);
191    }
192
193    @Test
194    public void now_ZoneId() {
195        ZoneId zone = ZoneId.of("UTC+01:02:03");
196        YearMonth expected = YearMonth.now(Clock.system(zone));
197        YearMonth test = YearMonth.now(zone);
198        for (int i = 0; i < 100; i++) {
199            if (expected.equals(test)) {
200                return;
201            }
202            expected = YearMonth.now(Clock.system(zone));
203            test = YearMonth.now(zone);
204        }
205        assertEquals(test, expected);
206    }
207
208    //-----------------------------------------------------------------------
209    // now(Clock)
210    //-----------------------------------------------------------------------
211    @Test
212    public void now_Clock() {
213        Instant instant = LocalDateTime.of(2010, 12, 31, 0, 0).toInstant(ZoneOffset.UTC);
214        Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
215        YearMonth test = YearMonth.now(clock);
216        assertEquals(test.getYear(), 2010);
217        assertEquals(test.getMonth(), Month.DECEMBER);
218    }
219
220    @Test(expectedExceptions=NullPointerException.class)
221    public void now_Clock_nullClock() {
222        YearMonth.now((Clock) null);
223    }
224
225    //-----------------------------------------------------------------------
226    @Test
227    public void factory_intsMonth() {
228        YearMonth test = YearMonth.of(2008, Month.FEBRUARY);
229        check(test, 2008, 2);
230    }
231
232    @Test(expectedExceptions=DateTimeException.class)
233    public void test_factory_intsMonth_yearTooLow() {
234        YearMonth.of(Year.MIN_VALUE - 1, Month.JANUARY);
235    }
236
237    @Test(expectedExceptions=DateTimeException.class)
238    public void test_factory_intsMonth_dayTooHigh() {
239        YearMonth.of(Year.MAX_VALUE + 1, Month.JANUARY);
240    }
241
242    @Test(expectedExceptions=NullPointerException.class)
243    public void factory_intsMonth_nullMonth() {
244        YearMonth.of(2008, null);
245    }
246
247    //-----------------------------------------------------------------------
248    @Test
249    public void factory_ints() {
250        YearMonth test = YearMonth.of(2008, 2);
251        check(test, 2008, 2);
252    }
253
254    @Test(expectedExceptions=DateTimeException.class)
255    public void test_factory_ints_yearTooLow() {
256        YearMonth.of(Year.MIN_VALUE - 1, 2);
257    }
258
259    @Test(expectedExceptions=DateTimeException.class)
260    public void test_factory_ints_dayTooHigh() {
261        YearMonth.of(Year.MAX_VALUE + 1, 2);
262    }
263
264    @Test(expectedExceptions=DateTimeException.class)
265    public void test_factory_ints_monthTooLow() {
266        YearMonth.of(2008, 0);
267    }
268
269    @Test(expectedExceptions=DateTimeException.class)
270    public void test_factory_ints_monthTooHigh() {
271        YearMonth.of(2008, 13);
272    }
273
274    //-----------------------------------------------------------------------
275    @Test
276    public void test_from_TemporalAccessor() {
277        assertEquals(YearMonth.from(LocalDate.of(2007, 7, 15)), YearMonth.of(2007, 7));
278    }
279
280    @Test(expectedExceptions=DateTimeException.class)
281    public void test_from_TemporalAccessor_invalid_noDerive() {
282        YearMonth.from(LocalTime.of(12, 30));
283    }
284
285    @Test(expectedExceptions=NullPointerException.class)
286    public void test_from_TemporalAccessor_null() {
287        YearMonth.from((TemporalAccessor) null);
288    }
289
290    //-----------------------------------------------------------------------
291    // parse()
292    //-----------------------------------------------------------------------
293    @DataProvider(name="goodParseData")
294    Object[][] provider_goodParseData() {
295        return new Object[][] {
296                {"0000-01", YearMonth.of(0, 1)},
297                {"0000-12", YearMonth.of(0, 12)},
298                {"9999-12", YearMonth.of(9999, 12)},
299                {"2000-01", YearMonth.of(2000, 1)},
300                {"2000-02", YearMonth.of(2000, 2)},
301                {"2000-03", YearMonth.of(2000, 3)},
302                {"2000-04", YearMonth.of(2000, 4)},
303                {"2000-05", YearMonth.of(2000, 5)},
304                {"2000-06", YearMonth.of(2000, 6)},
305                {"2000-07", YearMonth.of(2000, 7)},
306                {"2000-08", YearMonth.of(2000, 8)},
307                {"2000-09", YearMonth.of(2000, 9)},
308                {"2000-10", YearMonth.of(2000, 10)},
309                {"2000-11", YearMonth.of(2000, 11)},
310                {"2000-12", YearMonth.of(2000, 12)},
311
312                {"+12345678-03", YearMonth.of(12345678, 3)},
313                {"+123456-03", YearMonth.of(123456, 3)},
314                {"0000-03", YearMonth.of(0, 3)},
315                {"-1234-03", YearMonth.of(-1234, 3)},
316                {"-12345678-03", YearMonth.of(-12345678, 3)},
317
318                {"+" + Year.MAX_VALUE + "-03", YearMonth.of(Year.MAX_VALUE, 3)},
319                {Year.MIN_VALUE + "-03", YearMonth.of(Year.MIN_VALUE, 3)},
320        };
321    }
322
323    @Test(dataProvider="goodParseData")
324    public void factory_parse_success(String text, YearMonth expected) {
325        YearMonth yearMonth = YearMonth.parse(text);
326        assertEquals(yearMonth, expected);
327    }
328
329    //-----------------------------------------------------------------------
330    @DataProvider(name="badParseData")
331    Object[][] provider_badParseData() {
332        return new Object[][] {
333                {"", 0},
334                {"-00", 1},
335                {"--01-0", 1},
336                {"A01-3", 0},
337                {"200-01", 0},
338                {"2009/12", 4},
339
340                {"-0000-10", 0},
341                {"-12345678901-10", 11},
342                {"+1-10", 1},
343                {"+12-10", 1},
344                {"+123-10", 1},
345                {"+1234-10", 0},
346                {"12345-10", 0},
347                {"+12345678901-10", 11},
348        };
349    }
350
351    @Test(dataProvider="badParseData", expectedExceptions=DateTimeParseException.class)
352    public void factory_parse_fail(String text, int pos) {
353        try {
354            YearMonth.parse(text);
355            fail(String.format("Parse should have failed for %s at position %d", text, pos));
356        } catch (DateTimeParseException ex) {
357            assertEquals(ex.getParsedString(), text);
358            assertEquals(ex.getErrorIndex(), pos);
359            throw ex;
360        }
361    }
362
363    //-----------------------------------------------------------------------
364    @Test(expectedExceptions=DateTimeParseException.class)
365    public void factory_parse_illegalValue_Month() {
366        YearMonth.parse("2008-13");
367    }
368
369    @Test(expectedExceptions=NullPointerException.class)
370    public void factory_parse_nullText() {
371        YearMonth.parse(null);
372    }
373
374    //-----------------------------------------------------------------------
375    // parse(DateTimeFormatter)
376    //-----------------------------------------------------------------------
377    @Test
378    public void factory_parse_formatter() {
379        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M");
380        YearMonth test = YearMonth.parse("2010 12", f);
381        assertEquals(test, YearMonth.of(2010, 12));
382    }
383
384    @Test(expectedExceptions=NullPointerException.class)
385    public void factory_parse_formatter_nullText() {
386        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M");
387        YearMonth.parse((String) null, f);
388    }
389
390    @Test(expectedExceptions=NullPointerException.class)
391    public void factory_parse_formatter_nullFormatter() {
392        YearMonth.parse("ANY", null);
393    }
394
395    //-----------------------------------------------------------------------
396    // isSupported(TemporalField)
397    //-----------------------------------------------------------------------
398    @Test
399    public void test_isSupported_TemporalField() {
400        assertEquals(TEST_2008_06.isSupported((TemporalField) null), false);
401        assertEquals(TEST_2008_06.isSupported(ChronoField.NANO_OF_SECOND), false);
402        assertEquals(TEST_2008_06.isSupported(ChronoField.NANO_OF_DAY), false);
403        assertEquals(TEST_2008_06.isSupported(ChronoField.MICRO_OF_SECOND), false);
404        assertEquals(TEST_2008_06.isSupported(ChronoField.MICRO_OF_DAY), false);
405        assertEquals(TEST_2008_06.isSupported(ChronoField.MILLI_OF_SECOND), false);
406        assertEquals(TEST_2008_06.isSupported(ChronoField.MILLI_OF_DAY), false);
407        assertEquals(TEST_2008_06.isSupported(ChronoField.SECOND_OF_MINUTE), false);
408        assertEquals(TEST_2008_06.isSupported(ChronoField.SECOND_OF_DAY), false);
409        assertEquals(TEST_2008_06.isSupported(ChronoField.MINUTE_OF_HOUR), false);
410        assertEquals(TEST_2008_06.isSupported(ChronoField.MINUTE_OF_DAY), false);
411        assertEquals(TEST_2008_06.isSupported(ChronoField.HOUR_OF_AMPM), false);
412        assertEquals(TEST_2008_06.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false);
413        assertEquals(TEST_2008_06.isSupported(ChronoField.HOUR_OF_DAY), false);
414        assertEquals(TEST_2008_06.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false);
415        assertEquals(TEST_2008_06.isSupported(ChronoField.AMPM_OF_DAY), false);
416        assertEquals(TEST_2008_06.isSupported(ChronoField.DAY_OF_WEEK), false);
417        assertEquals(TEST_2008_06.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false);
418        assertEquals(TEST_2008_06.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false);
419        assertEquals(TEST_2008_06.isSupported(ChronoField.DAY_OF_MONTH), false);
420        assertEquals(TEST_2008_06.isSupported(ChronoField.DAY_OF_YEAR), false);
421        assertEquals(TEST_2008_06.isSupported(ChronoField.EPOCH_DAY), false);
422        assertEquals(TEST_2008_06.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false);
423        assertEquals(TEST_2008_06.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false);
424        assertEquals(TEST_2008_06.isSupported(ChronoField.MONTH_OF_YEAR), true);
425        assertEquals(TEST_2008_06.isSupported(ChronoField.PROLEPTIC_MONTH), true);
426        assertEquals(TEST_2008_06.isSupported(ChronoField.YEAR), true);
427        assertEquals(TEST_2008_06.isSupported(ChronoField.YEAR_OF_ERA), true);
428        assertEquals(TEST_2008_06.isSupported(ChronoField.ERA), true);
429        assertEquals(TEST_2008_06.isSupported(ChronoField.INSTANT_SECONDS), false);
430        assertEquals(TEST_2008_06.isSupported(ChronoField.OFFSET_SECONDS), false);
431    }
432
433    //-----------------------------------------------------------------------
434    // isSupported(TemporalUnit)
435    //-----------------------------------------------------------------------
436    @Test
437    public void test_isSupported_TemporalUnit() {
438        assertEquals(TEST_2008_06.isSupported((TemporalUnit) null), false);
439        assertEquals(TEST_2008_06.isSupported(ChronoUnit.NANOS), false);
440        assertEquals(TEST_2008_06.isSupported(ChronoUnit.MICROS), false);
441        assertEquals(TEST_2008_06.isSupported(ChronoUnit.MILLIS), false);
442        assertEquals(TEST_2008_06.isSupported(ChronoUnit.SECONDS), false);
443        assertEquals(TEST_2008_06.isSupported(ChronoUnit.MINUTES), false);
444        assertEquals(TEST_2008_06.isSupported(ChronoUnit.HOURS), false);
445        assertEquals(TEST_2008_06.isSupported(ChronoUnit.HALF_DAYS), false);
446        assertEquals(TEST_2008_06.isSupported(ChronoUnit.DAYS), false);
447        assertEquals(TEST_2008_06.isSupported(ChronoUnit.WEEKS), false);
448        assertEquals(TEST_2008_06.isSupported(ChronoUnit.MONTHS), true);
449        assertEquals(TEST_2008_06.isSupported(ChronoUnit.YEARS), true);
450        assertEquals(TEST_2008_06.isSupported(ChronoUnit.DECADES), true);
451        assertEquals(TEST_2008_06.isSupported(ChronoUnit.CENTURIES), true);
452        assertEquals(TEST_2008_06.isSupported(ChronoUnit.MILLENNIA), true);
453        assertEquals(TEST_2008_06.isSupported(ChronoUnit.ERAS), true);
454        assertEquals(TEST_2008_06.isSupported(ChronoUnit.FOREVER), false);
455    }
456
457    //-----------------------------------------------------------------------
458    // get(TemporalField)
459    //-----------------------------------------------------------------------
460    @Test
461    public void test_get_TemporalField() {
462        assertEquals(TEST_2008_06.get(YEAR), 2008);
463        assertEquals(TEST_2008_06.get(MONTH_OF_YEAR), 6);
464        assertEquals(TEST_2008_06.get(YEAR_OF_ERA), 2008);
465        assertEquals(TEST_2008_06.get(ERA), 1);
466    }
467
468    @Test
469    public void test_getLong_TemporalField() {
470        assertEquals(TEST_2008_06.getLong(YEAR), 2008);
471        assertEquals(TEST_2008_06.getLong(MONTH_OF_YEAR), 6);
472        assertEquals(TEST_2008_06.getLong(YEAR_OF_ERA), 2008);
473        assertEquals(TEST_2008_06.getLong(ERA), 1);
474        assertEquals(TEST_2008_06.getLong(PROLEPTIC_MONTH), 2008 * 12 + 6 - 1);
475    }
476
477    //-----------------------------------------------------------------------
478    // query(TemporalQuery)
479    //-----------------------------------------------------------------------
480    @DataProvider(name="query")
481    Object[][] data_query() {
482        return new Object[][] {
483                {TEST_2008_06, TemporalQueries.chronology(), IsoChronology.INSTANCE},
484                {TEST_2008_06, TemporalQueries.zoneId(), null},
485                {TEST_2008_06, TemporalQueries.precision(), ChronoUnit.MONTHS},
486                {TEST_2008_06, TemporalQueries.zone(), null},
487                {TEST_2008_06, TemporalQueries.offset(), null},
488                {TEST_2008_06, TemporalQueries.localDate(), null},
489                {TEST_2008_06, TemporalQueries.localTime(), null},
490        };
491    }
492
493    @Test(dataProvider="query")
494    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
495        assertEquals(temporal.query(query), expected);
496    }
497
498    @Test(dataProvider="query")
499    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
500        assertEquals(query.queryFrom(temporal), expected);
501    }
502
503    @Test(expectedExceptions=NullPointerException.class)
504    public void test_query_null() {
505        TEST_2008_06.query(null);
506    }
507
508    //-----------------------------------------------------------------------
509    // get*()
510    //-----------------------------------------------------------------------
511    @DataProvider(name="sampleDates")
512    Object[][] provider_sampleDates() {
513        return new Object[][] {
514            {2008, 1},
515            {2008, 2},
516            {-1, 3},
517            {0, 12},
518        };
519    }
520
521    @Test(dataProvider="sampleDates")
522    public void test_get(int y, int m) {
523        YearMonth a = YearMonth.of(y, m);
524        assertEquals(a.getYear(), y);
525        assertEquals(a.getMonth(), Month.of(m));
526        assertEquals(a.getMonthValue(), m);
527    }
528
529    //-----------------------------------------------------------------------
530    // with(Year)
531    //-----------------------------------------------------------------------
532    @Test
533    public void test_with_Year() {
534        YearMonth test = YearMonth.of(2008, 6);
535        assertEquals(test.with(Year.of(2000)), YearMonth.of(2000, 6));
536    }
537
538    @Test
539    public void test_with_Year_noChange_equal() {
540        YearMonth test = YearMonth.of(2008, 6);
541        assertEquals(test.with(Year.of(2008)), test);
542    }
543
544    @Test(expectedExceptions=NullPointerException.class)
545    public void test_with_Year_null() {
546        YearMonth test = YearMonth.of(2008, 6);
547        test.with((Year) null);
548    }
549
550    //-----------------------------------------------------------------------
551    // with(Month)
552    //-----------------------------------------------------------------------
553    @Test
554    public void test_with_Month() {
555        YearMonth test = YearMonth.of(2008, 6);
556        assertEquals(test.with(Month.JANUARY), YearMonth.of(2008, 1));
557    }
558
559    @Test
560    public void test_with_Month_noChange_equal() {
561        YearMonth test = YearMonth.of(2008, 6);
562        assertEquals(test.with(Month.JUNE), test);
563    }
564
565    @Test(expectedExceptions=NullPointerException.class)
566    public void test_with_Month_null() {
567        YearMonth test = YearMonth.of(2008, 6);
568        test.with((Month) null);
569    }
570
571    //-----------------------------------------------------------------------
572    // withYear()
573    //-----------------------------------------------------------------------
574    @Test
575    public void test_withYear() {
576        YearMonth test = YearMonth.of(2008, 6);
577        assertEquals(test.withYear(1999), YearMonth.of(1999, 6));
578    }
579
580    @Test
581    public void test_withYear_int_noChange_equal() {
582        YearMonth test = YearMonth.of(2008, 6);
583        assertEquals(test.withYear(2008), test);
584    }
585
586    @Test(expectedExceptions=DateTimeException.class)
587    public void test_withYear_tooLow() {
588        YearMonth test = YearMonth.of(2008, 6);
589        test.withYear(Year.MIN_VALUE - 1);
590    }
591
592    @Test(expectedExceptions=DateTimeException.class)
593    public void test_withYear_tooHigh() {
594        YearMonth test = YearMonth.of(2008, 6);
595        test.withYear(Year.MAX_VALUE + 1);
596    }
597
598    //-----------------------------------------------------------------------
599    // withMonth()
600    //-----------------------------------------------------------------------
601    @Test
602    public void test_withMonth() {
603        YearMonth test = YearMonth.of(2008, 6);
604        assertEquals(test.withMonth(1), YearMonth.of(2008, 1));
605    }
606
607    @Test
608    public void test_withMonth_int_noChange_equal() {
609        YearMonth test = YearMonth.of(2008, 6);
610        assertEquals(test.withMonth(6), test);
611    }
612
613    @Test(expectedExceptions=DateTimeException.class)
614    public void test_withMonth_tooLow() {
615        YearMonth test = YearMonth.of(2008, 6);
616        test.withMonth(0);
617    }
618
619    @Test(expectedExceptions=DateTimeException.class)
620    public void test_withMonth_tooHigh() {
621        YearMonth test = YearMonth.of(2008, 6);
622        test.withMonth(13);
623    }
624
625    //-----------------------------------------------------------------------
626    // plusYears()
627    //-----------------------------------------------------------------------
628    @Test
629    public void test_plusYears_long() {
630        YearMonth test = YearMonth.of(2008, 6);
631        assertEquals(test.plusYears(1), YearMonth.of(2009, 6));
632    }
633
634    @Test
635    public void test_plusYears_long_noChange_equal() {
636        YearMonth test = YearMonth.of(2008, 6);
637        assertEquals(test.plusYears(0), test);
638    }
639
640    @Test
641    public void test_plusYears_long_negative() {
642        YearMonth test = YearMonth.of(2008, 6);
643        assertEquals(test.plusYears(-1), YearMonth.of(2007, 6));
644    }
645
646    @Test
647    public void test_plusYears_long_big() {
648        YearMonth test = YearMonth.of(-40, 6);
649        assertEquals(test.plusYears(20L + Year.MAX_VALUE), YearMonth.of((int) (-40L + 20L + Year.MAX_VALUE), 6));
650    }
651
652    @Test(expectedExceptions=DateTimeException.class)
653    public void test_plusYears_long_invalidTooLarge() {
654        YearMonth test = YearMonth.of(Year.MAX_VALUE, 6);
655        test.plusYears(1);
656    }
657
658    @Test(expectedExceptions=DateTimeException.class)
659    public void test_plusYears_long_invalidTooLargeMaxAddMax() {
660        YearMonth test = YearMonth.of(Year.MAX_VALUE, 12);
661        test.plusYears(Long.MAX_VALUE);
662    }
663
664    @Test(expectedExceptions=DateTimeException.class)
665    public void test_plusYears_long_invalidTooLargeMaxAddMin() {
666        YearMonth test = YearMonth.of(Year.MAX_VALUE, 12);
667        test.plusYears(Long.MIN_VALUE);
668    }
669
670    @Test(expectedExceptions=DateTimeException.class)
671    public void test_plusYears_long_invalidTooSmall() {
672        YearMonth test = YearMonth.of(Year.MIN_VALUE, 6);
673        test.plusYears(-1);
674    }
675
676    //-----------------------------------------------------------------------
677    // plusMonths()
678    //-----------------------------------------------------------------------
679    @Test
680    public void test_plusMonths_long() {
681        YearMonth test = YearMonth.of(2008, 6);
682        assertEquals(test.plusMonths(1), YearMonth.of(2008, 7));
683    }
684
685    @Test
686    public void test_plusMonths_long_noChange_equal() {
687        YearMonth test = YearMonth.of(2008, 6);
688        assertEquals(test.plusMonths(0), test);
689    }
690
691    @Test
692    public void test_plusMonths_long_overYears() {
693        YearMonth test = YearMonth.of(2008, 6);
694        assertEquals(test.plusMonths(7), YearMonth.of(2009, 1));
695    }
696
697    @Test
698    public void test_plusMonths_long_negative() {
699        YearMonth test = YearMonth.of(2008, 6);
700        assertEquals(test.plusMonths(-1), YearMonth.of(2008, 5));
701    }
702
703    @Test
704    public void test_plusMonths_long_negativeOverYear() {
705        YearMonth test = YearMonth.of(2008, 6);
706        assertEquals(test.plusMonths(-6), YearMonth.of(2007, 12));
707    }
708
709    @Test
710    public void test_plusMonths_long_big() {
711        YearMonth test = YearMonth.of(-40, 6);
712        long months = 20L + Integer.MAX_VALUE;
713        assertEquals(test.plusMonths(months), YearMonth.of((int) (-40L + months / 12), 6 + (int) (months % 12)));
714    }
715
716    @Test(expectedExceptions={DateTimeException.class})
717    public void test_plusMonths_long_invalidTooLarge() {
718        YearMonth test = YearMonth.of(Year.MAX_VALUE, 12);
719        test.plusMonths(1);
720    }
721
722    @Test(expectedExceptions=DateTimeException.class)
723    public void test_plusMonths_long_invalidTooLargeMaxAddMax() {
724        YearMonth test = YearMonth.of(Year.MAX_VALUE, 12);
725        test.plusMonths(Long.MAX_VALUE);
726    }
727
728    @Test(expectedExceptions=DateTimeException.class)
729    public void test_plusMonths_long_invalidTooLargeMaxAddMin() {
730        YearMonth test = YearMonth.of(Year.MAX_VALUE, 12);
731        test.plusMonths(Long.MIN_VALUE);
732    }
733
734    @Test(expectedExceptions={DateTimeException.class})
735    public void test_plusMonths_long_invalidTooSmall() {
736        YearMonth test = YearMonth.of(Year.MIN_VALUE, 1);
737        test.plusMonths(-1);
738    }
739
740    //-----------------------------------------------------------------------
741    // plus(long, TemporalUnit)
742    //-----------------------------------------------------------------------
743    @DataProvider(name="plus_long_TemporalUnit")
744    Object[][] data_plus_long_TemporalUnit() {
745        return new Object[][] {
746            {YearMonth.of(1, 10), 1, ChronoUnit.YEARS, YearMonth.of(2, 10), null},
747            {YearMonth.of(1, 10), -12, ChronoUnit.YEARS, YearMonth.of(-11, 10), null},
748            {YearMonth.of(1, 10), 0, ChronoUnit.YEARS, YearMonth.of(1, 10), null},
749            {YearMonth.of(999999999, 12), 0, ChronoUnit.YEARS, YearMonth.of(999999999, 12), null},
750            {YearMonth.of(-999999999, 1), 0, ChronoUnit.YEARS, YearMonth.of(-999999999, 1), null},
751            {YearMonth.of(0, 1), -999999999, ChronoUnit.YEARS, YearMonth.of(-999999999, 1), null},
752            {YearMonth.of(0, 12), 999999999, ChronoUnit.YEARS, YearMonth.of(999999999, 12), null},
753
754            {YearMonth.of(1, 10), 1, ChronoUnit.MONTHS, YearMonth.of(1, 11), null},
755            {YearMonth.of(1, 10), -12, ChronoUnit.MONTHS, YearMonth.of(0, 10), null},
756            {YearMonth.of(1, 10), 0, ChronoUnit.MONTHS, YearMonth.of(1, 10), null},
757            {YearMonth.of(999999999, 12), 0, ChronoUnit.MONTHS, YearMonth.of(999999999, 12), null},
758            {YearMonth.of(-999999999, 1), 0, ChronoUnit.MONTHS, YearMonth.of(-999999999, 1), null},
759            {YearMonth.of(-999999999, 2), -1, ChronoUnit.MONTHS, YearMonth.of(-999999999, 1), null},
760            {YearMonth.of(999999999, 3), 9, ChronoUnit.MONTHS, YearMonth.of(999999999, 12), null},
761
762            {YearMonth.of(-1, 10), 1, ChronoUnit.ERAS, YearMonth.of(2, 10), null},
763            {YearMonth.of(5, 10), 1, ChronoUnit.CENTURIES, YearMonth.of(105, 10), null},
764            {YearMonth.of(5, 10), 1, ChronoUnit.DECADES, YearMonth.of(15, 10), null},
765
766            {YearMonth.of(999999999, 12), 1, ChronoUnit.MONTHS, null, DateTimeException.class},
767            {YearMonth.of(-999999999, 1), -1, ChronoUnit.MONTHS, null, DateTimeException.class},
768
769            {YearMonth.of(1, 1), 0, ChronoUnit.DAYS, null, DateTimeException.class},
770            {YearMonth.of(1, 1), 0, ChronoUnit.WEEKS, null, DateTimeException.class},
771        };
772    }
773
774    @Test(dataProvider="plus_long_TemporalUnit")
775    public void test_plus_long_TemporalUnit(YearMonth base, long amount, TemporalUnit unit, YearMonth expectedYearMonth, Class<?> expectedEx) {
776        if (expectedEx == null) {
777            assertEquals(base.plus(amount, unit), expectedYearMonth);
778        } else {
779            try {
780                YearMonth result = base.plus(amount, unit);
781                fail();
782            } catch (Exception ex) {
783                assertTrue(expectedEx.isInstance(ex));
784            }
785        }
786    }
787
788    //-----------------------------------------------------------------------
789    // plus(TemporalAmount)
790    //-----------------------------------------------------------------------
791    @DataProvider(name="plus_TemporalAmount")
792    Object[][] data_plus_TemporalAmount() {
793        return new Object[][] {
794            {YearMonth.of(1, 1), Period.ofYears(1), YearMonth.of(2, 1), null},
795            {YearMonth.of(1, 1), Period.ofYears(-12), YearMonth.of(-11, 1), null},
796            {YearMonth.of(1, 1), Period.ofYears(0), YearMonth.of(1, 1), null},
797            {YearMonth.of(999999999, 12), Period.ofYears(0), YearMonth.of(999999999, 12), null},
798            {YearMonth.of(-999999999, 1), Period.ofYears(0), YearMonth.of(-999999999, 1), null},
799            {YearMonth.of(0, 1), Period.ofYears(-999999999), YearMonth.of(-999999999, 1), null},
800            {YearMonth.of(0, 12), Period.ofYears(999999999), YearMonth.of(999999999, 12), null},
801
802            {YearMonth.of(1, 1), Period.ofMonths(1), YearMonth.of(1, 2), null},
803            {YearMonth.of(1, 1), Period.ofMonths(-12), YearMonth.of(0, 1), null},
804            {YearMonth.of(1, 1), Period.ofMonths(121), YearMonth.of(11, 2), null},
805            {YearMonth.of(1, 1), Period.ofMonths(0), YearMonth.of(1, 1), null},
806            {YearMonth.of(999999999, 12), Period.ofMonths(0), YearMonth.of(999999999, 12), null},
807            {YearMonth.of(-999999999, 1), Period.ofMonths(0), YearMonth.of(-999999999, 1), null},
808            {YearMonth.of(-999999999, 2), Period.ofMonths(-1), YearMonth.of(-999999999, 1), null},
809            {YearMonth.of(999999999, 11), Period.ofMonths(1), YearMonth.of(999999999, 12), null},
810
811            {YearMonth.of(1, 1), Period.ofYears(1).withMonths(2), YearMonth.of(2, 3), null},
812            {YearMonth.of(1, 1), Period.ofYears(-12).withMonths(-1), YearMonth.of(-12, 12), null},
813
814            {YearMonth.of(1, 1), Period.ofMonths(2).withYears(1), YearMonth.of(2, 3), null},
815            {YearMonth.of(1, 1), Period.ofMonths(-1).withYears(-12), YearMonth.of(-12, 12), null},
816
817            {YearMonth.of(1, 1), Period.ofDays(365), null, DateTimeException.class},
818            {YearMonth.of(1, 1), Duration.ofDays(365), null, DateTimeException.class},
819            {YearMonth.of(1, 1), Duration.ofHours(365*24), null, DateTimeException.class},
820            {YearMonth.of(1, 1), Duration.ofMinutes(365*24*60), null, DateTimeException.class},
821            {YearMonth.of(1, 1), Duration.ofSeconds(365*24*3600), null, DateTimeException.class},
822            {YearMonth.of(1, 1), Duration.ofNanos(365*24*3600*1000000000), null, DateTimeException.class},
823        };
824    }
825
826    @Test(dataProvider="plus_TemporalAmount")
827    public void test_plus_TemporalAmount(YearMonth base, TemporalAmount temporalAmount, YearMonth expectedYearMonth, Class<?> expectedEx) {
828        if (expectedEx == null) {
829            assertEquals(base.plus(temporalAmount), expectedYearMonth);
830        } else {
831            try {
832                YearMonth result = base.plus(temporalAmount);
833                fail();
834            } catch (Exception ex) {
835                assertTrue(expectedEx.isInstance(ex));
836            }
837        }
838    }
839
840    //-----------------------------------------------------------------------
841    // minusYears()
842    //-----------------------------------------------------------------------
843    @Test
844    public void test_minusYears_long() {
845        YearMonth test = YearMonth.of(2008, 6);
846        assertEquals(test.minusYears(1), YearMonth.of(2007, 6));
847    }
848
849    @Test
850    public void test_minusYears_long_noChange_equal() {
851        YearMonth test = YearMonth.of(2008, 6);
852        assertEquals(test.minusYears(0), test);
853    }
854
855    @Test
856    public void test_minusYears_long_negative() {
857        YearMonth test = YearMonth.of(2008, 6);
858        assertEquals(test.minusYears(-1), YearMonth.of(2009, 6));
859    }
860
861    @Test
862    public void test_minusYears_long_big() {
863        YearMonth test = YearMonth.of(40, 6);
864        assertEquals(test.minusYears(20L + Year.MAX_VALUE), YearMonth.of((int) (40L - 20L - Year.MAX_VALUE), 6));
865    }
866
867    @Test(expectedExceptions=DateTimeException.class)
868    public void test_minusYears_long_invalidTooLarge() {
869        YearMonth test = YearMonth.of(Year.MAX_VALUE, 6);
870        test.minusYears(-1);
871    }
872
873    @Test(expectedExceptions=DateTimeException.class)
874    public void test_minusYears_long_invalidTooLargeMaxSubtractMax() {
875        YearMonth test = YearMonth.of(Year.MIN_VALUE, 12);
876        test.minusYears(Long.MAX_VALUE);
877    }
878
879    @Test(expectedExceptions=DateTimeException.class)
880    public void test_minusYears_long_invalidTooLargeMaxSubtractMin() {
881        YearMonth test = YearMonth.of(Year.MIN_VALUE, 12);
882        test.minusYears(Long.MIN_VALUE);
883    }
884
885    @Test(expectedExceptions=DateTimeException.class)
886    public void test_minusYears_long_invalidTooSmall() {
887        YearMonth test = YearMonth.of(Year.MIN_VALUE, 6);
888        test.minusYears(1);
889    }
890
891    //-----------------------------------------------------------------------
892    // minusMonths()
893    //-----------------------------------------------------------------------
894    @Test
895    public void test_minusMonths_long() {
896        YearMonth test = YearMonth.of(2008, 6);
897        assertEquals(test.minusMonths(1), YearMonth.of(2008, 5));
898    }
899
900    @Test
901    public void test_minusMonths_long_noChange_equal() {
902        YearMonth test = YearMonth.of(2008, 6);
903        assertEquals(test.minusMonths(0), test);
904    }
905
906    @Test
907    public void test_minusMonths_long_overYears() {
908        YearMonth test = YearMonth.of(2008, 6);
909        assertEquals(test.minusMonths(6), YearMonth.of(2007, 12));
910    }
911
912    @Test
913    public void test_minusMonths_long_negative() {
914        YearMonth test = YearMonth.of(2008, 6);
915        assertEquals(test.minusMonths(-1), YearMonth.of(2008, 7));
916    }
917
918    @Test
919    public void test_minusMonths_long_negativeOverYear() {
920        YearMonth test = YearMonth.of(2008, 6);
921        assertEquals(test.minusMonths(-7), YearMonth.of(2009, 1));
922    }
923
924    @Test
925    public void test_minusMonths_long_big() {
926        YearMonth test = YearMonth.of(40, 6);
927        long months = 20L + Integer.MAX_VALUE;
928        assertEquals(test.minusMonths(months), YearMonth.of((int) (40L - months / 12), 6 - (int) (months % 12)));
929    }
930
931    @Test(expectedExceptions={DateTimeException.class})
932    public void test_minusMonths_long_invalidTooLarge() {
933        YearMonth test = YearMonth.of(Year.MAX_VALUE, 12);
934        test.minusMonths(-1);
935    }
936
937    @Test(expectedExceptions=DateTimeException.class)
938    public void test_minusMonths_long_invalidTooLargeMaxSubtractMax() {
939        YearMonth test = YearMonth.of(Year.MAX_VALUE, 12);
940        test.minusMonths(Long.MAX_VALUE);
941    }
942
943    @Test(expectedExceptions=DateTimeException.class)
944    public void test_minusMonths_long_invalidTooLargeMaxSubtractMin() {
945        YearMonth test = YearMonth.of(Year.MAX_VALUE, 12);
946        test.minusMonths(Long.MIN_VALUE);
947    }
948
949    @Test(expectedExceptions={DateTimeException.class})
950    public void test_minusMonths_long_invalidTooSmall() {
951        YearMonth test = YearMonth.of(Year.MIN_VALUE, 1);
952        test.minusMonths(1);
953    }
954
955    //-----------------------------------------------------------------------
956    // minus(long, TemporalUnit)
957    //-----------------------------------------------------------------------
958    @DataProvider(name="minus_long_TemporalUnit")
959    Object[][] data_minus_long_TemporalUnit() {
960        return new Object[][] {
961            {YearMonth.of(1, 10), 1, ChronoUnit.YEARS, YearMonth.of(0, 10), null},
962            {YearMonth.of(1, 10), 12, ChronoUnit.YEARS, YearMonth.of(-11, 10), null},
963            {YearMonth.of(1, 10), 0, ChronoUnit.YEARS, YearMonth.of(1, 10), null},
964            {YearMonth.of(999999999, 12), 0, ChronoUnit.YEARS, YearMonth.of(999999999, 12), null},
965            {YearMonth.of(-999999999, 1), 0, ChronoUnit.YEARS, YearMonth.of(-999999999, 1), null},
966            {YearMonth.of(0, 1), 999999999, ChronoUnit.YEARS, YearMonth.of(-999999999, 1), null},
967            {YearMonth.of(0, 12), -999999999, ChronoUnit.YEARS, YearMonth.of(999999999, 12), null},
968
969            {YearMonth.of(1, 10), 1, ChronoUnit.MONTHS, YearMonth.of(1, 9), null},
970            {YearMonth.of(1, 10), 12, ChronoUnit.MONTHS, YearMonth.of(0, 10), null},
971            {YearMonth.of(1, 10), 0, ChronoUnit.MONTHS, YearMonth.of(1, 10), null},
972            {YearMonth.of(999999999, 12), 0, ChronoUnit.MONTHS, YearMonth.of(999999999, 12), null},
973            {YearMonth.of(-999999999, 1), 0, ChronoUnit.MONTHS, YearMonth.of(-999999999, 1), null},
974            {YearMonth.of(-999999999, 2), 1, ChronoUnit.MONTHS, YearMonth.of(-999999999, 1), null},
975            {YearMonth.of(999999999, 11), -1, ChronoUnit.MONTHS, YearMonth.of(999999999, 12), null},
976
977            {YearMonth.of(1, 10), 1, ChronoUnit.ERAS, YearMonth.of(0, 10), null},
978            {YearMonth.of(5, 10), 1, ChronoUnit.CENTURIES, YearMonth.of(-95, 10), null},
979            {YearMonth.of(5, 10), 1, ChronoUnit.DECADES, YearMonth.of(-5, 10), null},
980
981            {YearMonth.of(999999999, 12), -1, ChronoUnit.MONTHS, null, DateTimeException.class},
982            {YearMonth.of(-999999999, 1), 1, ChronoUnit.MONTHS, null, DateTimeException.class},
983
984            {YearMonth.of(1, 1), 0, ChronoUnit.DAYS, null, DateTimeException.class},
985            {YearMonth.of(1, 1), 0, ChronoUnit.WEEKS, null, DateTimeException.class},
986        };
987    }
988
989    @Test(dataProvider="minus_long_TemporalUnit")
990    public void test_minus_long_TemporalUnit(YearMonth base, long amount, TemporalUnit unit, YearMonth expectedYearMonth, Class<?> expectedEx) {
991        if (expectedEx == null) {
992            assertEquals(base.minus(amount, unit), expectedYearMonth);
993        } else {
994            try {
995                YearMonth result = base.minus(amount, unit);
996                fail();
997            } catch (Exception ex) {
998                assertTrue(expectedEx.isInstance(ex));
999            }
1000        }
1001    }
1002
1003    //-----------------------------------------------------------------------
1004    // minus(TemporalAmount)
1005    //-----------------------------------------------------------------------
1006    @DataProvider(name="minus_TemporalAmount")
1007    Object[][] data_minus_TemporalAmount() {
1008        return new Object[][] {
1009            {YearMonth.of(1, 1), Period.ofYears(1), YearMonth.of(0, 1), null},
1010            {YearMonth.of(1, 1), Period.ofYears(-12), YearMonth.of(13, 1), null},
1011            {YearMonth.of(1, 1), Period.ofYears(0), YearMonth.of(1, 1), null},
1012            {YearMonth.of(999999999, 12), Period.ofYears(0), YearMonth.of(999999999, 12), null},
1013            {YearMonth.of(-999999999, 1), Period.ofYears(0), YearMonth.of(-999999999, 1), null},
1014            {YearMonth.of(0, 1), Period.ofYears(999999999), YearMonth.of(-999999999, 1), null},
1015            {YearMonth.of(0, 12), Period.ofYears(-999999999), YearMonth.of(999999999, 12), null},
1016
1017            {YearMonth.of(1, 1), Period.ofMonths(1), YearMonth.of(0, 12), null},
1018            {YearMonth.of(1, 1), Period.ofMonths(-12), YearMonth.of(2, 1), null},
1019            {YearMonth.of(1, 1), Period.ofMonths(121), YearMonth.of(-10, 12), null},
1020            {YearMonth.of(1, 1), Period.ofMonths(0), YearMonth.of(1, 1), null},
1021            {YearMonth.of(999999999, 12), Period.ofMonths(0), YearMonth.of(999999999, 12), null},
1022            {YearMonth.of(-999999999, 1), Period.ofMonths(0), YearMonth.of(-999999999, 1), null},
1023            {YearMonth.of(-999999999, 2), Period.ofMonths(1), YearMonth.of(-999999999, 1), null},
1024            {YearMonth.of(999999999, 11), Period.ofMonths(-1), YearMonth.of(999999999, 12), null},
1025
1026            {YearMonth.of(1, 1), Period.ofYears(1).withMonths(2), YearMonth.of(-1, 11), null},
1027            {YearMonth.of(1, 1), Period.ofYears(-12).withMonths(-1), YearMonth.of(13, 2), null},
1028
1029            {YearMonth.of(1, 1), Period.ofMonths(2).withYears(1), YearMonth.of(-1, 11), null},
1030            {YearMonth.of(1, 1), Period.ofMonths(-1).withYears(-12), YearMonth.of(13, 2), null},
1031
1032            {YearMonth.of(1, 1), Period.ofDays(365), null, DateTimeException.class},
1033            {YearMonth.of(1, 1), Duration.ofDays(365), null, DateTimeException.class},
1034            {YearMonth.of(1, 1), Duration.ofHours(365*24), null, DateTimeException.class},
1035            {YearMonth.of(1, 1), Duration.ofMinutes(365*24*60), null, DateTimeException.class},
1036            {YearMonth.of(1, 1), Duration.ofSeconds(365*24*3600), null, DateTimeException.class},
1037            {YearMonth.of(1, 1), Duration.ofNanos(365*24*3600*1000000000), null, DateTimeException.class},
1038        };
1039    }
1040
1041    @Test(dataProvider="minus_TemporalAmount")
1042    public void test_minus_TemporalAmount(YearMonth base, TemporalAmount temporalAmount, YearMonth expectedYearMonth, Class<?> expectedEx) {
1043        if (expectedEx == null) {
1044            assertEquals(base.minus(temporalAmount), expectedYearMonth);
1045        } else {
1046            try {
1047                YearMonth result = base.minus(temporalAmount);
1048                fail();
1049            } catch (Exception ex) {
1050                assertTrue(expectedEx.isInstance(ex));
1051            }
1052        }
1053    }
1054
1055    //-----------------------------------------------------------------------
1056    // adjustInto()
1057    //-----------------------------------------------------------------------
1058    @Test
1059    public void test_adjustDate() {
1060        YearMonth test = YearMonth.of(2008, 6);
1061        LocalDate date = LocalDate.of(2007, 1, 1);
1062        assertEquals(test.adjustInto(date), LocalDate.of(2008, 6, 1));
1063    }
1064
1065    @Test
1066    public void test_adjustDate_preserveDoM() {
1067        YearMonth test = YearMonth.of(2011, 3);
1068        LocalDate date = LocalDate.of(2008, 2, 29);
1069        assertEquals(test.adjustInto(date), LocalDate.of(2011, 3, 29));
1070    }
1071
1072    @Test
1073    public void test_adjustDate_resolve() {
1074        YearMonth test = YearMonth.of(2007, 2);
1075        LocalDate date = LocalDate.of(2008, 3, 31);
1076        assertEquals(test.adjustInto(date), LocalDate.of(2007, 2, 28));
1077    }
1078
1079    @Test
1080    public void test_adjustDate_equal() {
1081        YearMonth test = YearMonth.of(2008, 6);
1082        LocalDate date = LocalDate.of(2008, 6, 30);
1083        assertEquals(test.adjustInto(date), date);
1084    }
1085
1086    @Test(expectedExceptions=NullPointerException.class)
1087    public void test_adjustDate_null() {
1088        TEST_2008_06.adjustInto((LocalDate) null);
1089    }
1090
1091    //-----------------------------------------------------------------------
1092    // isLeapYear()
1093    //-----------------------------------------------------------------------
1094    @Test
1095    public void test_isLeapYear() {
1096        assertEquals(YearMonth.of(2007, 6).isLeapYear(), false);
1097        assertEquals(YearMonth.of(2008, 6).isLeapYear(), true);
1098    }
1099
1100    //-----------------------------------------------------------------------
1101    // lengthOfMonth()
1102    //-----------------------------------------------------------------------
1103    @Test
1104    public void test_lengthOfMonth_june() {
1105        YearMonth test = YearMonth.of(2007, 6);
1106        assertEquals(test.lengthOfMonth(), 30);
1107    }
1108
1109    @Test
1110    public void test_lengthOfMonth_febNonLeap() {
1111        YearMonth test = YearMonth.of(2007, 2);
1112        assertEquals(test.lengthOfMonth(), 28);
1113    }
1114
1115    @Test
1116    public void test_lengthOfMonth_febLeap() {
1117        YearMonth test = YearMonth.of(2008, 2);
1118        assertEquals(test.lengthOfMonth(), 29);
1119    }
1120
1121    //-----------------------------------------------------------------------
1122    // lengthOfYear()
1123    //-----------------------------------------------------------------------
1124    @Test
1125    public void test_lengthOfYear() {
1126        assertEquals(YearMonth.of(2007, 6).lengthOfYear(), 365);
1127        assertEquals(YearMonth.of(2008, 6).lengthOfYear(), 366);
1128    }
1129
1130    //-----------------------------------------------------------------------
1131    // isValidDay(int)
1132    //-----------------------------------------------------------------------
1133    @Test
1134    public void test_isValidDay_int_june() {
1135        YearMonth test = YearMonth.of(2007, 6);
1136        assertEquals(test.isValidDay(1), true);
1137        assertEquals(test.isValidDay(30), true);
1138
1139        assertEquals(test.isValidDay(-1), false);
1140        assertEquals(test.isValidDay(0), false);
1141        assertEquals(test.isValidDay(31), false);
1142        assertEquals(test.isValidDay(32), false);
1143    }
1144
1145    @Test
1146    public void test_isValidDay_int_febNonLeap() {
1147        YearMonth test = YearMonth.of(2007, 2);
1148        assertEquals(test.isValidDay(1), true);
1149        assertEquals(test.isValidDay(28), true);
1150
1151        assertEquals(test.isValidDay(-1), false);
1152        assertEquals(test.isValidDay(0), false);
1153        assertEquals(test.isValidDay(29), false);
1154        assertEquals(test.isValidDay(32), false);
1155    }
1156
1157    @Test
1158    public void test_isValidDay_int_febLeap() {
1159        YearMonth test = YearMonth.of(2008, 2);
1160        assertEquals(test.isValidDay(1), true);
1161        assertEquals(test.isValidDay(29), true);
1162
1163        assertEquals(test.isValidDay(-1), false);
1164        assertEquals(test.isValidDay(0), false);
1165        assertEquals(test.isValidDay(30), false);
1166        assertEquals(test.isValidDay(32), false);
1167    }
1168
1169    //-----------------------------------------------------------------------
1170    // until(Temporal, TemporalUnit)
1171    //-----------------------------------------------------------------------
1172    @DataProvider(name="periodUntilUnit")
1173    Object[][] data_periodUntilUnit() {
1174        return new Object[][] {
1175                {ym(2000, 1), ym(-1, 12), MONTHS, -2000 * 12 - 1},
1176                {ym(2000, 1), ym(0, 1), MONTHS, -2000 * 12},
1177                {ym(2000, 1), ym(0, 12), MONTHS, -1999 * 12 - 1},
1178                {ym(2000, 1), ym(1, 1), MONTHS, -1999 * 12},
1179                {ym(2000, 1), ym(1999, 12), MONTHS, -1},
1180                {ym(2000, 1), ym(2000, 1), MONTHS, 0},
1181                {ym(2000, 1), ym(2000, 2), MONTHS, 1},
1182                {ym(2000, 1), ym(2000, 3), MONTHS, 2},
1183                {ym(2000, 1), ym(2000, 12), MONTHS, 11},
1184                {ym(2000, 1), ym(2001, 1), MONTHS, 12},
1185                {ym(2000, 1), ym(2246, 5), MONTHS, 246 * 12 + 4},
1186
1187                {ym(2000, 1), ym(-1, 12), YEARS, -2000},
1188                {ym(2000, 1), ym(0, 1), YEARS, -2000},
1189                {ym(2000, 1), ym(0, 12), YEARS, -1999},
1190                {ym(2000, 1), ym(1, 1), YEARS, -1999},
1191                {ym(2000, 1), ym(1998, 12), YEARS, -1},
1192                {ym(2000, 1), ym(1999, 1), YEARS, -1},
1193                {ym(2000, 1), ym(1999, 2), YEARS, 0},
1194                {ym(2000, 1), ym(1999, 12), YEARS, 0},
1195                {ym(2000, 1), ym(2000, 1), YEARS, 0},
1196                {ym(2000, 1), ym(2000, 2), YEARS, 0},
1197                {ym(2000, 1), ym(2000, 12), YEARS, 0},
1198                {ym(2000, 1), ym(2001, 1), YEARS, 1},
1199                {ym(2000, 1), ym(2246, 5), YEARS, 246},
1200
1201                {ym(2000, 5), ym(-1, 5), DECADES, -200},
1202                {ym(2000, 5), ym(0, 4), DECADES, -200},
1203                {ym(2000, 5), ym(0, 5), DECADES, -200},
1204                {ym(2000, 5), ym(0, 6), DECADES, -199},
1205                {ym(2000, 5), ym(1, 5), DECADES, -199},
1206                {ym(2000, 5), ym(1990, 4), DECADES, -1},
1207                {ym(2000, 5), ym(1990, 5), DECADES, -1},
1208                {ym(2000, 5), ym(1990, 6), DECADES, 0},
1209                {ym(2000, 5), ym(2000, 4), DECADES, 0},
1210                {ym(2000, 5), ym(2000, 5), DECADES, 0},
1211                {ym(2000, 5), ym(2000, 6), DECADES, 0},
1212                {ym(2000, 5), ym(2010, 4), DECADES, 0},
1213                {ym(2000, 5), ym(2010, 5), DECADES, 1},
1214                {ym(2000, 5), ym(2010, 6), DECADES, 1},
1215
1216                {ym(2000, 5), ym(-1, 5), CENTURIES, -20},
1217                {ym(2000, 5), ym(0, 4), CENTURIES, -20},
1218                {ym(2000, 5), ym(0, 5), CENTURIES, -20},
1219                {ym(2000, 5), ym(0, 6), CENTURIES, -19},
1220                {ym(2000, 5), ym(1, 5), CENTURIES, -19},
1221                {ym(2000, 5), ym(1900, 4), CENTURIES, -1},
1222                {ym(2000, 5), ym(1900, 5), CENTURIES, -1},
1223                {ym(2000, 5), ym(1900, 6), CENTURIES, 0},
1224                {ym(2000, 5), ym(2000, 4), CENTURIES, 0},
1225                {ym(2000, 5), ym(2000, 5), CENTURIES, 0},
1226                {ym(2000, 5), ym(2000, 6), CENTURIES, 0},
1227                {ym(2000, 5), ym(2100, 4), CENTURIES, 0},
1228                {ym(2000, 5), ym(2100, 5), CENTURIES, 1},
1229                {ym(2000, 5), ym(2100, 6), CENTURIES, 1},
1230
1231                {ym(2000, 5), ym(-1, 5), MILLENNIA, -2},
1232                {ym(2000, 5), ym(0, 4), MILLENNIA, -2},
1233                {ym(2000, 5), ym(0, 5), MILLENNIA, -2},
1234                {ym(2000, 5), ym(0, 6), MILLENNIA, -1},
1235                {ym(2000, 5), ym(1, 5), MILLENNIA, -1},
1236                {ym(2000, 5), ym(1000, 4), MILLENNIA, -1},
1237                {ym(2000, 5), ym(1000, 5), MILLENNIA, -1},
1238                {ym(2000, 5), ym(1000, 6), MILLENNIA, 0},
1239                {ym(2000, 5), ym(2000, 4), MILLENNIA, 0},
1240                {ym(2000, 5), ym(2000, 5), MILLENNIA, 0},
1241                {ym(2000, 5), ym(2000, 6), MILLENNIA, 0},
1242                {ym(2000, 5), ym(3000, 4), MILLENNIA, 0},
1243                {ym(2000, 5), ym(3000, 5), MILLENNIA, 1},
1244                {ym(2000, 5), ym(3000, 5), MILLENNIA, 1},
1245        };
1246    }
1247
1248    @Test(dataProvider="periodUntilUnit")
1249    public void test_until_TemporalUnit(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) {
1250        long amount = ym1.until(ym2, unit);
1251        assertEquals(amount, expected);
1252    }
1253
1254    @Test(dataProvider="periodUntilUnit")
1255    public void test_until_TemporalUnit_negated(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) {
1256        long amount = ym2.until(ym1, unit);
1257        assertEquals(amount, -expected);
1258    }
1259
1260    @Test(dataProvider="periodUntilUnit")
1261    public void test_until_TemporalUnit_between(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) {
1262        long amount = unit.between(ym1, ym2);
1263        assertEquals(amount, expected);
1264    }
1265
1266    @Test
1267    public void test_until_convertedType() {
1268        YearMonth start = YearMonth.of(2010, 6);
1269        LocalDate end = start.plusMonths(2).atDay(12);
1270        assertEquals(start.until(end, MONTHS), 2);
1271    }
1272
1273    @Test(expectedExceptions=DateTimeException.class)
1274    public void test_until_invalidType() {
1275        YearMonth start = YearMonth.of(2010, 6);
1276        start.until(LocalTime.of(11, 30), MONTHS);
1277    }
1278
1279    @Test(expectedExceptions = UnsupportedTemporalTypeException.class)
1280    public void test_until_TemporalUnit_unsupportedUnit() {
1281        TEST_2008_06.until(TEST_2008_06, HOURS);
1282    }
1283
1284    @Test(expectedExceptions = NullPointerException.class)
1285    public void test_until_TemporalUnit_nullEnd() {
1286        TEST_2008_06.until(null, DAYS);
1287    }
1288
1289    @Test(expectedExceptions = NullPointerException.class)
1290    public void test_until_TemporalUnit_nullUnit() {
1291        TEST_2008_06.until(TEST_2008_06, null);
1292    }
1293
1294    //-----------------------------------------------------------------------
1295    // format(DateTimeFormatter)
1296    //-----------------------------------------------------------------------
1297    @Test
1298    public void test_format_formatter() {
1299        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M");
1300        String t = YearMonth.of(2010, 12).format(f);
1301        assertEquals(t, "2010 12");
1302    }
1303
1304    @Test(expectedExceptions=NullPointerException.class)
1305    public void test_format_formatter_null() {
1306        YearMonth.of(2010, 12).format(null);
1307    }
1308
1309    //-----------------------------------------------------------------------
1310    // atDay(int)
1311    //-----------------------------------------------------------------------
1312    @DataProvider(name="atDay")
1313    Object[][] data_atDay() {
1314        return new Object[][] {
1315                {YearMonth.of(2008, 6), 8, LocalDate.of(2008, 6, 8)},
1316
1317                {YearMonth.of(2008, 1), 31, LocalDate.of(2008, 1, 31)},
1318                {YearMonth.of(2008, 2), 29, LocalDate.of(2008, 2, 29)},
1319                {YearMonth.of(2008, 3), 31, LocalDate.of(2008, 3, 31)},
1320                {YearMonth.of(2008, 4), 30, LocalDate.of(2008, 4, 30)},
1321
1322                {YearMonth.of(2009, 1), 32, null},
1323                {YearMonth.of(2009, 1), 0, null},
1324                {YearMonth.of(2009, 2), 29, null},
1325                {YearMonth.of(2009, 2), 30, null},
1326                {YearMonth.of(2009, 2), 31, null},
1327                {YearMonth.of(2009, 4), 31, null},
1328        };
1329    }
1330
1331    @Test(dataProvider="atDay")
1332    public void test_atDay(YearMonth test, int day, LocalDate expected) {
1333        if (expected != null) {
1334            assertEquals(test.atDay(day), expected);
1335        } else {
1336            try {
1337                test.atDay(day);
1338                fail();
1339            } catch (DateTimeException ex) {
1340                // expected
1341            }
1342        }
1343    }
1344
1345    //-----------------------------------------------------------------------
1346    // atEndOfMonth()
1347    //-----------------------------------------------------------------------
1348    @DataProvider(name="atEndOfMonth")
1349    Object[][] data_atEndOfMonth() {
1350        return new Object[][] {
1351                {YearMonth.of(2008, 1), LocalDate.of(2008, 1, 31)},
1352                {YearMonth.of(2008, 2), LocalDate.of(2008, 2, 29)},
1353                {YearMonth.of(2008, 3), LocalDate.of(2008, 3, 31)},
1354                {YearMonth.of(2008, 4), LocalDate.of(2008, 4, 30)},
1355                {YearMonth.of(2008, 5), LocalDate.of(2008, 5, 31)},
1356                {YearMonth.of(2008, 6), LocalDate.of(2008, 6, 30)},
1357                {YearMonth.of(2008, 12), LocalDate.of(2008, 12, 31)},
1358
1359                {YearMonth.of(2009, 1), LocalDate.of(2009, 1, 31)},
1360                {YearMonth.of(2009, 2), LocalDate.of(2009, 2, 28)},
1361                {YearMonth.of(2009, 3), LocalDate.of(2009, 3, 31)},
1362                {YearMonth.of(2009, 4), LocalDate.of(2009, 4, 30)},
1363                {YearMonth.of(2009, 5), LocalDate.of(2009, 5, 31)},
1364                {YearMonth.of(2009, 6), LocalDate.of(2009, 6, 30)},
1365                {YearMonth.of(2009, 12), LocalDate.of(2009, 12, 31)},
1366        };
1367    }
1368
1369    @Test(dataProvider="atEndOfMonth")
1370    public void test_atEndOfMonth(YearMonth test, LocalDate expected) {
1371        assertEquals(test.atEndOfMonth(), expected);
1372    }
1373
1374    //-----------------------------------------------------------------------
1375    // compareTo()
1376    //-----------------------------------------------------------------------
1377    @Test
1378    public void test_comparisons() {
1379        doTest_comparisons_YearMonth(
1380            YearMonth.of(-1, 1),
1381            YearMonth.of(0, 1),
1382            YearMonth.of(0, 12),
1383            YearMonth.of(1, 1),
1384            YearMonth.of(1, 2),
1385            YearMonth.of(1, 12),
1386            YearMonth.of(2008, 1),
1387            YearMonth.of(2008, 6),
1388            YearMonth.of(2008, 12)
1389        );
1390    }
1391
1392    void doTest_comparisons_YearMonth(YearMonth... localDates) {
1393        for (int i = 0; i < localDates.length; i++) {
1394            YearMonth a = localDates[i];
1395            for (int j = 0; j < localDates.length; j++) {
1396                YearMonth b = localDates[j];
1397                if (i < j) {
1398                    assertTrue(a.compareTo(b) < 0, a + " <=> " + b);
1399                    assertEquals(a.isBefore(b), true, a + " <=> " + b);
1400                    assertEquals(a.isAfter(b), false, a + " <=> " + b);
1401                    assertEquals(a.equals(b), false, a + " <=> " + b);
1402                } else if (i > j) {
1403                    assertTrue(a.compareTo(b) > 0, a + " <=> " + b);
1404                    assertEquals(a.isBefore(b), false, a + " <=> " + b);
1405                    assertEquals(a.isAfter(b), true, a + " <=> " + b);
1406                    assertEquals(a.equals(b), false, a + " <=> " + b);
1407                } else {
1408                    assertEquals(a.compareTo(b), 0, a + " <=> " + b);
1409                    assertEquals(a.isBefore(b), false, a + " <=> " + b);
1410                    assertEquals(a.isAfter(b), false, a + " <=> " + b);
1411                    assertEquals(a.equals(b), true, a + " <=> " + b);
1412                }
1413            }
1414        }
1415    }
1416
1417    @Test(expectedExceptions=NullPointerException.class)
1418    public void test_compareTo_ObjectNull() {
1419        TEST_2008_06.compareTo(null);
1420    }
1421
1422    @Test(expectedExceptions=NullPointerException.class)
1423    public void test_isBefore_ObjectNull() {
1424        TEST_2008_06.isBefore(null);
1425    }
1426
1427    @Test(expectedExceptions=NullPointerException.class)
1428    public void test_isAfter_ObjectNull() {
1429        TEST_2008_06.isAfter(null);
1430    }
1431
1432    //-----------------------------------------------------------------------
1433    // equals()
1434    //-----------------------------------------------------------------------
1435    @Test
1436    public void test_equals() {
1437        YearMonth a = YearMonth.of(2008, 6);
1438        YearMonth b = YearMonth.of(2008, 6);
1439        YearMonth c = YearMonth.of(2007, 6);
1440        YearMonth d = YearMonth.of(2008, 5);
1441
1442        assertEquals(a.equals(a), true);
1443        assertEquals(a.equals(b), true);
1444        assertEquals(a.equals(c), false);
1445        assertEquals(a.equals(d), false);
1446
1447        assertEquals(b.equals(a), true);
1448        assertEquals(b.equals(b), true);
1449        assertEquals(b.equals(c), false);
1450        assertEquals(b.equals(d), false);
1451
1452        assertEquals(c.equals(a), false);
1453        assertEquals(c.equals(b), false);
1454        assertEquals(c.equals(c), true);
1455        assertEquals(c.equals(d), false);
1456
1457        assertEquals(d.equals(a), false);
1458        assertEquals(d.equals(b), false);
1459        assertEquals(d.equals(c), false);
1460        assertEquals(d.equals(d), true);
1461    }
1462
1463    @Test
1464    public void test_equals_itself_true() {
1465        assertEquals(TEST_2008_06.equals(TEST_2008_06), true);
1466    }
1467
1468    @Test
1469    public void test_equals_string_false() {
1470        assertEquals(TEST_2008_06.equals("2007-07-15"), false);
1471    }
1472
1473    @Test
1474    public void test_equals_null_false() {
1475        assertEquals(TEST_2008_06.equals(null), false);
1476    }
1477
1478    //-----------------------------------------------------------------------
1479    // hashCode()
1480    //-----------------------------------------------------------------------
1481    @Test(dataProvider="sampleDates")
1482    public void test_hashCode(int y, int m) {
1483        YearMonth a = YearMonth.of(y, m);
1484        assertEquals(a.hashCode(), a.hashCode());
1485        YearMonth b = YearMonth.of(y, m);
1486        assertEquals(a.hashCode(), b.hashCode());
1487    }
1488
1489    @Test
1490    public void test_hashCode_unique() {
1491        Set<Integer> uniques = new HashSet<Integer>(201 * 12);
1492        for (int i = 1900; i <= 2100; i++) {
1493            for (int j = 1; j <= 12; j++) {
1494                assertTrue(uniques.add(YearMonth.of(i, j).hashCode()));
1495            }
1496        }
1497    }
1498
1499    //-----------------------------------------------------------------------
1500    // toString()
1501    //-----------------------------------------------------------------------
1502    @DataProvider(name="sampleToString")
1503    Object[][] provider_sampleToString() {
1504        return new Object[][] {
1505            {2008, 1, "2008-01"},
1506            {2008, 12, "2008-12"},
1507            {7, 5, "0007-05"},
1508            {0, 5, "0000-05"},
1509            {-1, 1, "-0001-01"},
1510        };
1511    }
1512
1513    @Test(dataProvider="sampleToString")
1514    public void test_toString(int y, int m, String expected) {
1515        YearMonth test = YearMonth.of(y, m);
1516        String str = test.toString();
1517        assertEquals(str, expected);
1518    }
1519
1520    private YearMonth ym(int year, int month) {
1521        return YearMonth.of(year, month);
1522    }
1523
1524}
1525