From 28128a9577c9352479c9c970654e3f6bc09ed866 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 6 Jul 2020 19:57:26 +0100 Subject: [PATCH] Add support for ChronoUnit.WEEKS when using PeriodUnit Fixes gh-22225 --- .../boot/convert/PeriodStyle.java | 14 ++++++++++---- .../convert/NumberToPeriodConverterTests.java | 7 ++++++- .../convert/PeriodToStringConverterTests.java | 7 +++++++ .../convert/StringToPeriodConverterTests.java | 17 +++++++++++++++++ 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/PeriodStyle.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/PeriodStyle.java index ac457727dd..660e9501d1 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/PeriodStyle.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/PeriodStyle.java @@ -212,13 +212,18 @@ public enum PeriodStyle { throw new IllegalArgumentException("'" + value + "' is not a valid period"); } - enum Unit { + private enum Unit { /** * Days, represented by suffix {@code d}. */ DAYS(ChronoUnit.DAYS, "d", Period::getDays, Period::ofDays), + /** + * Weeks, represented by suffix {@code w}. + */ + WEEKS(ChronoUnit.WEEKS, "w", null, Period::ofWeeks), + /** * Months, represented by suffix {@code m}. */ @@ -253,15 +258,16 @@ public enum PeriodStyle { return intValue(value) + this.suffix; } - public boolean isZero(Period value) { + private boolean isZero(Period value) { return intValue(value) == 0; } - public int intValue(Period value) { + private int intValue(Period value) { + Assert.notNull(this.intValue, () -> "intValue cannot be extracted from " + this.name()); return this.intValue.apply(value); } - public static Unit fromChronoUnit(ChronoUnit chronoUnit) { + private static Unit fromChronoUnit(ChronoUnit chronoUnit) { if (chronoUnit == null) { return Unit.DAYS; } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/NumberToPeriodConverterTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/NumberToPeriodConverterTests.java index 045715d3a7..460502406c 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/NumberToPeriodConverterTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/NumberToPeriodConverterTests.java @@ -48,9 +48,14 @@ class NumberToPeriodConverterTests { @ConversionServiceTest void convertWhenSimpleWithoutSuffixButWithAnnotationShouldReturnPeriod(ConversionService conversionService) { + assertThat(convert(conversionService, 10, ChronoUnit.DAYS)).isEqualTo(Period.ofDays(10)); + assertThat(convert(conversionService, -10, ChronoUnit.DAYS)).isEqualTo(Period.ofDays(-10)); + assertThat(convert(conversionService, 10, ChronoUnit.WEEKS)).isEqualTo(Period.ofWeeks(10)); + assertThat(convert(conversionService, -10, ChronoUnit.WEEKS)).isEqualTo(Period.ofWeeks(-10)); assertThat(convert(conversionService, 10, ChronoUnit.MONTHS)).isEqualTo(Period.ofMonths(10)); - assertThat(convert(conversionService, +10, ChronoUnit.MONTHS)).isEqualTo(Period.ofMonths(10)); assertThat(convert(conversionService, -10, ChronoUnit.MONTHS)).isEqualTo(Period.ofMonths(-10)); + assertThat(convert(conversionService, 10, ChronoUnit.YEARS)).isEqualTo(Period.ofYears(10)); + assertThat(convert(conversionService, -10, ChronoUnit.YEARS)).isEqualTo(Period.ofYears(-10)); } private Period convert(ConversionService conversionService, Integer source) { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/PeriodToStringConverterTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/PeriodToStringConverterTests.java index 5eb142058d..96d37d0a96 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/PeriodToStringConverterTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/PeriodToStringConverterTests.java @@ -71,6 +71,13 @@ class PeriodToStringConverterTests { assertThat(converted).isEqualTo("1y3d"); } + @ConversionServiceTest + void convertWithWeekUnitShouldConvertToStringInDays(ConversionService conversionService) { + String converted = (String) conversionService.convert(Period.ofWeeks(53), + MockPeriodTypeDescriptor.get(null, PeriodStyle.SIMPLE), TypeDescriptor.valueOf(String.class)); + assertThat(converted).isEqualTo("371d"); + } + static Stream conversionServices() throws Exception { return ConversionServiceArguments.with(new PeriodToStringConverter()); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/StringToPeriodConverterTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/StringToPeriodConverterTests.java index e3a28c26b0..5339ad0f8b 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/StringToPeriodConverterTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/convert/StringToPeriodConverterTests.java @@ -55,6 +55,14 @@ class StringToPeriodConverterTests { assertThat(convert(conversionService, "-10D")).isEqualTo(Period.ofDays(-10)); } + @ConversionServiceTest + void convertWhenSimpleWeeksShouldReturnPeriod(ConversionService conversionService) { + assertThat(convert(conversionService, "10w")).isEqualTo(Period.ofWeeks(10)); + assertThat(convert(conversionService, "10W")).isEqualTo(Period.ofWeeks(10)); + assertThat(convert(conversionService, "+10w")).isEqualTo(Period.ofWeeks(10)); + assertThat(convert(conversionService, "-10W")).isEqualTo(Period.ofWeeks(-10)); + } + @ConversionServiceTest void convertWhenSimpleMonthsShouldReturnPeriod(ConversionService conversionService) { assertThat(convert(conversionService, "10m")).isEqualTo(Period.ofMonths(10)); @@ -80,9 +88,18 @@ class StringToPeriodConverterTests { @ConversionServiceTest void convertWhenSimpleWithoutSuffixButWithAnnotationShouldReturnPeriod(ConversionService conversionService) { + assertThat(convert(conversionService, "10", ChronoUnit.DAYS, null)).isEqualTo(Period.ofDays(10)); + assertThat(convert(conversionService, "+10", ChronoUnit.DAYS, null)).isEqualTo(Period.ofDays(10)); + assertThat(convert(conversionService, "-10", ChronoUnit.DAYS, null)).isEqualTo(Period.ofDays(-10)); + assertThat(convert(conversionService, "10", ChronoUnit.WEEKS, null)).isEqualTo(Period.ofWeeks(10)); + assertThat(convert(conversionService, "+10", ChronoUnit.WEEKS, null)).isEqualTo(Period.ofWeeks(10)); + assertThat(convert(conversionService, "-10", ChronoUnit.WEEKS, null)).isEqualTo(Period.ofWeeks(-10)); assertThat(convert(conversionService, "10", ChronoUnit.MONTHS, null)).isEqualTo(Period.ofMonths(10)); assertThat(convert(conversionService, "+10", ChronoUnit.MONTHS, null)).isEqualTo(Period.ofMonths(10)); assertThat(convert(conversionService, "-10", ChronoUnit.MONTHS, null)).isEqualTo(Period.ofMonths(-10)); + assertThat(convert(conversionService, "10", ChronoUnit.YEARS, null)).isEqualTo(Period.ofYears(10)); + assertThat(convert(conversionService, "+10", ChronoUnit.YEARS, null)).isEqualTo(Period.ofYears(10)); + assertThat(convert(conversionService, "-10", ChronoUnit.YEARS, null)).isEqualTo(Period.ofYears(-10)); } private Period convert(ConversionService conversionService, String source) {