Add multi-unit DurationFormat.Style for duration parsing/printing
This adds the COMPOSITE style, which allows multiple segments each similar to the SIMPLE style. See gh-30396 Closes gh-33262
This commit is contained in:
@@ -27,7 +27,9 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.format.annotation.DurationFormat.Unit;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.springframework.format.annotation.DurationFormat.Style.COMPOSITE;
|
||||
import static org.springframework.format.annotation.DurationFormat.Style.ISO8601;
|
||||
import static org.springframework.format.annotation.DurationFormat.Style.SIMPLE;
|
||||
|
||||
@@ -132,6 +134,60 @@ class DurationFormatterUtilsTests {
|
||||
.withCause(new DateTimeParseException("Text cannot be parsed to a Duration", "", 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseComposite() {
|
||||
assertThat(DurationFormatterUtils.parse("1d2h34m57s28ms3us2ns", COMPOSITE))
|
||||
.isEqualTo(Duration.ofDays(1).plusHours(2)
|
||||
.plusMinutes(34).plusSeconds(57)
|
||||
.plusMillis(28).plusNanos(3002));
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseCompositeWithExplicitPlusSign() {
|
||||
assertThat(DurationFormatterUtils.parse("+1d2h34m57s28ms3us2ns", COMPOSITE))
|
||||
.isEqualTo(Duration.ofDays(1).plusHours(2)
|
||||
.plusMinutes(34).plusSeconds(57)
|
||||
.plusMillis(28).plusNanos(3002));
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseCompositeWithExplicitMinusSign() {
|
||||
assertThat(DurationFormatterUtils.parse("-1d2h34m57s28ms3us2ns", COMPOSITE))
|
||||
.isEqualTo(Duration.ofDays(-1).plusHours(-2)
|
||||
.plusMinutes(-34).plusSeconds(-57)
|
||||
.plusMillis(-28).plusNanos(-3002));
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseCompositePartial() {
|
||||
assertThat(DurationFormatterUtils.parse("34m57s", COMPOSITE))
|
||||
.isEqualTo(Duration.ofMinutes(34).plusSeconds(57));
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseCompositePartialWithSpaces() {
|
||||
assertThat(DurationFormatterUtils.parse("34m 57s", COMPOSITE))
|
||||
.isEqualTo(Duration.ofMinutes(34).plusSeconds(57));
|
||||
}
|
||||
|
||||
@Test //Kotlin style compatibility
|
||||
void parseCompositeNegativeWithSpacesAndParenthesis() {
|
||||
assertThat(DurationFormatterUtils.parse("-(34m 57s)", COMPOSITE))
|
||||
.isEqualTo(Duration.ofMinutes(-34).plusSeconds(-57));
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseCompositeBadSign() {
|
||||
assertThatException().isThrownBy(() -> DurationFormatterUtils.parse("+-34m57s", COMPOSITE))
|
||||
.havingCause().withMessage("Does not match composite duration pattern");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseCompositeBadUnit() {
|
||||
assertThatException().isThrownBy(() -> DurationFormatterUtils.parse("34mo57s", COMPOSITE))
|
||||
.havingCause().withMessage("Does not match composite duration pattern");
|
||||
}
|
||||
|
||||
@Test
|
||||
void printSimple() {
|
||||
assertThat(DurationFormatterUtils.print(Duration.ofNanos(12345), SIMPLE, Unit.NANOS))
|
||||
@@ -164,6 +220,26 @@ class DurationFormatterUtilsTests {
|
||||
.isEqualTo("PT-3S");
|
||||
}
|
||||
|
||||
@Test
|
||||
void printCompositePositive() {
|
||||
Duration composite = DurationFormatterUtils.parse("+1d2h34m57s28ms3us2ns", COMPOSITE);
|
||||
assertThat(DurationFormatterUtils.print(composite, COMPOSITE))
|
||||
.isEqualTo("1d2h34m57s28ms3us2ns");
|
||||
}
|
||||
|
||||
@Test
|
||||
void printCompositeZero() {
|
||||
assertThat(DurationFormatterUtils.print(Duration.ZERO, COMPOSITE))
|
||||
.isEqualTo("0s");
|
||||
}
|
||||
|
||||
@Test
|
||||
void printCompositeNegative() {
|
||||
Duration composite = DurationFormatterUtils.parse("-1d2h34m57s28ms3us2ns", COMPOSITE);
|
||||
assertThat(DurationFormatterUtils.print(composite, COMPOSITE))
|
||||
.isEqualTo("-1d2h34m57s28ms3us2ns");
|
||||
}
|
||||
|
||||
@Test
|
||||
void detectAndParse() {
|
||||
assertThat(DurationFormatterUtils.detectAndParse("PT1.234S", Unit.NANOS))
|
||||
@@ -177,6 +253,10 @@ class DurationFormatterUtilsTests {
|
||||
assertThat(DurationFormatterUtils.detectAndParse("1234", Unit.NANOS))
|
||||
.as("simple without suffix")
|
||||
.isEqualTo(Duration.ofNanos(1234));
|
||||
|
||||
assertThat(DurationFormatterUtils.detectAndParse("3s45ms", Unit.NANOS))
|
||||
.as("composite")
|
||||
.isEqualTo(Duration.ofMillis(3045));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -192,6 +272,10 @@ class DurationFormatterUtilsTests {
|
||||
assertThat(DurationFormatterUtils.detectAndParse("1234"))
|
||||
.as("simple without suffix")
|
||||
.isEqualTo(Duration.ofMillis(1234));
|
||||
|
||||
assertThat(DurationFormatterUtils.detectAndParse("3s45ms"))
|
||||
.as("composite")
|
||||
.isEqualTo(Duration.ofMillis(3045));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -210,6 +294,10 @@ class DurationFormatterUtilsTests {
|
||||
.as("invalid yet matching ISO8601 pattern")
|
||||
.isEqualTo(ISO8601);
|
||||
|
||||
assertThat(DurationFormatterUtils.detect("-(1d 2h 34m 2ns)"))
|
||||
.as("COMPOSITE")
|
||||
.isEqualTo(COMPOSITE);
|
||||
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> DurationFormatterUtils.detect("WPT2H-4M"))
|
||||
.withMessage("'WPT2H-4M' is not a valid duration, cannot detect any known style")
|
||||
.withNoCause();
|
||||
|
||||
Reference in New Issue
Block a user