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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
  28  *
  29  * All rights reserved.
  30  *
  31  * Redistribution and use in source and binary forms, with or without
  32  * modification, are permitted provided that the following conditions are met:
  33  *
  34  *  * Redistributions of source code must retain the above copyright notice,
  35  *    this list of conditions and the following disclaimer.
  36  *
  37  *  * Redistributions in binary form must reproduce the above copyright notice,
  38  *    this list of conditions and the following disclaimer in the documentation
  39  *    and/or other materials provided with the distribution.
  40  *
  41  *  * Neither the name of JSR-310 nor the names of its contributors
  42  *    may be used to endorse or promote products derived from this software
  43  *    without specific prior written permission.
  44  *
  45  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  46  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  47  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  48  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  49  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  50  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  51  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  52  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  53  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  54  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  55  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  56  */
  57 package tck.java.time.chrono;
  58 
  59 import static org.testng.Assert.assertEquals;
  60 import static org.testng.Assert.fail;
  61 
  62 import java.time.DateTimeException;
  63 import java.time.LocalDate;
  64 import java.time.LocalDateTime;
  65 import java.time.LocalTime;
  66 import java.time.ZoneId;
  67 import java.time.ZonedDateTime;
  68 import java.time.chrono.Chronology;
  69 import java.time.chrono.IsoChronology;
  70 import java.time.format.ResolverStyle;
  71 import java.time.temporal.ChronoField;
  72 import java.time.temporal.TemporalAccessor;
  73 import java.time.temporal.TemporalAdjusters;
  74 import java.time.temporal.TemporalField;
  75 import java.time.temporal.TemporalQueries;
  76 import java.time.temporal.TemporalQuery;
  77 import java.util.HashMap;
  78 import java.util.Map;
  79 
  80 import org.testng.annotations.DataProvider;
  81 import org.testng.annotations.Test;
  82 
  83 /**
  84  * Test.
  85  */
  86 @Test
  87 public class TCKIsoChronology {
  88     // Can only work with IsoChronology here
  89     // others may be in separate module
  90 
  91     @Test
  92     public void factory_from_TemporalAccessor_dateWithChronlogy() {
  93         assertEquals(Chronology.from(LocalDate.of(2012, 6, 30)), IsoChronology.INSTANCE);
  94     }
  95 
  96     @Test
  97     public void factory_from_TemporalAccessor_chronology() {
  98         assertEquals(Chronology.from(new TemporalAccessor() {
  99             @Override
 100             public boolean isSupported(TemporalField field) {
 101                 throw new UnsupportedOperationException();
 102             }
 103 
 104             @Override
 105             public long getLong(TemporalField field) {
 106                 throw new UnsupportedOperationException();
 107             }
 108 
 109             @SuppressWarnings("unchecked")
 110             @Override
 111             public <R> R query(TemporalQuery<R> query) {
 112                 if (query == TemporalQueries.chronology()) {
 113                     return (R) IsoChronology.INSTANCE;
 114                 }
 115                 throw new UnsupportedOperationException();
 116             }
 117         }), IsoChronology.INSTANCE);
 118     }
 119 
 120     @Test
 121     public void factory_from_TemporalAccessor_noChronology() {
 122         assertEquals(Chronology.from(new TemporalAccessor() {
 123             @Override
 124             public boolean isSupported(TemporalField field) {
 125                 throw new UnsupportedOperationException();
 126             }
 127 
 128             @Override
 129             public long getLong(TemporalField field) {
 130                 throw new UnsupportedOperationException();
 131             }
 132 
 133             @Override
 134             public <R> R query(TemporalQuery<R> query) {
 135                 if (query == TemporalQueries.chronology()) {
 136                     return null;
 137                 }
 138                 throw new UnsupportedOperationException();
 139             }
 140         }), IsoChronology.INSTANCE);
 141     }
 142 
 143     @Test(expectedExceptions=NullPointerException.class)
 144     public void factory_from_TemporalAccessor_null() {
 145         Chronology.from(null);
 146     }
 147 
 148     //-----------------------------------------------------------------------
 149     @Test
 150     public void test_date_TemporalAccessor() {
 151         assertEquals(IsoChronology.INSTANCE.date(new TemporalAccessor() {
 152             @Override
 153             public boolean isSupported(TemporalField field) {
 154                 if (field == ChronoField.EPOCH_DAY) {
 155                     return true;
 156                 }
 157                 throw new UnsupportedOperationException();
 158             }
 159 
 160             @Override
 161             public long getLong(TemporalField field) {
 162                 if (field == ChronoField.EPOCH_DAY) {
 163                     return LocalDate.of(2012, 6, 30).toEpochDay();
 164                 }
 165                 throw new UnsupportedOperationException();
 166             }
 167 
 168             @SuppressWarnings("unchecked")
 169             @Override
 170             public <R> R query(TemporalQuery<R> query) {
 171                 if (query == TemporalQueries.localDate()) {
 172                     return (R) LocalDate.of(2012, 6, 30);
 173                 }
 174                 throw new UnsupportedOperationException();
 175             }
 176         }), LocalDate.of(2012, 6, 30));
 177     }
 178 
 179     @Test(expectedExceptions=NullPointerException.class)
 180     public void test_date_TemporalAccessor_null() {
 181         IsoChronology.INSTANCE.date(null);
 182     }
 183 
 184     //-----------------------------------------------------------------------
 185     @Test
 186     public void test_localDateTime_TemporalAccessor() {
 187         assertEquals(IsoChronology.INSTANCE.localDateTime(new TemporalAccessor() {
 188             @Override
 189             public boolean isSupported(TemporalField field) {
 190                 if (field == ChronoField.EPOCH_DAY || field == ChronoField.NANO_OF_DAY) {
 191                     return true;
 192                 }
 193                 throw new UnsupportedOperationException();
 194             }
 195 
 196             @Override
 197             public long getLong(TemporalField field) {
 198                 if (field == ChronoField.EPOCH_DAY) {
 199                     return LocalDate.of(2012, 6, 30).toEpochDay();
 200                 }
 201                 if (field == ChronoField.NANO_OF_DAY) {
 202                     return LocalTime.of(12, 30, 40).toNanoOfDay();
 203                 }
 204                 throw new UnsupportedOperationException();
 205             }
 206 
 207             @SuppressWarnings("unchecked")
 208             @Override
 209             public <R> R query(TemporalQuery<R> query) {
 210                 if (query == TemporalQueries.localDate()) {
 211                     return (R) LocalDate.of(2012, 6, 30);
 212                 }
 213                 if (query == TemporalQueries.localTime()) {
 214                     return (R) LocalTime.of(12, 30, 40);
 215                 }
 216                 throw new UnsupportedOperationException();
 217             }
 218         }), LocalDateTime.of(2012, 6, 30, 12, 30, 40));
 219     }
 220 
 221     @Test(expectedExceptions=NullPointerException.class)
 222     public void test_localDateTime_TemporalAccessor_null() {
 223         IsoChronology.INSTANCE.localDateTime(null);
 224     }
 225 
 226     //-----------------------------------------------------------------------
 227     @Test
 228     public void test_zonedDateTime_TemporalAccessor() {
 229         assertEquals(IsoChronology.INSTANCE.zonedDateTime(new TemporalAccessor() {
 230             @Override
 231             public boolean isSupported(TemporalField field) {
 232                 if (field == ChronoField.EPOCH_DAY || field == ChronoField.NANO_OF_DAY ||
 233                         field == ChronoField.INSTANT_SECONDS || field == ChronoField.NANO_OF_SECOND) {
 234                     return true;
 235                 }
 236                 throw new UnsupportedOperationException();
 237             }
 238 
 239             @Override
 240             public long getLong(TemporalField field) {
 241                 if (field == ChronoField.INSTANT_SECONDS) {
 242                     return ZonedDateTime.of(2012, 6, 30, 12, 30, 40, 0, ZoneId.of("Europe/London")).toEpochSecond();
 243                 }
 244                 if (field == ChronoField.NANO_OF_SECOND) {
 245                     return 0;
 246                 }
 247                 if (field == ChronoField.EPOCH_DAY) {
 248                     return LocalDate.of(2012, 6, 30).toEpochDay();
 249                 }
 250                 if (field == ChronoField.NANO_OF_DAY) {
 251                     return LocalTime.of(12, 30, 40).toNanoOfDay();
 252                 }
 253                 throw new UnsupportedOperationException();
 254             }
 255 
 256             @SuppressWarnings("unchecked")
 257             @Override
 258             public <R> R query(TemporalQuery<R> query) {
 259                 if (query == TemporalQueries.localDate()) {
 260                     return (R) LocalDate.of(2012, 6, 30);
 261                 }
 262                 if (query == TemporalQueries.localTime()) {
 263                     return (R) LocalTime.of(12, 30, 40);
 264                 }
 265                 if (query == TemporalQueries.zoneId() || query == TemporalQueries.zone()) {
 266                     return (R) ZoneId.of("Europe/London");
 267                 }
 268                 throw new UnsupportedOperationException();
 269             }
 270         }), ZonedDateTime.of(2012, 6, 30, 12, 30, 40, 0, ZoneId.of("Europe/London")));
 271     }
 272 
 273     @Test(expectedExceptions=NullPointerException.class)
 274     public void test_zonedDateTime_TemporalAccessor_null() {
 275         IsoChronology.INSTANCE.zonedDateTime(null);
 276     }
 277 
 278     //-----------------------------------------------------------------------
 279     //-----------------------------------------------------------------------
 280     @DataProvider(name = "resolve_yearOfEra")
 281     Object[][] data_resolve_yearOfEra() {
 282         return new Object[][] {
 283                 // era only
 284                 {ResolverStyle.STRICT, -1, null, null, null, null},
 285                 {ResolverStyle.SMART, -1, null, null, null, null},
 286                 {ResolverStyle.LENIENT, -1, null, null, null, null},
 287 
 288                 {ResolverStyle.STRICT, 0, null, null, ChronoField.ERA, 0},
 289                 {ResolverStyle.SMART, 0, null, null, ChronoField.ERA, 0},
 290                 {ResolverStyle.LENIENT, 0, null, null, ChronoField.ERA, 0},
 291 
 292                 {ResolverStyle.STRICT, 1, null, null, ChronoField.ERA, 1},
 293                 {ResolverStyle.SMART, 1, null, null, ChronoField.ERA, 1},
 294                 {ResolverStyle.LENIENT, 1, null, null, ChronoField.ERA, 1},
 295 
 296                 {ResolverStyle.STRICT, 2, null, null, null, null},
 297                 {ResolverStyle.SMART, 2, null, null, null, null},
 298                 {ResolverStyle.LENIENT, 2, null, null, null, null},
 299 
 300                 // era and year-of-era
 301                 {ResolverStyle.STRICT, -1, 2012, null, null, null},
 302                 {ResolverStyle.SMART, -1, 2012, null, null, null},
 303                 {ResolverStyle.LENIENT, -1, 2012, null, null, null},
 304 
 305                 {ResolverStyle.STRICT, 0, 2012, null, ChronoField.YEAR, -2011},
 306                 {ResolverStyle.SMART, 0, 2012, null, ChronoField.YEAR, -2011},
 307                 {ResolverStyle.LENIENT, 0, 2012, null, ChronoField.YEAR, -2011},
 308 
 309                 {ResolverStyle.STRICT, 1, 2012, null, ChronoField.YEAR, 2012},
 310                 {ResolverStyle.SMART, 1, 2012, null, ChronoField.YEAR, 2012},
 311                 {ResolverStyle.LENIENT, 1, 2012, null, ChronoField.YEAR, 2012},
 312 
 313                 {ResolverStyle.STRICT, 2, 2012, null, null, null},
 314                 {ResolverStyle.SMART, 2, 2012, null, null, null},
 315                 {ResolverStyle.LENIENT, 2, 2012, null, null, null},
 316 
 317                 // year-of-era only
 318                 {ResolverStyle.STRICT, null, 2012, null, ChronoField.YEAR_OF_ERA, 2012},
 319                 {ResolverStyle.SMART, null, 2012, null, ChronoField.YEAR, 2012},
 320                 {ResolverStyle.LENIENT, null, 2012, null, ChronoField.YEAR, 2012},
 321 
 322                 {ResolverStyle.STRICT, null, Integer.MAX_VALUE, null, null, null},
 323                 {ResolverStyle.SMART, null, Integer.MAX_VALUE, null, null, null},
 324                 {ResolverStyle.LENIENT, null, Integer.MAX_VALUE, null, ChronoField.YEAR, Integer.MAX_VALUE},
 325 
 326                 // year-of-era and year
 327                 {ResolverStyle.STRICT, null, 2012, 2012, ChronoField.YEAR, 2012},
 328                 {ResolverStyle.SMART, null, 2012, 2012, ChronoField.YEAR, 2012},
 329                 {ResolverStyle.LENIENT, null, 2012, 2012, ChronoField.YEAR, 2012},
 330 
 331                 {ResolverStyle.STRICT, null, 2012, -2011, ChronoField.YEAR, -2011},
 332                 {ResolverStyle.SMART, null, 2012, -2011, ChronoField.YEAR, -2011},
 333                 {ResolverStyle.LENIENT, null, 2012, -2011, ChronoField.YEAR, -2011},
 334 
 335                 {ResolverStyle.STRICT, null, 2012, 2013, null, null},
 336                 {ResolverStyle.SMART, null, 2012, 2013, null, null},
 337                 {ResolverStyle.LENIENT, null, 2012, 2013, null, null},
 338 
 339                 {ResolverStyle.STRICT, null, 2012, -2013, null, null},
 340                 {ResolverStyle.SMART, null, 2012, -2013, null, null},
 341                 {ResolverStyle.LENIENT, null, 2012, -2013, null, null},
 342         };
 343     }
 344 
 345     @Test(dataProvider = "resolve_yearOfEra")
 346     public void test_resolve_yearOfEra(ResolverStyle style, Integer e, Integer yoe, Integer y, ChronoField field, Integer expected) {
 347         Map<TemporalField, Long> fieldValues = new HashMap<>();
 348         if (e != null) {
 349             fieldValues.put(ChronoField.ERA, (long) e);
 350         }
 351         if (yoe != null) {
 352             fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe);
 353         }
 354         if (y != null) {
 355             fieldValues.put(ChronoField.YEAR, (long) y);
 356         }
 357         if (field != null) {
 358             LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, style);
 359             assertEquals(date, null);
 360             assertEquals(fieldValues.get(field), (Long) expected.longValue());
 361             assertEquals(fieldValues.size(), 1);
 362         } else {
 363             try {
 364                 IsoChronology.INSTANCE.resolveDate(fieldValues, style);
 365                 fail("Should have failed");
 366             } catch (DateTimeException ex) {
 367                 // expected
 368             }
 369         }
 370     }
 371 
 372     //-----------------------------------------------------------------------
 373     //-----------------------------------------------------------------------
 374     @DataProvider(name = "resolve_ymd")
 375     Object[][] data_resolve_ymd() {
 376         return new Object[][] {
 377                 {2012, 1, -365, date(2010, 12, 31), false, false},
 378                 {2012, 1, -364, date(2011, 1, 1), false, false},
 379                 {2012, 1, -31, date(2011, 11, 30), false, false},
 380                 {2012, 1, -30, date(2011, 12, 1), false, false},
 381                 {2012, 1, -12, date(2011, 12, 19), false, false},
 382                 {2012, 1, 1, date(2012, 1, 1), true, true},
 383                 {2012, 1, 27, date(2012, 1, 27), true, true},
 384                 {2012, 1, 28, date(2012, 1, 28), true, true},
 385                 {2012, 1, 29, date(2012, 1, 29), true, true},
 386                 {2012, 1, 30, date(2012, 1, 30), true, true},
 387                 {2012, 1, 31, date(2012, 1, 31), true, true},
 388                 {2012, 1, 59, date(2012, 2, 28), false, false},
 389                 {2012, 1, 60, date(2012, 2, 29), false, false},
 390                 {2012, 1, 61, date(2012, 3, 1), false, false},
 391                 {2012, 1, 365, date(2012, 12, 30), false, false},
 392                 {2012, 1, 366, date(2012, 12, 31), false, false},
 393                 {2012, 1, 367, date(2013, 1, 1), false, false},
 394                 {2012, 1, 367 + 364, date(2013, 12, 31), false, false},
 395                 {2012, 1, 367 + 365, date(2014, 1, 1), false, false},
 396 
 397                 {2012, 2, 1, date(2012, 2, 1), true, true},
 398                 {2012, 2, 28, date(2012, 2, 28), true, true},
 399                 {2012, 2, 29, date(2012, 2, 29), true, true},
 400                 {2012, 2, 30, date(2012, 3, 1), date(2012, 2, 29), false},
 401                 {2012, 2, 31, date(2012, 3, 2), date(2012, 2, 29), false},
 402                 {2012, 2, 32, date(2012, 3, 3), false, false},
 403 
 404                 {2012, -12, 1, date(2010, 12, 1), false, false},
 405                 {2012, -11, 1, date(2011, 1, 1), false, false},
 406                 {2012, -1, 1, date(2011, 11, 1), false, false},
 407                 {2012, 0, 1, date(2011, 12, 1), false, false},
 408                 {2012, 1, 1, date(2012, 1, 1), true, true},
 409                 {2012, 12, 1, date(2012, 12, 1), true, true},
 410                 {2012, 13, 1, date(2013, 1, 1), false, false},
 411                 {2012, 24, 1, date(2013, 12, 1), false, false},
 412                 {2012, 25, 1, date(2014, 1, 1), false, false},
 413 
 414                 {2012, 6, -31, date(2012, 4, 30), false, false},
 415                 {2012, 6, -30, date(2012, 5, 1), false, false},
 416                 {2012, 6, -1, date(2012, 5, 30), false, false},
 417                 {2012, 6, 0, date(2012, 5, 31), false, false},
 418                 {2012, 6, 1, date(2012, 6, 1), true, true},
 419                 {2012, 6, 30, date(2012, 6, 30), true, true},
 420                 {2012, 6, 31, date(2012, 7, 1), date(2012, 6, 30), false},
 421                 {2012, 6, 61, date(2012, 7, 31), false, false},
 422                 {2012, 6, 62, date(2012, 8, 1), false, false},
 423 
 424                 {2011, 2, 1, date(2011, 2, 1), true, true},
 425                 {2011, 2, 28, date(2011, 2, 28), true, true},
 426                 {2011, 2, 29, date(2011, 3, 1), date(2011, 2, 28), false},
 427                 {2011, 2, 30, date(2011, 3, 2), date(2011, 2, 28), false},
 428                 {2011, 2, 31, date(2011, 3, 3), date(2011, 2, 28), false},
 429                 {2011, 2, 32, date(2011, 3, 4), false, false},
 430         };
 431     }
 432 
 433     @Test(dataProvider = "resolve_ymd")
 434     public void test_resolve_ymd_lenient(int y, int m, int d, LocalDate expected, Object smart, boolean strict) {
 435         Map<TemporalField, Long> fieldValues = new HashMap<>();
 436         fieldValues.put(ChronoField.YEAR, (long) y);
 437         fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m);
 438         fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d);
 439         LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT);
 440         assertEquals(date, expected);
 441         assertEquals(fieldValues.size(), 0);
 442     }
 443 
 444     @Test(dataProvider = "resolve_ymd")
 445     public void test_resolve_ymd_smart(int y, int m, int d, LocalDate expected, Object smart, boolean strict) {
 446         Map<TemporalField, Long> fieldValues = new HashMap<>();
 447         fieldValues.put(ChronoField.YEAR, (long) y);
 448         fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m);
 449         fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d);
 450         if (Boolean.TRUE.equals(smart)) {
 451             LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART);
 452             assertEquals(date, expected);
 453             assertEquals(fieldValues.size(), 0);
 454         } else if (smart instanceof LocalDate) {
 455             LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART);
 456             assertEquals(date, smart);
 457         } else {
 458             try {
 459                 IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART);
 460                 fail("Should have failed");
 461             } catch (DateTimeException ex) {
 462                 // expected
 463             }
 464         }
 465     }
 466 
 467     @Test(dataProvider = "resolve_ymd")
 468     public void test_resolve_ymd_strict(int y, int m, int d, LocalDate expected, Object smart, boolean strict) {
 469         Map<TemporalField, Long> fieldValues = new HashMap<>();
 470         fieldValues.put(ChronoField.YEAR, (long) y);
 471         fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m);
 472         fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d);
 473         if (strict) {
 474             LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT);
 475             assertEquals(date, expected);
 476             assertEquals(fieldValues.size(), 0);
 477         } else {
 478             try {
 479                 IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT);
 480                 fail("Should have failed");
 481             } catch (DateTimeException ex) {
 482                 // expected
 483             }
 484         }
 485     }
 486 
 487     //-----------------------------------------------------------------------
 488     //-----------------------------------------------------------------------
 489     @DataProvider(name = "resolve_yd")
 490     Object[][] data_resolve_yd() {
 491         return new Object[][] {
 492                 {2012, -365, date(2010, 12, 31), false, false},
 493                 {2012, -364, date(2011, 1, 1), false, false},
 494                 {2012, -31, date(2011, 11, 30), false, false},
 495                 {2012, -30, date(2011, 12, 1), false, false},
 496                 {2012, -12, date(2011, 12, 19), false, false},
 497                 {2012, -1, date(2011, 12, 30), false, false},
 498                 {2012, 0, date(2011, 12, 31), false, false},
 499                 {2012, 1, date(2012, 1, 1), true, true},
 500                 {2012, 2, date(2012, 1, 2), true, true},
 501                 {2012, 31, date(2012, 1, 31), true, true},
 502                 {2012, 32, date(2012, 2, 1), true, true},
 503                 {2012, 59, date(2012, 2, 28), true, true},
 504                 {2012, 60, date(2012, 2, 29), true, true},
 505                 {2012, 61, date(2012, 3, 1), true, true},
 506                 {2012, 365, date(2012, 12, 30), true, true},
 507                 {2012, 366, date(2012, 12, 31), true, true},
 508                 {2012, 367, date(2013, 1, 1), false, false},
 509                 {2012, 367 + 364, date(2013, 12, 31), false, false},
 510                 {2012, 367 + 365, date(2014, 1, 1), false, false},
 511 
 512                 {2011, 59, date(2011, 2, 28), true, true},
 513                 {2011, 60, date(2011, 3, 1), true, true},
 514         };
 515     }
 516 
 517     @Test(dataProvider = "resolve_yd")
 518     public void test_resolve_yd_lenient(int y, int d, LocalDate expected, boolean smart, boolean strict) {
 519         Map<TemporalField, Long> fieldValues = new HashMap<>();
 520         fieldValues.put(ChronoField.YEAR, (long) y);
 521         fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d);
 522         LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT);
 523         assertEquals(date, expected);
 524         assertEquals(fieldValues.size(), 0);
 525     }
 526 
 527     @Test(dataProvider = "resolve_yd")
 528     public void test_resolve_yd_smart(int y, int d, LocalDate expected, boolean smart, boolean strict) {
 529         Map<TemporalField, Long> fieldValues = new HashMap<>();
 530         fieldValues.put(ChronoField.YEAR, (long) y);
 531         fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d);
 532         if (smart) {
 533             LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART);
 534             assertEquals(date, expected);
 535             assertEquals(fieldValues.size(), 0);
 536         } else {
 537             try {
 538                 IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART);
 539                 fail("Should have failed");
 540             } catch (DateTimeException ex) {
 541                 // expected
 542             }
 543         }
 544     }
 545 
 546     @Test(dataProvider = "resolve_yd")
 547     public void test_resolve_yd_strict(int y, int d, LocalDate expected, boolean smart, boolean strict) {
 548         Map<TemporalField, Long> fieldValues = new HashMap<>();
 549         fieldValues.put(ChronoField.YEAR, (long) y);
 550         fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d);
 551         if (strict) {
 552             LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT);
 553             assertEquals(date, expected);
 554             assertEquals(fieldValues.size(), 0);
 555         } else {
 556             try {
 557                 IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT);
 558                 fail("Should have failed");
 559             } catch (DateTimeException ex) {
 560                 // expected
 561             }
 562         }
 563     }
 564 
 565     //-----------------------------------------------------------------------
 566     //-----------------------------------------------------------------------
 567     @DataProvider(name = "resolve_ymaa")
 568     Object[][] data_resolve_ymaa() {
 569         return new Object[][] {
 570                 {2012, 1, 1, -365, date(2010, 12, 31), false, false},
 571                 {2012, 1, 1, -364, date(2011, 1, 1), false, false},
 572                 {2012, 1, 1, -31, date(2011, 11, 30), false, false},
 573                 {2012, 1, 1, -30, date(2011, 12, 1), false, false},
 574                 {2012, 1, 1, -12, date(2011, 12, 19), false, false},
 575                 {2012, 1, 1, 1, date(2012, 1, 1), true, true},
 576                 {2012, 1, 1, 59, date(2012, 2, 28), false, false},
 577                 {2012, 1, 1, 60, date(2012, 2, 29), false, false},
 578                 {2012, 1, 1, 61, date(2012, 3, 1), false, false},
 579                 {2012, 1, 1, 365, date(2012, 12, 30), false, false},
 580                 {2012, 1, 1, 366, date(2012, 12, 31), false, false},
 581                 {2012, 1, 1, 367, date(2013, 1, 1), false, false},
 582                 {2012, 1, 1, 367 + 364, date(2013, 12, 31), false, false},
 583                 {2012, 1, 1, 367 + 365, date(2014, 1, 1), false, false},
 584 
 585                 {2012, 2, 0, 1, date(2012, 1, 25), false, false},
 586                 {2012, 2, 0, 7, date(2012, 1, 31), false, false},
 587                 {2012, 2, 1, 1, date(2012, 2, 1), true, true},
 588                 {2012, 2, 1, 7, date(2012, 2, 7), true, true},
 589                 {2012, 2, 2, 1, date(2012, 2, 8), true, true},
 590                 {2012, 2, 2, 7, date(2012, 2, 14), true, true},
 591                 {2012, 2, 3, 1, date(2012, 2, 15), true, true},
 592                 {2012, 2, 3, 7, date(2012, 2, 21), true, true},
 593                 {2012, 2, 4, 1, date(2012, 2, 22), true, true},
 594                 {2012, 2, 4, 7, date(2012, 2, 28), true, true},
 595                 {2012, 2, 5, 1, date(2012, 2, 29), true, true},
 596                 {2012, 2, 5, 2, date(2012, 3, 1), true, false},
 597                 {2012, 2, 5, 7, date(2012, 3, 6), true, false},
 598                 {2012, 2, 6, 1, date(2012, 3, 7), false, false},
 599                 {2012, 2, 6, 7, date(2012, 3, 13), false, false},
 600 
 601                 {2012, 12, 1, 1, date(2012, 12, 1), true, true},
 602                 {2012, 12, 5, 1, date(2012, 12, 29), true, true},
 603                 {2012, 12, 5, 2, date(2012, 12, 30), true, true},
 604                 {2012, 12, 5, 3, date(2012, 12, 31), true, true},
 605                 {2012, 12, 5, 4, date(2013, 1, 1), true, false},
 606                 {2012, 12, 5, 7, date(2013, 1, 4), true, false},
 607 
 608                 {2012, -12, 1, 1, date(2010, 12, 1), false, false},
 609                 {2012, -11, 1, 1, date(2011, 1, 1), false, false},
 610                 {2012, -1, 1, 1, date(2011, 11, 1), false, false},
 611                 {2012, 0, 1, 1, date(2011, 12, 1), false, false},
 612                 {2012, 1, 1, 1, date(2012, 1, 1), true, true},
 613                 {2012, 12, 1, 1, date(2012, 12, 1), true, true},
 614                 {2012, 13, 1, 1, date(2013, 1, 1), false, false},
 615                 {2012, 24, 1, 1, date(2013, 12, 1), false, false},
 616                 {2012, 25, 1, 1, date(2014, 1, 1), false, false},
 617 
 618                 {2011, 2, 1, 1, date(2011, 2, 1), true, true},
 619                 {2011, 2, 4, 7, date(2011, 2, 28), true, true},
 620                 {2011, 2, 5, 1, date(2011, 3, 1), true, false},
 621         };
 622     }
 623 
 624     @Test(dataProvider = "resolve_ymaa")
 625     public void test_resolve_ymaa_lenient(int y, int m, int w, int d, LocalDate expected, boolean smart, boolean strict) {
 626         Map<TemporalField, Long> fieldValues = new HashMap<>();
 627         fieldValues.put(ChronoField.YEAR, (long) y);
 628         fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m);
 629         fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w);
 630         fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d);
 631         LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT);
 632         assertEquals(date, expected);
 633         assertEquals(fieldValues.size(), 0);
 634     }
 635 
 636     @Test(dataProvider = "resolve_ymaa")
 637     public void test_resolve_ymaa_smart(int y, int m, int w, int d, LocalDate expected, boolean smart, boolean strict) {
 638         Map<TemporalField, Long> fieldValues = new HashMap<>();
 639         fieldValues.put(ChronoField.YEAR, (long) y);
 640         fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m);
 641         fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w);
 642         fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d);
 643         if (smart) {
 644             LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART);
 645             assertEquals(date, expected);
 646             assertEquals(fieldValues.size(), 0);
 647         } else {
 648             try {
 649                 IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART);
 650                 fail("Should have failed");
 651             } catch (DateTimeException ex) {
 652                 // expected
 653             }
 654         }
 655     }
 656 
 657     @Test(dataProvider = "resolve_ymaa")
 658     public void test_resolve_ymaa_strict(int y, int m, int w, int d, LocalDate expected, boolean smart, boolean strict) {
 659         Map<TemporalField, Long> fieldValues = new HashMap<>();
 660         fieldValues.put(ChronoField.YEAR, (long) y);
 661         fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m);
 662         fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w);
 663         fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d);
 664         if (strict) {
 665             LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT);
 666             assertEquals(date, expected);
 667             assertEquals(fieldValues.size(), 0);
 668         } else {
 669             try {
 670                 IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT);
 671                 fail("Should have failed");
 672             } catch (DateTimeException ex) {
 673                 // expected
 674             }
 675         }
 676     }
 677 
 678     //-----------------------------------------------------------------------
 679     private static LocalDate date(int y, int m, int d) {
 680         return LocalDate.of(y, m, d);
 681     }
 682 
 683 }