1 /* 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * This file is available under and governed by the GNU General Public 26 * License version 2 only, as published by the Free Software Foundation. 27 * However, the following notice accompanied the original version of this 28 * file: 29 * 30 * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos 31 * 32 * All rights reserved. 33 * 34 * Redistribution and use in source and binary forms, with or without 35 * modification, are permitted provided that the following conditions are met: 36 * 37 * * Redistributions of source code must retain the above copyright notice, 38 * this list of conditions and the following disclaimer. 39 * 40 * * Redistributions in binary form must reproduce the above copyright notice, 41 * this list of conditions and the following disclaimer in the documentation 42 * and/or other materials provided with the distribution. 43 * 44 * * Neither the name of JSR-310 nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 49 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 50 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 51 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 52 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 53 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 54 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 55 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 56 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 57 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 58 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59 */ 60 package test.java.time.format; 61 62 import static java.time.temporal.ChronoField.DAY_OF_MONTH; 63 import static java.time.temporal.ChronoField.DAY_OF_WEEK; 64 import static java.time.temporal.ChronoField.DAY_OF_YEAR; 65 import static java.time.temporal.ChronoField.MONTH_OF_YEAR; 66 import static org.testng.Assert.assertEquals; 67 import static org.testng.Assert.assertTrue; 68 import static org.testng.Assert.fail; 69 70 import java.text.ParsePosition; 71 import java.time.format.DateTimeFormatter; 72 import java.time.format.SignStyle; 73 import java.time.temporal.TemporalAccessor; 74 import java.time.temporal.TemporalField; 75 import java.time.temporal.TemporalQueries; 76 77 import org.testng.annotations.DataProvider; 78 import org.testng.annotations.Test; 79 80 /** 81 * Test NumberPrinterParser. 82 */ 83 @Test 84 public class TestNumberParser extends AbstractTestPrinterParser { 85 86 //----------------------------------------------------------------------- 87 @DataProvider(name="error") data_error()88 Object[][] data_error() { 89 return new Object[][] { 90 {DAY_OF_MONTH, 1, 2, SignStyle.NEVER, "12", -1, IndexOutOfBoundsException.class}, 91 {DAY_OF_MONTH, 1, 2, SignStyle.NEVER, "12", 3, IndexOutOfBoundsException.class}, 92 }; 93 } 94 95 @Test(dataProvider="error") test_parse_error(TemporalField field, int min, int max, SignStyle style, String text, int pos, Class<?> expected)96 public void test_parse_error(TemporalField field, int min, int max, SignStyle style, String text, int pos, Class<?> expected) { 97 try { 98 getFormatter(field, min, max, style).parseUnresolved(text, new ParsePosition(pos)); 99 fail(); 100 } catch (RuntimeException ex) { 101 assertTrue(expected.isInstance(ex)); 102 } 103 } 104 105 //----------------------------------------------------------------------- 106 @DataProvider(name="parseData") provider_parseData()107 Object[][] provider_parseData() { 108 return new Object[][] { 109 // normal 110 {1, 2, SignStyle.NEVER, 0, "12", 0, 2, 12L}, // normal 111 {1, 2, SignStyle.NEVER, 0, "Xxx12Xxx", 3, 5, 12L}, // parse in middle 112 {1, 2, SignStyle.NEVER, 0, "99912999", 3, 5, 12L}, // parse in middle 113 {2, 4, SignStyle.NEVER, 0, "12345", 0, 4, 1234L}, // stops at max width 114 {2, 4, SignStyle.NEVER, 0, "12-45", 0, 2, 12L}, // stops at dash 115 {2, 4, SignStyle.NEVER, 0, "123-5", 0, 3, 123L}, // stops at dash 116 {1, 10, SignStyle.NORMAL, 0, "2147483647", 0, 10, Integer.MAX_VALUE}, 117 {1, 10, SignStyle.NORMAL, 0, "-2147483648", 0, 11, Integer.MIN_VALUE}, 118 {1, 10, SignStyle.NORMAL, 0, "2147483648", 0, 10, 2147483648L}, 119 {1, 10, SignStyle.NORMAL, 0, "-2147483649", 0, 11, -2147483649L}, 120 {1, 10, SignStyle.NORMAL, 0, "987659876598765", 0, 10, 9876598765L}, 121 {1, 19, SignStyle.NORMAL, 0, "999999999999999999", 0, 18, 999999999999999999L}, 122 {1, 19, SignStyle.NORMAL, 0, "-999999999999999999", 0, 19, -999999999999999999L}, 123 {1, 19, SignStyle.NORMAL, 0, "1000000000000000000", 0, 19, 1000000000000000000L}, 124 {1, 19, SignStyle.NORMAL, 0, "-1000000000000000000", 0, 20, -1000000000000000000L}, 125 {1, 19, SignStyle.NORMAL, 0, "000000000000000000", 0, 18, 0L}, 126 {1, 19, SignStyle.NORMAL, 0, "0000000000000000000", 0, 19, 0L}, 127 {1, 19, SignStyle.NORMAL, 0, "9223372036854775807", 0, 19, Long.MAX_VALUE}, 128 {1, 19, SignStyle.NORMAL, 0, "-9223372036854775808", 0, 20, Long.MIN_VALUE}, 129 {1, 19, SignStyle.NORMAL, 0, "9223372036854775808", 0, 18, 922337203685477580L}, // last digit not parsed 130 {1, 19, SignStyle.NORMAL, 0, "-9223372036854775809", 0, 19, -922337203685477580L}, // last digit not parsed 131 // no match 132 {1, 2, SignStyle.NEVER, 1, "A1", 0, 0, 0}, 133 {1, 2, SignStyle.NEVER, 1, " 1", 0, 0, 0}, 134 {1, 2, SignStyle.NEVER, 1, " 1", 1, 1, 0}, 135 {2, 2, SignStyle.NEVER, 1, "1", 0, 0, 0}, 136 {2, 2, SignStyle.NEVER, 1, "Xxx1", 0, 0, 0}, 137 {2, 2, SignStyle.NEVER, 1, "1", 1, 1, 0}, 138 {2, 2, SignStyle.NEVER, 1, "Xxx1", 4, 4, 0}, 139 {2, 2, SignStyle.NEVER, 1, "1-2", 0, 0, 0}, 140 {1, 19, SignStyle.NORMAL, 0, "-000000000000000000", 0, 0, 0}, 141 {1, 19, SignStyle.NORMAL, 0, "-0000000000000000000", 0, 0, 0}, 142 // parse reserving space 1 (adjacent-parsing) 143 {1, 1, SignStyle.NEVER, 1, "12", 0, 1, 1L}, 144 {1, 19, SignStyle.NEVER, 1, "12", 0, 1, 1L}, 145 {1, 19, SignStyle.NEVER, 1, "12345", 0, 4, 1234L}, 146 {1, 19, SignStyle.NEVER, 1, "12345678901", 0, 10, 1234567890L}, 147 {1, 19, SignStyle.NEVER, 1, "123456789012345678901234567890", 0, 19, 1234567890123456789L}, 148 {1, 19, SignStyle.NEVER, 1, "1", 0, 1, 1L}, // error from next field 149 {2, 2, SignStyle.NEVER, 1, "12", 0, 2, 12L}, // error from next field 150 {2, 19, SignStyle.NEVER, 1, "1", 0, 0, 0}, 151 // parse reserving space 2 (adjacent-parsing) 152 {1, 1, SignStyle.NEVER, 2, "123", 0, 1, 1L}, 153 {1, 19, SignStyle.NEVER, 2, "123", 0, 1, 1L}, 154 {1, 19, SignStyle.NEVER, 2, "12345", 0, 3, 123L}, 155 {1, 19, SignStyle.NEVER, 2, "12345678901", 0, 9, 123456789L}, 156 {1, 19, SignStyle.NEVER, 2, "123456789012345678901234567890", 0, 19, 1234567890123456789L}, 157 {1, 19, SignStyle.NEVER, 2, "1", 0, 1, 1L}, // error from next field 158 {1, 19, SignStyle.NEVER, 2, "12", 0, 1, 1L}, // error from next field 159 {2, 2, SignStyle.NEVER, 2, "12", 0, 2, 12L}, // error from next field 160 {2, 19, SignStyle.NEVER, 2, "1", 0, 0, 0}, 161 {2, 19, SignStyle.NEVER, 2, "1AAAAABBBBBCCCCC", 0, 0, 0}, 162 }; 163 } 164 165 //----------------------------------------------------------------------- 166 @Test(dataProvider="parseData") test_parse_fresh(int minWidth, int maxWidth, SignStyle signStyle, int subsequentWidth, String text, int pos, int expectedPos, long expectedValue)167 public void test_parse_fresh(int minWidth, int maxWidth, SignStyle signStyle, int subsequentWidth, String text, int pos, int expectedPos, long expectedValue) { 168 ParsePosition ppos = new ParsePosition(pos); 169 DateTimeFormatter dtf = getFormatter(DAY_OF_MONTH, minWidth, maxWidth, signStyle); 170 if (subsequentWidth > 0) { 171 // hacky, to reserve space 172 dtf = builder.appendValue(DAY_OF_YEAR, subsequentWidth).toFormatter(locale).withDecimalStyle(decimalStyle); 173 } 174 TemporalAccessor parsed = dtf.parseUnresolved(text, ppos); 175 if (ppos.getErrorIndex() != -1) { 176 assertEquals(ppos.getErrorIndex(), expectedPos); 177 } else { 178 assertTrue(subsequentWidth >= 0); 179 assertEquals(ppos.getIndex(), expectedPos + subsequentWidth); 180 assertEquals(parsed.getLong(DAY_OF_MONTH), expectedValue); 181 assertEquals(parsed.query(TemporalQueries.chronology()), null); 182 assertEquals(parsed.query(TemporalQueries.zoneId()), null); 183 } 184 } 185 186 @Test(dataProvider="parseData") test_parse_textField(int minWidth, int maxWidth, SignStyle signStyle, int subsequentWidth, String text, int pos, int expectedPos, long expectedValue)187 public void test_parse_textField(int minWidth, int maxWidth, SignStyle signStyle, int subsequentWidth, String text, int pos, int expectedPos, long expectedValue) { 188 ParsePosition ppos = new ParsePosition(pos); 189 DateTimeFormatter dtf = getFormatter(DAY_OF_WEEK, minWidth, maxWidth, signStyle); 190 if (subsequentWidth > 0) { 191 // hacky, to reserve space 192 dtf = builder.appendValue(DAY_OF_YEAR, subsequentWidth).toFormatter(locale).withDecimalStyle(decimalStyle); 193 } 194 TemporalAccessor parsed = dtf.parseUnresolved(text, ppos); 195 if (ppos.getErrorIndex() != -1) { 196 assertEquals(ppos.getErrorIndex(), expectedPos); 197 } else { 198 assertTrue(subsequentWidth >= 0); 199 assertEquals(ppos.getIndex(), expectedPos + subsequentWidth); 200 assertEquals(parsed.getLong(DAY_OF_WEEK), expectedValue); 201 assertEquals(parsed.query(TemporalQueries.chronology()), null); 202 assertEquals(parsed.query(TemporalQueries.zoneId()), null); 203 } 204 } 205 206 //----------------------------------------------------------------------- 207 @DataProvider(name="parseSignsStrict") provider_parseSignsStrict()208 Object[][] provider_parseSignsStrict() { 209 return new Object[][] { 210 // basics 211 {"0", 1, 2, SignStyle.NEVER, 1, 0}, 212 {"1", 1, 2, SignStyle.NEVER, 1, 1}, 213 {"2", 1, 2, SignStyle.NEVER, 1, 2}, 214 {"3", 1, 2, SignStyle.NEVER, 1, 3}, 215 {"4", 1, 2, SignStyle.NEVER, 1, 4}, 216 {"5", 1, 2, SignStyle.NEVER, 1, 5}, 217 {"6", 1, 2, SignStyle.NEVER, 1, 6}, 218 {"7", 1, 2, SignStyle.NEVER, 1, 7}, 219 {"8", 1, 2, SignStyle.NEVER, 1, 8}, 220 {"9", 1, 2, SignStyle.NEVER, 1, 9}, 221 {"10", 1, 2, SignStyle.NEVER, 2, 10}, 222 {"100", 1, 2, SignStyle.NEVER, 2, 10}, 223 {"100", 1, 3, SignStyle.NEVER, 3, 100}, 224 225 // never 226 {"0", 1, 2, SignStyle.NEVER, 1, 0}, 227 {"5", 1, 2, SignStyle.NEVER, 1, 5}, 228 {"50", 1, 2, SignStyle.NEVER, 2, 50}, 229 {"500", 1, 2, SignStyle.NEVER, 2, 50}, 230 {"-0", 1, 2, SignStyle.NEVER, 0, null}, 231 {"-5", 1, 2, SignStyle.NEVER, 0, null}, 232 {"-50", 1, 2, SignStyle.NEVER, 0, null}, 233 {"-500", 1, 2, SignStyle.NEVER, 0, null}, 234 {"-AAA", 1, 2, SignStyle.NEVER, 0, null}, 235 {"+0", 1, 2, SignStyle.NEVER, 0, null}, 236 {"+5", 1, 2, SignStyle.NEVER, 0, null}, 237 {"+50", 1, 2, SignStyle.NEVER, 0, null}, 238 {"+500", 1, 2, SignStyle.NEVER, 0, null}, 239 {"+AAA", 1, 2, SignStyle.NEVER, 0, null}, 240 241 // not negative 242 {"0", 1, 2, SignStyle.NOT_NEGATIVE, 1, 0}, 243 {"5", 1, 2, SignStyle.NOT_NEGATIVE, 1, 5}, 244 {"50", 1, 2, SignStyle.NOT_NEGATIVE, 2, 50}, 245 {"500", 1, 2, SignStyle.NOT_NEGATIVE, 2, 50}, 246 {"-0", 1, 2, SignStyle.NOT_NEGATIVE, 0, null}, 247 {"-5", 1, 2, SignStyle.NOT_NEGATIVE, 0, null}, 248 {"-50", 1, 2, SignStyle.NOT_NEGATIVE, 0, null}, 249 {"-500", 1, 2, SignStyle.NOT_NEGATIVE, 0, null}, 250 {"-AAA", 1, 2, SignStyle.NOT_NEGATIVE, 0, null}, 251 {"+0", 1, 2, SignStyle.NOT_NEGATIVE, 0, null}, 252 {"+5", 1, 2, SignStyle.NOT_NEGATIVE, 0, null}, 253 {"+50", 1, 2, SignStyle.NOT_NEGATIVE, 0, null}, 254 {"+500", 1, 2, SignStyle.NOT_NEGATIVE, 0, null}, 255 {"+AAA", 1, 2, SignStyle.NOT_NEGATIVE, 0, null}, 256 257 // normal 258 {"0", 1, 2, SignStyle.NORMAL, 1, 0}, 259 {"5", 1, 2, SignStyle.NORMAL, 1, 5}, 260 {"50", 1, 2, SignStyle.NORMAL, 2, 50}, 261 {"500", 1, 2, SignStyle.NORMAL, 2, 50}, 262 {"-0", 1, 2, SignStyle.NORMAL, 0, null}, 263 {"-5", 1, 2, SignStyle.NORMAL, 2, -5}, 264 {"-50", 1, 2, SignStyle.NORMAL, 3, -50}, 265 {"-500", 1, 2, SignStyle.NORMAL, 3, -50}, 266 {"-AAA", 1, 2, SignStyle.NORMAL, 1, null}, 267 {"+0", 1, 2, SignStyle.NORMAL, 0, null}, 268 {"+5", 1, 2, SignStyle.NORMAL, 0, null}, 269 {"+50", 1, 2, SignStyle.NORMAL, 0, null}, 270 {"+500", 1, 2, SignStyle.NORMAL, 0, null}, 271 {"+AAA", 1, 2, SignStyle.NORMAL, 0, null}, 272 273 // always 274 {"0", 1, 2, SignStyle.ALWAYS, 0, null}, 275 {"5", 1, 2, SignStyle.ALWAYS, 0, null}, 276 {"50", 1, 2, SignStyle.ALWAYS, 0, null}, 277 {"500", 1, 2, SignStyle.ALWAYS, 0, null}, 278 {"-0", 1, 2, SignStyle.ALWAYS, 0, null}, 279 {"-5", 1, 2, SignStyle.ALWAYS, 2, -5}, 280 {"-50", 1, 2, SignStyle.ALWAYS, 3, -50}, 281 {"-500", 1, 2, SignStyle.ALWAYS, 3, -50}, 282 {"-AAA", 1, 2, SignStyle.ALWAYS, 1, null}, 283 {"+0", 1, 2, SignStyle.ALWAYS, 2, 0}, 284 {"+5", 1, 2, SignStyle.ALWAYS, 2, 5}, 285 {"+50", 1, 2, SignStyle.ALWAYS, 3, 50}, 286 {"+500", 1, 2, SignStyle.ALWAYS, 3, 50}, 287 {"+AAA", 1, 2, SignStyle.ALWAYS, 1, null}, 288 289 // exceeds pad 290 {"0", 1, 2, SignStyle.EXCEEDS_PAD, 1, 0}, 291 {"5", 1, 2, SignStyle.EXCEEDS_PAD, 1, 5}, 292 {"50", 1, 2, SignStyle.EXCEEDS_PAD, 0, null}, 293 {"500", 1, 2, SignStyle.EXCEEDS_PAD, 0, null}, 294 {"-0", 1, 2, SignStyle.EXCEEDS_PAD, 0, null}, 295 {"-5", 1, 2, SignStyle.EXCEEDS_PAD, 2, -5}, 296 {"-50", 1, 2, SignStyle.EXCEEDS_PAD, 3, -50}, 297 {"-500", 1, 2, SignStyle.EXCEEDS_PAD, 3, -50}, 298 {"-AAA", 1, 2, SignStyle.EXCEEDS_PAD, 1, null}, 299 {"+0", 1, 2, SignStyle.EXCEEDS_PAD, 0, null}, 300 {"+5", 1, 2, SignStyle.EXCEEDS_PAD, 0, null}, 301 {"+50", 1, 2, SignStyle.EXCEEDS_PAD, 3, 50}, 302 {"+500", 1, 2, SignStyle.EXCEEDS_PAD, 3, 50}, 303 {"+AAA", 1, 2, SignStyle.EXCEEDS_PAD, 1, null}, 304 }; 305 } 306 307 @Test(dataProvider="parseSignsStrict") test_parseSignsStrict(String input, int min, int max, SignStyle style, int parseLen, Integer parseVal)308 public void test_parseSignsStrict(String input, int min, int max, SignStyle style, int parseLen, Integer parseVal) throws Exception { 309 ParsePosition pos = new ParsePosition(0); 310 TemporalAccessor parsed = getFormatter(DAY_OF_MONTH, min, max, style).parseUnresolved(input, pos); 311 if (pos.getErrorIndex() != -1) { 312 assertEquals(pos.getErrorIndex(), parseLen); 313 } else { 314 assertEquals(pos.getIndex(), parseLen); 315 assertEquals(parsed.getLong(DAY_OF_MONTH), (long)parseVal); 316 assertEquals(parsed.query(TemporalQueries.chronology()), null); 317 assertEquals(parsed.query(TemporalQueries.zoneId()), null); 318 } 319 } 320 321 //----------------------------------------------------------------------- 322 @DataProvider(name="parseSignsLenient") provider_parseSignsLenient()323 Object[][] provider_parseSignsLenient() { 324 return new Object[][] { 325 // never 326 {"0", 1, 2, SignStyle.NEVER, 1, 0}, 327 {"5", 1, 2, SignStyle.NEVER, 1, 5}, 328 {"50", 1, 2, SignStyle.NEVER, 2, 50}, 329 {"500", 1, 2, SignStyle.NEVER, 3, 500}, 330 {"-0", 1, 2, SignStyle.NEVER, 2, 0}, 331 {"-5", 1, 2, SignStyle.NEVER, 2, -5}, 332 {"-50", 1, 2, SignStyle.NEVER, 3, -50}, 333 {"-500", 1, 2, SignStyle.NEVER, 4, -500}, 334 {"-AAA", 1, 2, SignStyle.NEVER, 1, null}, 335 {"+0", 1, 2, SignStyle.NEVER, 2, 0}, 336 {"+5", 1, 2, SignStyle.NEVER, 2, 5}, 337 {"+50", 1, 2, SignStyle.NEVER, 3, 50}, 338 {"+500", 1, 2, SignStyle.NEVER, 4, 500}, 339 {"+AAA", 1, 2, SignStyle.NEVER, 1, null}, 340 {"50", 2, 2, SignStyle.NEVER, 2, 50}, 341 {"-50", 2, 2, SignStyle.NEVER, 0, null}, 342 {"+50", 2, 2, SignStyle.NEVER, 0, null}, 343 344 // not negative 345 {"0", 1, 2, SignStyle.NOT_NEGATIVE, 1, 0}, 346 {"5", 1, 2, SignStyle.NOT_NEGATIVE, 1, 5}, 347 {"50", 1, 2, SignStyle.NOT_NEGATIVE, 2, 50}, 348 {"500", 1, 2, SignStyle.NOT_NEGATIVE, 3, 500}, 349 {"-0", 1, 2, SignStyle.NOT_NEGATIVE, 2, 0}, 350 {"-5", 1, 2, SignStyle.NOT_NEGATIVE, 2, -5}, 351 {"-50", 1, 2, SignStyle.NOT_NEGATIVE, 3, -50}, 352 {"-500", 1, 2, SignStyle.NOT_NEGATIVE, 4, -500}, 353 {"-AAA", 1, 2, SignStyle.NOT_NEGATIVE, 1, null}, 354 {"+0", 1, 2, SignStyle.NOT_NEGATIVE, 2, 0}, 355 {"+5", 1, 2, SignStyle.NOT_NEGATIVE, 2, 5}, 356 {"+50", 1, 2, SignStyle.NOT_NEGATIVE, 3, 50}, 357 {"+500", 1, 2, SignStyle.NOT_NEGATIVE, 4, 500}, 358 {"+AAA", 1, 2, SignStyle.NOT_NEGATIVE, 1, null}, 359 {"50", 2, 2, SignStyle.NOT_NEGATIVE, 2, 50}, 360 {"-50", 2, 2, SignStyle.NOT_NEGATIVE, 0, null}, 361 {"+50", 2, 2, SignStyle.NOT_NEGATIVE, 0, null}, 362 363 // normal 364 {"0", 1, 2, SignStyle.NORMAL, 1, 0}, 365 {"5", 1, 2, SignStyle.NORMAL, 1, 5}, 366 {"50", 1, 2, SignStyle.NORMAL, 2, 50}, 367 {"500", 1, 2, SignStyle.NORMAL, 3, 500}, 368 {"-0", 1, 2, SignStyle.NORMAL, 2, 0}, 369 {"-5", 1, 2, SignStyle.NORMAL, 2, -5}, 370 {"-50", 1, 2, SignStyle.NORMAL, 3, -50}, 371 {"-500", 1, 2, SignStyle.NORMAL, 4, -500}, 372 {"-AAA", 1, 2, SignStyle.NORMAL, 1, null}, 373 {"+0", 1, 2, SignStyle.NORMAL, 2, 0}, 374 {"+5", 1, 2, SignStyle.NORMAL, 2, 5}, 375 {"+50", 1, 2, SignStyle.NORMAL, 3, 50}, 376 {"+500", 1, 2, SignStyle.NORMAL, 4, 500}, 377 {"+AAA", 1, 2, SignStyle.NORMAL, 1, null}, 378 {"50", 2, 2, SignStyle.NORMAL, 2, 50}, 379 {"-50", 2, 2, SignStyle.NORMAL, 3, -50}, 380 {"+50", 2, 2, SignStyle.NORMAL, 3, 50}, 381 382 // always 383 {"0", 1, 2, SignStyle.ALWAYS, 1, 0}, 384 {"5", 1, 2, SignStyle.ALWAYS, 1, 5}, 385 {"50", 1, 2, SignStyle.ALWAYS, 2, 50}, 386 {"500", 1, 2, SignStyle.ALWAYS, 3, 500}, 387 {"-0", 1, 2, SignStyle.ALWAYS, 2, 0}, 388 {"-5", 1, 2, SignStyle.ALWAYS, 2, -5}, 389 {"-50", 1, 2, SignStyle.ALWAYS, 3, -50}, 390 {"-500", 1, 2, SignStyle.ALWAYS, 4, -500}, 391 {"-AAA", 1, 2, SignStyle.ALWAYS, 1, null}, 392 {"+0", 1, 2, SignStyle.ALWAYS, 2, 0}, 393 {"+5", 1, 2, SignStyle.ALWAYS, 2, 5}, 394 {"+50", 1, 2, SignStyle.ALWAYS, 3, 50}, 395 {"+500", 1, 2, SignStyle.ALWAYS, 4, 500}, 396 {"+AAA", 1, 2, SignStyle.ALWAYS, 1, null}, 397 398 // exceeds pad 399 {"0", 1, 2, SignStyle.EXCEEDS_PAD, 1, 0}, 400 {"5", 1, 2, SignStyle.EXCEEDS_PAD, 1, 5}, 401 {"50", 1, 2, SignStyle.EXCEEDS_PAD, 2, 50}, 402 {"500", 1, 2, SignStyle.EXCEEDS_PAD, 3, 500}, 403 {"-0", 1, 2, SignStyle.EXCEEDS_PAD, 2, 0}, 404 {"-5", 1, 2, SignStyle.EXCEEDS_PAD, 2, -5}, 405 {"-50", 1, 2, SignStyle.EXCEEDS_PAD, 3, -50}, 406 {"-500", 1, 2, SignStyle.EXCEEDS_PAD, 4, -500}, 407 {"-AAA", 1, 2, SignStyle.EXCEEDS_PAD, 1, null}, 408 {"+0", 1, 2, SignStyle.EXCEEDS_PAD, 2, 0}, 409 {"+5", 1, 2, SignStyle.EXCEEDS_PAD, 2, 5}, 410 {"+50", 1, 2, SignStyle.EXCEEDS_PAD, 3, 50}, 411 {"+500", 1, 2, SignStyle.EXCEEDS_PAD, 4, 500}, 412 {"+AAA", 1, 2, SignStyle.EXCEEDS_PAD, 1, null}, 413 }; 414 } 415 416 @Test(dataProvider="parseSignsLenient") test_parseSignsLenient(String input, int min, int max, SignStyle style, int parseLen, Integer parseVal)417 public void test_parseSignsLenient(String input, int min, int max, SignStyle style, int parseLen, Integer parseVal) throws Exception { 418 setStrict(false); 419 ParsePosition pos = new ParsePosition(0); 420 TemporalAccessor parsed = getFormatter(DAY_OF_MONTH, min, max, style).parseUnresolved(input, pos); 421 if (pos.getErrorIndex() != -1) { 422 assertEquals(pos.getErrorIndex(), parseLen); 423 } else { 424 assertEquals(pos.getIndex(), parseLen); 425 assertEquals(parsed.getLong(DAY_OF_MONTH), (long)parseVal); 426 assertEquals(parsed.query(TemporalQueries.chronology()), null); 427 assertEquals(parsed.query(TemporalQueries.zoneId()), null); 428 } 429 } 430 431 //----------------------------------------------------------------------- 432 @DataProvider(name="parseDigitsLenient") provider_parseDigitsLenient()433 Object[][] provider_parseDigitsLenient() { 434 return new Object[][] { 435 // never 436 {"5", 1, 2, SignStyle.NEVER, 1, 5}, 437 {"5", 2, 2, SignStyle.NEVER, 1, 5}, 438 {"54", 1, 3, SignStyle.NEVER, 2, 54}, 439 {"54", 2, 3, SignStyle.NEVER, 2, 54}, 440 {"54", 3, 3, SignStyle.NEVER, 2, 54}, 441 {"543", 1, 3, SignStyle.NEVER, 3, 543}, 442 {"543", 2, 3, SignStyle.NEVER, 3, 543}, 443 {"543", 3, 3, SignStyle.NEVER, 3, 543}, 444 {"5432", 1, 3, SignStyle.NEVER, 4, 5432}, 445 {"5432", 2, 3, SignStyle.NEVER, 4, 5432}, 446 {"5432", 3, 3, SignStyle.NEVER, 4, 5432}, 447 {"5AAA", 2, 3, SignStyle.NEVER, 1, 5}, 448 449 // not negative 450 {"5", 1, 2, SignStyle.NOT_NEGATIVE, 1, 5}, 451 {"5", 2, 2, SignStyle.NOT_NEGATIVE, 1, 5}, 452 {"54", 1, 3, SignStyle.NOT_NEGATIVE, 2, 54}, 453 {"54", 2, 3, SignStyle.NOT_NEGATIVE, 2, 54}, 454 {"54", 3, 3, SignStyle.NOT_NEGATIVE, 2, 54}, 455 {"543", 1, 3, SignStyle.NOT_NEGATIVE, 3, 543}, 456 {"543", 2, 3, SignStyle.NOT_NEGATIVE, 3, 543}, 457 {"543", 3, 3, SignStyle.NOT_NEGATIVE, 3, 543}, 458 {"5432", 1, 3, SignStyle.NOT_NEGATIVE, 4, 5432}, 459 {"5432", 2, 3, SignStyle.NOT_NEGATIVE, 4, 5432}, 460 {"5432", 3, 3, SignStyle.NOT_NEGATIVE, 4, 5432}, 461 {"5AAA", 2, 3, SignStyle.NOT_NEGATIVE, 1, 5}, 462 463 // normal 464 {"5", 1, 2, SignStyle.NORMAL, 1, 5}, 465 {"5", 2, 2, SignStyle.NORMAL, 1, 5}, 466 {"54", 1, 3, SignStyle.NORMAL, 2, 54}, 467 {"54", 2, 3, SignStyle.NORMAL, 2, 54}, 468 {"54", 3, 3, SignStyle.NORMAL, 2, 54}, 469 {"543", 1, 3, SignStyle.NORMAL, 3, 543}, 470 {"543", 2, 3, SignStyle.NORMAL, 3, 543}, 471 {"543", 3, 3, SignStyle.NORMAL, 3, 543}, 472 {"5432", 1, 3, SignStyle.NORMAL, 4, 5432}, 473 {"5432", 2, 3, SignStyle.NORMAL, 4, 5432}, 474 {"5432", 3, 3, SignStyle.NORMAL, 4, 5432}, 475 {"5AAA", 2, 3, SignStyle.NORMAL, 1, 5}, 476 477 // always 478 {"5", 1, 2, SignStyle.ALWAYS, 1, 5}, 479 {"5", 2, 2, SignStyle.ALWAYS, 1, 5}, 480 {"54", 1, 3, SignStyle.ALWAYS, 2, 54}, 481 {"54", 2, 3, SignStyle.ALWAYS, 2, 54}, 482 {"54", 3, 3, SignStyle.ALWAYS, 2, 54}, 483 {"543", 1, 3, SignStyle.ALWAYS, 3, 543}, 484 {"543", 2, 3, SignStyle.ALWAYS, 3, 543}, 485 {"543", 3, 3, SignStyle.ALWAYS, 3, 543}, 486 {"5432", 1, 3, SignStyle.ALWAYS, 4, 5432}, 487 {"5432", 2, 3, SignStyle.ALWAYS, 4, 5432}, 488 {"5432", 3, 3, SignStyle.ALWAYS, 4, 5432}, 489 {"5AAA", 2, 3, SignStyle.ALWAYS, 1, 5}, 490 491 // exceeds pad 492 {"5", 1, 2, SignStyle.EXCEEDS_PAD, 1, 5}, 493 {"5", 2, 2, SignStyle.EXCEEDS_PAD, 1, 5}, 494 {"54", 1, 3, SignStyle.EXCEEDS_PAD, 2, 54}, 495 {"54", 2, 3, SignStyle.EXCEEDS_PAD, 2, 54}, 496 {"54", 3, 3, SignStyle.EXCEEDS_PAD, 2, 54}, 497 {"543", 1, 3, SignStyle.EXCEEDS_PAD, 3, 543}, 498 {"543", 2, 3, SignStyle.EXCEEDS_PAD, 3, 543}, 499 {"543", 3, 3, SignStyle.EXCEEDS_PAD, 3, 543}, 500 {"5432", 1, 3, SignStyle.EXCEEDS_PAD, 4, 5432}, 501 {"5432", 2, 3, SignStyle.EXCEEDS_PAD, 4, 5432}, 502 {"5432", 3, 3, SignStyle.EXCEEDS_PAD, 4, 5432}, 503 {"5AAA", 2, 3, SignStyle.EXCEEDS_PAD, 1, 5}, 504 }; 505 } 506 507 @Test(dataProvider="parseDigitsLenient") test_parseDigitsLenient(String input, int min, int max, SignStyle style, int parseLen, Integer parseVal)508 public void test_parseDigitsLenient(String input, int min, int max, SignStyle style, int parseLen, Integer parseVal) throws Exception { 509 setStrict(false); 510 ParsePosition pos = new ParsePosition(0); 511 TemporalAccessor parsed = getFormatter(DAY_OF_MONTH, min, max, style).parseUnresolved(input, pos); 512 if (pos.getErrorIndex() != -1) { 513 assertEquals(pos.getErrorIndex(), parseLen); 514 } else { 515 assertEquals(pos.getIndex(), parseLen); 516 assertEquals(parsed.getLong(DAY_OF_MONTH), (long)parseVal); 517 assertEquals(parsed.query(TemporalQueries.chronology()), null); 518 assertEquals(parsed.query(TemporalQueries.zoneId()), null); 519 } 520 } 521 522 //----------------------------------------------------------------------- 523 @DataProvider(name="parseDigitsAdjacentLenient") provider_parseDigitsAdjacentLenient()524 Object[][] provider_parseDigitsAdjacentLenient() { 525 return new Object[][] { 526 // never 527 {"5", 1, null, null}, 528 {"54", 1, null, null}, 529 530 {"543", 3, 5, 43}, 531 {"543A", 3, 5, 43}, 532 533 {"5432", 4, 54, 32}, 534 {"5432A", 4, 54, 32}, 535 536 {"54321", 5, 543, 21}, 537 {"54321A", 5, 543, 21}, 538 }; 539 } 540 541 @Test(dataProvider="parseDigitsAdjacentLenient") test_parseDigitsAdjacentLenient(String input, int parseLen, Integer parseMonth, Integer parsedDay)542 public void test_parseDigitsAdjacentLenient(String input, int parseLen, Integer parseMonth, Integer parsedDay) throws Exception { 543 setStrict(false); 544 ParsePosition pos = new ParsePosition(0); 545 DateTimeFormatter f = builder 546 .appendValue(MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL) 547 .appendValue(DAY_OF_MONTH, 2).toFormatter(locale).withDecimalStyle(decimalStyle); 548 TemporalAccessor parsed = f.parseUnresolved(input, pos); 549 if (pos.getErrorIndex() != -1) { 550 assertEquals(pos.getErrorIndex(), parseLen); 551 } else { 552 assertEquals(pos.getIndex(), parseLen); 553 assertEquals(parsed.getLong(MONTH_OF_YEAR), (long) parseMonth); 554 assertEquals(parsed.getLong(DAY_OF_MONTH), (long) parsedDay); 555 assertEquals(parsed.query(TemporalQueries.chronology()), null); 556 assertEquals(parsed.query(TemporalQueries.zoneId()), null); 557 } 558 } 559 560 } 561