From f6b2509b1269931f98e8c88068f568083ad04f35 Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 24 Dec 2024 10:44:05 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=AE=8C=E6=88=90=20IWithCode=20=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ProgressOfTesting.txt | 10 +- .../plusone/commons/base/IWithCodeTests.java | 115 ++++++++++++++---- .../commons/base/IWithIntCodeTests.java | 38 ------ 3 files changed, 96 insertions(+), 67 deletions(-) delete mode 100644 src/test/java/xyz/zhouxy/plusone/commons/base/IWithIntCodeTests.java diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt index 1171bef..961b926 100644 --- a/ProgressOfTesting.txt +++ b/ProgressOfTesting.txt @@ -1,7 +1,7 @@ [x] 无需测试 - 6 [ ] 未开始测试 - 34 -[-] 测试未完成 - 17 -[Y] 测试完成 - 12 +[-] 测试未完成 - 15 +[Y] 测试完成 - 15 xyz.zhouxy.plusone.commons ├───annotation @@ -17,9 +17,9 @@ xyz.zhouxy.plusone.commons │ CharRef.java [Y] │ DoubleRef.java [Y] │ IntRef.java [Y] - │ IWithCode.java [-] - │ IWithIntCode.java [-] - │ IWithLongCode.java [ ] + │ IWithCode.java [Y] + │ IWithIntCode.java [Y] + │ IWithLongCode.java [Y] │ JRE.java [ ] │ LongRef.java [Y] │ Ref.java [Y] diff --git a/src/test/java/xyz/zhouxy/plusone/commons/base/IWithCodeTests.java b/src/test/java/xyz/zhouxy/plusone/commons/base/IWithCodeTests.java index 693d1b6..bbd60a3 100644 --- a/src/test/java/xyz/zhouxy/plusone/commons/base/IWithCodeTests.java +++ b/src/test/java/xyz/zhouxy/plusone/commons/base/IWithCodeTests.java @@ -1,22 +1,80 @@ package xyz.zhouxy.plusone.commons.base; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import javax.annotation.Nonnull; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import xyz.zhouxy.plusone.commons.util.AssertTools; class IWithCodeTests { - private static class WithCodeImpl implements IWithCode { + @Test + void equalsCode_SameCode_ReturnsTrue() { + assertTrue(WithCode.INSTANCE.equalsCode("testCode")); + Integer intCode = 0; + Long longCode = 0L; + assertTrue(WithIntCode.INSTANCE.equalsCode(intCode)); + assertTrue(WithLongCode.INSTANCE.equalsCode(intCode)); + assertTrue(WithLongCode.INSTANCE.equalsCode(longCode)); + + assertTrue(WithCode.INSTANCE.equalsCode(WithCode.SAME_CODE_INSTANCE)); + assertTrue(WithIntCode.INSTANCE.equalsCode(WithIntCode.SAME_CODE_INSTANCE)); + assertTrue(WithIntCode.INSTANCE.equalsCode(WithLongCode.SAME_CODE_INSTANCE)); + assertTrue(WithLongCode.INSTANCE.equalsCode(WithLongCode.SAME_CODE_INSTANCE)); + assertTrue(WithLongCode.INSTANCE.equalsCode(WithIntCode.SAME_CODE_INSTANCE)); + } + + @Test + void equalsCode_DifferentCode_ReturnsFalse() { + assertFalse(WithCode.INSTANCE.equalsCode("wrongCode")); + Integer intCode = 108; + Long longCode = 108L; + assertFalse(WithIntCode.INSTANCE.equalsCode(intCode)); + assertFalse(WithLongCode.INSTANCE.equalsCode(intCode)); + assertFalse(WithLongCode.INSTANCE.equalsCode(longCode)); + + assertFalse(WithCode.INSTANCE.equalsCode(WithCode.WRONG_CODE_INSTANCE)); + assertFalse(WithIntCode.INSTANCE.equalsCode(WithIntCode.WRONG_CODE_INSTANCE)); + assertFalse(WithIntCode.INSTANCE.equalsCode(WithLongCode.WRONG_CODE_INSTANCE)); + assertFalse(WithLongCode.INSTANCE.equalsCode(WithLongCode.WRONG_CODE_INSTANCE)); + assertFalse(WithLongCode.INSTANCE.equalsCode(WithIntCode.WRONG_CODE_INSTANCE)); + } + + @Test + @SuppressWarnings("null") + void equalsCode_NullCode_ReturnsFalse() { + assertFalse(WithCode.INSTANCE.equalsCode((WithCode) null)); + assertFalse(WithCode.INSTANCE.equalsCode((WithIntCode) null)); + assertFalse(WithCode.INSTANCE.equalsCode((WithLongCode) null)); + + assertFalse(WithIntCode.INSTANCE.equalsCode((WithCode) null)); + assertFalse(WithIntCode.INSTANCE.equalsCode((WithIntCode) null)); + assertFalse(WithIntCode.INSTANCE.equalsCode((WithLongCode) null)); + + assertFalse(WithLongCode.INSTANCE.equalsCode((WithCode) null)); + assertFalse(WithLongCode.INSTANCE.equalsCode((WithIntCode) null)); + assertFalse(WithLongCode.INSTANCE.equalsCode((WithLongCode) null)); + + assertFalse(WithCode.INSTANCE.equalsCode((String) null)); + Integer intCode = null; + Long longCode = null; + assertThrows(NullPointerException.class, () -> WithIntCode.INSTANCE.equalsCode(intCode)); + assertThrows(NullPointerException.class, () -> WithLongCode.INSTANCE.equalsCode(intCode)); + assertThrows(NullPointerException.class, () -> WithLongCode.INSTANCE.equalsCode(longCode)); + } + + private static enum WithCode implements IWithCode { + INSTANCE("testCode"), + SAME_CODE_INSTANCE("testCode"), + WRONG_CODE_INSTANCE("wrongCode"), + ; + @Nonnull private final String code; - WithCodeImpl(String code) { + WithCode(String code) { AssertTools.checkNotNull(code); this.code = code; } @@ -28,30 +86,39 @@ class IWithCodeTests { } } - private WithCodeImpl instance; + private static enum WithIntCode implements IWithIntCode { + INSTANCE(0), + SAME_CODE_INSTANCE(0), + WRONG_CODE_INSTANCE(1), + ; - @BeforeEach - void setUp() { - instance = new WithCodeImpl("testCode"); + private final int code; + + WithIntCode(int code) { + this.code = code; + } + + @Override + public int getCode() { + return code; + } } - @Test - void equalsCode_SameCode_ReturnsTrue() { - assertTrue(instance.equalsCode("testCode")); - } + private static enum WithLongCode implements IWithLongCode { + INSTANCE(0L), + SAME_CODE_INSTANCE(0L), + WRONG_CODE_INSTANCE(108L), + ; - @Test - void equalsCode_DifferentCode_ReturnsFalse() { - assertFalse(instance.equalsCode("wrongCode")); - } + private final long code; - @Test - void equalsCode_NullCode_ReturnsFalse() { - assertFalse(instance.equalsCode((String) null)); - } + WithLongCode(long code) { + this.code = code; + } - @Test - void equalsCode_NullObject_ReturnsFalse() { - assertFalse(instance.equalsCode((String) null)); + @Override + public long getCode() { + return code; + } } } diff --git a/src/test/java/xyz/zhouxy/plusone/commons/base/IWithIntCodeTests.java b/src/test/java/xyz/zhouxy/plusone/commons/base/IWithIntCodeTests.java deleted file mode 100644 index 60fa5ab..0000000 --- a/src/test/java/xyz/zhouxy/plusone/commons/base/IWithIntCodeTests.java +++ /dev/null @@ -1,38 +0,0 @@ -package xyz.zhouxy.plusone.commons.base; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -class IWithIntCodeTests { - @Test - void test() { - IWithIntCode instance1 = new WithIntCodeImpl(10); - IWithIntCode instance2 = new WithIntCodeImpl(20); - IWithIntCode instance3 = new WithIntCodeImpl(10); - - // Test for equalsCode method - assertTrue(instance1.equalsCode(10)); - assertFalse(instance1.equalsCode(20)); - assertTrue(instance2.equalsCode(20)); - assertTrue(instance3.equalsCode(10)); - - // Test for distinct instances with same code - assertTrue(instance1.equalsCode(instance3.getCode())); // because they have the same code - assertFalse(instance1.equalsCode(instance2.getCode())); // because they have different codes - } -} - -class WithIntCodeImpl implements IWithIntCode { - private int code; - - public WithIntCodeImpl(int code) { - this.code = code; - } - - @Override - public int getCode() { - return code; - } -} From 424857df6ad4000bdc0c5cd89f42423874c61f38 Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Tue, 24 Dec 2024 11:35:02 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=AE=8C=E6=88=90=20TreeBuilder=20?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ProgressOfTesting.txt | 6 +- .../commons/util/TreeBuilderTests.java | 292 +++++++++++------- 2 files changed, 182 insertions(+), 116 deletions(-) diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt index 961b926..f6a9972 100644 --- a/ProgressOfTesting.txt +++ b/ProgressOfTesting.txt @@ -1,7 +1,7 @@ [x] 无需测试 - 6 [ ] 未开始测试 - 34 -[-] 测试未完成 - 15 -[Y] 测试完成 - 15 +[-] 测试未完成 - 14 +[Y] 测试完成 - 16 xyz.zhouxy.plusone.commons ├───annotation @@ -97,4 +97,4 @@ xyz.zhouxy.plusone.commons RegexTools.java [ ] SnowflakeIdGenerator.java [ ] StringTools.java [Y] - TreeBuilder.java [-] + TreeBuilder.java [Y] diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/TreeBuilderTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/TreeBuilderTests.java index 753e267..4249c40 100644 --- a/src/test/java/xyz/zhouxy/plusone/commons/util/TreeBuilderTests.java +++ b/src/test/java/xyz/zhouxy/plusone/commons/util/TreeBuilderTests.java @@ -16,8 +16,14 @@ package xyz.zhouxy.plusone.commons.util; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.io.Serializable; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -25,143 +31,203 @@ import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.gson.Gson; import cn.hutool.core.util.ObjectUtil; +import lombok.EqualsAndHashCode; import lombok.ToString; class TreeBuilderTests { private static final Logger log = LoggerFactory.getLogger(TreeBuilderTests.class); + + private final MenuItem A = MenuItem.of("A", "首页", "/home", 1); + private final MenuList B = MenuList.of("B", "系统管理", 3); + private final MenuItem B001 = /**/MenuItem.of("B", "B001", "功能管理", "/sys/function-mgmt", 4); + private final MenuItem B002 = /**/MenuItem.of("B", "B002", "角色管理", "/sys/role-mgmt", 3); + private final MenuItem B003 = /**/MenuItem.of("B", "B003", "账号管理", "/sys/account-mgmt", 2); + private final MenuItem B004 = /**/MenuItem.of("B", "B004", "系统参数管理", "/sys/param-mgmt", 1); + private final MenuList C = MenuList.of("C", "一级菜单C", 2); + private final MenuList C1 = /**/MenuList.of("C", "C1", "二级菜单C1", 3); + private final MenuItem C1001 = /**//**/MenuItem.of("C1", "C1001", "三级菜单C1001", "/c/c1/c1001", 1); + private final MenuItem C1002 = /**//**/MenuItem.of("C1", "C1002", "三级菜单C1002", "/c/c1/c1002", 2); + private final MenuItem C2 = /**/MenuItem.of("C", "C2", "二级菜单C2", "/c/c2", 1); + private final MenuItem C3 = /**/MenuItem.of("C", "C3", "二级菜单C3", "/c/c3", 2); + + private final List menus = ImmutableList.of(B, C1002, A, B004, C3, B001, B003, C1, C1001, B002, C, C2); + private final TreeBuilder treeBuilder = new TreeBuilder<>( Menu::getMenuCode, menu -> Optional.ofNullable(menu.parentMenuCode), MenuList::addChild, - (a, b) -> Integer.compare(a.getOrderNum(), b.getOrderNum())); + Menu.orderNumComparator); @Test - void testBuildTree() { - List menus = Lists.newArrayList( - MenuList.of("B", "系统管理", 3), - MenuItem.of("A", "首页", "/home", 1), - /**/MenuItem.of("B", "B002", "角色管理", "/sys/role-mgmt", 3), - /**/MenuItem.of("B", "B001", "功能管理", "/sys/function-mgmt", 4), - /**/MenuItem.of("B", "B004", "系统参数管理", "/sys/param-mgmt", 1), - /**/MenuItem.of("B", "B003", "账号管理", "/sys/account-mgmt", 2), - MenuList.of("C", "一级菜单C", 2), - /**/MenuItem.of("C", "C3", "二级菜单C3", "/c/c3", 2), - /**/MenuList.of("C", "C1", "二级菜单C1", 2), - /**//**/MenuItem.of("C1", "C1001", "三级菜单C1001", "/c/c1/c1001", 1), - /**//**/MenuItem.of("C1", "C1002", "三级菜单C1002", "/c/c1/c1002", 2), - /**/MenuItem.of("C", "C2", "二级菜单C2", "/c/c2", 1)); - - List clonedMenus; - - clonedMenus = menus.stream().map(m -> ObjectUtil.clone(m)).collect(Collectors.toList()); + void testBuildTreeAndSortedByOrderNum() { + List clonedMenus = menus.stream().map(ObjectUtil::clone).collect(Collectors.toList()); List menuTreeSortedByOrderNum = treeBuilder.buildTree(clonedMenus); log.info("menuTreeSortedByOrderNum: {}", new Gson().toJson(menuTreeSortedByOrderNum)); - clonedMenus = menus.stream().map(m -> ObjectUtil.clone(m)).collect(Collectors.toList()); + assertEquals(clonedMenus.stream() + .filter(menu -> menu.getParentMenuCode() == null) + .sorted(Menu.orderNumComparator) + .collect(Collectors.toList()), + menuTreeSortedByOrderNum); + + Map menuMap = new HashMap<>(); + for (Menu element : clonedMenus) { + menuMap.put(element.getMenuCode(), element); + } + + assertEquals(Arrays.stream(new Menu[] { B001, B002, B003, B004 }) + .sorted(Menu.orderNumComparator) + .collect(Collectors.toList()), + MenuList.class.cast(menuMap.get("B")).children); + + assertEquals(Arrays.stream(new Menu[] { C1, C2, C3 }) + .sorted(Menu.orderNumComparator) + .collect(Collectors.toList()), + MenuList.class.cast(menuMap.get("C")).children); + + assertEquals(Arrays.stream(new Menu[] { C1001, C1002 }) + .sorted(Menu.orderNumComparator) + .collect(Collectors.toList()), + MenuList.class.cast(menuMap.get("C1")).children); + + } + + @Test + void testBuildTreeAndSortedByMenuCode() { + List clonedMenus; + + clonedMenus = menus.stream().map(ObjectUtil::clone).collect(Collectors.toList()); List menuTreeSortedByMenuCode = treeBuilder.buildTree( clonedMenus, - (a, b) -> a.getMenuCode().compareTo(b.getMenuCode()) - ); + (a, b) -> a.getMenuCode().compareTo(b.getMenuCode())); log.info("menuTreeSortedByMenuCode: {}", new Gson().toJson(menuTreeSortedByMenuCode)); - } -} -@ToString -abstract class Menu implements Serializable { - protected final String parentMenuCode; - protected final String menuCode; - protected final String title; - protected final int orderNum; + assertEquals(clonedMenus.stream() + .filter(menu -> menu.getParentMenuCode() == null) + .sorted((a, b) -> a.getMenuCode().compareTo(b.getMenuCode())) + .collect(Collectors.toList()), + menuTreeSortedByMenuCode); - public Menu(String parentMenuCode, String menuCode, String title, int orderNum) { - this.parentMenuCode = parentMenuCode; - this.menuCode = menuCode; - this.title = title; - this.orderNum = orderNum; - } - - public String getMenuCode() { - return menuCode; - } - - public String getParentMenuCode() { - return parentMenuCode; - } - - public String getTitle() { - return title; - } - - public int getOrderNum() { - return orderNum; - } - - private static final long serialVersionUID = 20240917181424L; -} - -@ToString(callSuper = true) -class MenuItem extends Menu { - - private final String url; - - private MenuItem(String parentMenuCode, String menuCode, String title, String url, int orderNum) { - super(parentMenuCode, menuCode, title, orderNum); - this.url = url; - } - - static MenuItem of(String parentMenuCode, String menuCode, String title, String url, int orderNum) { - return new MenuItem(parentMenuCode, menuCode, title, url, orderNum); - } - - static MenuItem of(String menuCode, String title, String url, int orderNum) { - return new MenuItem(null, menuCode, title, url, orderNum); - } - - public String getUrl() { - return url; - } - - private static final long serialVersionUID = 20240917181910L; -} - -@ToString(callSuper = true) -class MenuList extends Menu { - - private List children; - - private MenuList(String parentMenuCode, String menuCode, String title, int orderNum) { - super(parentMenuCode, menuCode, title, orderNum); - } - - static MenuList of(String parentMenuCode, String menuCode, String title, int orderNum) { - return new MenuList(parentMenuCode, menuCode, title, orderNum); - } - - static MenuList of(String menuCode, String title, int orderNum) { - return new MenuList(null, menuCode, title, orderNum); - } - - static MenuList of(String menuCode, String title, Iterable children, int orderNum) { - return of(null, menuCode, title, children, orderNum); - } - - static MenuList of(String parentMenuCode, String menuCode, String title, Iterable children, int orderNum) { - final MenuList instance = of(parentMenuCode, menuCode, title, orderNum); - children.forEach(instance::addChild); - return instance; - } - - public void addChild(Menu child) { - if (this.children == null) { - this.children = Lists.newArrayList(); + Map menuMap = new HashMap<>(); + for (Menu element : clonedMenus) { + menuMap.put(element.getMenuCode(), element); } - this.children.add(child); + + assertEquals(ImmutableList.of(B001, B002, B003, B004), + MenuList.class.cast(menuMap.get("B")).children); + + assertEquals(ImmutableList.of(C1, C2, C3), + MenuList.class.cast(menuMap.get("C")).children); + + assertEquals(ImmutableList.of(C1001, C1002), + MenuList.class.cast(menuMap.get("C1")).children); } - private static final long serialVersionUID = 20240917181917L; + @ToString + @EqualsAndHashCode + private static abstract class Menu implements Serializable { // NOSONAR + protected final String parentMenuCode; + protected final String menuCode; + protected final String title; + protected final int orderNum; + + public Menu(String parentMenuCode, String menuCode, String title, int orderNum) { + this.parentMenuCode = parentMenuCode; + this.menuCode = menuCode; + this.title = title; + this.orderNum = orderNum; + } + + public String getMenuCode() { + return menuCode; + } + + public String getParentMenuCode() { + return parentMenuCode; + } + + public String getTitle() { + return title; + } + + public int getOrderNum() { + return orderNum; + } + + public static Comparator orderNumComparator = + (a, b) -> Integer.compare(a.getOrderNum(), b.getOrderNum()); + + private static final long serialVersionUID = 20240917181424L; + } + + @ToString(callSuper = true) + @EqualsAndHashCode(callSuper = true) + private static final class MenuItem extends Menu { + + private final String url; + + private MenuItem(String parentMenuCode, String menuCode, String title, String url, int orderNum) { + super(parentMenuCode, menuCode, title, orderNum); + this.url = url; + } + + static MenuItem of(String parentMenuCode, String menuCode, String title, String url, int orderNum) { + return new MenuItem(parentMenuCode, menuCode, title, url, orderNum); + } + + static MenuItem of(String menuCode, String title, String url, int orderNum) { + return new MenuItem(null, menuCode, title, url, orderNum); + } + + public String getUrl() { + return url; + } + + private static final long serialVersionUID = 20240917181910L; + } + + @ToString(callSuper = true) + private static final class MenuList extends Menu { + + private List children; + + private MenuList(String parentMenuCode, String menuCode, String title, int orderNum) { + super(parentMenuCode, menuCode, title, orderNum); + } + + static MenuList of(String parentMenuCode, String menuCode, String title, int orderNum) { + return new MenuList(parentMenuCode, menuCode, title, orderNum); + } + + static MenuList of(String menuCode, String title, int orderNum) { + return new MenuList(null, menuCode, title, orderNum); + } + + @SuppressWarnings("unused") + static MenuList of(String menuCode, String title, Iterable children, int orderNum) { + return of(null, menuCode, title, children, orderNum); + } + + static MenuList of(String parentMenuCode, String menuCode, String title, Iterable children, + int orderNum) { + final MenuList instance = of(parentMenuCode, menuCode, title, orderNum); + children.forEach(instance::addChild); + return instance; + } + + public void addChild(Menu child) { + if (this.children == null) { + this.children = Lists.newArrayList(); + } + this.children.add(child); + } + + private static final long serialVersionUID = 20240917181917L; + } }