From 8afe83e8df8cd2737af3463a04ce970f5ec173a7 Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 21 Oct 2025 14:40:53 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E5=AE=8C=E5=96=84=20`MapModifier`=20?= =?UTF-8?q?=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commons/collection/MapModifierTests.java | 228 ++++++++++++++++-- 1 file changed, 213 insertions(+), 15 deletions(-) diff --git a/plusone-commons/src/test/java/xyz/zhouxy/plusone/commons/collection/MapModifierTests.java b/plusone-commons/src/test/java/xyz/zhouxy/plusone/commons/collection/MapModifierTests.java index d1117d3..d372d27 100644 --- a/plusone-commons/src/test/java/xyz/zhouxy/plusone/commons/collection/MapModifierTests.java +++ b/plusone-commons/src/test/java/xyz/zhouxy/plusone/commons/collection/MapModifierTests.java @@ -16,36 +16,42 @@ package xyz.zhouxy.plusone.commons.collection; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import javax.annotation.Nullable; + import org.junit.jupiter.api.Test; import com.google.common.collect.ImmutableMap; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; -// TODO 完善单元测试 @Slf4j public class MapModifierTests { private static final String APP_START_ID = UUID.randomUUID().toString(); private static final String LOCKED = "LOCKED"; - private static final Map commonProperties = ImmutableMap.builder() + private static final Map commonProperties = ImmutableMap.builder() .put("channel", "MOBILE") .put("appStartId", APP_START_ID) .build(); @Test - void initMap() { - Map expected = new HashMap() { + void demo() { + Map expected = new HashMap() { { put("channel", "MOBILE"); put("appStartId", APP_START_ID); @@ -55,31 +61,33 @@ public class MapModifierTests { }; // MapModifier - MapModifier modifier = new MapModifier() + MapModifier modifier = new MapModifier() .putAll(commonProperties) .put("username", "Ben") .put("accountStatus", LOCKED); // 从 Supplier 中获取 Map,并修改数据 - HashMap hashMap1 = modifier.getAndModify(HashMap::new); + HashMap hashMap1 = modifier.getAndModify(HashMap::new); assertEquals(expected, hashMap1); // 可以灵活使用不同 Map 类型的不同构造器 - HashMap hashMap2 = modifier.getAndModify(() -> new HashMap<>(8)); + HashMap hashMap2 = modifier.getAndModify(() -> new HashMap<>(8)); assertEquals(expected, hashMap2); - // HashMap hashMap3 = modifier.getAndModify(() -> new HashMap<>(anotherMap)); - TreeMap treeMap = modifier.getAndModify(TreeMap::new); + // HashMap hashMap3 = modifier.getAndModify(() -> new HashMap<>(anotherMap)); + TreeMap treeMap = modifier.getAndModify(TreeMap::new); assertEquals(expected, treeMap); - ConcurrentHashMap concurrentHashMap = modifier.getAndModify(ConcurrentHashMap::new); + ConcurrentHashMap concurrentHashMap = modifier.getAndModify(ConcurrentHashMap::new); assertEquals(expected, concurrentHashMap); + assertNull(modifier.getAndModify(() -> (Map) null)); + // 修改已有的 Map - Map srcMap = new HashMap<>(); + Map srcMap = new HashMap<>(); srcMap.put("srcKey1", "srcValue1"); srcMap.put("srcKey2", "srcValue2"); modifier.modify(srcMap); - assertEquals(new HashMap() { + assertEquals(new HashMap() { { putAll(commonProperties); put("username", "Ben"); @@ -89,8 +97,10 @@ public class MapModifierTests { } }, srcMap); + assertDoesNotThrow(() -> modifier.modify((Map) null)); + // 创建一个有初始化数据的不可变的 {@code Map} - Map unmodifiableMap = modifier.getUnmodifiableMap(); + Map unmodifiableMap = modifier.getUnmodifiableMap(); assertEquals(expected, unmodifiableMap); assertThrows(UnsupportedOperationException.class, () -> unmodifiableMap.put("key", "value")); @@ -99,13 +109,13 @@ public class MapModifierTests { @Test void createAndInitData() { // 链式调用创建并初始化数据 - HashMap map = new MapModifier() + HashMap map = new MapModifier() .putAll(commonProperties) .put("username", "Ben") .put("accountStatus", LOCKED) .getAndModify(HashMap::new); - HashMap expected = new HashMap() { + HashMap expected = new HashMap() { { put("channel", "MOBILE"); put("appStartId", APP_START_ID); @@ -115,4 +125,192 @@ public class MapModifierTests { }; assertEquals(expected, map); } + + @Test + void put() { + Map map = new MapModifier() + .put("key1", "value0") + .put("key1", "value1") + .getAndModify(HashMap::new); + + assertEquals(new HashMap() { + { + put("key1", "value0"); + put("key1", "value1"); + } + }, map); + + new MapModifier() + .put("key1", "newValue1") + .put("key2", null) + .modify(map); + + assertEquals("newValue1", map.get("key1")); + assertTrue(map.containsKey("key2")); + assertNull(map.get("key2")); + } + + @Test + void putIfAbsent() { + Map map = new MapModifier() + .putIfAbsent("key1", null) + .putIfAbsent("key1", "value1") + .putIfAbsent("key1", "value2") + .getAndModify(HashMap::new); + + assertEquals(new HashMap() { + { + putIfAbsent("key1", null); + putIfAbsent("key1", "value1"); + putIfAbsent("key1", "value2"); + } + }, map); + + new MapModifier() + .putIfAbsent("key1", "newValue1") + .modify(map); + + assertTrue(map.containsKey("key1")); + assertEquals("value1", map.get("key1")); + } + + @Test + void putAll_map() { + Map entries = new HashMap() { + { + put("key1", "value1"); + put("key2", "value2"); + } + }; + Map map = new MapModifier() + .putAll((Map) null) + .putAll(Collections.emptyMap()) + .putAll(entries) + .getAndModify(HashMap::new); + assertEquals(entries, map); + new MapModifier() + .putAll(new HashMap() { + { + put("key2", "newValue2"); + put("key3", "value3"); + } + }) + .modify(map); + assertEquals(new HashMap() { + { + put("key1", "value1"); + put("key2", "value2"); + put("key2", "newValue2"); + put("key3", "value3"); + } + }, map); + } + + @Test + void putAll_entries() { + Map entries = new HashMap() { + { + put("key1", "value1"); + put("key2", "value2"); + } + }; + Map map = new MapModifier() + .putAll(new SimpleEntry<>("key1", "value1"), + new SimpleEntry<>("key2", "value2")) + .getAndModify(HashMap::new); + assertEquals(entries, map); + new MapModifier() + .putAll() + .putAll(new SimpleEntry<>("key2", "newValue2"), + new SimpleEntry<>("key3", "value3")) + .modify(map); + assertEquals(new HashMap() { + { + put("key1", "value1"); + put("key2", "value2"); + put("key2", "newValue2"); + put("key3", "value3"); + } + }, map); + } + + @Test + void computeIfAbsent_keyAndFunction() { + Map map = new MapModifier() + .computeIfAbsent("key1", k -> null) + .computeIfAbsent("key1", k -> "value1") + .computeIfAbsent("key1", k -> "value2") + .getAndModify(HashMap::new); + + assertEquals(new HashMap() { + { + computeIfAbsent("key1", k -> null); + computeIfAbsent("key1", k -> "value1"); + computeIfAbsent("key1", k -> "value2"); + } + }, map); + + new MapModifier() + .computeIfAbsent("key1", k -> "newValue1") + .modify(map); + + assertTrue(map.containsKey("key1")); + assertEquals("value1", map.get("key1")); + } + + @Test + void computeIfPresent_keyAndBiFunction() { + Map map = new HashMap() {{ + put("key1", "value1"); + }}; + new MapModifier() + .computeIfPresent("key1", (k, v) -> k + v) + .computeIfPresent("key2", (k, v) -> k + v) + .modify(map); + assertEquals(new HashMap() {{ + put("key1", "key1value1"); + }}, map); + } + + @Test + void remove() { + Map map = new HashMap() {{ + put("key1", "value1"); + put("key2", "value2"); + }}; + new MapModifier() + .remove("key2") + .modify(map); + assertEquals(new HashMap() {{ + put("key1", "value1"); + }}, map); + } + + @Test + void clear() { + Map map = new HashMap() {{ + put("key1", "value1"); + put("key2", "value2"); + }}; + new MapModifier() + .clear() + .modify(map); + assertTrue(map.isEmpty()); + } + + @Getter + static class SimpleEntry implements Map.Entry { + private final K key; + private final V value; + + public SimpleEntry(K key, V value) { + this.key = key; + this.value = value; + } + + @Override + public V setValue(@Nullable V value) { + throw new UnsupportedOperationException("Unimplemented method 'setValue'"); + } + } }