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