Merge branch '6.2.x'

This commit is contained in:
Sam Brannen 2024-11-18 14:16:20 +01:00
commit 8d4a8cbbe5
6 changed files with 89 additions and 87 deletions

View File

@ -29,7 +29,8 @@ import org.springframework.lang.Nullable;
/** /**
* Declares that a field or method parameter should be formatted as a * Declares that a field or method parameter should be formatted as a
* {@link java.time.Duration}, according to the specified {@link #style style}. * {@link java.time.Duration}, according to the specified {@link #style Style}
* and {@link #defaultUnit Unit}.
* *
* @author Simon Baslé * @author Simon Baslé
* @since 6.2 * @since 6.2
@ -40,20 +41,20 @@ import org.springframework.lang.Nullable;
public @interface DurationFormat { public @interface DurationFormat {
/** /**
* The {@code Style} to use for parsing and printing a {@code Duration}. * The {@link Style} to use for parsing and printing a {@link Duration}.
* <p>Defaults to the JDK style ({@link Style#ISO8601}). * <p>Defaults to the JDK style ({@link Style#ISO8601}).
*/ */
Style style() default Style.ISO8601; Style style() default Style.ISO8601;
/** /**
* The {@link Unit} to fall back to in case the {@code style()} needs a unit * The {@link Unit} to fall back to in case the {@link #style Style} needs a unit
* for either parsing or printing, and none is explicitly provided in the input. * for either parsing or printing, and none is explicitly provided in the input.
* <p>Defaults to {@link Unit#MILLIS} if unspecified. * <p>Defaults to {@link Unit#MILLIS} if unspecified.
*/ */
Unit defaultUnit() default Unit.MILLIS; Unit defaultUnit() default Unit.MILLIS;
/** /**
* Duration format styles. * {@link Duration} format styles.
*/ */
enum Style { enum Style {
@ -62,7 +63,7 @@ public @interface DurationFormat {
* <p>Supported unit suffixes include: {@code ns, us, ms, s, m, h, d}. * <p>Supported unit suffixes include: {@code ns, us, ms, s, m, h, d}.
* Those correspond to nanoseconds, microseconds, milliseconds, seconds, * Those correspond to nanoseconds, microseconds, milliseconds, seconds,
* minutes, hours, and days, respectively. * minutes, hours, and days, respectively.
* <p>Note that when printing a {@code Duration}, this style can be * <p>Note that when printing a {@link Duration}, this style can be
* lossy if the selected unit is bigger than the resolution of the * lossy if the selected unit is bigger than the resolution of the
* duration. For example, {@code Duration.ofMillis(5).plusNanos(1234)} * duration. For example, {@code Duration.ofMillis(5).plusNanos(1234)}
* would get truncated to {@code "5ms"} when printing using * would get truncated to {@code "5ms"} when printing using
@ -73,7 +74,7 @@ public @interface DurationFormat {
/** /**
* ISO-8601 formatting. * ISO-8601 formatting.
* <p>This is what the JDK uses in {@link java.time.Duration#parse(CharSequence)} * <p>This is what the JDK uses in {@link Duration#parse(CharSequence)}
* and {@link Duration#toString()}. * and {@link Duration#toString()}.
*/ */
ISO8601, ISO8601,
@ -90,11 +91,11 @@ public @interface DurationFormat {
} }
/** /**
* Duration format unit, which mirrors a subset of {@link ChronoUnit} and * {@link Duration} format unit, which mirrors a subset of {@link ChronoUnit} and
* allows conversion to and from a supported {@code ChronoUnit} as well as * allows conversion to and from a supported {@code ChronoUnit} as well as
* conversion from durations to longs. * conversion from durations to longs.
* *
* <p>The enum includes its corresponding suffix in the {@link Style#SIMPLE simple} * <p>The enum includes its corresponding suffix in the {@link Style#SIMPLE SIMPLE}
* {@code Duration} format style. * {@code Duration} format style.
*/ */
enum Unit { enum Unit {
@ -147,25 +148,24 @@ public @interface DurationFormat {
} }
/** /**
* Convert this {@code DurationFormat.Unit} to its {@link ChronoUnit} * Convert this {@code Unit} to its {@link ChronoUnit} equivalent.
* equivalent.
*/ */
public ChronoUnit asChronoUnit() { public ChronoUnit asChronoUnit() {
return this.chronoUnit; return this.chronoUnit;
} }
/** /**
* Convert this {@code DurationFormat.Unit} to a simple {@code String} * Convert this {@code Unit} to a simple {@code String} suffix, suitable
* suffix, suitable for the {@link Style#SIMPLE SIMPLE} style. * for the {@link Style#SIMPLE SIMPLE} style.
*/ */
public String asSuffix() { public String asSuffix() {
return this.suffix; return this.suffix;
} }
/** /**
* Parse a {@code long} from a {@code String} and interpret it to be a * Parse a {@code long} from the given {@link String} and interpret it to be a
* {@code Duration} in the current unit. * {@link Duration} in the current unit.
* @param value the String representation of the long * @param value the {@code String} representation of the long
* @return the corresponding {@code Duration} * @return the corresponding {@code Duration}
*/ */
public Duration parse(String value) { public Duration parse(String value) {
@ -173,11 +173,11 @@ public @interface DurationFormat {
} }
/** /**
* Print a {@code Duration} as a {@code String}, converting it to a long * Print the given {@link Duration} as a {@link String}, converting it to a long
* value using this unit's precision via {@link #longValue(Duration)} * value using this unit's precision via {@link #longValue(Duration)}
* and appending this unit's simple {@link #asSuffix() suffix}. * and appending this unit's simple {@link #asSuffix() suffix}.
* @param value the {@code Duration} to convert to a String * @param value the {@code Duration} to convert to a {@code String}
* @return the String representation of the {@code Duration} in the * @return the {@code String} representation of the {@code Duration} in the
* {@link Style#SIMPLE SIMPLE} style * {@link Style#SIMPLE SIMPLE} style
*/ */
public String print(Duration value) { public String print(Duration value) {
@ -185,11 +185,12 @@ public @interface DurationFormat {
} }
/** /**
* Convert the given {@code Duration} to a long value in the resolution * Convert the given {@link Duration} to a long value in the resolution
* of this unit. Note that this can be lossy if the current unit is * of this unit.
* bigger than the actual resolution of the duration. * <p>Note that this can be lossy if the current unit is bigger than the
* <p>For example, {@code Duration.ofMillis(5).plusNanos(1234)} would * actual resolution of the duration. For example,
* get truncated to {@code 5} for unit {@code MILLIS}. * {@code Duration.ofMillis(5).plusNanos(1234)} would get truncated to
* {@code 5} for unit {@code MILLIS}.
* @param value the {@code Duration} to convert to a long * @param value the {@code Duration} to convert to a long
* @return the long value for the {@code Duration} in this {@code Unit} * @return the long value for the {@code Duration} in this {@code Unit}
*/ */
@ -198,7 +199,7 @@ public @interface DurationFormat {
} }
/** /**
* Get the {@code Unit} corresponding to the given {@code ChronoUnit}. * Get the {@link Unit} corresponding to the given {@link ChronoUnit}.
* @throws IllegalArgumentException if the given {@code ChronoUnit} is * @throws IllegalArgumentException if the given {@code ChronoUnit} is
* not supported * not supported
*/ */
@ -215,7 +216,7 @@ public @interface DurationFormat {
} }
/** /**
* Get the {@code Unit} corresponding to the given {@code String} suffix. * Get the {@link Unit} corresponding to the given {@link String} suffix.
* @throws IllegalArgumentException if the given suffix is not supported * @throws IllegalArgumentException if the given suffix is not supported
*/ */
public static Unit fromSuffix(String suffix) { public static Unit fromSuffix(String suffix) {

View File

@ -42,7 +42,7 @@ import static org.springframework.format.annotation.DurationFormat.Style.SIMPLE;
class DurationFormatterUtilsTests { class DurationFormatterUtilsTests {
@ParameterizedTest @ParameterizedTest
@EnumSource(DurationFormat.Style.class) @EnumSource
void parseEmptyStringFailsWithDedicatedException(DurationFormat.Style style) { void parseEmptyStringFailsWithDedicatedException(DurationFormat.Style style) {
assertThatIllegalArgumentException() assertThatIllegalArgumentException()
.isThrownBy(() -> DurationFormatterUtils.parse("", style)) .isThrownBy(() -> DurationFormatterUtils.parse("", style))
@ -50,7 +50,7 @@ class DurationFormatterUtilsTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(DurationFormat.Style.class) @EnumSource
void parseNullStringFailsWithDedicatedException(DurationFormat.Style style) { void parseNullStringFailsWithDedicatedException(DurationFormat.Style style) {
assertThatIllegalArgumentException() assertThatIllegalArgumentException()
.isThrownBy(() -> DurationFormatterUtils.parse(null, style)) .isThrownBy(() -> DurationFormatterUtils.parse(null, style))
@ -113,29 +113,30 @@ class DurationFormatterUtilsTests {
@Test @Test
void parseIsoNoChronoUnit() { void parseIsoNoChronoUnit() {
//these are based on the examples given in Duration.parse // These are based on the examples given in Duration.parse.
// "PT20.345S" -- parses as "20.345 seconds"
// "PT20.345S" -- parses as "20.345 seconds"
assertThat(DurationFormatterUtils.parse("PT20.345S", ISO8601)) assertThat(DurationFormatterUtils.parse("PT20.345S", ISO8601))
.hasMillis(20345); .hasMillis(20345);
// "PT15M" -- parses as "15 minutes" (where a minute is 60 seconds) // "PT15M" -- parses as "15 minutes" (where a minute is 60 seconds)
assertThat(DurationFormatterUtils.parse("PT15M", ISO8601)) assertThat(DurationFormatterUtils.parse("PT15M", ISO8601))
.hasSeconds(15*60); .hasSeconds(15*60);
// "PT10H" -- parses as "10 hours" (where an hour is 3600 seconds) // "PT10H" -- parses as "10 hours" (where an hour is 3600 seconds)
assertThat(DurationFormatterUtils.parse("PT10H", ISO8601)) assertThat(DurationFormatterUtils.parse("PT10H", ISO8601))
.hasHours(10); .hasHours(10);
// "P2D" -- parses as "2 days" (where a day is 24 hours or 86400 seconds) // "P2D" -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
assertThat(DurationFormatterUtils.parse("P2D", ISO8601)) assertThat(DurationFormatterUtils.parse("P2D", ISO8601))
.hasDays(2); .hasDays(2);
// "P2DT3H4M" -- parses as "2 days, 3 hours and 4 minutes" // "P2DT3H4M" -- parses as "2 days, 3 hours and 4 minutes"
assertThat(DurationFormatterUtils.parse("P2DT3H4M", ISO8601)) assertThat(DurationFormatterUtils.parse("P2DT3H4M", ISO8601))
.isEqualTo(Duration.ofDays(2).plusHours(3).plusMinutes(4)); .isEqualTo(Duration.ofDays(2).plusHours(3).plusMinutes(4));
// "PT-6H3M" -- parses as "-6 hours and +3 minutes" // "PT-6H3M" -- parses as "-6 hours and +3 minutes"
assertThat(DurationFormatterUtils.parse("PT-6H3M", ISO8601)) assertThat(DurationFormatterUtils.parse("PT-6H3M", ISO8601))
.isEqualTo(Duration.ofHours(-6).plusMinutes(3)); .isEqualTo(Duration.ofHours(-6).plusMinutes(3));
// "-PT6H3M" -- parses as "-6 hours and -3 minutes" // "-PT6H3M" -- parses as "-6 hours and -3 minutes"
assertThat(DurationFormatterUtils.parse("-PT6H3M", ISO8601)) assertThat(DurationFormatterUtils.parse("-PT6H3M", ISO8601))
.isEqualTo(Duration.ofHours(-6).plusMinutes(-3)); .isEqualTo(Duration.ofHours(-6).plusMinutes(-3));
// "-PT-6H+3M" -- parses as "+6 hours and -3 minutes" // "-PT-6H+3M" -- parses as "+6 hours and -3 minutes"
assertThat(DurationFormatterUtils.parse("-PT-6H+3M", ISO8601)) assertThat(DurationFormatterUtils.parse("-PT-6H+3M", ISO8601))
.isEqualTo(Duration.ofHours(6).plusMinutes(-3)); .isEqualTo(Duration.ofHours(6).plusMinutes(-3));
} }
@ -189,7 +190,7 @@ class DurationFormatterUtilsTests {
.isEqualTo(Duration.ofMinutes(34).plusSeconds(57)); .isEqualTo(Duration.ofMinutes(34).plusSeconds(57));
} }
@Test //Kotlin style compatibility @Test // Kotlin style compatibility
void parseCompositeNegativeWithSpacesAndParenthesis() { void parseCompositeNegativeWithSpacesAndParenthesis() {
assertThat(DurationFormatterUtils.parse("-(34m 57s)", COMPOSITE)) assertThat(DurationFormatterUtils.parse("-(34m 57s)", COMPOSITE))
.isEqualTo(Duration.ofMinutes(-34).plusSeconds(-57)); .isEqualTo(Duration.ofMinutes(-34).plusSeconds(-57));
@ -315,7 +316,7 @@ class DurationFormatterUtilsTests {
assertThat(DurationFormatterUtils.detect("-(1d 2h 34m 2ns)")) assertThat(DurationFormatterUtils.detect("-(1d 2h 34m 2ns)"))
.as("COMPOSITE") .as("COMPOSITE")
.isEqualTo(COMPOSITE); .isEqualTo(COMPOSITE);
assertThatIllegalArgumentException().isThrownBy(() -> DurationFormatterUtils.detect("WPT2H-4M")) assertThatIllegalArgumentException().isThrownBy(() -> DurationFormatterUtils.detect("WPT2H-4M"))
.withMessage("'WPT2H-4M' is not a valid duration, cannot detect any known style") .withMessage("'WPT2H-4M' is not a valid duration, cannot detect any known style")

View File

@ -67,7 +67,7 @@ class H2SequenceMaxValueIncrementerTests {
* Tests that the incrementer works when using all supported H2 <em>compatibility modes</em>. * Tests that the incrementer works when using all supported H2 <em>compatibility modes</em>.
*/ */
@ParameterizedTest @ParameterizedTest
@EnumSource(ModeEnum.class) @EnumSource
void incrementsSequenceWithExplicitH2CompatibilityMode(ModeEnum mode) { void incrementsSequenceWithExplicitH2CompatibilityMode(ModeEnum mode) {
String connectionUrl = String.format("jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false;MODE=%s", UUID.randomUUID(), mode); String connectionUrl = String.format("jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false;MODE=%s", UUID.randomUUID(), mode);
DataSource dataSource = new SimpleDriverDataSource(new org.h2.Driver(), connectionUrl, "sa", ""); DataSource dataSource = new SimpleDriverDataSource(new org.h2.Driver(), connectionUrl, "sa", "");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2023 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -52,7 +52,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
class UriComponentsBuilderTests { class UriComponentsBuilderTests {
@ParameterizedTest // see gh-26453 @ParameterizedTest // see gh-26453
@EnumSource(value = ParserType.class) @EnumSource
void examplesInReferenceManual(ParserType parserType) { void examplesInReferenceManual(ParserType parserType) {
final String expected = "/hotel%20list/New%20York?q=foo%2Bbar"; final String expected = "/hotel%20list/New%20York?q=foo%2Bbar";
@ -156,7 +156,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // see gh-9317 @ParameterizedTest // see gh-9317
@EnumSource(value = ParserType.class) @EnumSource
void fromUriEncodedQuery(ParserType parserType) { void fromUriEncodedQuery(ParserType parserType) {
URI uri = URI.create("https://www.example.org/?param=aGVsbG9Xb3JsZA%3D%3D"); URI uri = URI.create("https://www.example.org/?param=aGVsbG9Xb3JsZA%3D%3D");
String fromUri = UriComponentsBuilder.fromUri(uri).build().getQueryParams().get("param").get(0); String fromUri = UriComponentsBuilder.fromUri(uri).build().getQueryParams().get("param").get(0);
@ -167,7 +167,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void fromUriString(ParserType parserType) { void fromUriString(ParserType parserType) {
UriComponents result = UriComponentsBuilder.fromUriString("https://www.ietf.org/rfc/rfc3986.txt", parserType).build(); UriComponents result = UriComponentsBuilder.fromUriString("https://www.ietf.org/rfc/rfc3986.txt", parserType).build();
assertThat(result.getScheme()).isEqualTo("https"); assertThat(result.getScheme()).isEqualTo("https");
@ -224,7 +224,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // see SPR-9832 @ParameterizedTest // see SPR-9832
@EnumSource(value = ParserType.class) @EnumSource
void fromUriStringQueryParamWithReservedCharInValue(ParserType parserType) { void fromUriStringQueryParamWithReservedCharInValue(ParserType parserType) {
String uri = "https://www.google.com/ig/calculator?q=1USD=?EUR"; String uri = "https://www.google.com/ig/calculator?q=1USD=?EUR";
UriComponents result = UriComponentsBuilder.fromUriString(uri, parserType).build(); UriComponents result = UriComponentsBuilder.fromUriString(uri, parserType).build();
@ -234,7 +234,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // see SPR-14828 @ParameterizedTest // see SPR-14828
@EnumSource(value = ParserType.class) @EnumSource
void fromUriStringQueryParamEncodedAndContainingPlus(ParserType parserType) { void fromUriStringQueryParamEncodedAndContainingPlus(ParserType parserType) {
String httpUrl = "http://localhost:8080/test/print?value=%EA%B0%80+%EB%82%98"; String httpUrl = "http://localhost:8080/test/print?value=%EA%B0%80+%EB%82%98";
URI uri = UriComponentsBuilder.fromUriString(httpUrl, parserType).build(true).toUri(); URI uri = UriComponentsBuilder.fromUriString(httpUrl, parserType).build(true).toUri();
@ -243,7 +243,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // see SPR-10539 @ParameterizedTest // see SPR-10539
@EnumSource(value = ParserType.class) @EnumSource
void fromUriStringIPv6Host(ParserType parserType) { void fromUriStringIPv6Host(ParserType parserType) {
UriComponents result = UriComponentsBuilder UriComponents result = UriComponentsBuilder
.fromUriString("http://[1abc:2abc:3abc::5ABC:6abc]:8080/resource", parserType).build().encode(); .fromUriString("http://[1abc:2abc:3abc::5ABC:6abc]:8080/resource", parserType).build().encode();
@ -251,14 +251,14 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void fromUriStringInvalidIPv6Host(ParserType parserType) { void fromUriStringInvalidIPv6Host(ParserType parserType) {
assertThatIllegalArgumentException().isThrownBy(() -> assertThatIllegalArgumentException().isThrownBy(() ->
UriComponentsBuilder.fromUriString("http://[1abc:2abc:3abc::5ABC:6abc:8080/resource", parserType)); UriComponentsBuilder.fromUriString("http://[1abc:2abc:3abc::5ABC:6abc:8080/resource", parserType));
} }
@ParameterizedTest // see SPR-11970 @ParameterizedTest // see SPR-11970
@EnumSource(value = ParserType.class) @EnumSource
void fromUriStringNoPathWithReservedCharInQuery(ParserType parserType) { void fromUriStringNoPathWithReservedCharInQuery(ParserType parserType) {
UriComponents result = UriComponentsBuilder.fromUriString("https://example.com?foo=bar@baz", parserType).build(); UriComponents result = UriComponentsBuilder.fromUriString("https://example.com?foo=bar@baz", parserType).build();
assertThat(result.getUserInfo()).isNull(); assertThat(result.getUserInfo()).isNull();
@ -268,7 +268,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // see SPR-1428 @ParameterizedTest // see SPR-1428
@EnumSource(value = ParserType.class) @EnumSource
void fromHttpUrlQueryParamEncodedAndContainingPlus(ParserType parserType) { void fromHttpUrlQueryParamEncodedAndContainingPlus(ParserType parserType) {
String httpUrl = "http://localhost:8080/test/print?value=%EA%B0%80+%EB%82%98"; String httpUrl = "http://localhost:8080/test/print?value=%EA%B0%80+%EB%82%98";
URI uri = UriComponentsBuilder.fromUriString(httpUrl, parserType).build(true).toUri(); URI uri = UriComponentsBuilder.fromUriString(httpUrl, parserType).build(true).toUri();
@ -277,7 +277,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // see SPR-10779 @ParameterizedTest // see SPR-10779
@EnumSource(value = ParserType.class) @EnumSource
void fromHttpUrlCaseInsensitiveScheme(ParserType parserType) { void fromHttpUrlCaseInsensitiveScheme(ParserType parserType) {
assertThat(UriComponentsBuilder.fromUriString("HTTP://www.google.com", parserType).build().getScheme()) assertThat(UriComponentsBuilder.fromUriString("HTTP://www.google.com", parserType).build().getScheme())
.isEqualTo("http"); .isEqualTo("http");
@ -286,14 +286,14 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // see SPR-10539 @ParameterizedTest // see SPR-10539
@EnumSource(value = ParserType.class) @EnumSource
void fromHttpUrlInvalidIPv6Host(ParserType parserType) { void fromHttpUrlInvalidIPv6Host(ParserType parserType) {
assertThatIllegalArgumentException().isThrownBy(() -> assertThatIllegalArgumentException().isThrownBy(() ->
UriComponentsBuilder.fromUriString("http://[1abc:2abc:3abc::5ABC:6abc:8080/resource", parserType)); UriComponentsBuilder.fromUriString("http://[1abc:2abc:3abc::5ABC:6abc:8080/resource", parserType));
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void fromHttpUrlWithoutFragment(ParserType parserType) { void fromHttpUrlWithoutFragment(ParserType parserType) {
String httpUrl = "http://localhost:8080/test/print"; String httpUrl = "http://localhost:8080/test/print";
UriComponents uriComponents = UriComponentsBuilder.fromUriString(httpUrl, parserType).build(); UriComponents uriComponents = UriComponentsBuilder.fromUriString(httpUrl, parserType).build();
@ -333,7 +333,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // see gh-25300 @ParameterizedTest // see gh-25300
@EnumSource(value = ParserType.class) @EnumSource
void fromHttpUrlWithFragment(ParserType parserType) { void fromHttpUrlWithFragment(ParserType parserType) {
String httpUrl = "https://example.com/#baz"; String httpUrl = "https://example.com/#baz";
UriComponents uriComponents = UriComponentsBuilder.fromUriString(httpUrl, parserType).build(); UriComponents uriComponents = UriComponentsBuilder.fromUriString(httpUrl, parserType).build();
@ -449,7 +449,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void replacePath(ParserType parserType) { void replacePath(ParserType parserType) {
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString("https://www.ietf.org/rfc/rfc2396.txt", parserType); UriComponentsBuilder builder = UriComponentsBuilder.fromUriString("https://www.ietf.org/rfc/rfc2396.txt", parserType);
builder.replacePath("/rfc/rfc3986.txt"); builder.replacePath("/rfc/rfc3986.txt");
@ -465,7 +465,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void replaceQuery(ParserType parserType) { void replaceQuery(ParserType parserType) {
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString("https://example.com/foo?foo=bar&baz=qux", parserType); UriComponentsBuilder builder = UriComponentsBuilder.fromUriString("https://example.com/foo?foo=bar&baz=qux", parserType);
builder.replaceQuery("baz=42"); builder.replaceQuery("baz=42");
@ -605,7 +605,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void parseBuildAndExpandHierarchical(ParserType parserType) { void parseBuildAndExpandHierarchical(ParserType parserType) {
URI uri = UriComponentsBuilder URI uri = UriComponentsBuilder
.fromUriString("{scheme}://{host}:{port}/{segment}?{query}#{fragment}", parserType) .fromUriString("{scheme}://{host}:{port}/{segment}?{query}#{fragment}", parserType)
@ -617,7 +617,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void buildAndExpandOpaque(ParserType parserType) { void buildAndExpandOpaque(ParserType parserType) {
UriComponents result = UriComponentsBuilder.fromUriString("mailto:{user}@{domain}", parserType) UriComponents result = UriComponentsBuilder.fromUriString("mailto:{user}@{domain}", parserType)
.buildAndExpand("foo", "example.com"); .buildAndExpand("foo", "example.com");
@ -631,7 +631,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // gh-33699 @ParameterizedTest // gh-33699
@EnumSource(value = ParserType.class) @EnumSource
void schemeVariableMixedCase(ParserType parserType) { void schemeVariableMixedCase(ParserType parserType) {
BiConsumer<String, String> tester = (scheme, value) -> { BiConsumer<String, String> tester = (scheme, value) -> {
@ -647,7 +647,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void queryParamWithValueWithEquals(ParserType parserType) { void queryParamWithValueWithEquals(ParserType parserType) {
UriComponents uriComponents = UriComponentsBuilder.fromUriString("https://example.com/foo?bar=baz", parserType).build(); UriComponents uriComponents = UriComponentsBuilder.fromUriString("https://example.com/foo?bar=baz", parserType).build();
assertThat(uriComponents.toUriString()).isEqualTo("https://example.com/foo?bar=baz"); assertThat(uriComponents.toUriString()).isEqualTo("https://example.com/foo?bar=baz");
@ -655,7 +655,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void queryParamWithoutValueWithEquals(ParserType parserType) { void queryParamWithoutValueWithEquals(ParserType parserType) {
UriComponents uriComponents = UriComponentsBuilder.fromUriString("https://example.com/foo?bar=", parserType).build(); UriComponents uriComponents = UriComponentsBuilder.fromUriString("https://example.com/foo?bar=", parserType).build();
assertThat(uriComponents.toUriString()).isEqualTo("https://example.com/foo?bar="); assertThat(uriComponents.toUriString()).isEqualTo("https://example.com/foo?bar=");
@ -663,7 +663,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void queryParamWithoutValueWithoutEquals(ParserType parserType) { void queryParamWithoutValueWithoutEquals(ParserType parserType) {
UriComponents uriComponents = UriComponentsBuilder.fromUriString("https://example.com/foo?bar", parserType).build(); UriComponents uriComponents = UriComponentsBuilder.fromUriString("https://example.com/foo?bar", parserType).build();
assertThat(uriComponents.toUriString()).isEqualTo("https://example.com/foo?bar"); assertThat(uriComponents.toUriString()).isEqualTo("https://example.com/foo?bar");
@ -688,7 +688,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void relativeUrls(ParserType parserType) { void relativeUrls(ParserType parserType) {
String baseUrl = "https://example.com"; String baseUrl = "https://example.com";
assertThat(UriComponentsBuilder.fromUriString(baseUrl + "/foo/../bar", parserType).build().toString()) assertThat(UriComponentsBuilder.fromUriString(baseUrl + "/foo/../bar", parserType).build().toString())
@ -706,7 +706,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void emptySegments(ParserType parserType) { void emptySegments(ParserType parserType) {
String baseUrl = "https://example.com/abc/"; String baseUrl = "https://example.com/abc/";
assertThat(UriComponentsBuilder.fromUriString(baseUrl, parserType).path("/x/y/z").build().toString()) assertThat(UriComponentsBuilder.fromUriString(baseUrl, parserType).path("/x/y/z").build().toString())
@ -720,7 +720,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void parsesEmptyFragment(ParserType parserType) { void parsesEmptyFragment(ParserType parserType) {
UriComponents components = UriComponentsBuilder.fromUriString("/example#", parserType).build(); UriComponents components = UriComponentsBuilder.fromUriString("/example#", parserType).build();
assertThat(components.getFragment()).isNull(); assertThat(components.getFragment()).isNull();
@ -728,7 +728,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // SPR-13257 @ParameterizedTest // SPR-13257
@EnumSource(value = ParserType.class) @EnumSource
void parsesEmptyUri(ParserType parserType) { void parsesEmptyUri(ParserType parserType) {
UriComponents components = UriComponentsBuilder.fromUriString("", parserType).build(); UriComponents components = UriComponentsBuilder.fromUriString("", parserType).build();
assertThat(components.toString()).isEmpty(); assertThat(components.toString()).isEmpty();
@ -791,7 +791,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // gh-26466 @ParameterizedTest // gh-26466
@EnumSource(value = ParserType.class) @EnumSource
void encodeTemplateWithInvalidPlaceholderSyntax(ParserType parserType) { void encodeTemplateWithInvalidPlaceholderSyntax(ParserType parserType) {
BiConsumer<String, String> tester = (in, out) -> BiConsumer<String, String> tester = (in, out) ->
@ -821,7 +821,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // SPR-16364 @ParameterizedTest // SPR-16364
@EnumSource(value = ParserType.class) @EnumSource
void uriComponentsNotEqualAfterNormalization(ParserType parserType) { void uriComponentsNotEqualAfterNormalization(ParserType parserType) {
UriComponents uri1 = UriComponentsBuilder.fromUriString("http://test.com", parserType).build().normalize(); UriComponents uri1 = UriComponentsBuilder.fromUriString("http://test.com", parserType).build().normalize();
UriComponents uri2 = UriComponentsBuilder.fromUriString("http://test.com/", parserType).build(); UriComponents uri2 = UriComponentsBuilder.fromUriString("http://test.com/", parserType).build();
@ -832,7 +832,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // SPR-17256 @ParameterizedTest // SPR-17256
@EnumSource(value = ParserType.class) @EnumSource
void uriComponentsWithMergedQueryParams(ParserType parserType) { void uriComponentsWithMergedQueryParams(ParserType parserType) {
String uri = UriComponentsBuilder.fromUriString("http://localhost:8081", parserType) String uri = UriComponentsBuilder.fromUriString("http://localhost:8081", parserType)
.uriComponents(UriComponentsBuilder.fromUriString("/{path}?sort={sort}", parserType).build()) .uriComponents(UriComponentsBuilder.fromUriString("/{path}?sort={sort}", parserType).build())
@ -842,7 +842,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // SPR-17630 @ParameterizedTest // SPR-17630
@EnumSource(value = ParserType.class) @EnumSource
void toUriStringWithCurlyBraces(ParserType parserType) { void toUriStringWithCurlyBraces(ParserType parserType) {
assertThat(UriComponentsBuilder.fromUriString("/path?q={asa}asa", parserType).toUriString()) assertThat(UriComponentsBuilder.fromUriString("/path?q={asa}asa", parserType).toUriString())
.isEqualTo("/path?q=%7Basa%7Dasa"); .isEqualTo("/path?q=%7Basa%7Dasa");
@ -855,7 +855,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void validPort(ParserType parserType) { void validPort(ParserType parserType) {
UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://localhost:52567/path", parserType).build(); UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://localhost:52567/path", parserType).build();
assertThat(uriComponents.getPort()).isEqualTo(52567); assertThat(uriComponents.getPort()).isEqualTo(52567);
@ -871,7 +871,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void verifyInvalidPort(ParserType parserType) { void verifyInvalidPort(ParserType parserType) {
String url = "http://localhost:XXX/path"; String url = "http://localhost:XXX/path";
assertThatIllegalArgumentException() assertThatIllegalArgumentException()
@ -881,7 +881,7 @@ class UriComponentsBuilderTests {
} }
@ParameterizedTest // gh-27039 @ParameterizedTest // gh-27039
@EnumSource(value = ParserType.class) @EnumSource
void expandPortAndPathWithoutSeparator(ParserType parserType) { void expandPortAndPathWithoutSeparator(ParserType parserType) {
URI uri = UriComponentsBuilder URI uri = UriComponentsBuilder
.fromUriString("ws://localhost:{port}/{path}", parserType) .fromUriString("ws://localhost:{port}/{path}", parserType)

View File

@ -79,28 +79,28 @@ class UriComponentsTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void toUriEncoded(ParserType parserType) { void toUriEncoded(ParserType parserType) {
UriComponents uri = UriComponentsBuilder.fromUriString("https://example.com/hotel list/Z\u00fcrich", parserType).build(); UriComponents uri = UriComponentsBuilder.fromUriString("https://example.com/hotel list/Z\u00fcrich", parserType).build();
assertThat(uri.encode().toUri()).isEqualTo(URI.create("https://example.com/hotel%20list/Z%C3%BCrich")); assertThat(uri.encode().toUri()).isEqualTo(URI.create("https://example.com/hotel%20list/Z%C3%BCrich"));
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void toUriNotEncoded(ParserType parserType) { void toUriNotEncoded(ParserType parserType) {
UriComponents uri = UriComponentsBuilder.fromUriString("https://example.com/hotel list/Z\u00fcrich", parserType).build(); UriComponents uri = UriComponentsBuilder.fromUriString("https://example.com/hotel list/Z\u00fcrich", parserType).build();
assertThat(uri.toUri()).isEqualTo(URI.create("https://example.com/hotel%20list/Z\u00fcrich")); assertThat(uri.toUri()).isEqualTo(URI.create("https://example.com/hotel%20list/Z\u00fcrich"));
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void toUriAlreadyEncoded(ParserType parserType) { void toUriAlreadyEncoded(ParserType parserType) {
UriComponents uri = UriComponentsBuilder.fromUriString("https://example.com/hotel%20list/Z%C3%BCrich", parserType).build(true); UriComponents uri = UriComponentsBuilder.fromUriString("https://example.com/hotel%20list/Z%C3%BCrich", parserType).build(true);
assertThat(uri.encode().toUri()).isEqualTo(URI.create("https://example.com/hotel%20list/Z%C3%BCrich")); assertThat(uri.encode().toUri()).isEqualTo(URI.create("https://example.com/hotel%20list/Z%C3%BCrich"));
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void toUriWithIpv6HostAlreadyEncoded(ParserType parserType) { void toUriWithIpv6HostAlreadyEncoded(ParserType parserType) {
UriComponents uri = UriComponentsBuilder.fromUriString( UriComponents uri = UriComponentsBuilder.fromUriString(
"http://[1abc:2abc:3abc::5ABC:6abc]:8080/hotel%20list/Z%C3%BCrich", parserType).build(true); "http://[1abc:2abc:3abc::5ABC:6abc]:8080/hotel%20list/Z%C3%BCrich", parserType).build(true);
@ -110,14 +110,14 @@ class UriComponentsTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void toUriStringWithPortVariable(ParserType parserType) { void toUriStringWithPortVariable(ParserType parserType) {
String url = "http://localhost:{port}/first"; String url = "http://localhost:{port}/first";
assertThat(UriComponentsBuilder.fromUriString(url, parserType).build().toUriString()).isEqualTo(url); assertThat(UriComponentsBuilder.fromUriString(url, parserType).build().toUriString()).isEqualTo(url);
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void expand(ParserType parserType) { void expand(ParserType parserType) {
UriComponents uri = UriComponentsBuilder.fromUriString("https://example.com", parserType).path("/{foo} {bar}").build(); UriComponents uri = UriComponentsBuilder.fromUriString("https://example.com", parserType).path("/{foo} {bar}").build();
uri = uri.expand("1 2", "3 4"); uri = uri.expand("1 2", "3 4");
@ -127,7 +127,7 @@ class UriComponentsTests {
} }
@ParameterizedTest // SPR-13311 @ParameterizedTest // SPR-13311
@EnumSource(value = ParserType.class) @EnumSource
void expandWithRegexVar(ParserType parserType) { void expandWithRegexVar(ParserType parserType) {
String template = "/myurl/{name:[a-z]{1,5}}/show"; String template = "/myurl/{name:[a-z]{1,5}}/show";
UriComponents uri = UriComponentsBuilder.fromUriString(template, parserType).build(); UriComponents uri = UriComponentsBuilder.fromUriString(template, parserType).build();
@ -137,14 +137,14 @@ class UriComponentsTests {
} }
@ParameterizedTest // SPR-17630 @ParameterizedTest // SPR-17630
@EnumSource(value = ParserType.class) @EnumSource
void uirTemplateExpandWithMismatchedCurlyBraces(ParserType parserType) { void uirTemplateExpandWithMismatchedCurlyBraces(ParserType parserType) {
UriComponents uri = UriComponentsBuilder.fromUriString("/myurl/?q={{{{", parserType).encode().build(); UriComponents uri = UriComponentsBuilder.fromUriString("/myurl/?q={{{{", parserType).encode().build();
assertThat(uri.toUriString()).isEqualTo("/myurl/?q=%7B%7B%7B%7B"); assertThat(uri.toUriString()).isEqualTo("/myurl/?q=%7B%7B%7B%7B");
} }
@ParameterizedTest // gh-22447 @ParameterizedTest // gh-22447
@EnumSource(value = ParserType.class) @EnumSource
void expandWithFragmentOrder(ParserType parserType) { void expandWithFragmentOrder(ParserType parserType) {
UriComponents uri = UriComponentsBuilder UriComponents uri = UriComponentsBuilder
.fromUriString("https://{host}/{path}#{fragment}", parserType).build() .fromUriString("https://{host}/{path}#{fragment}", parserType).build()
@ -154,7 +154,7 @@ class UriComponentsTests {
} }
@ParameterizedTest // SPR-12123 @ParameterizedTest // SPR-12123
@EnumSource(value = ParserType.class) @EnumSource
void port(ParserType parserType) { void port(ParserType parserType) {
UriComponents uri1 = fromUriString("https://example.com:8080/bar", parserType).build(); UriComponents uri1 = fromUriString("https://example.com:8080/bar", parserType).build();
UriComponents uri2 = fromUriString("https://example.com/bar", parserType).port(8080).build(); UriComponents uri2 = fromUriString("https://example.com/bar", parserType).port(8080).build();
@ -172,7 +172,7 @@ class UriComponentsTests {
} }
@ParameterizedTest // gh-28521 @ParameterizedTest // gh-28521
@EnumSource(value = ParserType.class) @EnumSource
void invalidPort(ParserType parserType) { void invalidPort(ParserType parserType) {
assertThatExceptionOfType(InvalidUrlException.class) assertThatExceptionOfType(InvalidUrlException.class)
.isThrownBy(() -> fromUriString("https://example.com:XXX/bar", parserType)); .isThrownBy(() -> fromUriString("https://example.com:XXX/bar", parserType));
@ -207,14 +207,14 @@ class UriComponentsTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void normalize(ParserType parserType) { void normalize(ParserType parserType) {
UriComponents uri = UriComponentsBuilder.fromUriString("https://example.com/foo/../bar", parserType).build(); UriComponents uri = UriComponentsBuilder.fromUriString("https://example.com/foo/../bar", parserType).build();
assertThat(uri.normalize().toString()).isEqualTo("https://example.com/bar"); assertThat(uri.normalize().toString()).isEqualTo("https://example.com/bar");
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void serializable(ParserType parserType) throws Exception { void serializable(ParserType parserType) throws Exception {
UriComponents uri = UriComponentsBuilder.fromUriString( UriComponents uri = UriComponentsBuilder.fromUriString(
"https://example.com", parserType).path("/{foo}").query("bar={baz}").build(); "https://example.com", parserType).path("/{foo}").query("bar={baz}").build();
@ -240,7 +240,7 @@ class UriComponentsTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void equalsHierarchicalUriComponents(ParserType parserType) { void equalsHierarchicalUriComponents(ParserType parserType) {
String url = "https://example.com"; String url = "https://example.com";
UriComponents uric1 = UriComponentsBuilder.fromUriString(url, parserType).path("/{foo}").query("bar={baz}").build(); UriComponents uric1 = UriComponentsBuilder.fromUriString(url, parserType).path("/{foo}").query("bar={baz}").build();
@ -254,7 +254,7 @@ class UriComponentsTests {
} }
@ParameterizedTest @ParameterizedTest
@EnumSource(value = ParserType.class) @EnumSource
void equalsOpaqueUriComponents(ParserType parserType) { void equalsOpaqueUriComponents(ParserType parserType) {
String baseUrl = "http:example.com"; String baseUrl = "http:example.com";
UriComponents uric1 = UriComponentsBuilder.fromUriString(baseUrl + "/foo/bar", parserType).build(); UriComponents uric1 = UriComponentsBuilder.fromUriString(baseUrl + "/foo/bar", parserType).build();