|
|
|
|
@@ -42,6 +42,7 @@ import org.junit.jupiter.api.AfterEach;
|
|
|
|
|
import org.junit.jupiter.api.BeforeEach;
|
|
|
|
|
import org.junit.jupiter.api.Nested;
|
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
|
import org.junit.jupiter.api.condition.EnabledForJreRange;
|
|
|
|
|
import org.junit.jupiter.params.ParameterizedTest;
|
|
|
|
|
import org.junit.jupiter.params.provider.ValueSource;
|
|
|
|
|
|
|
|
|
|
@@ -58,6 +59,8 @@ import org.springframework.validation.DataBinder;
|
|
|
|
|
import org.springframework.validation.FieldError;
|
|
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
|
|
|
import static org.junit.jupiter.api.condition.JRE.JAVA_19;
|
|
|
|
|
import static org.junit.jupiter.api.condition.JRE.JAVA_20;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @author Keith Donald
|
|
|
|
|
@@ -68,6 +71,12 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|
|
|
|
*/
|
|
|
|
|
class DateTimeFormattingTests {
|
|
|
|
|
|
|
|
|
|
// JDK <= 19 requires a standard space before "AM/PM".
|
|
|
|
|
// JDK >= 20 requires a NNBSP before "AM/PM".
|
|
|
|
|
// \u202F is a narrow non-breaking space (NNBSP).
|
|
|
|
|
private static final String TIME_SEPARATOR = (Runtime.version().feature() < 20 ? " " : "\u202F");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final FormattingConversionService conversionService = new FormattingConversionService();
|
|
|
|
|
|
|
|
|
|
private DataBinder binder;
|
|
|
|
|
@@ -210,10 +219,11 @@ class DateTimeFormattingTests {
|
|
|
|
|
@Test
|
|
|
|
|
void testBindLocalTime() {
|
|
|
|
|
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
|
|
|
|
propertyValues.add("localTime", "12:00 PM");
|
|
|
|
|
propertyValues.add("localTime", "12:00%sPM".formatted(TIME_SEPARATOR));
|
|
|
|
|
binder.bind(propertyValues);
|
|
|
|
|
assertThat(binder.getBindingResult().getErrorCount()).isZero();
|
|
|
|
|
assertThat(binder.getBindingResult().getFieldValue("localTime")).isEqualTo("12:00 PM");
|
|
|
|
|
// \p{Zs} matches any Unicode space character
|
|
|
|
|
assertThat(binder.getBindingResult().getFieldValue("localTime")).asString().matches("12:00\\p{Zs}PM");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@@ -222,7 +232,8 @@ class DateTimeFormattingTests {
|
|
|
|
|
propertyValues.add("localTime", "12:00:00");
|
|
|
|
|
binder.bind(propertyValues);
|
|
|
|
|
assertThat(binder.getBindingResult().getErrorCount()).isZero();
|
|
|
|
|
assertThat(binder.getBindingResult().getFieldValue("localTime")).isEqualTo("12:00 PM");
|
|
|
|
|
// \p{Zs} matches any Unicode space character
|
|
|
|
|
assertThat(binder.getBindingResult().getFieldValue("localTime")).asString().matches("12:00\\p{Zs}PM");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@@ -231,10 +242,11 @@ class DateTimeFormattingTests {
|
|
|
|
|
registrar.setTimeStyle(FormatStyle.MEDIUM);
|
|
|
|
|
setup(registrar);
|
|
|
|
|
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
|
|
|
|
propertyValues.add("localTime", "12:00:00 PM");
|
|
|
|
|
propertyValues.add("localTime", "12:00:00%sPM".formatted(TIME_SEPARATOR));
|
|
|
|
|
binder.bind(propertyValues);
|
|
|
|
|
assertThat(binder.getBindingResult().getErrorCount()).isZero();
|
|
|
|
|
assertThat(binder.getBindingResult().getFieldValue("localTime")).isEqualTo("12:00:00 PM");
|
|
|
|
|
// \p{Zs} matches any Unicode space character
|
|
|
|
|
assertThat(binder.getBindingResult().getFieldValue("localTime")).asString().matches("12:00:00\\p{Zs}PM");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@@ -252,10 +264,11 @@ class DateTimeFormattingTests {
|
|
|
|
|
@Test
|
|
|
|
|
void testBindLocalTimeAnnotated() {
|
|
|
|
|
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
|
|
|
|
propertyValues.add("styleLocalTime", "12:00:00 PM");
|
|
|
|
|
propertyValues.add("styleLocalTime", "12:00:00%sPM".formatted(TIME_SEPARATOR));
|
|
|
|
|
binder.bind(propertyValues);
|
|
|
|
|
assertThat(binder.getBindingResult().getErrorCount()).isZero();
|
|
|
|
|
assertThat(binder.getBindingResult().getFieldValue("styleLocalTime")).isEqualTo("12:00:00 PM");
|
|
|
|
|
// \p{Zs} matches any Unicode space character
|
|
|
|
|
assertThat(binder.getBindingResult().getFieldValue("styleLocalTime")).asString().matches("12:00:00\\p{Zs}PM");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@@ -264,7 +277,8 @@ class DateTimeFormattingTests {
|
|
|
|
|
propertyValues.add("localTime", new GregorianCalendar(1970, 0, 0, 12, 0));
|
|
|
|
|
binder.bind(propertyValues);
|
|
|
|
|
assertThat(binder.getBindingResult().getErrorCount()).isZero();
|
|
|
|
|
assertThat(binder.getBindingResult().getFieldValue("localTime")).isEqualTo("12:00 PM");
|
|
|
|
|
// \p{Zs} matches any Unicode space character
|
|
|
|
|
assertThat(binder.getBindingResult().getFieldValue("localTime")).asString().matches("12:00\\p{Zs}PM");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@@ -274,7 +288,8 @@ class DateTimeFormattingTests {
|
|
|
|
|
binder.bind(propertyValues);
|
|
|
|
|
assertThat(binder.getBindingResult().getErrorCount()).isZero();
|
|
|
|
|
String value = binder.getBindingResult().getFieldValue("localDateTime").toString();
|
|
|
|
|
assertThat(value).startsWith("10/31/09").endsWith("12:00 PM");
|
|
|
|
|
// \p{Zs} matches any Unicode space character
|
|
|
|
|
assertThat(value).startsWith("10/31/09").matches(".+?12:00\\p{Zs}PM");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@@ -284,7 +299,8 @@ class DateTimeFormattingTests {
|
|
|
|
|
binder.bind(propertyValues);
|
|
|
|
|
assertThat(binder.getBindingResult().getErrorCount()).isZero();
|
|
|
|
|
String value = binder.getBindingResult().getFieldValue("localDateTime").toString();
|
|
|
|
|
assertThat(value).startsWith("10/31/09").endsWith("12:00 PM");
|
|
|
|
|
// \p{Zs} matches any Unicode space character
|
|
|
|
|
assertThat(value).startsWith("10/31/09").matches(".+?12:00\\p{Zs}PM");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@@ -294,7 +310,8 @@ class DateTimeFormattingTests {
|
|
|
|
|
binder.bind(propertyValues);
|
|
|
|
|
assertThat(binder.getBindingResult().getErrorCount()).isZero();
|
|
|
|
|
String value = binder.getBindingResult().getFieldValue("styleLocalDateTime").toString();
|
|
|
|
|
assertThat(value).startsWith("Oct 31, 2009").endsWith("12:00:00 PM");
|
|
|
|
|
// \p{Zs} matches any Unicode space character
|
|
|
|
|
assertThat(value).startsWith("Oct 31, 2009").matches(".+?12:00:00\\p{Zs}PM");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@@ -304,7 +321,8 @@ class DateTimeFormattingTests {
|
|
|
|
|
binder.bind(propertyValues);
|
|
|
|
|
assertThat(binder.getBindingResult().getErrorCount()).isZero();
|
|
|
|
|
String value = binder.getBindingResult().getFieldValue("localDateTime").toString();
|
|
|
|
|
assertThat(value).startsWith("10/31/09").endsWith("12:00 PM");
|
|
|
|
|
// \p{Zs} matches any Unicode space character
|
|
|
|
|
assertThat(value).startsWith("10/31/09").matches(".+?12:00\\p{Zs}PM");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@@ -317,7 +335,8 @@ class DateTimeFormattingTests {
|
|
|
|
|
binder.bind(propertyValues);
|
|
|
|
|
assertThat(binder.getBindingResult().getErrorCount()).isZero();
|
|
|
|
|
String value = binder.getBindingResult().getFieldValue("localDateTime").toString();
|
|
|
|
|
assertThat(value).startsWith("Oct 31, 2009").endsWith("12:00:00 PM");
|
|
|
|
|
// \p{Zs} matches any Unicode space character
|
|
|
|
|
assertThat(value).startsWith("Oct 31, 2009").matches(".+?12:00:00\\p{Zs}PM");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@@ -558,18 +577,32 @@ class DateTimeFormattingTests {
|
|
|
|
|
assertThat(bindingResult.getFieldValue(propertyName)).isEqualTo("2021-03-02");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@EnabledForJreRange(max = JAVA_19)
|
|
|
|
|
@ParameterizedTest(name = "input date: {0}")
|
|
|
|
|
// @ValueSource(strings = {"12:00:00\u202FPM", "12:00:00", "12:00"})
|
|
|
|
|
// JDK <= 19 requires a standard space before the "PM".
|
|
|
|
|
@ValueSource(strings = {"12:00:00 PM", "12:00:00", "12:00"})
|
|
|
|
|
void styleLocalTime(String propertyValue) {
|
|
|
|
|
void styleLocalTime_PreJDK20(String propertyValue) {
|
|
|
|
|
styleLocalTime(propertyValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@EnabledForJreRange(min = JAVA_20)
|
|
|
|
|
@ParameterizedTest(name = "input date: {0}")
|
|
|
|
|
// JDK >= 20 requires a NNBSP before the "PM".
|
|
|
|
|
// \u202F is a narrow non-breaking space (NNBSP).
|
|
|
|
|
@ValueSource(strings = {"12:00:00\u202FPM", "12:00:00", "12:00"})
|
|
|
|
|
void styleLocalTime_PostJDK20(String propertyValue) {
|
|
|
|
|
styleLocalTime(propertyValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void styleLocalTime(String propertyValue) {
|
|
|
|
|
String propertyName = "styleLocalTimeWithFallbackPatterns";
|
|
|
|
|
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
|
|
|
|
propertyValues.add(propertyName, propertyValue);
|
|
|
|
|
binder.bind(propertyValues);
|
|
|
|
|
BindingResult bindingResult = binder.getBindingResult();
|
|
|
|
|
assertThat(bindingResult.getErrorCount()).isZero();
|
|
|
|
|
// assertThat(bindingResult.getFieldValue(propertyName)).asString().matches("12:00:00\\SPM");
|
|
|
|
|
assertThat(bindingResult.getFieldValue(propertyName)).isEqualTo("12:00:00 PM");
|
|
|
|
|
// \p{Zs} matches any Unicode space character
|
|
|
|
|
assertThat(bindingResult.getFieldValue(propertyName)).asString().matches("12:00:00\\p{Zs}PM");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ParameterizedTest(name = "input date: {0}")
|
|
|
|
|
|