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.temporal; 58 59 import static org.testng.Assert.assertEquals; 60 import static org.testng.Assert.assertTrue; 61 62 import java.io.ByteArrayInputStream; 63 import java.io.ByteArrayOutputStream; 64 import java.io.ObjectInputStream; 65 import java.io.ObjectOutputStream; 66 import java.util.ArrayList; 67 import java.util.Collections; 68 import java.util.List; 69 70 import java.time.Duration; 71 import java.time.LocalDate; 72 import java.time.temporal.Chrono; 73 import java.time.temporal.ChronoLocalDate; 74 import java.time.temporal.ChronoUnit; 75 import java.time.temporal.SimplePeriod; 76 import java.time.temporal.Temporal; 77 import java.time.temporal.TemporalAccessor; 78 import java.time.format.DateTimeBuilder; 79 import java.time.temporal.TemporalAdder; 80 import java.time.temporal.TemporalAdjuster; 81 import java.time.temporal.TemporalField; 82 import java.time.temporal.TemporalSubtractor; 83 import java.time.temporal.ValueRange; 84 import java.time.temporal.TemporalUnit; 85 import java.time.temporal.ISOChrono; 86 87 import org.testng.Assert; 88 import org.testng.annotations.DataProvider; 89 import org.testng.annotations.Test; 90 91 /** 92 * Test assertions that must be true for the built-in ISO chronology. 93 */ 94 @Test 95 public class TestChronoLocalDate { 96 97 //----------------------------------------------------------------------- 98 // regular data factory for names and descriptions of ISO calendar 99 //----------------------------------------------------------------------- 100 @DataProvider(name = "calendars") 101 Chrono<?>[][] data_of_calendars() { 102 return new Chrono[][]{ 103 {ISOChrono.INSTANCE}, 104 }; 105 } 106 107 @Test(groups={"tck"}, dataProvider="calendars") 108 public void test_badWithAdjusterChrono(Chrono<?> chrono) { 109 LocalDate refDate = LocalDate.of(1900, 1, 1); 110 ChronoLocalDate<?> date = chrono.date(refDate); 111 for (Chrono<?>[] clist : data_of_calendars()) { 112 Chrono<?> chrono2 = clist[0]; 113 ChronoLocalDate<?> date2 = chrono2.date(refDate); 114 TemporalAdjuster adjuster = new FixedAdjuster(date2); 115 if (chrono != chrono2) { 116 try { 117 date.with(adjuster); 118 Assert.fail("WithAdjuster should have thrown a ClassCastException"); 119 } catch (ClassCastException cce) { 120 // Expected exception; not an error 121 } 122 } else { 123 // Same chronology, 124 ChronoLocalDate<?> result = date.with(adjuster); 125 assertEquals(result, date2, "WithAdjuster failed to replace date"); 126 } 127 } 128 } 129 130 @Test(groups={"tck"}, dataProvider="calendars") 131 public void test_badPlusAdjusterChrono(Chrono<?> chrono) { 132 LocalDate refDate = LocalDate.of(1900, 1, 1); 133 ChronoLocalDate<?> date = chrono.date(refDate); 134 for (Chrono<?>[] clist : data_of_calendars()) { 135 Chrono<?> chrono2 = clist[0]; 136 ChronoLocalDate<?> date2 = chrono2.date(refDate); 137 TemporalAdder adjuster = new FixedAdjuster(date2); 138 if (chrono != chrono2) { 139 try { 140 date.plus(adjuster); 141 Assert.fail("WithAdjuster should have thrown a ClassCastException"); 142 } catch (ClassCastException cce) { 143 // Expected exception; not an error 144 } 145 } else { 146 // Same chronology, 147 ChronoLocalDate<?> result = date.plus(adjuster); 148 assertEquals(result, date2, "WithAdjuster failed to replace date"); 149 } 150 } 151 } 152 153 @Test(groups={"tck"}, dataProvider="calendars") 154 public void test_badMinusAdjusterChrono(Chrono<?> chrono) { 155 LocalDate refDate = LocalDate.of(1900, 1, 1); 156 ChronoLocalDate<?> date = chrono.date(refDate); 157 for (Chrono<?>[] clist : data_of_calendars()) { 158 Chrono<?> chrono2 = clist[0]; 159 ChronoLocalDate<?> date2 = chrono2.date(refDate); 160 TemporalSubtractor adjuster = new FixedAdjuster(date2); 161 if (chrono != chrono2) { 162 try { 163 date.minus(adjuster); 164 Assert.fail("WithAdjuster should have thrown a ClassCastException"); 165 } catch (ClassCastException cce) { 166 // Expected exception; not an error 167 } 168 } else { 169 // Same chronology, 170 ChronoLocalDate<?> result = date.minus(adjuster); 171 assertEquals(result, date2, "WithAdjuster failed to replace date"); 172 } 173 } 174 } 175 176 @Test(groups={"tck"}, dataProvider="calendars") 177 public void test_badPlusTemporalUnitChrono(Chrono<?> chrono) { 178 LocalDate refDate = LocalDate.of(1900, 1, 1); 179 ChronoLocalDate<?> date = chrono.date(refDate); 180 for (Chrono<?>[] clist : data_of_calendars()) { 181 Chrono<?> chrono2 = clist[0]; 182 ChronoLocalDate<?> date2 = chrono2.date(refDate); 183 TemporalUnit adjuster = new FixedTemporalUnit(date2); 184 if (chrono != chrono2) { 185 try { 186 date.plus(1, adjuster); 187 Assert.fail("TemporalUnit.doPlus plus should have thrown a ClassCastException" + date.getClass() 188 + ", can not be cast to " + date2.getClass()); 189 } catch (ClassCastException cce) { 190 // Expected exception; not an error 191 } 192 } else { 193 // Same chronology, 194 ChronoLocalDate<?> result = date.plus(1, adjuster); 195 assertEquals(result, date2, "WithAdjuster failed to replace date"); 196 } 197 } 198 } 199 200 @Test(groups={"tck"}, dataProvider="calendars") 201 public void test_badMinusTemporalUnitChrono(Chrono<?> chrono) { 202 LocalDate refDate = LocalDate.of(1900, 1, 1); 203 ChronoLocalDate<?> date = chrono.date(refDate); 204 for (Chrono<?>[] clist : data_of_calendars()) { 205 Chrono<?> chrono2 = clist[0]; 206 ChronoLocalDate<?> date2 = chrono2.date(refDate); 207 TemporalUnit adjuster = new FixedTemporalUnit(date2); 208 if (chrono != chrono2) { 209 try { 210 date.minus(1, adjuster); 211 Assert.fail("TemporalUnit.doPlus minus should have thrown a ClassCastException" + date.getClass() 212 + ", can not be cast to " + date2.getClass()); 213 } catch (ClassCastException cce) { 214 // Expected exception; not an error 215 } 216 } else { 217 // Same chronology, 218 ChronoLocalDate<?> result = date.minus(1, adjuster); 219 assertEquals(result, date2, "WithAdjuster failed to replace date"); 220 } 221 } 222 } 223 224 @Test(groups={"tck"}, dataProvider="calendars") 225 public void test_badTemporalFieldChrono(Chrono<?> chrono) { 226 LocalDate refDate = LocalDate.of(1900, 1, 1); 227 ChronoLocalDate<?> date = chrono.date(refDate); 228 for (Chrono<?>[] clist : data_of_calendars()) { 229 Chrono<?> chrono2 = clist[0]; 230 ChronoLocalDate<?> date2 = chrono2.date(refDate); 231 TemporalField adjuster = new FixedTemporalField(date2); 232 if (chrono != chrono2) { 233 try { 234 date.with(adjuster, 1); 235 Assert.fail("TemporalField doWith() should have thrown a ClassCastException" + date.getClass() 236 + ", can not be cast to " + date2.getClass()); 237 } catch (ClassCastException cce) { 238 // Expected exception; not an error 239 } 240 } else { 241 // Same chronology, 242 ChronoLocalDate<?> result = date.with(adjuster, 1); 243 assertEquals(result, date2, "TemporalField doWith() failed to replace date"); 244 } 245 } 246 } 247 248 //----------------------------------------------------------------------- 249 // isBefore, isAfter, isEqual, DATE_COMPARATOR 250 //----------------------------------------------------------------------- 251 @Test(groups={"tck"}, dataProvider="calendars") 252 public void test_date_comparisons(Chrono<?> chrono) { 253 List<ChronoLocalDate<?>> dates = new ArrayList<>(); 254 255 ChronoLocalDate<?> date = chrono.date(LocalDate.of(1900, 1, 1)); 256 257 // Insert dates in order, no duplicates 258 dates.add(date.minus(1000, ChronoUnit.YEARS)); 259 dates.add(date.minus(100, ChronoUnit.YEARS)); 260 dates.add(date.minus(10, ChronoUnit.YEARS)); 261 dates.add(date.minus(1, ChronoUnit.YEARS)); 262 dates.add(date.minus(1, ChronoUnit.MONTHS)); 263 dates.add(date.minus(1, ChronoUnit.WEEKS)); 264 dates.add(date.minus(1, ChronoUnit.DAYS)); 265 dates.add(date); 266 dates.add(date.plus(1, ChronoUnit.DAYS)); 267 dates.add(date.plus(1, ChronoUnit.WEEKS)); 268 dates.add(date.plus(1, ChronoUnit.MONTHS)); 269 dates.add(date.plus(1, ChronoUnit.YEARS)); 270 dates.add(date.plus(10, ChronoUnit.YEARS)); 271 dates.add(date.plus(100, ChronoUnit.YEARS)); 272 dates.add(date.plus(1000, ChronoUnit.YEARS)); 273 274 // Check these dates against the corresponding dates for every calendar 275 for (Chrono<?>[] clist : data_of_calendars()) { 276 List<ChronoLocalDate<?>> otherDates = new ArrayList<>(); 277 Chrono<?> chrono2 = clist[0]; 278 for (ChronoLocalDate<?> d : dates) { 279 otherDates.add(chrono2.date(d)); 280 } 281 282 // Now compare the sequence of original dates with the sequence of converted dates 283 for (int i = 0; i < dates.size(); i++) { 284 ChronoLocalDate<?> a = dates.get(i); 285 for (int j = 0; j < otherDates.size(); j++) { 286 ChronoLocalDate<?> b = otherDates.get(j); 287 int cmp = ChronoLocalDate.DATE_COMPARATOR.compare(a, b); 288 if (i < j) { 289 assertTrue(cmp < 0, a + " compare " + b); 290 assertEquals(a.isBefore(b), true, a + " isBefore " + b); 291 assertEquals(a.isAfter(b), false, a + " isAfter " + b); 292 assertEquals(a.isEqual(b), false, a + " isEqual " + b); 293 } else if (i > j) { 294 assertTrue(cmp > 0, a + " compare " + b); 295 assertEquals(a.isBefore(b), false, a + " isBefore " + b); 296 assertEquals(a.isAfter(b), true, a + " isAfter " + b); 297 assertEquals(a.isEqual(b), false, a + " isEqual " + b); 298 } else { 299 assertTrue(cmp == 0, a + " compare " + b); 300 assertEquals(a.isBefore(b), false, a + " isBefore " + b); 301 assertEquals(a.isAfter(b), false, a + " isAfter " + b); 302 assertEquals(a.isEqual(b), true, a + " isEqual " + b); 303 } 304 } 305 } 306 } 307 } 308 309 public void test_date_comparator_checkGenerics_ISO() { 310 List<ChronoLocalDate<ISOChrono>> dates = new ArrayList<>(); 311 ChronoLocalDate<ISOChrono> date = LocalDate.of(1900, 1, 1); 312 313 // Insert dates in order, no duplicates 314 dates.add(date.minus(10, ChronoUnit.YEARS)); 315 dates.add(date.minus(1, ChronoUnit.YEARS)); 316 dates.add(date.minus(1, ChronoUnit.MONTHS)); 317 dates.add(date.minus(1, ChronoUnit.WEEKS)); 318 dates.add(date.minus(1, ChronoUnit.DAYS)); 319 dates.add(date); 320 dates.add(date.plus(1, ChronoUnit.DAYS)); 321 dates.add(date.plus(1, ChronoUnit.WEEKS)); 322 dates.add(date.plus(1, ChronoUnit.MONTHS)); 323 dates.add(date.plus(1, ChronoUnit.YEARS)); 324 dates.add(date.plus(10, ChronoUnit.YEARS)); 325 326 List<ChronoLocalDate<ISOChrono>> copy = new ArrayList<>(dates); 327 Collections.shuffle(copy); 328 Collections.sort(copy, ChronoLocalDate.DATE_COMPARATOR); 329 assertEquals(copy, dates); 330 assertTrue(ChronoLocalDate.DATE_COMPARATOR.compare(copy.get(0), copy.get(1)) < 0); 331 } 332 333 public void test_date_comparator_checkGenerics_LocalDate() { 334 List<LocalDate> dates = new ArrayList<>(); 335 LocalDate date = LocalDate.of(1900, 1, 1); 336 337 // Insert dates in order, no duplicates 338 dates.add(date.minus(10, ChronoUnit.YEARS)); 339 dates.add(date.minus(1, ChronoUnit.YEARS)); 340 dates.add(date.minus(1, ChronoUnit.MONTHS)); 341 dates.add(date.minus(1, ChronoUnit.WEEKS)); 342 dates.add(date.minus(1, ChronoUnit.DAYS)); 343 dates.add(date); 344 dates.add(date.plus(1, ChronoUnit.DAYS)); 345 dates.add(date.plus(1, ChronoUnit.WEEKS)); 346 dates.add(date.plus(1, ChronoUnit.MONTHS)); 347 dates.add(date.plus(1, ChronoUnit.YEARS)); 348 dates.add(date.plus(10, ChronoUnit.YEARS)); 349 350 List<LocalDate> copy = new ArrayList<>(dates); 351 Collections.shuffle(copy); 352 Collections.sort(copy, ChronoLocalDate.DATE_COMPARATOR); 353 assertEquals(copy, dates); 354 assertTrue(ChronoLocalDate.DATE_COMPARATOR.compare(copy.get(0), copy.get(1)) < 0); 355 } 356 357 //----------------------------------------------------------------------- 358 // Test Serialization of ISO via chrono API 359 //----------------------------------------------------------------------- 360 @Test( groups={"tck"}, dataProvider="calendars") 361 public <C extends Chrono<C>> void test_ChronoSerialization(C chrono) throws Exception { 362 LocalDate ref = LocalDate.of(2000, 1, 5); 363 ChronoLocalDate<C> orginal = chrono.date(ref); 364 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 365 ObjectOutputStream out = new ObjectOutputStream(baos); 366 out.writeObject(orginal); 367 out.close(); 368 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 369 ObjectInputStream in = new ObjectInputStream(bais); 370 @SuppressWarnings("unchecked") 371 ChronoLocalDate<C> ser = (ChronoLocalDate<C>) in.readObject(); 372 assertEquals(ser, orginal, "deserialized date is wrong"); 373 } 374 375 /** 376 * FixedAdjusted returns a fixed Temporal in all adjustments. 377 * Construct an adjuster with the Temporal that should be returned from adjust. 378 */ 379 static class FixedAdjuster implements TemporalAdjuster, TemporalAdder, TemporalSubtractor { 380 private Temporal datetime; 381 382 FixedAdjuster(Temporal datetime) { 383 this.datetime = datetime; 384 } 385 386 @Override 387 public Temporal adjustInto(Temporal ignore) { 388 return datetime; 389 } 390 391 @Override 392 public Temporal addTo(Temporal ignore) { 393 return datetime; 394 } 395 396 @Override 397 public Temporal subtractFrom(Temporal ignore) { 398 return datetime; 399 } 400 401 } 402 403 /** 404 * FixedTemporalUnit returns a fixed Temporal in all adjustments. 405 * Construct an FixedTemporalUnit with the Temporal that should be returned from doPlus. 406 */ 407 static class FixedTemporalUnit implements TemporalUnit { 408 private Temporal temporal; 409 410 FixedTemporalUnit(Temporal temporal) { 411 this.temporal = temporal; 412 } 413 414 @Override 415 public String getName() { 416 return "FixedTemporalUnit"; 417 } 418 419 @Override 420 public Duration getDuration() { 421 throw new UnsupportedOperationException("Not supported yet."); 422 } 423 424 @Override 425 public boolean isDurationEstimated() { 426 throw new UnsupportedOperationException("Not supported yet."); 427 } 428 429 @Override 430 public boolean isSupported(Temporal temporal) { 431 throw new UnsupportedOperationException("Not supported yet."); 432 } 433 434 @SuppressWarnings("unchecked") 435 @Override 436 public <R extends Temporal> R doPlus(R dateTime, long periodToAdd) { 437 return (R) this.temporal; 438 } 439 440 @Override 441 public <R extends Temporal> SimplePeriod between(R dateTime1, R dateTime2) { 442 throw new UnsupportedOperationException("Not supported yet."); 443 } 444 } 445 446 /** 447 * FixedTemporalField returns a fixed Temporal in all adjustments. 448 * Construct an FixedTemporalField with the Temporal that should be returned from doWith. 449 */ 450 static class FixedTemporalField implements TemporalField { 451 private Temporal temporal; 452 FixedTemporalField(Temporal temporal) { 453 this.temporal = temporal; 454 } 455 456 @Override 457 public String getName() { 458 return "FixedTemporalField"; 459 } 460 461 @Override 462 public TemporalUnit getBaseUnit() { 463 throw new UnsupportedOperationException("Not supported yet."); 464 } 465 466 @Override 467 public TemporalUnit getRangeUnit() { 468 throw new UnsupportedOperationException("Not supported yet."); 469 } 470 471 @Override 472 public ValueRange range() { 473 throw new UnsupportedOperationException("Not supported yet."); 474 } 475 476 @Override 477 public boolean doIsSupported(TemporalAccessor temporal) { 478 throw new UnsupportedOperationException("Not supported yet."); 479 } 480 481 @Override 482 public ValueRange doRange(TemporalAccessor temporal) { 483 throw new UnsupportedOperationException("Not supported yet."); 484 } 485 486 @Override 487 public long doGet(TemporalAccessor temporal) { 488 throw new UnsupportedOperationException("Not supported yet."); 489 } 490 491 @SuppressWarnings("unchecked") 492 @Override 493 public <R extends Temporal> R doWith(R temporal, long newValue) { 494 return (R) this.temporal; 495 } 496 497 @Override 498 public boolean resolve(DateTimeBuilder builder, long value) { 499 throw new UnsupportedOperationException("Not supported yet."); 500 } 501 502 } 503 } | 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.temporal; 58 59 import static org.testng.Assert.assertEquals; 60 import static org.testng.Assert.assertTrue; 61 62 import java.io.ByteArrayInputStream; 63 import java.io.ByteArrayOutputStream; 64 import java.io.ObjectInputStream; 65 import java.io.ObjectOutputStream; 66 import java.time.Duration; 67 import java.time.LocalDate; 68 import java.time.chrono.Chronology; 69 import java.time.chrono.ChronoLocalDate; 70 import java.time.chrono.IsoChronology; 71 import java.time.temporal.ChronoUnit; 72 import java.time.temporal.Temporal; 73 import java.time.temporal.TemporalAccessor; 74 import java.time.temporal.TemporalAdjuster; 75 import java.time.temporal.TemporalAmount; 76 import java.time.temporal.TemporalField; 77 import java.time.temporal.TemporalUnit; 78 import java.time.temporal.ValueRange; 79 import java.util.ArrayList; 80 import java.util.Collections; 81 import java.util.List; 82 83 import org.testng.Assert; 84 import org.testng.annotations.DataProvider; 85 import org.testng.annotations.Test; 86 87 /** 88 * Test assertions that must be true for the built-in ISO chronology. 89 */ 90 @Test 91 public class TestChronoLocalDate { 92 93 //----------------------------------------------------------------------- 94 // regular data factory for names and descriptions of ISO calendar 95 //----------------------------------------------------------------------- 96 @DataProvider(name = "calendars") 97 Chronology[][] data_of_calendars() { 98 return new Chronology[][]{ 99 {IsoChronology.INSTANCE}, 100 }; 101 } 102 103 @Test(groups={"tck"}, dataProvider="calendars") 104 public void test_badWithAdjusterChrono(Chronology chrono) { 105 LocalDate refDate = LocalDate.of(1900, 1, 1); 106 ChronoLocalDate date = chrono.date(refDate); 107 for (Chronology[] clist : data_of_calendars()) { 108 Chronology chrono2 = clist[0]; 109 ChronoLocalDate date2 = chrono2.date(refDate); 110 TemporalAdjuster adjuster = new FixedAdjuster(date2); 111 if (chrono != chrono2) { 112 try { 113 date.with(adjuster); 114 Assert.fail("WithAdjuster should have thrown a ClassCastException"); 115 } catch (ClassCastException cce) { 116 // Expected exception; not an error 117 } 118 } else { 119 // Same chronology, 120 ChronoLocalDate result = date.with(adjuster); 121 assertEquals(result, date2, "WithAdjuster failed to replace date"); 122 } 123 } 124 } 125 126 @Test(groups={"tck"}, dataProvider="calendars") 127 public void test_badPlusAdjusterChrono(Chronology chrono) { 128 LocalDate refDate = LocalDate.of(1900, 1, 1); 129 ChronoLocalDate date = chrono.date(refDate); 130 for (Chronology[] clist : data_of_calendars()) { 131 Chronology chrono2 = clist[0]; 132 ChronoLocalDate date2 = chrono2.date(refDate); 133 TemporalAmount adjuster = new FixedAdjuster(date2); 134 if (chrono != chrono2) { 135 try { 136 date.plus(adjuster); 137 Assert.fail("WithAdjuster should have thrown a ClassCastException"); 138 } catch (ClassCastException cce) { 139 // Expected exception; not an error 140 } 141 } else { 142 // Same chronology, 143 ChronoLocalDate result = date.plus(adjuster); 144 assertEquals(result, date2, "WithAdjuster failed to replace date"); 145 } 146 } 147 } 148 149 @Test(groups={"tck"}, dataProvider="calendars") 150 public void test_badMinusAdjusterChrono(Chronology chrono) { 151 LocalDate refDate = LocalDate.of(1900, 1, 1); 152 ChronoLocalDate date = chrono.date(refDate); 153 for (Chronology[] clist : data_of_calendars()) { 154 Chronology chrono2 = clist[0]; 155 ChronoLocalDate date2 = chrono2.date(refDate); 156 TemporalAmount adjuster = new FixedAdjuster(date2); 157 if (chrono != chrono2) { 158 try { 159 date.minus(adjuster); 160 Assert.fail("WithAdjuster should have thrown a ClassCastException"); 161 } catch (ClassCastException cce) { 162 // Expected exception; not an error 163 } 164 } else { 165 // Same chronology, 166 ChronoLocalDate result = date.minus(adjuster); 167 assertEquals(result, date2, "WithAdjuster failed to replace date"); 168 } 169 } 170 } 171 172 @Test(groups={"tck"}, dataProvider="calendars") 173 public void test_badPlusTemporalUnitChrono(Chronology chrono) { 174 LocalDate refDate = LocalDate.of(1900, 1, 1); 175 ChronoLocalDate date = chrono.date(refDate); 176 for (Chronology[] clist : data_of_calendars()) { 177 Chronology chrono2 = clist[0]; 178 ChronoLocalDate date2 = chrono2.date(refDate); 179 TemporalUnit adjuster = new FixedTemporalUnit(date2); 180 if (chrono != chrono2) { 181 try { 182 date.plus(1, adjuster); 183 Assert.fail("TemporalUnit.doPlus plus should have thrown a ClassCastException" + date.getClass() 184 + ", can not be cast to " + date2.getClass()); 185 } catch (ClassCastException cce) { 186 // Expected exception; not an error 187 } 188 } else { 189 // Same chronology, 190 ChronoLocalDate result = date.plus(1, adjuster); 191 assertEquals(result, date2, "WithAdjuster failed to replace date"); 192 } 193 } 194 } 195 196 @Test(groups={"tck"}, dataProvider="calendars") 197 public void test_badMinusTemporalUnitChrono(Chronology chrono) { 198 LocalDate refDate = LocalDate.of(1900, 1, 1); 199 ChronoLocalDate date = chrono.date(refDate); 200 for (Chronology[] clist : data_of_calendars()) { 201 Chronology chrono2 = clist[0]; 202 ChronoLocalDate date2 = chrono2.date(refDate); 203 TemporalUnit adjuster = new FixedTemporalUnit(date2); 204 if (chrono != chrono2) { 205 try { 206 date.minus(1, adjuster); 207 Assert.fail("TemporalUnit.doPlus minus should have thrown a ClassCastException" + date.getClass() 208 + ", can not be cast to " + date2.getClass()); 209 } catch (ClassCastException cce) { 210 // Expected exception; not an error 211 } 212 } else { 213 // Same chronology, 214 ChronoLocalDate result = date.minus(1, adjuster); 215 assertEquals(result, date2, "WithAdjuster failed to replace date"); 216 } 217 } 218 } 219 220 @Test(groups={"tck"}, dataProvider="calendars") 221 public void test_badTemporalFieldChrono(Chronology chrono) { 222 LocalDate refDate = LocalDate.of(1900, 1, 1); 223 ChronoLocalDate date = chrono.date(refDate); 224 for (Chronology[] clist : data_of_calendars()) { 225 Chronology chrono2 = clist[0]; 226 ChronoLocalDate date2 = chrono2.date(refDate); 227 TemporalField adjuster = new FixedTemporalField(date2); 228 if (chrono != chrono2) { 229 try { 230 date.with(adjuster, 1); 231 Assert.fail("TemporalField doWith() should have thrown a ClassCastException" + date.getClass() 232 + ", can not be cast to " + date2.getClass()); 233 } catch (ClassCastException cce) { 234 // Expected exception; not an error 235 } 236 } else { 237 // Same chronology, 238 ChronoLocalDate result = date.with(adjuster, 1); 239 assertEquals(result, date2, "TemporalField doWith() failed to replace date"); 240 } 241 } 242 } 243 244 //----------------------------------------------------------------------- 245 // isBefore, isAfter, isEqual, DATE_COMPARATOR 246 //----------------------------------------------------------------------- 247 @Test(groups={"tck"}, dataProvider="calendars") 248 public void test_date_comparisons(Chronology chrono) { 249 List<ChronoLocalDate> dates = new ArrayList<>(); 250 251 ChronoLocalDate date = chrono.date(LocalDate.of(1900, 1, 1)); 252 253 // Insert dates in order, no duplicates 254 dates.add(date.minus(1000, ChronoUnit.YEARS)); 255 dates.add(date.minus(100, ChronoUnit.YEARS)); 256 dates.add(date.minus(10, ChronoUnit.YEARS)); 257 dates.add(date.minus(1, ChronoUnit.YEARS)); 258 dates.add(date.minus(1, ChronoUnit.MONTHS)); 259 dates.add(date.minus(1, ChronoUnit.WEEKS)); 260 dates.add(date.minus(1, ChronoUnit.DAYS)); 261 dates.add(date); 262 dates.add(date.plus(1, ChronoUnit.DAYS)); 263 dates.add(date.plus(1, ChronoUnit.WEEKS)); 264 dates.add(date.plus(1, ChronoUnit.MONTHS)); 265 dates.add(date.plus(1, ChronoUnit.YEARS)); 266 dates.add(date.plus(10, ChronoUnit.YEARS)); 267 dates.add(date.plus(100, ChronoUnit.YEARS)); 268 dates.add(date.plus(1000, ChronoUnit.YEARS)); 269 270 // Check these dates against the corresponding dates for every calendar 271 for (Chronology[] clist : data_of_calendars()) { 272 List<ChronoLocalDate> otherDates = new ArrayList<>(); 273 Chronology chrono2 = clist[0]; 274 for (ChronoLocalDate d : dates) { 275 otherDates.add(chrono2.date(d)); 276 } 277 278 // Now compare the sequence of original dates with the sequence of converted dates 279 for (int i = 0; i < dates.size(); i++) { 280 ChronoLocalDate a = dates.get(i); 281 for (int j = 0; j < otherDates.size(); j++) { 282 ChronoLocalDate b = otherDates.get(j); 283 int cmp = ChronoLocalDate.DATE_COMPARATOR.compare(a, b); 284 if (i < j) { 285 assertTrue(cmp < 0, a + " compare " + b); 286 assertEquals(a.isBefore(b), true, a + " isBefore " + b); 287 assertEquals(a.isAfter(b), false, a + " isAfter " + b); 288 assertEquals(a.isEqual(b), false, a + " isEqual " + b); 289 } else if (i > j) { 290 assertTrue(cmp > 0, a + " compare " + b); 291 assertEquals(a.isBefore(b), false, a + " isBefore " + b); 292 assertEquals(a.isAfter(b), true, a + " isAfter " + b); 293 assertEquals(a.isEqual(b), false, a + " isEqual " + b); 294 } else { 295 assertTrue(cmp == 0, a + " compare " + b); 296 assertEquals(a.isBefore(b), false, a + " isBefore " + b); 297 assertEquals(a.isAfter(b), false, a + " isAfter " + b); 298 assertEquals(a.isEqual(b), true, a + " isEqual " + b); 299 } 300 } 301 } 302 } 303 } 304 305 public void test_date_comparator_checkGenerics_ISO() { 306 List<LocalDate> dates = new ArrayList<>(); 307 LocalDate date = LocalDate.of(1900, 1, 1); 308 309 // Insert dates in order, no duplicates 310 dates.add(date.minus(10, ChronoUnit.YEARS)); 311 dates.add(date.minus(1, ChronoUnit.YEARS)); 312 dates.add(date.minus(1, ChronoUnit.MONTHS)); 313 dates.add(date.minus(1, ChronoUnit.WEEKS)); 314 dates.add(date.minus(1, ChronoUnit.DAYS)); 315 dates.add(date); 316 dates.add(date.plus(1, ChronoUnit.DAYS)); 317 dates.add(date.plus(1, ChronoUnit.WEEKS)); 318 dates.add(date.plus(1, ChronoUnit.MONTHS)); 319 dates.add(date.plus(1, ChronoUnit.YEARS)); 320 dates.add(date.plus(10, ChronoUnit.YEARS)); 321 322 List<LocalDate> copy = new ArrayList<>(dates); 323 Collections.shuffle(copy); 324 Collections.sort(copy, ChronoLocalDate.DATE_COMPARATOR); 325 assertEquals(copy, dates); 326 assertTrue(ChronoLocalDate.DATE_COMPARATOR.compare(copy.get(0), copy.get(1)) < 0); 327 } 328 329 public void test_date_comparator_checkGenerics_LocalDate() { 330 List<LocalDate> dates = new ArrayList<>(); 331 LocalDate date = LocalDate.of(1900, 1, 1); 332 333 // Insert dates in order, no duplicates 334 dates.add(date.minus(10, ChronoUnit.YEARS)); 335 dates.add(date.minus(1, ChronoUnit.YEARS)); 336 dates.add(date.minus(1, ChronoUnit.MONTHS)); 337 dates.add(date.minus(1, ChronoUnit.WEEKS)); 338 dates.add(date.minus(1, ChronoUnit.DAYS)); 339 dates.add(date); 340 dates.add(date.plus(1, ChronoUnit.DAYS)); 341 dates.add(date.plus(1, ChronoUnit.WEEKS)); 342 dates.add(date.plus(1, ChronoUnit.MONTHS)); 343 dates.add(date.plus(1, ChronoUnit.YEARS)); 344 dates.add(date.plus(10, ChronoUnit.YEARS)); 345 346 List<LocalDate> copy = new ArrayList<>(dates); 347 Collections.shuffle(copy); 348 Collections.sort(copy, ChronoLocalDate.DATE_COMPARATOR); 349 assertEquals(copy, dates); 350 assertTrue(ChronoLocalDate.DATE_COMPARATOR.compare(copy.get(0), copy.get(1)) < 0); 351 } 352 353 //----------------------------------------------------------------------- 354 // Test Serialization of ISO via chrono API 355 //----------------------------------------------------------------------- 356 @Test( groups={"tck"}, dataProvider="calendars") 357 public void test_ChronoSerialization(Chronology chrono) throws Exception { 358 LocalDate ref = LocalDate.of(2000, 1, 5); 359 ChronoLocalDate orginal = chrono.date(ref); 360 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 361 ObjectOutputStream out = new ObjectOutputStream(baos); 362 out.writeObject(orginal); 363 out.close(); 364 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 365 ObjectInputStream in = new ObjectInputStream(bais); 366 @SuppressWarnings("unchecked") 367 ChronoLocalDate ser = (ChronoLocalDate) in.readObject(); 368 assertEquals(ser, orginal, "deserialized date is wrong"); 369 } 370 371 /** 372 * FixedAdjusted returns a fixed Temporal in all adjustments. 373 * Construct an adjuster with the Temporal that should be returned from adjust. 374 */ 375 static class FixedAdjuster implements TemporalAdjuster, TemporalAmount { 376 private Temporal datetime; 377 378 FixedAdjuster(Temporal datetime) { 379 this.datetime = datetime; 380 } 381 382 @Override 383 public Temporal adjustInto(Temporal ignore) { 384 return datetime; 385 } 386 387 @Override 388 public Temporal addTo(Temporal ignore) { 389 return datetime; 390 } 391 392 @Override 393 public Temporal subtractFrom(Temporal ignore) { 394 return datetime; 395 } 396 397 @Override 398 public long get(TemporalUnit unit) { 399 throw new UnsupportedOperationException("Not supported yet."); 400 } 401 402 @Override 403 public List<TemporalUnit> getUnits() { 404 throw new UnsupportedOperationException("Not supported yet."); 405 } 406 407 } 408 409 /** 410 * FixedTemporalUnit returns a fixed Temporal in all adjustments. 411 * Construct an FixedTemporalUnit with the Temporal that should be returned from addTo. 412 */ 413 static class FixedTemporalUnit implements TemporalUnit { 414 private Temporal temporal; 415 416 FixedTemporalUnit(Temporal temporal) { 417 this.temporal = temporal; 418 } 419 420 @Override 421 public String getName() { 422 return "FixedTemporalUnit"; 423 } 424 425 @Override 426 public Duration getDuration() { 427 throw new UnsupportedOperationException("Not supported yet."); 428 } 429 430 @Override 431 public boolean isDurationEstimated() { 432 throw new UnsupportedOperationException("Not supported yet."); 433 } 434 435 @Override 436 public boolean isSupportedBy(Temporal temporal) { 437 throw new UnsupportedOperationException("Not supported yet."); 438 } 439 440 @SuppressWarnings("unchecked") 441 @Override 442 public <R extends Temporal> R addTo(R temporal, long amount) { 443 return (R) this.temporal; 444 } 445 446 @Override 447 public long between(Temporal temporal1, Temporal temporal2) { 448 throw new UnsupportedOperationException("Not supported yet."); 449 } 450 } 451 452 /** 453 * FixedTemporalField returns a fixed Temporal in all adjustments. 454 * Construct an FixedTemporalField with the Temporal that should be returned from adjustInto. 455 */ 456 static class FixedTemporalField implements TemporalField { 457 private Temporal temporal; 458 FixedTemporalField(Temporal temporal) { 459 this.temporal = temporal; 460 } 461 462 @Override 463 public String getName() { 464 return "FixedTemporalField"; 465 } 466 467 @Override 468 public TemporalUnit getBaseUnit() { 469 throw new UnsupportedOperationException("Not supported yet."); 470 } 471 472 @Override 473 public TemporalUnit getRangeUnit() { 474 throw new UnsupportedOperationException("Not supported yet."); 475 } 476 477 @Override 478 public ValueRange range() { 479 throw new UnsupportedOperationException("Not supported yet."); 480 } 481 482 @Override 483 public boolean isSupportedBy(TemporalAccessor temporal) { 484 throw new UnsupportedOperationException("Not supported yet."); 485 } 486 487 @Override 488 public ValueRange rangeRefinedBy(TemporalAccessor temporal) { 489 throw new UnsupportedOperationException("Not supported yet."); 490 } 491 492 @Override 493 public long getFrom(TemporalAccessor temporal) { 494 throw new UnsupportedOperationException("Not supported yet."); 495 } 496 497 @SuppressWarnings("unchecked") 498 @Override 499 public <R extends Temporal> R adjustInto(R temporal, long newValue) { 500 return (R) this.temporal; 501 } 502 } 503 } |