From 325edbec7d62f85c4f9c6bafee54c1d72cdac49e Mon Sep 17 00:00:00 2001 From: Mihai Dumitrescu Date: Fri, 29 May 2020 00:47:53 +0200 Subject: [PATCH 1/2] Add additional tests for MultiValueMap See gh-25140 See gh-25160 --- .../util/CollectionUtilsTests.java | 26 +++ .../util/MultiValueMapRelatedTests.java | 214 ++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 spring-core/src/test/java/org/springframework/util/MultiValueMapRelatedTests.java diff --git a/spring-core/src/test/java/org/springframework/util/CollectionUtilsTests.java b/spring-core/src/test/java/org/springframework/util/CollectionUtilsTests.java index ac9999ff1fbe..28264d8fcb1e 100644 --- a/spring-core/src/test/java/org/springframework/util/CollectionUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/CollectionUtilsTests.java @@ -17,6 +17,7 @@ package org.springframework.util; import java.util.ArrayList; +import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; @@ -211,6 +212,31 @@ void hasUniqueObject() { assertThat(CollectionUtils.hasUniqueObject(list)).isFalse(); } + @Test + void conversionOfEmptyMap() { + MultiValueMap> asMultiValueMap = CollectionUtils.toMultiValueMap(new HashMap<>()); + assertThat(asMultiValueMap.isEmpty()).isTrue(); + assertThat(asMultiValueMap).isEmpty(); + } + + @Test + void conversionOfNonEmptyMap() { + Map> wrapped = new HashMap<>(); + wrapped.put("key", Arrays.asList("first", "second")); + MultiValueMap asMultiValueMap = CollectionUtils.toMultiValueMap(wrapped); + assertThat(asMultiValueMap).containsAllEntriesOf(wrapped); + } + + @Test + void changesValueByReference() { + Map> wrapped = new HashMap<>(); + MultiValueMap asMultiValueMap = CollectionUtils.toMultiValueMap(wrapped); + assertThat(asMultiValueMap).doesNotContainKeys("key"); + wrapped.put("key", new ArrayList<>()); + + assertThat(asMultiValueMap).containsKey("key"); + } + private static final class Instance { diff --git a/spring-core/src/test/java/org/springframework/util/MultiValueMapRelatedTests.java b/spring-core/src/test/java/org/springframework/util/MultiValueMapRelatedTests.java new file mode 100644 index 000000000000..686d77a1a2d5 --- /dev/null +++ b/spring-core/src/test/java/org/springframework/util/MultiValueMapRelatedTests.java @@ -0,0 +1,214 @@ +/* + * Copyright 2002-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.util; + +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Mihai Dumitrescu + * @author Arjen Poutsma + * @author Juergen Hoeller + */ +class MultiValueMapRelatedTests { + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void add(MultiValueMap objectUnderTest) { + int startingSize = objectUnderTest.size(); + objectUnderTest.add("key", "value1"); + objectUnderTest.add("key", "value2"); + assertThat(objectUnderTest).hasSize(startingSize + 1); + assertThat(objectUnderTest.get("key")).containsExactly("value1", "value2"); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void addIfAbsentWhenAbsent(MultiValueMap objectUnderTest) { + objectUnderTest.addIfAbsent("key", "value1"); + assertThat(objectUnderTest.get("key")).containsExactly("value1"); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void addIfAbsentWhenPresent(MultiValueMap objectUnderTest) { + objectUnderTest.add("key", "value1"); + objectUnderTest.addIfAbsent("key", "value2"); + assertThat(objectUnderTest.get("key")).containsExactly("value1"); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void set(MultiValueMap objectUnderTest) { + objectUnderTest.set("key", "value1"); + objectUnderTest.set("key", "value2"); + assertThat(objectUnderTest.get("key")).containsExactly("value2"); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void addAll(MultiValueMap objectUnderTest) { + int startingSize = objectUnderTest.size(); + + objectUnderTest.add("key", "value1"); + objectUnderTest.addAll("key", Arrays.asList("value2", "value3")); + assertThat(objectUnderTest).hasSize(startingSize + 1); + assertThat(objectUnderTest.get("key")).containsExactly("value1", "value2", "value3"); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + @Disabled("to be fixed in gh-25140") + void addAllWithEmptyList(MultiValueMap objectUnderTest) { + objectUnderTest.addAll("key", Collections.emptyList()); + assertThat(objectUnderTest).hasSize(1); + assertThat(objectUnderTest.get("key")).isEmpty(); + assertThat(objectUnderTest.getFirst("key")).isNull(); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void getFirst(MultiValueMap objectUnderTest) { + List values = new ArrayList<>(2); + values.add("value1"); + values.add("value2"); + objectUnderTest.put("key", values); + assertThat(objectUnderTest.getFirst("key")).isEqualTo("value1"); + assertThat(objectUnderTest.getFirst("other")).isNull(); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void toSingleValueMap(MultiValueMap objectUnderTest) { + + int startingSize = objectUnderTest.size(); + + List values = new ArrayList<>(2); + values.add("value1"); + values.add("value2"); + objectUnderTest.put("key", values); + Map singleValueMap = objectUnderTest.toSingleValueMap(); + assertThat(singleValueMap).hasSize(startingSize + 1); + assertThat(singleValueMap.get("key")).isEqualTo("value1"); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + @Disabled("to be fixed in gh-25140") + void toSingleValueMapWithEmptyList(MultiValueMap objectUnderTest) { + objectUnderTest.put("key", Collections.emptyList()); + Map singleValueMap = objectUnderTest.toSingleValueMap(); + assertThat(singleValueMap).isEmpty(); + assertThat(singleValueMap.get("key")).isNull(); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void equalsOnExistingValues(MultiValueMap objectUnderTest) { + objectUnderTest.clear(); + objectUnderTest.set("key1", "value1"); + assertThat(objectUnderTest).isEqualTo(objectUnderTest); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void equalsOnEmpty(MultiValueMap objectUnderTest) { + objectUnderTest.clear(); + objectUnderTest.set("key1", "value1"); + MultiValueMap o1 = new LinkedMultiValueMap<>(); + o1.set("key1", "value1"); + assertThat(o1).isEqualTo(objectUnderTest); + assertThat(objectUnderTest).isEqualTo(o1); + Map> o2 = new HashMap<>(); + o2.put("key1", Collections.singletonList("value1")); + assertThat(o2).isEqualTo(objectUnderTest); + assertThat(objectUnderTest).isEqualTo(o2); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void canNotChangeAnUnmodifiableMultiValueMap(MultiValueMap objectUnderTest) { + MultiValueMap asUnmodifiableMultiValueMap = CollectionUtils.unmodifiableMultiValueMap(objectUnderTest); + Assertions.assertAll( + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.add("key", "value")), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.addIfAbsent("key", "value")), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.addAll("key", exampleListOfValues())), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.addAll(exampleMultiValueMap())), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.set("key", "value")), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.setAll(exampleHashMap())), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.put("key", exampleListOfValues())), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.putIfAbsent("key", exampleListOfValues())), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.putAll(exampleMultiValueMap())), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.remove("key1")) + ); + + } + + @NotNull + private List exampleListOfValues() { + return Arrays.asList("value1", "value2"); + } + + @NotNull + private HashMap exampleHashMap() { + return new HashMap() {{ + put("key2", "key2.value1"); + }}; + } + + private MultiValueMap exampleMultiValueMap() { + return new LinkedMultiValueMap() {{ + put("key1", Arrays.asList("key1.value1", "key1.value2")); + }}; + } + + static Stream> objectsUnderTest() { + return Stream.of( + new LinkedMultiValueMap<>(), + new LinkedMultiValueMap<>(new HashMap<>()), + new LinkedMultiValueMap<>(new LinkedHashMap<>()), + new LinkedMultiValueMap<>(new HashMap>(){{ + put("existingkey", Arrays.asList("existingvalue1", "existingvalue2")); + }}), + CollectionUtils.toMultiValueMap(new HashMap<>())); + } + +} From 352c7cd8b33c9b4d566b8c5425ce0de27f2cd957 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 25 Aug 2023 11:44:35 +0200 Subject: [PATCH 2/2] Polish "Add additional tests for MultiValueMap" See gh-25160 --- .../util/CollectionUtilsTests.java | 5 +- .../util/MultiValueMapRelatedTests.java | 214 ------------------ .../util/MultiValueMapTests.java | 198 ++++++++++++++++ 3 files changed, 201 insertions(+), 216 deletions(-) delete mode 100644 spring-core/src/test/java/org/springframework/util/MultiValueMapRelatedTests.java create mode 100644 spring-core/src/test/java/org/springframework/util/MultiValueMapTests.java diff --git a/spring-core/src/test/java/org/springframework/util/CollectionUtilsTests.java b/spring-core/src/test/java/org/springframework/util/CollectionUtilsTests.java index 28264d8fcb1e..325c76ad64ea 100644 --- a/spring-core/src/test/java/org/springframework/util/CollectionUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/CollectionUtilsTests.java @@ -35,6 +35,8 @@ import static org.assertj.core.api.Assertions.assertThat; /** + * Tests for {@link CollectionUtils}. + * * @author Rob Harrop * @author Juergen Hoeller * @author Rick Evans @@ -214,7 +216,7 @@ void hasUniqueObject() { @Test void conversionOfEmptyMap() { - MultiValueMap> asMultiValueMap = CollectionUtils.toMultiValueMap(new HashMap<>()); + MultiValueMap asMultiValueMap = CollectionUtils.toMultiValueMap(new HashMap<>()); assertThat(asMultiValueMap.isEmpty()).isTrue(); assertThat(asMultiValueMap).isEmpty(); } @@ -233,7 +235,6 @@ void changesValueByReference() { MultiValueMap asMultiValueMap = CollectionUtils.toMultiValueMap(wrapped); assertThat(asMultiValueMap).doesNotContainKeys("key"); wrapped.put("key", new ArrayList<>()); - assertThat(asMultiValueMap).containsKey("key"); } diff --git a/spring-core/src/test/java/org/springframework/util/MultiValueMapRelatedTests.java b/spring-core/src/test/java/org/springframework/util/MultiValueMapRelatedTests.java deleted file mode 100644 index 686d77a1a2d5..000000000000 --- a/spring-core/src/test/java/org/springframework/util/MultiValueMapRelatedTests.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2002-2020 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util; - -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Mihai Dumitrescu - * @author Arjen Poutsma - * @author Juergen Hoeller - */ -class MultiValueMapRelatedTests { - - @ParameterizedTest - @MethodSource("objectsUnderTest") - void add(MultiValueMap objectUnderTest) { - int startingSize = objectUnderTest.size(); - objectUnderTest.add("key", "value1"); - objectUnderTest.add("key", "value2"); - assertThat(objectUnderTest).hasSize(startingSize + 1); - assertThat(objectUnderTest.get("key")).containsExactly("value1", "value2"); - } - - @ParameterizedTest - @MethodSource("objectsUnderTest") - void addIfAbsentWhenAbsent(MultiValueMap objectUnderTest) { - objectUnderTest.addIfAbsent("key", "value1"); - assertThat(objectUnderTest.get("key")).containsExactly("value1"); - } - - @ParameterizedTest - @MethodSource("objectsUnderTest") - void addIfAbsentWhenPresent(MultiValueMap objectUnderTest) { - objectUnderTest.add("key", "value1"); - objectUnderTest.addIfAbsent("key", "value2"); - assertThat(objectUnderTest.get("key")).containsExactly("value1"); - } - - @ParameterizedTest - @MethodSource("objectsUnderTest") - void set(MultiValueMap objectUnderTest) { - objectUnderTest.set("key", "value1"); - objectUnderTest.set("key", "value2"); - assertThat(objectUnderTest.get("key")).containsExactly("value2"); - } - - @ParameterizedTest - @MethodSource("objectsUnderTest") - void addAll(MultiValueMap objectUnderTest) { - int startingSize = objectUnderTest.size(); - - objectUnderTest.add("key", "value1"); - objectUnderTest.addAll("key", Arrays.asList("value2", "value3")); - assertThat(objectUnderTest).hasSize(startingSize + 1); - assertThat(objectUnderTest.get("key")).containsExactly("value1", "value2", "value3"); - } - - @ParameterizedTest - @MethodSource("objectsUnderTest") - @Disabled("to be fixed in gh-25140") - void addAllWithEmptyList(MultiValueMap objectUnderTest) { - objectUnderTest.addAll("key", Collections.emptyList()); - assertThat(objectUnderTest).hasSize(1); - assertThat(objectUnderTest.get("key")).isEmpty(); - assertThat(objectUnderTest.getFirst("key")).isNull(); - } - - @ParameterizedTest - @MethodSource("objectsUnderTest") - void getFirst(MultiValueMap objectUnderTest) { - List values = new ArrayList<>(2); - values.add("value1"); - values.add("value2"); - objectUnderTest.put("key", values); - assertThat(objectUnderTest.getFirst("key")).isEqualTo("value1"); - assertThat(objectUnderTest.getFirst("other")).isNull(); - } - - @ParameterizedTest - @MethodSource("objectsUnderTest") - void toSingleValueMap(MultiValueMap objectUnderTest) { - - int startingSize = objectUnderTest.size(); - - List values = new ArrayList<>(2); - values.add("value1"); - values.add("value2"); - objectUnderTest.put("key", values); - Map singleValueMap = objectUnderTest.toSingleValueMap(); - assertThat(singleValueMap).hasSize(startingSize + 1); - assertThat(singleValueMap.get("key")).isEqualTo("value1"); - } - - @ParameterizedTest - @MethodSource("objectsUnderTest") - @Disabled("to be fixed in gh-25140") - void toSingleValueMapWithEmptyList(MultiValueMap objectUnderTest) { - objectUnderTest.put("key", Collections.emptyList()); - Map singleValueMap = objectUnderTest.toSingleValueMap(); - assertThat(singleValueMap).isEmpty(); - assertThat(singleValueMap.get("key")).isNull(); - } - - @ParameterizedTest - @MethodSource("objectsUnderTest") - void equalsOnExistingValues(MultiValueMap objectUnderTest) { - objectUnderTest.clear(); - objectUnderTest.set("key1", "value1"); - assertThat(objectUnderTest).isEqualTo(objectUnderTest); - } - - @ParameterizedTest - @MethodSource("objectsUnderTest") - void equalsOnEmpty(MultiValueMap objectUnderTest) { - objectUnderTest.clear(); - objectUnderTest.set("key1", "value1"); - MultiValueMap o1 = new LinkedMultiValueMap<>(); - o1.set("key1", "value1"); - assertThat(o1).isEqualTo(objectUnderTest); - assertThat(objectUnderTest).isEqualTo(o1); - Map> o2 = new HashMap<>(); - o2.put("key1", Collections.singletonList("value1")); - assertThat(o2).isEqualTo(objectUnderTest); - assertThat(objectUnderTest).isEqualTo(o2); - } - - @ParameterizedTest - @MethodSource("objectsUnderTest") - void canNotChangeAnUnmodifiableMultiValueMap(MultiValueMap objectUnderTest) { - MultiValueMap asUnmodifiableMultiValueMap = CollectionUtils.unmodifiableMultiValueMap(objectUnderTest); - Assertions.assertAll( - () -> Assertions.assertThrows(UnsupportedOperationException.class, - () -> asUnmodifiableMultiValueMap.add("key", "value")), - () -> Assertions.assertThrows(UnsupportedOperationException.class, - () -> asUnmodifiableMultiValueMap.addIfAbsent("key", "value")), - () -> Assertions.assertThrows(UnsupportedOperationException.class, - () -> asUnmodifiableMultiValueMap.addAll("key", exampleListOfValues())), - () -> Assertions.assertThrows(UnsupportedOperationException.class, - () -> asUnmodifiableMultiValueMap.addAll(exampleMultiValueMap())), - () -> Assertions.assertThrows(UnsupportedOperationException.class, - () -> asUnmodifiableMultiValueMap.set("key", "value")), - () -> Assertions.assertThrows(UnsupportedOperationException.class, - () -> asUnmodifiableMultiValueMap.setAll(exampleHashMap())), - () -> Assertions.assertThrows(UnsupportedOperationException.class, - () -> asUnmodifiableMultiValueMap.put("key", exampleListOfValues())), - () -> Assertions.assertThrows(UnsupportedOperationException.class, - () -> asUnmodifiableMultiValueMap.putIfAbsent("key", exampleListOfValues())), - () -> Assertions.assertThrows(UnsupportedOperationException.class, - () -> asUnmodifiableMultiValueMap.putAll(exampleMultiValueMap())), - () -> Assertions.assertThrows(UnsupportedOperationException.class, - () -> asUnmodifiableMultiValueMap.remove("key1")) - ); - - } - - @NotNull - private List exampleListOfValues() { - return Arrays.asList("value1", "value2"); - } - - @NotNull - private HashMap exampleHashMap() { - return new HashMap() {{ - put("key2", "key2.value1"); - }}; - } - - private MultiValueMap exampleMultiValueMap() { - return new LinkedMultiValueMap() {{ - put("key1", Arrays.asList("key1.value1", "key1.value2")); - }}; - } - - static Stream> objectsUnderTest() { - return Stream.of( - new LinkedMultiValueMap<>(), - new LinkedMultiValueMap<>(new HashMap<>()), - new LinkedMultiValueMap<>(new LinkedHashMap<>()), - new LinkedMultiValueMap<>(new HashMap>(){{ - put("existingkey", Arrays.asList("existingvalue1", "existingvalue2")); - }}), - CollectionUtils.toMultiValueMap(new HashMap<>())); - } - -} diff --git a/spring-core/src/test/java/org/springframework/util/MultiValueMapTests.java b/spring-core/src/test/java/org/springframework/util/MultiValueMapTests.java new file mode 100644 index 000000000000..0f7128fbf2e4 --- /dev/null +++ b/spring-core/src/test/java/org/springframework/util/MultiValueMapTests.java @@ -0,0 +1,198 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.util; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link MultiValueMap}. + * + * @author Mihai Dumitrescu + * @author Arjen Poutsma + * @author Juergen Hoeller + * @author Stephane Nicoll + */ +class MultiValueMapTests { + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void add(MultiValueMap map) { + int initialSize = map.size(); + map.add("key", "value1"); + map.add("key", "value2"); + assertThat(map).hasSize(initialSize + 1); + assertThat(map.get("key")).containsExactly("value1", "value2"); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void addIfAbsentWhenAbsent(MultiValueMap map) { + map.addIfAbsent("key", "value1"); + assertThat(map.get("key")).containsExactly("value1"); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void addIfAbsentWhenPresent(MultiValueMap map) { + map.add("key", "value1"); + map.addIfAbsent("key", "value2"); + assertThat(map.get("key")).containsExactly("value1"); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void set(MultiValueMap map) { + map.set("key", "value1"); + map.set("key", "value2"); + assertThat(map.get("key")).containsExactly("value2"); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void addAll(MultiValueMap map) { + int initialSize = map.size(); + map.add("key", "value1"); + map.addAll("key", Arrays.asList("value2", "value3")); + assertThat(map).hasSize(initialSize + 1); + assertThat(map.get("key")).containsExactly("value1", "value2", "value3"); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void addAllWithEmptyList(MultiValueMap map) { + int initialSize = map.size(); + map.addAll("key", Collections.emptyList()); + assertThat(map).hasSize(initialSize + 1); + assertThat(map.get("key")).isEmpty(); + assertThat(map.getFirst("key")).isNull(); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void getFirst(MultiValueMap map) { + List values = List.of("value1", "value2"); + map.put("key", values); + assertThat(map.getFirst("key")).isEqualTo("value1"); + assertThat(map.getFirst("other")).isNull(); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void toSingleValueMap(MultiValueMap map) { + int initialSize = map.size(); + List values = List.of("value1", "value2"); + map.put("key", values); + Map singleValueMap = map.toSingleValueMap(); + assertThat(singleValueMap).hasSize(initialSize + 1); + assertThat(singleValueMap.get("key")).isEqualTo("value1"); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void toSingleValueMapWithEmptyList(MultiValueMap map) { + int initialSize = map.size(); + map.put("key", Collections.emptyList()); + Map singleValueMap = map.toSingleValueMap(); + assertThat(singleValueMap).hasSize(initialSize); + assertThat(singleValueMap.get("key")).isNull(); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void equalsOnExistingValues(MultiValueMap map) { + map.clear(); + map.set("key1", "value1"); + assertThat(map).isEqualTo(map); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void equalsOnEmpty(MultiValueMap map) { + map.clear(); + map.set("key1", "value1"); + MultiValueMap o1 = new LinkedMultiValueMap<>(); + o1.set("key1", "value1"); + assertThat(o1).isEqualTo(map); + assertThat(map).isEqualTo(o1); + Map> o2 = new HashMap<>(); + o2.put("key1", Collections.singletonList("value1")); + assertThat(o2).isEqualTo(map); + assertThat(map).isEqualTo(o2); + } + + @ParameterizedTest + @MethodSource("objectsUnderTest") + void canNotChangeAnUnmodifiableMultiValueMap(MultiValueMap map) { + MultiValueMap asUnmodifiableMultiValueMap = CollectionUtils.unmodifiableMultiValueMap(map); + Assertions.assertAll( + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.add("key", "value")), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.addIfAbsent("key", "value")), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.addAll("key", exampleListOfValues())), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.addAll(exampleMultiValueMap())), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.set("key", "value")), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.setAll(exampleHashMap())), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.put("key", exampleListOfValues())), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.putIfAbsent("key", exampleListOfValues())), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.putAll(exampleMultiValueMap())), + () -> Assertions.assertThrows(UnsupportedOperationException.class, + () -> asUnmodifiableMultiValueMap.remove("key1"))); + + } + + private List exampleListOfValues() { + return List.of("value1", "value2"); + } + + private Map exampleHashMap() { + return Map.of("key2", "key2.value1"); + } + + private MultiValueMap exampleMultiValueMap() { + LinkedMultiValueMap map = new LinkedMultiValueMap<>(); + map.put("key1", Arrays.asList("key1.value1", "key1.value2")); + return map; + } + + static Stream> objectsUnderTest() { + return Stream.of(new LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(new HashMap<>()), + new LinkedMultiValueMap<>(new LinkedHashMap<>()), + new LinkedMultiValueMap<>(Map.of("existingkey", Arrays.asList("existingvalue1", "existingvalue2"))), + CollectionUtils.toMultiValueMap(new HashMap<>())); + } + +}