exportMap() {
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/collection/SafeConcurrentHashMap.java b/src/main/java/xyz/zhouxy/plusone/commons/collection/SafeConcurrentHashMap.java
deleted file mode 100644
index 0b60882..0000000
--- a/src/main/java/xyz/zhouxy/plusone/commons/collection/SafeConcurrentHashMap.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2023-2024 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 xyz.zhouxy.plusone.commons.collection;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
-
-import javax.annotation.concurrent.ThreadSafe;
-
-import xyz.zhouxy.plusone.commons.base.JRE;
-import xyz.zhouxy.plusone.commons.util.ConcurrentHashMapTools;
-
-/**
- * SafeConcurrentHashMap
- *
- *
- * Java 8 的 {@link ConcurrentHashMap#computeIfAbsent(Object, Function)} 方法有 bug,
- * 使用 Java 8 时,可使用这个类进行替换。
- *
- * @author ZhouXY
- * @since 1.0
- * @see ConcurrentHashMap
- * @see ConcurrentHashMapTools#computeIfAbsentForJava8(ConcurrentHashMap, Object, Function)
- */
-@ThreadSafe
-public class SafeConcurrentHashMap extends ConcurrentHashMap {
-
- private static final long serialVersionUID = 4352954948768449595L;
-
- /**
- * Creates a new, empty map with the default initial table size (16).
- */
- public SafeConcurrentHashMap() {
- }
-
- /**
- * Creates a new, empty map with an initial table size
- * accommodating the specified number of elements without the need
- * to dynamically resize.
- *
- * @param initialCapacity The implementation performs internal
- * sizing to accommodate this many elements.
- * @throws IllegalArgumentException if the initial capacity of
- * elements is negative
- */
- public SafeConcurrentHashMap(int initialCapacity) {
- super(initialCapacity);
- }
-
- /**
- * Creates a new map with the same mappings as the given map.
- *
- * @param m the map
- */
- public SafeConcurrentHashMap(Map extends K, ? extends V> m) {
- super(m);
- }
-
- /**
- * Creates a new, empty map with an initial table size based on
- * the given number of elements ({@code initialCapacity}) and
- * initial table density ({@code loadFactor}).
- *
- * @param initialCapacity the initial capacity. The implementation
- * performs internal sizing to accommodate this many elements,
- * given the specified load factor.
- * @param loadFactor the load factor (table density) for
- * establishing the initial table size
- * @throws IllegalArgumentException if the initial capacity of
- * elements is negative or the load factor is nonpositive
- * @since 1.6
- */
- public SafeConcurrentHashMap(int initialCapacity, float loadFactor) {
- super(initialCapacity, loadFactor);
- }
-
- /**
- * Creates a new, empty map with an initial table size based on
- * the given number of elements ({@code initialCapacity}), table
- * density ({@code loadFactor}), and number of concurrently
- * updating threads ({@code concurrencyLevel}).
- *
- * @param initialCapacity the initial capacity. The implementation
- * performs internal sizing to accommodate this many elements,
- * given the specified load factor.
- * @param loadFactor the load factor (table density) for
- * establishing the initial table size
- * @param concurrencyLevel the estimated number of concurrently
- * updating threads. The implementation may use this value as
- * a sizing hint.
- * @throws IllegalArgumentException if the initial capacity is
- * negative or the load factor or concurrencyLevel are
- * nonpositive
- */
- public SafeConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) {
- super(initialCapacity, loadFactor, concurrencyLevel);
- }
-
- /** {@inheritDoc} */
- @Override
- public V computeIfAbsent(K key, Function super K, ? extends V> mappingFunction) {
- return JRE.isJava8()
- ? ConcurrentHashMapTools.computeIfAbsentForJava8(this, key, mappingFunction)
- : super.computeIfAbsent(key, mappingFunction);
- }
-}
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/ConcurrentHashMapTools.java b/src/main/java/xyz/zhouxy/plusone/commons/util/ConcurrentHashMapTools.java
deleted file mode 100644
index c36ecf0..0000000
--- a/src/main/java/xyz/zhouxy/plusone/commons/util/ConcurrentHashMapTools.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2023-2024 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 xyz.zhouxy.plusone.commons.util;
-
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
-
-import xyz.zhouxy.plusone.commons.base.JRE;
-import xyz.zhouxy.plusone.commons.collection.SafeConcurrentHashMap;
-
-/**
- * ConcurrentHashMapTools
- *
- *
- * Java 8 的 {@link ConcurrentHashMap#computeIfAbsent(Object, Function)} 方法有 bug,
- * 可使用这个工具类的 {@link computeIfAbsentForJava8} 进行替换。
- *
- *
- * NOTE: 方法来自Dubbo,见:issues#2349
- *
- * @author ZhouXY
- * @since 1.0
- * @see ConcurrentHashMap
- * @see SafeConcurrentHashMap
- */
-public class ConcurrentHashMapTools {
-
- public static V computeIfAbsent(
- ConcurrentHashMap map, final K key, // NOSONAR
- final Function super K, ? extends V> mappingFunction) {
- Objects.requireNonNull(map, "map");
- return JRE.isJava8()
- ? computeIfAbsentForJava8(map, key, mappingFunction)
- : map.computeIfAbsent(key, mappingFunction);
- }
-
- public static V computeIfAbsentForJava8(
- ConcurrentHashMap map, final K key, // NOSONAR
- final Function super K, ? extends V> mappingFunction) {
- Objects.requireNonNull(key);
- Objects.requireNonNull(mappingFunction);
- V v = map.get(key);
- if (null == v) {
- v = mappingFunction.apply(key);
- if (null == v) {
- return null;
- }
- final V res = map.putIfAbsent(key, v);
- if (null != res) {
- return res;
- }
- }
- return v;
- }
-
- private ConcurrentHashMapTools() {
- throw new IllegalStateException("Utility class");
- }
-}
From fb5ff43ed66f546988ff89b4b91bfacb6eb75e38 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Fri, 27 Dec 2024 15:50:45 +0800
Subject: [PATCH 04/24] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20ProgressOfTesting.tx?=
=?UTF-8?q?t?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ProgressOfTesting.txt | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt
index e757a12..fe401c4 100644
--- a/ProgressOfTesting.txt
+++ b/ProgressOfTesting.txt
@@ -1,7 +1,7 @@
-[ ] 未开始测试 - 15 (21.43%)
-[-] 测试未完成 - 10 (14.29%)
-[Y] 测试完成 - 24 (34.29%)
-[x] 无需测试 - 21 (30.00%)
+[ ] 未开始测试 - 13 (19.40%)
+[-] 测试未完成 - 9 (13.43%)
+[Y] 测试完成 - 24 (35.82%)
+[x] 无需测试 - 21 (31.34%)
xyz.zhouxy.plusone.commons
├───annotation
@@ -20,7 +20,6 @@ xyz.zhouxy.plusone.commons
│ IWithCode.java [Y]
│ IWithIntCode.java [Y]
│ IWithLongCode.java [Y]
- │ JRE.java [ ]
│ LongRef.java [Y]
│ Ref.java [Y]
│
@@ -28,7 +27,6 @@ xyz.zhouxy.plusone.commons
│ AbstractMapWrapper.java [ ]
│ CollectionTools.java [Y]
│ MapWrapper.java [ ]
- │ SafeConcurrentHashMap.java [ ]
│
├───constant
│ PatternConsts.java [ ]
@@ -86,7 +84,6 @@ xyz.zhouxy.plusone.commons
ArrayTools.java [-]
AssertTools.java [Y]
BigDecimals.java [Y]
- ConcurrentHashMapTools.java [-]
DateTimeTools.java [-]
Enumeration.java [Y]
EnumTools.java [Y]
From a887771565ca9c9e91c295561942256c5d7bfa39 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Fri, 27 Dec 2024 16:32:10 +0800
Subject: [PATCH 05/24] =?UTF-8?q?=E5=AE=8C=E6=88=90=20ID=20=E7=94=9F?=
=?UTF-8?q?=E6=88=90=E5=99=A8=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
---
ProgressOfTesting.txt | 10 +--
.../commons/util/SnowflakeIdGenerator.java | 77 +++++++++----------
.../commons/util/AssertToolsTests.java | 3 +-
.../commons/util/IdGeneratorTests.java | 65 ++++++++++++++++
4 files changed, 107 insertions(+), 48 deletions(-)
create mode 100644 src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java
diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt
index fe401c4..7223d75 100644
--- a/ProgressOfTesting.txt
+++ b/ProgressOfTesting.txt
@@ -1,6 +1,6 @@
-[ ] 未开始测试 - 13 (19.40%)
+[ ] 未开始测试 - 10 (14.93%)
[-] 测试未完成 - 9 (13.43%)
-[Y] 测试完成 - 24 (35.82%)
+[Y] 测试完成 - 27 (40.30%)
[x] 无需测试 - 21 (31.34%)
xyz.zhouxy.plusone.commons
@@ -87,12 +87,12 @@ xyz.zhouxy.plusone.commons
DateTimeTools.java [-]
Enumeration.java [Y]
EnumTools.java [Y]
- IdGenerator.java [ ]
- IdWorker.java [ ]
+ IdGenerator.java [Y]
+ IdWorker.java [Y]
Numbers.java [Y]
OptionalTools.java [Y]
RandomTools.java [ ]
RegexTools.java [ ]
- SnowflakeIdGenerator.java [ ]
+ SnowflakeIdGenerator.java [Y]
StringTools.java [Y]
TreeBuilder.java [Y]
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/SnowflakeIdGenerator.java b/src/main/java/xyz/zhouxy/plusone/commons/util/SnowflakeIdGenerator.java
index da9f71e..c8af751 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/util/SnowflakeIdGenerator.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/util/SnowflakeIdGenerator.java
@@ -64,9 +64,6 @@ public class SnowflakeIdGenerator {
/** 上次生成 ID 的时间截 */
private long lastTimestamp = -1L;
- /** 锁对象 */
- private final Object lock = new Object();
-
// ==============================Constructors=====================================
/**
@@ -90,51 +87,47 @@ public class SnowflakeIdGenerator {
*
* @return SnowflakeId
*/
- public long nextId() {
- long timestamp;
- synchronized (lock) {
- timestamp = timeGen();
+ public synchronized long nextId() {
+ long timestamp = timeGen();
- // 发生了回拨,此刻时间小于上次发号时间
- if (timestamp < lastTimestamp) {
- long offset = lastTimestamp - timestamp;
- if (offset <= 5) {
- // 时间偏差大小小于5ms,则等待两倍时间
- try {
- TimeUnit.MILLISECONDS.sleep(offset << 1);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new IllegalStateException(e);
- }
- timestamp = timeGen();
- if (timestamp < lastTimestamp) {
- // 还是小于,抛异常上报
- throwClockBackwardsEx(lastTimestamp, timestamp);
- }
- } else {
+ // 发生了回拨,此刻时间小于上次发号时间
+ if (timestamp < lastTimestamp) {
+ long offset = lastTimestamp - timestamp;
+ if (offset <= 5) {
+ // 时间偏差大小小于5ms,则等待两倍时间
+ try {
+ TimeUnit.MILLISECONDS.sleep(offset << 1);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new IllegalStateException(e);
+ }
+ timestamp = timeGen();
+ if (timestamp < lastTimestamp) {
+ // 还是小于,抛异常上报
throwClockBackwardsEx(lastTimestamp, timestamp);
}
+ } else {
+ throwClockBackwardsEx(lastTimestamp, timestamp);
}
-
- // 如果是同一时间生成的,则进行毫秒内序列
- if (lastTimestamp == timestamp) {
- sequence = (sequence + 1) & SEQUENCE_MASK;
- // 毫秒内序列溢出
- if (sequence == 0) {
- // 阻塞到下一个毫秒,获得新的时间戳
- timestamp = tilNextMillis(lastTimestamp);
- }
- }
- // 时间戳改变,毫秒内序列重置
- else {
- sequence = 0L;
- }
-
- // 上次生成 ID 的时间截
- lastTimestamp = timestamp;
-
}
+ // 如果是同一时间生成的,则进行毫秒内序列
+ if (lastTimestamp == timestamp) {
+ sequence = (sequence + 1) & SEQUENCE_MASK;
+ // 毫秒内序列溢出
+ if (sequence == 0) {
+ // 阻塞到下一个毫秒,获得新的时间戳
+ timestamp = tilNextMillis(lastTimestamp);
+ }
+ }
+ // 时间戳改变,毫秒内序列重置
+ else {
+ sequence = 0L;
+ }
+
+ // 上次生成 ID 的时间截
+ lastTimestamp = timestamp;
+
// 移位并通过或运算拼到一起组成64位的ID
return ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT) | datacenterIdAndWorkerId | sequence;
}
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/AssertToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/AssertToolsTests.java
index 6623b9c..b6ea20e 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/util/AssertToolsTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/AssertToolsTests.java
@@ -925,9 +925,10 @@ public class AssertToolsTests {
// #region - Condition
+ static final class MyException extends RuntimeException {}
+
@Test
void testCheckCondition() {
- class MyException extends RuntimeException {}
AssertTools.checkCondition(true, MyException::new);
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java
new file mode 100644
index 0000000..55edba9
--- /dev/null
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java
@@ -0,0 +1,65 @@
+package xyz.zhouxy.plusone.commons.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.jupiter.api.Test;
+
+import cn.hutool.core.collection.ConcurrentHashSet;
+
+public class IdGeneratorTests {
+
+ final ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue());
+
+ @Test
+ void testSnowflakeIdGenerator() { // NOSONAR
+ final SnowflakeIdGenerator snowflake = new SnowflakeIdGenerator(0, 0);
+ final Set ids = new ConcurrentHashSet<>();
+ for (int i = 0; i < 10000; i++) {
+ executor.execute(() -> {
+ for (int j = 0; j < 50000; j++) {
+ if (false == ids.add(snowflake.nextId())) {
+ throw new RuntimeException("重复ID!");
+ }
+ }
+ });
+ }
+ }
+
+ @Test
+ void testIdWorker() { // NOSONAR
+ final IdWorker idWorker = new IdWorker(0L);
+ final Set ids = new ConcurrentHashSet<>();
+ for (int i = 0; i < 10000; i++) {
+ executor.execute(() -> {
+ for (int j = 0; j < 50000; j++) {
+ if (false == ids.add(idWorker.nextId())) {
+ throw new RuntimeException("重复ID!");
+ }
+ }
+ });
+ executor.execute(() -> {
+ for (int j = 0; j < 50000; j++) {
+ if (false == ids.add(IdGenerator.nextSnowflakeId(0))) {
+ throw new RuntimeException("重复ID!");
+ }
+ }
+ });
+ }
+ }
+
+ @Test
+ void testToSimpleString() {
+ UUID id = UUID.randomUUID();
+ assertEquals(id.toString().replaceAll("-", ""),
+ IdGenerator.toSimpleString(id));
+ }
+
+}
From 76f612f2ccdd9e8b9fe6df6922f4c81425dd4510 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Fri, 27 Dec 2024 17:07:11 +0800
Subject: [PATCH 06/24] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=BA=AB=E4=BB=BD?=
=?UTF-8?q?=E8=AF=81=E5=8F=B7=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
---
.../model/Chinese2ndGenIDCardNumber.java | 2 +-
.../plusone/commons/model/IDCardNumber.java | 2 +-
.../model/Chinese2ndGenIDCardNumberTests.java | 59 +++++++++++--------
3 files changed, 38 insertions(+), 25 deletions(-)
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumber.java b/src/main/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumber.java
index d43fa6f..4e1fed2 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumber.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumber.java
@@ -226,5 +226,5 @@ public class Chinese2ndGenIDCardNumber implements IDCardNumber, Serializable {
return Objects.equals(value, other.value);
}
- private static final long serialVersionUID = 20241202095400L;
+ private static final long serialVersionUID = 8390082242712103716L;
}
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/model/IDCardNumber.java b/src/main/java/xyz/zhouxy/plusone/commons/model/IDCardNumber.java
index 76dcf1a..3e7c56d 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/model/IDCardNumber.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/model/IDCardNumber.java
@@ -43,7 +43,7 @@ public interface IDCardNumber {
LocalDate getBirthDate();
/** 计算年龄 */
- default int calculateAge() {
+ default int getAge() {
LocalDate now = LocalDate.now();
return Period.between(getBirthDate(), now).getYears();
}
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumberTests.java b/src/test/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumberTests.java
index 40bd5dc..6e68cff 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumberTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumberTests.java
@@ -17,35 +17,27 @@
package xyz.zhouxy.plusone.commons.model;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.time.LocalDate;
import java.time.format.DateTimeParseException;
-import java.util.regex.Matcher;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import lombok.extern.slf4j.Slf4j;
-import xyz.zhouxy.plusone.commons.constant.PatternConsts;
@Slf4j
public class Chinese2ndGenIDCardNumberTests {
@Test
- void testPattern() {
- Matcher matcher = PatternConsts.CHINESE_2ND_ID_CARD_NUMBER.matcher("11010520000101111X");
- assertTrue(matcher.matches());
- for (int i = 0; i < matcher.groupCount(); i++) {
- log.info("{}: {}", i, matcher.group(i));
- }
- }
-
- @Test
- void test() {
+ void testOf_success() {
Chinese2ndGenIDCardNumber idCardNumber = Chinese2ndGenIDCardNumber.of("11010520000101111X");
assertEquals("11010520000101111X", idCardNumber.value());
assertEquals(LocalDate.of(2000, 1, 1), idCardNumber.getBirthDate());
- assertEquals(Gender.MALE, idCardNumber.getGender());
+ assertSame(Gender.MALE, idCardNumber.getGender());
assertEquals("110105", idCardNumber.getCountyCode());
assertEquals("110105000000", idCardNumber.getFullCountyCode());
@@ -57,17 +49,38 @@ public class Chinese2ndGenIDCardNumberTests {
assertEquals("北京", idCardNumber.getProvinceName());
- assertThrows(IllegalArgumentException.class,
- () -> Chinese2ndGenIDCardNumber.of("1101520000101111"));
+ assertEquals("1***************1X", idCardNumber.toDesensitizedString());
+ assertEquals("110***********111X", idCardNumber.toDesensitizedString(3, 4));
+ assertEquals("11############111X", idCardNumber.toDesensitizedString('#', 2, 4));
+ }
- assertThrows(IllegalArgumentException.class,
- () -> Chinese2ndGenIDCardNumber.of("11010520002101111X"));
-
- try {
- Chinese2ndGenIDCardNumber.of("11010520002101111X");
- }
- catch (IllegalArgumentException e) {
- assertTrue(e.getCause() instanceof DateTimeParseException);
+ @Test
+ void testOf_blankValue() {
+ String[] strings = { null, "", " " };
+ for (String value : strings) {
+ IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
+ () -> Chinese2ndGenIDCardNumber.of(value));
+ assertEquals("二代居民身份证校验失败:号码为空", e.getMessage());
}
}
+ @ParameterizedTest
+ @ValueSource(strings = { "1101520000101111", "110A0520000101111X", "110105220000101111X" })
+ void testOf_mismatched(String value) {
+ IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
+ () -> Chinese2ndGenIDCardNumber.of(value));
+ assertEquals("二代居民身份证校验失败:" + value, e.getMessage());
+ }
+
+ @Test
+ void testOf_wrongBirthDate() {
+ IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
+ () -> Chinese2ndGenIDCardNumber.of("11010520002101111X"));
+ assertTrue(e.getCause() instanceof DateTimeParseException);
+ }
+
+ @Test
+ void testOf_wrongProvince() {
+ assertThrows(IllegalArgumentException.class,
+ () -> Chinese2ndGenIDCardNumber.of("99010520000101111X"));
+ }
}
From 36823c11818d3961e710a83ec8cdb92cc67b6ff2 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Fri, 27 Dec 2024 17:09:28 +0800
Subject: [PATCH 07/24] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20ProgressOfTesting.tx?=
=?UTF-8?q?t?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ProgressOfTesting.txt | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt
index 7223d75..1895c4d 100644
--- a/ProgressOfTesting.txt
+++ b/ProgressOfTesting.txt
@@ -1,7 +1,7 @@
-[ ] 未开始测试 - 10 (14.93%)
-[-] 测试未完成 - 9 (13.43%)
-[Y] 测试完成 - 27 (40.30%)
-[x] 无需测试 - 21 (31.34%)
+[ ] 未开始测试 - 8 (11.94%)
+[-] 测试未完成 - 8 (11.94%)
+[Y] 测试完成 - 29 (43.28%)
+[x] 无需测试 - 22 (32.84%)
xyz.zhouxy.plusone.commons
├───annotation
@@ -60,9 +60,9 @@ xyz.zhouxy.plusone.commons
│ ToOptionalFunction.java [x]
│
├───model
- │ │ Chinese2ndGenIDCardNumber.java [-]
- │ │ Gender.java [ ]
- │ │ IDCardNumber.java [ ]
+ │ │ Chinese2ndGenIDCardNumber.java [Y]
+ │ │ Gender.java [x]
+ │ │ IDCardNumber.java [Y]
│ │ ValidatableStringRecord.java [-]
│ │
│ └───dto
From f1491117de8a91a70da5239a285150138604d1c4 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Fri, 27 Dec 2024 18:05:59 +0800
Subject: [PATCH 08/24] =?UTF-8?q?=E5=AE=8C=E6=88=90=20RandomTools=20?=
=?UTF-8?q?=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
---
ProgressOfTesting.txt | 6 +-
.../plusone/commons/util/RandomTools.java | 29 +++++-
.../commons/util/RandomToolsTests.java | 89 +++++++++++++++++++
3 files changed, 120 insertions(+), 4 deletions(-)
create mode 100644 src/test/java/xyz/zhouxy/plusone/commons/util/RandomToolsTests.java
diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt
index 1895c4d..0af1f01 100644
--- a/ProgressOfTesting.txt
+++ b/ProgressOfTesting.txt
@@ -1,6 +1,6 @@
-[ ] 未开始测试 - 8 (11.94%)
+[ ] 未开始测试 - 7 (10.45%)
[-] 测试未完成 - 8 (11.94%)
-[Y] 测试完成 - 29 (43.28%)
+[Y] 测试完成 - 30 (44.78%)
[x] 无需测试 - 22 (32.84%)
xyz.zhouxy.plusone.commons
@@ -91,7 +91,7 @@ xyz.zhouxy.plusone.commons
IdWorker.java [Y]
Numbers.java [Y]
OptionalTools.java [Y]
- RandomTools.java [ ]
+ RandomTools.java [Y]
RegexTools.java [ ]
SnowflakeIdGenerator.java [Y]
StringTools.java [Y]
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/RandomTools.java b/src/main/java/xyz/zhouxy/plusone/commons/util/RandomTools.java
index f9bc4a2..07f54bf 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/util/RandomTools.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/util/RandomTools.java
@@ -16,6 +16,7 @@
package xyz.zhouxy.plusone.commons.util;
+import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Objects;
import java.util.Random;
@@ -23,14 +24,40 @@ import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.Nonnull;
+/**
+ * 随机工具类
+ *
+ * 建议调用方自行维护 Random 对象
+ *
+ * @author ZhouXY
+ */
public final class RandomTools {
- public static final SecureRandom DEFAULT_SECURE_RANDOM = new SecureRandom();
+ private static final SecureRandom DEFAULT_SECURE_RANDOM;
+
+ static {
+ SecureRandom secureRandom = null;
+ try {
+ secureRandom = SecureRandom.getInstanceStrong(); // 获取高强度安全随机数生成器
+ }
+ catch (NoSuchAlgorithmException e) {
+ secureRandom = new SecureRandom(); // 获取普通的安全随机数生成器
+ }
+ DEFAULT_SECURE_RANDOM = secureRandom;
+ }
public static final String CAPITAL_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static final String LOWERCASE_LETTERS = "abcdefghijklmnopqrstuvwxyz";
public static final String NUMBERS = "0123456789";
+ public static SecureRandom defaultSecureRandom() {
+ return DEFAULT_SECURE_RANDOM;
+ }
+
+ public static ThreadLocalRandom currentThreadLocalRandom() {
+ return ThreadLocalRandom.current();
+ }
+
/**
* 使用传入的随机数生成器,生成指定长度的字符串
*
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/RandomToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/RandomToolsTests.java
new file mode 100644
index 0000000..fcf5f44
--- /dev/null
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/RandomToolsTests.java
@@ -0,0 +1,89 @@
+package xyz.zhouxy.plusone.commons.util;
+
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.security.SecureRandom;
+import java.util.Random;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+@SuppressWarnings("null")
+public class RandomToolsTests {
+
+ private static Random random;
+ private static SecureRandom secureRandom;
+ private static char[] sourceCharactersArray;
+ private static String sourceCharactersString;
+
+ @BeforeAll
+ public static void setUp() {
+ random = new Random();
+ secureRandom = new SecureRandom();
+ sourceCharactersArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
+ sourceCharactersString = "abcdefghijklmnopqrstuvwxyz";
+ }
+
+ @Test
+ public void randomStr_NullRandom_ThrowsException() {
+ assertThrows(IllegalArgumentException.class,
+ () -> RandomTools.randomStr(null, sourceCharactersArray, 5));
+ assertThrows(IllegalArgumentException.class,
+ () -> RandomTools.randomStr(null, sourceCharactersString, 5));
+ }
+
+ @Test
+ public void randomStr_NullSourceCharacters_ThrowsException() {
+ assertThrows(IllegalArgumentException.class, () -> RandomTools.randomStr(random, (char[]) null, 5));
+ assertThrows(IllegalArgumentException.class, () -> RandomTools.randomStr(random, (String) null, 5));
+ }
+
+ @Test
+ public void randomStr_NegativeLength_ThrowsException() {
+ assertThrows(IllegalArgumentException.class, () -> RandomTools.randomStr(random, sourceCharactersArray, -1));
+ }
+
+ @Test
+ public void randomStr_ZeroLength_ReturnsEmptyString() {
+ assertAll(
+ () -> assertEquals("", RandomTools.randomStr(random, sourceCharactersArray, 0)),
+ () -> assertEquals("", RandomTools.randomStr(random, sourceCharactersString, 0)),
+ () -> assertEquals("", RandomTools.randomStr(secureRandom, sourceCharactersArray, 0)),
+ () -> assertEquals("", RandomTools.randomStr(secureRandom, sourceCharactersString, 0)));
+ }
+
+ @Test
+ public void randomStr_PositiveLength_ReturnsRandomString() {
+ assertAll(
+ () -> assertEquals(5, RandomTools.randomStr(random, sourceCharactersArray, 5).length()),
+ () -> assertEquals(5, RandomTools.randomStr(random, sourceCharactersString, 5).length()),
+ () -> assertEquals(5, RandomTools.randomStr(secureRandom, sourceCharactersArray, 5).length()),
+ () -> assertEquals(5, RandomTools.randomStr(secureRandom, sourceCharactersString, 5).length()));
+ }
+
+ @Test
+ public void randomStr_ReturnsRandomString() {
+ String result = RandomTools.randomStr(sourceCharactersArray, 5);
+ assertEquals(5, result.length());
+ }
+
+ @Test
+ public void randomStr_StringSourceCharacters_ReturnsRandomString() {
+ String result = RandomTools.randomStr(sourceCharactersString, 5);
+ assertEquals(5, result.length());
+ }
+
+ @Test
+ public void secureRandomStr_ReturnsRandomString() {
+ String result = RandomTools.secureRandomStr(sourceCharactersArray, 5);
+ assertEquals(5, result.length());
+ }
+
+ @Test
+ public void secureRandomStr_StringSourceCharacters_ReturnsRandomString() {
+ String result = RandomTools.secureRandomStr(sourceCharactersString, 5);
+ assertEquals(5, result.length());
+ }
+}
From d72a5d32556a97783b24dea46fd691343b2bc284 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Sat, 28 Dec 2024 10:35:34 +0800
Subject: [PATCH 09/24] =?UTF-8?q?Chinese2ndGenIDCardNumber=20=E7=BB=A7?=
=?UTF-8?q?=E6=89=BF=E8=87=AA=20ValidatableStringRecord=EF=BC=9B=E6=B5=8B?=
=?UTF-8?q?=E8=AF=95=20ValidatableStringRecord=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../model/Chinese2ndGenIDCardNumber.java | 69 +++++++------------
.../model/ValidatableStringRecord.java | 17 +++--
.../model/Chinese2ndGenIDCardNumberTests.java | 7 +-
.../model/ValidatableStringRecordTests.java | 4 +-
4 files changed, 44 insertions(+), 53 deletions(-)
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumber.java b/src/main/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumber.java
index 4e1fed2..f802468 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumber.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumber.java
@@ -16,11 +16,9 @@
package xyz.zhouxy.plusone.commons.model;
-import java.io.Serializable;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Map;
-import java.util.Objects;
import java.util.regex.Matcher;
import com.google.common.base.Strings;
@@ -46,9 +44,9 @@ import xyz.zhouxy.plusone.commons.util.StringTools;
*/
@ValueObject
@Immutable
-public class Chinese2ndGenIDCardNumber implements IDCardNumber, Serializable {
-
- private final String value;
+public class Chinese2ndGenIDCardNumber
+ extends ValidatableStringRecord
+ implements IDCardNumber {
/** 省份编码 */
private final String provinceCode;
@@ -63,57 +61,49 @@ public class Chinese2ndGenIDCardNumber implements IDCardNumber, Serializable {
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
- private Chinese2ndGenIDCardNumber(String value, String provinceCode, String cityCode, String countyCode,
- Gender gender, LocalDate birthDate) {
- this.value = value;
- this.provinceCode = provinceCode;
- this.cityCode = cityCode;
- this.countyCode = countyCode;
- this.gender = gender;
- this.birthDate = birthDate;
- }
+ private Chinese2ndGenIDCardNumber(String value) {
+ super(value.toUpperCase(), PatternConsts.CHINESE_2ND_ID_CARD_NUMBER, () -> "二代居民身份证校验失败:" + value);
- public static Chinese2ndGenIDCardNumber of(final String value) {
- AssertTools.checkArgument(StringTools.isNotBlank(value), "二代居民身份证校验失败:号码为空");
- final String idNumber = value.toUpperCase();
+ final Matcher matcher = getMatcher();
- final Matcher matcher = PatternConsts.CHINESE_2ND_ID_CARD_NUMBER.matcher(idNumber);
- AssertTools.checkArgument(matcher.matches(), () -> "二代居民身份证校验失败:" + value);
+ final String provinceCodeValue = matcher.group("province");
+ AssertTools.checkArgument(Chinese2ndGenIDCardNumber.PROVINCE_CODES.containsKey(provinceCodeValue));
- final String provinceCode = matcher.group("province");
- AssertTools.checkArgument(Chinese2ndGenIDCardNumber.PROVINCE_CODES.containsKey(provinceCode));
+ final String cityCodeValue = matcher.group("city");
+ final String countyCodeValue = matcher.group("county");
- final String cityCode = matcher.group("city");
- final String countyCode = matcher.group("county");
-
- final Gender gender;
- final LocalDate birthDate;
+ final Gender genderValue;
+ final LocalDate birthDateValue;
try {
// 出生日期
final String birthDateStr = matcher.group("birthDate");
- birthDate = LocalDate.parse(birthDateStr, DATE_FORMATTER);
+ birthDateValue = LocalDate.parse(birthDateStr, DATE_FORMATTER);
// 性别
final int genderCode = Integer.parseInt(matcher.group("gender"));
- gender = genderCode % 2 == 0 ? Gender.FEMALE : Gender.MALE;
+ genderValue = genderCode % 2 == 0 ? Gender.FEMALE : Gender.MALE;
}
catch (Exception e) {
throw new IllegalArgumentException(e);
}
- return new Chinese2ndGenIDCardNumber(idNumber, provinceCode, cityCode, countyCode, gender, birthDate);
+ this.provinceCode = provinceCodeValue;
+ this.cityCode = cityCodeValue;
+ this.countyCode = countyCodeValue;
+ this.gender = genderValue;
+ this.birthDate = birthDateValue;
+ }
+
+ public static Chinese2ndGenIDCardNumber of(final String value) {
+ AssertTools.checkArgument(StringTools.isNotBlank(value), "二代居民身份证校验失败:号码为空");
+ return new Chinese2ndGenIDCardNumber(value);
}
// ================================
// #region - reader methods
// ================================
- @ReaderMethod
- public String value() {
- return value;
- }
-
@ReaderMethod
public String getProvinceCode() {
return provinceCode;
@@ -213,18 +203,11 @@ public class Chinese2ndGenIDCardNumber implements IDCardNumber, Serializable {
@Override
public int hashCode() {
- return Objects.hashCode(value);
+ return super.hashCode();
}
@Override
public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (!(obj instanceof Chinese2ndGenIDCardNumber))
- return false;
- Chinese2ndGenIDCardNumber other = (Chinese2ndGenIDCardNumber) obj;
- return Objects.equals(value, other.value);
+ return super.equals(obj);
}
-
- private static final long serialVersionUID = 8390082242712103716L;
}
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/model/ValidatableStringRecord.java b/src/main/java/xyz/zhouxy/plusone/commons/model/ValidatableStringRecord.java
index ce89ef5..c679a14 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/model/ValidatableStringRecord.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/model/ValidatableStringRecord.java
@@ -23,6 +23,7 @@ import java.util.regex.Pattern;
import javax.annotation.Nonnull;
+import xyz.zhouxy.plusone.commons.annotation.ReaderMethod;
import xyz.zhouxy.plusone.commons.util.AssertTools;
/**
@@ -31,8 +32,8 @@ import xyz.zhouxy.plusone.commons.util.AssertTools;
* @author ZhouXY
* @since 0.1.0
*/
-public abstract class ValidatableStringRecord
- implements Comparable {
+public abstract class ValidatableStringRecord>
+ implements Comparable {
@Nonnull
private final String value;
@@ -62,18 +63,19 @@ public abstract class ValidatableStringRecord
*
* @return 字符串(不为空)
*/
+ @ReaderMethod
public final String value() {
return this.value;
}
@Override
- public int compareTo(ValidatableStringRecord o) {
- return this.value.compareTo(o.value);
+ public int compareTo(T o) {
+ return this.value.compareTo(o.value());
}
@Override
public int hashCode() {
- return Objects.hash(value);
+ return Objects.hash(getClass(), value);
}
@Override
@@ -84,8 +86,9 @@ public abstract class ValidatableStringRecord
return false;
if (getClass() != obj.getClass())
return false;
- ValidatableStringRecord other = (ValidatableStringRecord) obj;
- return Objects.equals(value, other.value);
+ @SuppressWarnings("unchecked")
+ T other = (T) obj;
+ return Objects.equals(value, other.value());
}
@Override
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumberTests.java b/src/test/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumberTests.java
index 6e68cff..07421fe 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumberTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/model/Chinese2ndGenIDCardNumberTests.java
@@ -51,7 +51,12 @@ public class Chinese2ndGenIDCardNumberTests {
assertEquals("1***************1X", idCardNumber.toDesensitizedString());
assertEquals("110***********111X", idCardNumber.toDesensitizedString(3, 4));
- assertEquals("11############111X", idCardNumber.toDesensitizedString('#', 2, 4));
+ assertEquals("110###############", idCardNumber.toDesensitizedString('#', 3, 0));
+ assertEquals("11010520000101111X", idCardNumber.toDesensitizedString(10, 8));
+
+ assertThrows(IllegalArgumentException.class, () -> idCardNumber.toDesensitizedString(-1, 5));
+ assertThrows(IllegalArgumentException.class, () -> idCardNumber.toDesensitizedString(5, -1));
+ assertThrows(IllegalArgumentException.class, () -> idCardNumber.toDesensitizedString(10, 9));
}
@Test
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/model/ValidatableStringRecordTests.java b/src/test/java/xyz/zhouxy/plusone/commons/model/ValidatableStringRecordTests.java
index 6fd5209..be3eb22 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/model/ValidatableStringRecordTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/model/ValidatableStringRecordTests.java
@@ -84,7 +84,7 @@ class User {
}
@ValueObject
-class Email extends ValidatableStringRecord {
+class Email extends ValidatableStringRecord {
private Email(String value) {
super(value, PatternConsts.EMAIL);
}
@@ -96,7 +96,7 @@ class Email extends ValidatableStringRecord {
}
@ValueObject
-class Username extends ValidatableStringRecord {
+class Username extends ValidatableStringRecord {
private Username(String username) {
super(username, PatternConsts.USERNAME);
}
From 9ccaa2d1d64ae8a0f705c6f32529a64e5ee8e9b7 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Sat, 28 Dec 2024 10:41:37 +0800
Subject: [PATCH 10/24] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20ProgressOfTesting.tx?=
=?UTF-8?q?t?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ProgressOfTesting.txt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt
index 0af1f01..e022231 100644
--- a/ProgressOfTesting.txt
+++ b/ProgressOfTesting.txt
@@ -1,6 +1,6 @@
[ ] 未开始测试 - 7 (10.45%)
-[-] 测试未完成 - 8 (11.94%)
-[Y] 测试完成 - 30 (44.78%)
+[-] 测试未完成 - 7 (10.45%)
+[Y] 测试完成 - 31 (46.27%)
[x] 无需测试 - 22 (32.84%)
xyz.zhouxy.plusone.commons
@@ -63,7 +63,7 @@ xyz.zhouxy.plusone.commons
│ │ Chinese2ndGenIDCardNumber.java [Y]
│ │ Gender.java [x]
│ │ IDCardNumber.java [Y]
- │ │ ValidatableStringRecord.java [-]
+ │ │ ValidatableStringRecord.java [Y]
│ │
│ └───dto
│ PageResult.java [-]
From 40302d83cfefd3b1118625bce0cf2049de86097e Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Sat, 28 Dec 2024 22:27:00 +0800
Subject: [PATCH 11/24] =?UTF-8?q?=E5=88=A0=E9=99=A4=20SQL=20=E6=9E=84?=
=?UTF-8?q?=E9=80=A0=E5=99=A8=E3=80=82=E6=9A=82=E4=B8=8D=E8=80=83=E8=99=91?=
=?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=B7=A5=E5=85=B7=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ProgressOfTesting.txt | 14 +-
.../org/apache/ibatis/jdbc/AbstractSQL.java | 740 ------------------
.../zhouxy/plusone/commons/sql/JdbcSql.java | 72 --
.../plusone/commons/sql/MyBatisSql.java | 73 --
.../xyz/zhouxy/plusone/commons/sql/SQL.java | 47 --
.../commons/sql/MyBatisSqlBuilderTests.java | 37 -
6 files changed, 4 insertions(+), 979 deletions(-)
delete mode 100644 src/main/java/org/apache/ibatis/jdbc/AbstractSQL.java
delete mode 100644 src/main/java/xyz/zhouxy/plusone/commons/sql/JdbcSql.java
delete mode 100644 src/main/java/xyz/zhouxy/plusone/commons/sql/MyBatisSql.java
delete mode 100644 src/main/java/xyz/zhouxy/plusone/commons/sql/SQL.java
delete mode 100644 src/test/java/xyz/zhouxy/plusone/commons/sql/MyBatisSqlBuilderTests.java
diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt
index e022231..0db7d21 100644
--- a/ProgressOfTesting.txt
+++ b/ProgressOfTesting.txt
@@ -1,7 +1,7 @@
-[ ] 未开始测试 - 7 (10.45%)
-[-] 测试未完成 - 7 (10.45%)
-[Y] 测试完成 - 31 (46.27%)
-[x] 无需测试 - 22 (32.84%)
+[ ] 未开始测试 - 5 (7.94%)
+[-] 测试未完成 - 5 (7.94%)
+[Y] 测试完成 - 31 (49.21%)
+[x] 无需测试 - 22 (34.92%)
xyz.zhouxy.plusone.commons
├───annotation
@@ -69,12 +69,6 @@ xyz.zhouxy.plusone.commons
│ PageResult.java [-]
│ PagingAndSortingQueryParams.java [-]
│ PagingParams.java [-]
- │ UnifiedResponse.java [-]
- │
- ├───sql
- │ JdbcSql.java [ ]
- │ MyBatisSql.java [-]
- │ SQL.java [ ]
│
├───time
│ Quarter.java [Y]
diff --git a/src/main/java/org/apache/ibatis/jdbc/AbstractSQL.java b/src/main/java/org/apache/ibatis/jdbc/AbstractSQL.java
deleted file mode 100644
index 6e031c4..0000000
--- a/src/main/java/org/apache/ibatis/jdbc/AbstractSQL.java
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * Copyright 2009-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.apache.ibatis.jdbc;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * @author Clinton Begin
- * @author Jeff Butler
- * @author Adam Gent
- * @author Kazuki Shimizu
- */
-public abstract class AbstractSQL {
-
- private static final String AND = ") \nAND (";
- private static final String OR = ") \nOR (";
-
- private final SQLStatement sql = new SQLStatement();
-
- public abstract T getSelf();
-
- public T UPDATE(String table) {
- sql().statementType = SQLStatement.StatementType.UPDATE;
- sql().tables.add(table);
- return getSelf();
- }
-
- public T SET(String sets) {
- sql().sets.add(sets);
- return getSelf();
- }
-
- /**
- * Sets the.
- *
- * @param sets
- * the sets
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T SET(String... sets) {
- sql().sets.addAll(Arrays.asList(sets));
- return getSelf();
- }
-
- public T INSERT_INTO(String tableName) {
- sql().statementType = SQLStatement.StatementType.INSERT;
- sql().tables.add(tableName);
- return getSelf();
- }
-
- public T VALUES(String columns, String values) {
- INTO_COLUMNS(columns);
- INTO_VALUES(values);
- return getSelf();
- }
-
- /**
- * Into columns.
- *
- * @param columns
- * the columns
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T INTO_COLUMNS(String... columns) {
- sql().columns.addAll(Arrays.asList(columns));
- return getSelf();
- }
-
- /**
- * Into values.
- *
- * @param values
- * the values
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T INTO_VALUES(String... values) {
- List list = sql().valuesList.get(sql().valuesList.size() - 1);
- Collections.addAll(list, values);
- return getSelf();
- }
-
- public T SELECT(String columns) {
- sql().statementType = SQLStatement.StatementType.SELECT;
- sql().select.add(columns);
- return getSelf();
- }
-
- /**
- * Select.
- *
- * @param columns
- * the columns
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T SELECT(String... columns) {
- sql().statementType = SQLStatement.StatementType.SELECT;
- sql().select.addAll(Arrays.asList(columns));
- return getSelf();
- }
-
- public T SELECT_DISTINCT(String columns) {
- sql().distinct = true;
- SELECT(columns);
- return getSelf();
- }
-
- /**
- * Select distinct.
- *
- * @param columns
- * the columns
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T SELECT_DISTINCT(String... columns) {
- sql().distinct = true;
- SELECT(columns);
- return getSelf();
- }
-
- public T DELETE_FROM(String table) {
- sql().statementType = SQLStatement.StatementType.DELETE;
- sql().tables.add(table);
- return getSelf();
- }
-
- public T FROM(String table) {
- sql().tables.add(table);
- return getSelf();
- }
-
- /**
- * From.
- *
- * @param tables
- * the tables
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T FROM(String... tables) {
- sql().tables.addAll(Arrays.asList(tables));
- return getSelf();
- }
-
- public T JOIN(String join) {
- sql().join.add(join);
- return getSelf();
- }
-
- /**
- * Join.
- *
- * @param joins
- * the joins
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T JOIN(String... joins) {
- sql().join.addAll(Arrays.asList(joins));
- return getSelf();
- }
-
- public T INNER_JOIN(String join) {
- sql().innerJoin.add(join);
- return getSelf();
- }
-
- /**
- * Inner join.
- *
- * @param joins
- * the joins
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T INNER_JOIN(String... joins) {
- sql().innerJoin.addAll(Arrays.asList(joins));
- return getSelf();
- }
-
- public T LEFT_OUTER_JOIN(String join) {
- sql().leftOuterJoin.add(join);
- return getSelf();
- }
-
- /**
- * Left outer join.
- *
- * @param joins
- * the joins
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T LEFT_OUTER_JOIN(String... joins) {
- sql().leftOuterJoin.addAll(Arrays.asList(joins));
- return getSelf();
- }
-
- public T RIGHT_OUTER_JOIN(String join) {
- sql().rightOuterJoin.add(join);
- return getSelf();
- }
-
- /**
- * Right outer join.
- *
- * @param joins
- * the joins
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T RIGHT_OUTER_JOIN(String... joins) {
- sql().rightOuterJoin.addAll(Arrays.asList(joins));
- return getSelf();
- }
-
- public T OUTER_JOIN(String join) {
- sql().outerJoin.add(join);
- return getSelf();
- }
-
- /**
- * Outer join.
- *
- * @param joins
- * the joins
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T OUTER_JOIN(String... joins) {
- sql().outerJoin.addAll(Arrays.asList(joins));
- return getSelf();
- }
-
- public T WHERE(String conditions) {
- sql().where.add(conditions);
- sql().lastList = sql().where;
- return getSelf();
- }
-
- /**
- * Where.
- *
- * @param conditions
- * the conditions
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T WHERE(String... conditions) {
- sql().where.addAll(Arrays.asList(conditions));
- sql().lastList = sql().where;
- return getSelf();
- }
-
- public T OR() {
- sql().lastList.add(OR);
- return getSelf();
- }
-
- public T AND() {
- sql().lastList.add(AND);
- return getSelf();
- }
-
- public T GROUP_BY(String columns) {
- sql().groupBy.add(columns);
- return getSelf();
- }
-
- /**
- * Group by.
- *
- * @param columns
- * the columns
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T GROUP_BY(String... columns) {
- sql().groupBy.addAll(Arrays.asList(columns));
- return getSelf();
- }
-
- public T HAVING(String conditions) {
- sql().having.add(conditions);
- sql().lastList = sql().having;
- return getSelf();
- }
-
- /**
- * Having.
- *
- * @param conditions
- * the conditions
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T HAVING(String... conditions) {
- sql().having.addAll(Arrays.asList(conditions));
- sql().lastList = sql().having;
- return getSelf();
- }
-
- public T ORDER_BY(String columns) {
- sql().orderBy.add(columns);
- return getSelf();
- }
-
- /**
- * Order by.
- *
- * @param columns
- * the columns
- *
- * @return the t
- *
- * @since 3.4.2
- */
- public T ORDER_BY(String... columns) {
- sql().orderBy.addAll(Arrays.asList(columns));
- return getSelf();
- }
-
- /**
- * Set the limit variable string(e.g. {@code "#{limit}"}).
- *
- * @param variable
- * a limit variable string
- *
- * @return a self instance
- *
- * @see #OFFSET(String)
- *
- * @since 3.5.2
- */
- public T LIMIT(String variable) {
- sql().limit = variable;
- sql().limitingRowsStrategy = SQLStatement.LimitingRowsStrategy.OFFSET_LIMIT;
- return getSelf();
- }
-
- /**
- * Set the limit value.
- *
- * @param value
- * an offset value
- *
- * @return a self instance
- *
- * @see #OFFSET(long)
- *
- * @since 3.5.2
- */
- public T LIMIT(int value) {
- return LIMIT(String.valueOf(value));
- }
-
- /**
- * Set the offset variable string(e.g. {@code "#{offset}"}).
- *
- * @param variable
- * a offset variable string
- *
- * @return a self instance
- *
- * @see #LIMIT(String)
- *
- * @since 3.5.2
- */
- public T OFFSET(String variable) {
- sql().offset = variable;
- sql().limitingRowsStrategy = SQLStatement.LimitingRowsStrategy.OFFSET_LIMIT;
- return getSelf();
- }
-
- /**
- * Set the offset value.
- *
- * @param value
- * an offset value
- *
- * @return a self instance
- *
- * @see #LIMIT(int)
- *
- * @since 3.5.2
- */
- public T OFFSET(long value) {
- return OFFSET(String.valueOf(value));
- }
-
- /**
- * Set the fetch first rows variable string(e.g. {@code "#{fetchFirstRows}"}).
- *
- * @param variable
- * a fetch first rows variable string
- *
- * @return a self instance
- *
- * @see #OFFSET_ROWS(String)
- *
- * @since 3.5.2
- */
- public T FETCH_FIRST_ROWS_ONLY(String variable) {
- sql().limit = variable;
- sql().limitingRowsStrategy = SQLStatement.LimitingRowsStrategy.ISO;
- return getSelf();
- }
-
- /**
- * Set the fetch first rows value.
- *
- * @param value
- * a fetch first rows value
- *
- * @return a self instance
- *
- * @see #OFFSET_ROWS(long)
- *
- * @since 3.5.2
- */
- public T FETCH_FIRST_ROWS_ONLY(int value) {
- return FETCH_FIRST_ROWS_ONLY(String.valueOf(value));
- }
-
- /**
- * Set the offset rows variable string(e.g. {@code "#{offset}"}).
- *
- * @param variable
- * a offset rows variable string
- *
- * @return a self instance
- *
- * @see #FETCH_FIRST_ROWS_ONLY(String)
- *
- * @since 3.5.2
- */
- public T OFFSET_ROWS(String variable) {
- sql().offset = variable;
- sql().limitingRowsStrategy = SQLStatement.LimitingRowsStrategy.ISO;
- return getSelf();
- }
-
- /**
- * Set the offset rows value.
- *
- * @param value
- * an offset rows value
- *
- * @return a self instance
- *
- * @see #FETCH_FIRST_ROWS_ONLY(int)
- *
- * @since 3.5.2
- */
- public T OFFSET_ROWS(long value) {
- return OFFSET_ROWS(String.valueOf(value));
- }
-
- /**
- * used to add a new inserted row while do multi-row insert.
- *
- * @return the t
- *
- * @since 3.5.2
- */
- public T ADD_ROW() {
- sql().valuesList.add(new ArrayList<>());
- return getSelf();
- }
-
- private SQLStatement sql() {
- return sql;
- }
-
- public A usingAppender(A a) {
- sql().sql(a);
- return a;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sql().sql(sb);
- return sb.toString();
- }
-
- private static class SafeAppendable {
- private final Appendable appendable;
- private boolean empty = true;
-
- public SafeAppendable(Appendable a) {
- this.appendable = a;
- }
-
- public SafeAppendable append(CharSequence s) {
- try {
- if (empty && s.length() > 0) {
- empty = false;
- }
- appendable.append(s);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return this;
- }
-
- public boolean isEmpty() {
- return empty;
- }
-
- }
-
- private static class SQLStatement {
-
- public enum StatementType {
-
- DELETE,
-
- INSERT,
-
- SELECT,
-
- UPDATE
-
- }
-
- private enum LimitingRowsStrategy {
- NOP {
- @Override
- protected void appendClause(SafeAppendable builder, String offset, String limit) {
- // NOP
- }
- },
- ISO {
- @Override
- protected void appendClause(SafeAppendable builder, String offset, String limit) {
- if (offset != null) {
- builder.append(" OFFSET ").append(offset).append(" ROWS");
- }
- if (limit != null) {
- builder.append(" FETCH FIRST ").append(limit).append(" ROWS ONLY");
- }
- }
- },
- OFFSET_LIMIT {
- @Override
- protected void appendClause(SafeAppendable builder, String offset, String limit) {
- if (limit != null) {
- builder.append(" LIMIT ").append(limit);
- }
- if (offset != null) {
- builder.append(" OFFSET ").append(offset);
- }
- }
- };
-
- protected abstract void appendClause(SafeAppendable builder, String offset, String limit);
-
- }
-
- StatementType statementType;
- List sets = new ArrayList<>();
- List select = new ArrayList<>();
- List tables = new ArrayList<>();
- List join = new ArrayList<>();
- List innerJoin = new ArrayList<>();
- List outerJoin = new ArrayList<>();
- List leftOuterJoin = new ArrayList<>();
- List rightOuterJoin = new ArrayList<>();
- List where = new ArrayList<>();
- List having = new ArrayList<>();
- List groupBy = new ArrayList<>();
- List orderBy = new ArrayList<>();
- List lastList = new ArrayList<>();
- List columns = new ArrayList<>();
- List> valuesList = new ArrayList<>();
- boolean distinct;
- String offset;
- String limit;
- LimitingRowsStrategy limitingRowsStrategy = LimitingRowsStrategy.NOP;
-
- public SQLStatement() {
- // Prevent Synthetic Access
- valuesList.add(new ArrayList<>());
- }
-
- private void sqlClause(SafeAppendable builder, String keyword, List parts, String open, String close,
- String conjunction) {
- if (!parts.isEmpty()) {
- if (!builder.isEmpty()) {
- builder.append("\n");
- }
- builder.append(keyword);
- builder.append(" ");
- builder.append(open);
- String last = "________";
- for (int i = 0, n = parts.size(); i < n; i++) {
- String part = parts.get(i);
- if (i > 0 && !part.equals(AND) && !part.equals(OR) && !last.equals(AND) && !last.equals(OR)) {
- builder.append(conjunction);
- }
- builder.append(part);
- last = part;
- }
- builder.append(close);
- }
- }
-
- private String selectSQL(SafeAppendable builder) {
- if (distinct) {
- sqlClause(builder, "SELECT DISTINCT", select, "", "", ", ");
- } else {
- sqlClause(builder, "SELECT", select, "", "", ", ");
- }
-
- sqlClause(builder, "FROM", tables, "", "", ", ");
- joins(builder);
- sqlClause(builder, "WHERE", where, "(", ")", " AND ");
- sqlClause(builder, "GROUP BY", groupBy, "", "", ", ");
- sqlClause(builder, "HAVING", having, "(", ")", " AND ");
- sqlClause(builder, "ORDER BY", orderBy, "", "", ", ");
- limitingRowsStrategy.appendClause(builder, offset, limit);
- return builder.toString();
- }
-
- private void joins(SafeAppendable builder) {
- sqlClause(builder, "JOIN", join, "", "", "\nJOIN ");
- sqlClause(builder, "INNER JOIN", innerJoin, "", "", "\nINNER JOIN ");
- sqlClause(builder, "OUTER JOIN", outerJoin, "", "", "\nOUTER JOIN ");
- sqlClause(builder, "LEFT OUTER JOIN", leftOuterJoin, "", "", "\nLEFT OUTER JOIN ");
- sqlClause(builder, "RIGHT OUTER JOIN", rightOuterJoin, "", "", "\nRIGHT OUTER JOIN ");
- }
-
- private String insertSQL(SafeAppendable builder) {
- sqlClause(builder, "INSERT INTO", tables, "", "", "");
- sqlClause(builder, "", columns, "(", ")", ", ");
- for (int i = 0; i < valuesList.size(); i++) {
- sqlClause(builder, i > 0 ? "," : "VALUES", valuesList.get(i), "(", ")", ", ");
- }
- return builder.toString();
- }
-
- private String deleteSQL(SafeAppendable builder) {
- sqlClause(builder, "DELETE FROM", tables, "", "", "");
- sqlClause(builder, "WHERE", where, "(", ")", " AND ");
- limitingRowsStrategy.appendClause(builder, null, limit);
- return builder.toString();
- }
-
- private String updateSQL(SafeAppendable builder) {
- sqlClause(builder, "UPDATE", tables, "", "", "");
- joins(builder);
- sqlClause(builder, "SET", sets, "", "", ", ");
- sqlClause(builder, "WHERE", where, "(", ")", " AND ");
- limitingRowsStrategy.appendClause(builder, null, limit);
- return builder.toString();
- }
-
- public String sql(Appendable a) {
- SafeAppendable builder = new SafeAppendable(a);
- if (statementType == null) {
- return null;
- }
-
- String answer;
-
- switch (statementType) {
- case DELETE:
- answer = deleteSQL(builder);
- break;
-
- case INSERT:
- answer = insertSQL(builder);
- break;
-
- case SELECT:
- answer = selectSQL(builder);
- break;
-
- case UPDATE:
- answer = updateSQL(builder);
- break;
-
- default:
- answer = null;
- }
-
- return answer;
- }
- }
-}
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/sql/JdbcSql.java b/src/main/java/xyz/zhouxy/plusone/commons/sql/JdbcSql.java
deleted file mode 100644
index 5844d28..0000000
--- a/src/main/java/xyz/zhouxy/plusone/commons/sql/JdbcSql.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2023-2024 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 xyz.zhouxy.plusone.commons.sql;
-
-import java.util.Collection;
-
-import xyz.zhouxy.plusone.commons.util.StringTools;
-
-public class JdbcSql extends SQL {
-
- JdbcSql() {
- super();
- }
-
- public static JdbcSql newSql() {
- return new JdbcSql();
- }
-
- @Override
- public JdbcSql getSelf() {
- return this;
- }
-
- public static String IN(String col, Collection> c) { // NOSONAR
- return IN(col, c.size());
- }
-
- public static String IN(String col, T[] c) { // NOSONAR
- return IN(col, c.length);
- }
-
- private static String IN(String col, int length) { // NOSONAR
- if (length == 0) {
- return "false";
- }
- return col + " IN (" + buildQuestionsList(length) + ')';
- }
-
- public static String NOT_IN(String col, Collection> c) { // NOSONAR
- return NOT_IN(col, c.size());
- }
-
- public static String NOT_IN(String col, T[] c) { // NOSONAR
- return NOT_IN(col, c.length);
- }
-
- private static String NOT_IN(String col, int length) { // NOSONAR
- if (length == 0) {
- return "true";
- }
- return col + " NOT IN (" + buildQuestionsList(length) + ')';
- }
-
- private static String buildQuestionsList(int times) {
- final int length = times <= 0 ? 0 : (times * 3 - 2);
- return StringTools.repeat("?, ", times, length);
- }
-}
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/sql/MyBatisSql.java b/src/main/java/xyz/zhouxy/plusone/commons/sql/MyBatisSql.java
deleted file mode 100644
index 0382d43..0000000
--- a/src/main/java/xyz/zhouxy/plusone/commons/sql/MyBatisSql.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2023-2024 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 xyz.zhouxy.plusone.commons.sql;
-
-import com.google.common.annotations.Beta;
-
-@Beta
-public class MyBatisSql extends SQL {
-
- private final boolean withScript;
-
- MyBatisSql(boolean withScript) {
- super();
- this.withScript = withScript;
- }
-
- public static MyBatisSql newSql() {
- return new MyBatisSql(false);
- }
-
- public static MyBatisSql newScriptSql() {
- return new MyBatisSql(true);
- }
-
- @Override
- public MyBatisSql getSelf() {
- return this;
- }
-
- public static String IN(String col, String paramName) { // NOSONAR
- return " " + col + " IN" + buildForeach(col, paramName);
- }
-
- public static String NOT_IN(String col, String paramName) { // NOSONAR
- return col + " NOT IN" + buildForeach(col, paramName);
- }
-
- private static String buildForeach(String col, String paramName) {
- final String format = "" +
- "#{%s}" +
- " ";
- return String.format(format, col, paramName, col);
- }
-
- @Override
- public String toString() {
- if (withScript) {
- return "";
- }
- return super.toString();
- }
-}
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/sql/SQL.java b/src/main/java/xyz/zhouxy/plusone/commons/sql/SQL.java
deleted file mode 100644
index a699639..0000000
--- a/src/main/java/xyz/zhouxy/plusone/commons/sql/SQL.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2023-2024 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 xyz.zhouxy.plusone.commons.sql;
-
-import org.apache.ibatis.jdbc.AbstractSQL;
-
-import com.google.common.annotations.Beta;
-
-/**
- * @author ZhouXY
- */
-@Beta
-public abstract class SQL extends AbstractSQL {
-
- public static JdbcSql newJdbcSql() {
- return new JdbcSql();
- }
-
- public static MyBatisSql newMyBatisSql(boolean withScript) {
- return new MyBatisSql(withScript);
- }
-
- public T WHERE(boolean condition, String sqlCondition) { // NOSONAR
- if (condition) {
- return WHERE(sqlCondition);
- }
- return getSelf();
- }
-
- public T WHERE(boolean condition, String ifSqlCondition, String elseSqlCondition) { // NOSONAR
- return WHERE(condition ? ifSqlCondition : elseSqlCondition);
- }
-}
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/sql/MyBatisSqlBuilderTests.java b/src/test/java/xyz/zhouxy/plusone/commons/sql/MyBatisSqlBuilderTests.java
deleted file mode 100644
index 8576ad5..0000000
--- a/src/test/java/xyz/zhouxy/plusone/commons/sql/MyBatisSqlBuilderTests.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2023-2024 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 xyz.zhouxy.plusone.commons.sql;
-
-import static xyz.zhouxy.plusone.commons.sql.MyBatisSql.IN;
-
-import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class MyBatisSqlBuilderTests {
- private static final Logger log = LoggerFactory.getLogger(MyBatisSqlBuilderTests.class);
-
- @Test
- void test() {
- // List ids = Arrays.asList("2333", "4501477");
- MyBatisSql sql = MyBatisSql.newScriptSql()
- .SELECT("*")
- .FROM("test_table")
- .WHERE(IN("id", "ids"));
- log.info("sql: {}", sql);
- }
-}
From ab2fc541628d1ecfb771082a0f33fa44e4c77ea0 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Sun, 29 Dec 2024 00:20:12 +0800
Subject: [PATCH 12/24] =?UTF-8?q?=E5=AE=8C=E6=88=90=20UnifiedResponse=20?=
=?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=EF=BC=9B=E6=96=B0=E5=A2=9E?=
=?UTF-8?q?=20PageResult#empty=EF=BC=8C=E4=BF=AE=E6=94=B9=20PageResult#toS?=
=?UTF-8?q?tring=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ProgressOfTesting.txt | 9 +-
.../plusone/commons/model/dto/PageResult.java | 8 +-
.../model/dto/UnifiedResponseTests.java | 612 +++++++++++++++---
3 files changed, 525 insertions(+), 104 deletions(-)
diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt
index 0db7d21..4e65a24 100644
--- a/ProgressOfTesting.txt
+++ b/ProgressOfTesting.txt
@@ -1,7 +1,7 @@
-[ ] 未开始测试 - 5 (7.94%)
-[-] 测试未完成 - 5 (7.94%)
-[Y] 测试完成 - 31 (49.21%)
-[x] 无需测试 - 22 (34.92%)
+[ ] 未开始测试 - 5 (7.81%)
+[-] 测试未完成 - 5 (7.81%)
+[Y] 测试完成 - 32 (50.00%)
+[x] 无需测试 - 22 (34.38%)
xyz.zhouxy.plusone.commons
├───annotation
@@ -69,6 +69,7 @@ xyz.zhouxy.plusone.commons
│ PageResult.java [-]
│ PagingAndSortingQueryParams.java [-]
│ PagingParams.java [-]
+ │ UnifiedResponse.java [Y]
│
├───time
│ Quarter.java [Y]
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PageResult.java b/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PageResult.java
index 7f913a8..b73d0a0 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PageResult.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PageResult.java
@@ -16,6 +16,7 @@
package xyz.zhouxy.plusone.commons.model.dto;
+import java.util.Collections;
import java.util.List;
import xyz.zhouxy.plusone.commons.annotation.StaticFactoryMethod;
@@ -46,6 +47,11 @@ public class PageResult {
return new PageResult<>(content, total);
}
+ @StaticFactoryMethod(PageResult.class)
+ public static PageResult empty() {
+ return new PageResult<>(Collections.emptyList(), 0L);
+ }
+
public long getTotal() {
return total;
}
@@ -56,6 +62,6 @@ public class PageResult {
@Override
public String toString() {
- return "PageDTO [total=" + total + ", content=" + content + "]";
+ return "PageResult [total=" + total + ", content=" + content + "]";
}
}
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/model/dto/UnifiedResponseTests.java b/src/test/java/xyz/zhouxy/plusone/commons/model/dto/UnifiedResponseTests.java
index 15ceb13..45a6ed2 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/model/dto/UnifiedResponseTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/model/dto/UnifiedResponseTests.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2024 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 xyz.zhouxy.plusone.commons.model.dto;
import static org.junit.jupiter.api.Assertions.*;
@@ -13,6 +29,7 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import xyz.zhouxy.plusone.commons.exception.business.BizException;
import xyz.zhouxy.plusone.commons.model.dto.UnifiedResponse.SuccessResult;
@Slf4j
@@ -33,7 +50,7 @@ class UnifiedResponseTests {
}
@Test
- void testSuccess_WithOutArgument() throws Exception {
+ void testSuccess_WithoutArgument() throws Exception {
// 1. success without argument
UnifiedResponse success = UnifiedResponse.success();
assertEquals(SuccessResult.SUCCESS_STATUS, success.getStatus());
@@ -56,68 +73,6 @@ class UnifiedResponseTests {
assertEquals("{\"status\":\"2000000\",\"message\":\"成功\"}", jacksonSuccessWithMessage);
}
- @Test
- void testSuccess_WithNullMessage() throws Exception {
- // 3. success with null message
- UnifiedResponse successWithNullMessage = UnifiedResponse.success(null);
- assertEquals(SuccessResult.SUCCESS_STATUS, successWithNullMessage.getStatus());
- assertEquals("", successWithNullMessage.getMessage());
- assertNull(successWithNullMessage.getData());
- String jacksonSuccessWithNullMessage = jackson.writeValueAsString(successWithNullMessage);
- log.info("jacksonSuccessWithNullMessage: {}", jacksonSuccessWithNullMessage);
- assertEquals("{\"status\":\"2000000\",\"message\":\"\"}", jacksonSuccessWithNullMessage);
- }
-
- @Test
- void testSuccess_WithEmptyMessage() throws Exception {
- // 4. success with empty message
- UnifiedResponse successWithEmptyMessage = UnifiedResponse.success("");
- assertEquals(SuccessResult.SUCCESS_STATUS, successWithEmptyMessage.getStatus());
- assertEquals("", successWithEmptyMessage.getMessage());
- assertNull(successWithEmptyMessage.getData());
- String jacksonSuccessWithEmptyMessage = jackson.writeValueAsString(successWithEmptyMessage);
- log.info("jacksonSuccessWithEmptyMessage: {}", jacksonSuccessWithEmptyMessage);
- assertEquals("{\"status\":\"2000000\",\"message\":\"\"}", jacksonSuccessWithEmptyMessage);
- }
-
- @Test
- void testSuccess_WithData_String() throws Exception {
- UnifiedResponse successWithStringData = UnifiedResponse.success("查询成功", "zhouxy");
- assertEquals(SuccessResult.SUCCESS_STATUS, successWithStringData.getStatus());
- assertEquals("查询成功", successWithStringData.getMessage());
- assertEquals("zhouxy", successWithStringData.getData());
- String jacksonSuccessWithStringData = jackson.writeValueAsString(successWithStringData);
- log.info("jacksonSuccessWithStringData: {}", jacksonSuccessWithStringData);
- assertEquals("{\"status\":\"2000000\",\"message\":\"查询成功\",\"data\":\"zhouxy\"}", jacksonSuccessWithStringData);
-
- assertEquals("{status: \"2000000\", message: \"查询成功\", data: \"zhouxy\"}", successWithStringData.toString());
- }
-
- @Test
- void testSuccess_WithData_Integer() throws Exception {
- final UnifiedResponse successWithIntegerData = UnifiedResponse.success("查询成功", 1);
- assertEquals(SuccessResult.SUCCESS_STATUS, successWithIntegerData.getStatus());
- assertEquals("查询成功", successWithIntegerData.getMessage());
- assertEquals(1, successWithIntegerData.getData());
- final String jacksonSuccessWithIntegerData = jackson.writeValueAsString(successWithIntegerData);
- log.info("jacksonSuccessWithIntegerData: {}", jacksonSuccessWithIntegerData);
- assertEquals("{\"status\":\"2000000\",\"message\":\"查询成功\",\"data\":1}", jacksonSuccessWithIntegerData);
-
- assertEquals("{status: \"2000000\", message: \"查询成功\", data: 1}", successWithIntegerData.toString());
- }
-
- @Test
- void testSuccess_WithData_PageResult() throws Exception {
- UnifiedResponse successWithData = UnifiedResponse.success("查询成功", pageResult);
- assertEquals(SuccessResult.SUCCESS_STATUS, successWithData.getStatus());
- assertEquals("查询成功", successWithData.getMessage());
- assertNotNull(successWithData.getData());
- assertEquals(pageResult, successWithData.getData());
- String jacksonSuccessWithData = jackson.writeValueAsString(successWithData);
- log.info("jacksonSuccessWithData: {}", jacksonSuccessWithData);
- assertEquals("{\"status\":\"2000000\",\"message\":\"查询成功\",\"data\":{\"total\":108,\"content\":[{\"username\":\"zhouxy1\",\"email\":\"zhouxy1@gmail.com\"},{\"username\":\"zhouxy2\",\"email\":\"zhouxy2@gmail.com\"}]}}", jacksonSuccessWithData);
- }
-
@Test
void testSuccess_WithMessageAndNullData() throws Exception {
// success with message and null data
@@ -133,17 +88,53 @@ class UnifiedResponseTests {
}
@Test
- void testSuccess_WithNullMessageAndData() throws Exception {
- // success with null message and data
- final User user = new User("zhouxy", "zhouxy@code108.cn");
- final UnifiedResponse successWithNullMessageAndData = UnifiedResponse.success(null, user);
- assertEquals(SuccessResult.SUCCESS_STATUS, successWithNullMessageAndData.getStatus());
- assertEquals("", successWithNullMessageAndData.getMessage());
- assertEquals(user, successWithNullMessageAndData.getData());
- final String jacksonSuccessWithNullMessageAndData = jackson.writeValueAsString(successWithNullMessageAndData);
- log.info("jacksonSuccessWithNullMessageAndData: {}", jacksonSuccessWithNullMessageAndData);
- assertEquals("{\"status\":\"2000000\",\"message\":\"\",\"data\":{\"username\":\"zhouxy\",\"email\":\"zhouxy@code108.cn\"}}",
- jacksonSuccessWithNullMessageAndData);
+ void testSuccess_WithMessageAndStringData() throws Exception {
+ UnifiedResponse successWithStringData = UnifiedResponse.success("查询成功", "zhouxy");
+ assertEquals(SuccessResult.SUCCESS_STATUS, successWithStringData.getStatus());
+ assertEquals("查询成功", successWithStringData.getMessage());
+ assertEquals("zhouxy", successWithStringData.getData());
+ String jacksonSuccessWithStringData = jackson.writeValueAsString(successWithStringData);
+ log.info("jacksonSuccessWithStringData: {}", jacksonSuccessWithStringData);
+ assertEquals("{\"status\":\"2000000\",\"message\":\"查询成功\",\"data\":\"zhouxy\"}", jacksonSuccessWithStringData);
+
+ assertEquals("{status: \"2000000\", message: \"查询成功\", data: \"zhouxy\"}", successWithStringData.toString());
+ }
+
+ @Test
+ void testSuccess_WithMessageAndIntegerData() throws Exception {
+ final UnifiedResponse successWithIntegerData = UnifiedResponse.success("查询成功", 1);
+ assertEquals(SuccessResult.SUCCESS_STATUS, successWithIntegerData.getStatus());
+ assertEquals("查询成功", successWithIntegerData.getMessage());
+ assertEquals(1, successWithIntegerData.getData());
+ final String jacksonSuccessWithIntegerData = jackson.writeValueAsString(successWithIntegerData);
+ log.info("jacksonSuccessWithIntegerData: {}", jacksonSuccessWithIntegerData);
+ assertEquals("{\"status\":\"2000000\",\"message\":\"查询成功\",\"data\":1}", jacksonSuccessWithIntegerData);
+
+ assertEquals("{status: \"2000000\", message: \"查询成功\", data: 1}", successWithIntegerData.toString());
+ }
+
+ @Test
+ void testSuccess_WithMessageAndData() throws Exception {
+ UnifiedResponse successWithData = UnifiedResponse.success("查询成功", pageResult);
+ assertEquals(SuccessResult.SUCCESS_STATUS, successWithData.getStatus());
+ assertEquals("查询成功", successWithData.getMessage());
+ assertNotNull(successWithData.getData());
+ assertEquals(pageResult, successWithData.getData());
+ String jacksonSuccessWithData = jackson.writeValueAsString(successWithData);
+ log.info("jacksonSuccessWithData: {}", jacksonSuccessWithData);
+ assertEquals("{\"status\":\"2000000\",\"message\":\"查询成功\",\"data\":{\"total\":108,\"content\":[{\"username\":\"zhouxy1\",\"email\":\"zhouxy1@gmail.com\"},{\"username\":\"zhouxy2\",\"email\":\"zhouxy2@gmail.com\"}]}}", jacksonSuccessWithData);
+ }
+
+ @Test
+ void testSuccess_WithNullMessage() throws Exception {
+ // 3. success with null message
+ UnifiedResponse successWithNullMessage = UnifiedResponse.success(null);
+ assertEquals(SuccessResult.SUCCESS_STATUS, successWithNullMessage.getStatus());
+ assertEquals("", successWithNullMessage.getMessage());
+ assertNull(successWithNullMessage.getData());
+ String jacksonSuccessWithNullMessage = jackson.writeValueAsString(successWithNullMessage);
+ log.info("jacksonSuccessWithNullMessage: {}", jacksonSuccessWithNullMessage);
+ assertEquals("{\"status\":\"2000000\",\"message\":\"\"}", jacksonSuccessWithNullMessage);
}
// success with null message and null data
@@ -161,18 +152,30 @@ class UnifiedResponseTests {
assertEquals("{status: \"2000000\", message: \"\", data: null}", successWithNullMessageAndNullData.toString());
}
- // success with empty message and data
@Test
- void testSuccess_WithEmptyMessageAndData() throws Exception {
- final User user = new User("zhouxy", "zhouxy@gmail.com");
- final UnifiedResponse successWithEmptyMessageAndData = UnifiedResponse.success("", user);
- assertEquals(SuccessResult.SUCCESS_STATUS, successWithEmptyMessageAndData.getStatus());
- assertEquals("", successWithEmptyMessageAndData.getMessage());
- assertEquals(user, successWithEmptyMessageAndData.getData());
+ void testSuccess_WithNullMessageAndData() throws Exception {
+ // success with null message and data
+ final User user = new User("zhouxy", "zhouxy@code108.cn");
+ final UnifiedResponse successWithNullMessageAndData = UnifiedResponse.success(null, user);
+ assertEquals(SuccessResult.SUCCESS_STATUS, successWithNullMessageAndData.getStatus());
+ assertEquals("", successWithNullMessageAndData.getMessage());
+ assertEquals(user, successWithNullMessageAndData.getData());
+ final String jacksonSuccessWithNullMessageAndData = jackson.writeValueAsString(successWithNullMessageAndData);
+ log.info("jacksonSuccessWithNullMessageAndData: {}", jacksonSuccessWithNullMessageAndData);
+ assertEquals("{\"status\":\"2000000\",\"message\":\"\",\"data\":{\"username\":\"zhouxy\",\"email\":\"zhouxy@code108.cn\"}}",
+ jacksonSuccessWithNullMessageAndData);
+ }
- final String jacksonSuccessWithEmptyMessageAndData = jackson.writeValueAsString(successWithEmptyMessageAndData);
- log.info("jacksonSuccessWithEmptyMessageAndData: {}", jacksonSuccessWithEmptyMessageAndData);
- assertEquals("{\"status\":\"2000000\",\"message\":\"\",\"data\":{\"username\":\"zhouxy\",\"email\":\"zhouxy@gmail.com\"}}", jacksonSuccessWithEmptyMessageAndData);
+ @Test
+ void testSuccess_WithEmptyMessage() throws Exception {
+ // 4. success with empty message
+ UnifiedResponse successWithEmptyMessage = UnifiedResponse.success("");
+ assertEquals(SuccessResult.SUCCESS_STATUS, successWithEmptyMessage.getStatus());
+ assertEquals("", successWithEmptyMessage.getMessage());
+ assertNull(successWithEmptyMessage.getData());
+ String jacksonSuccessWithEmptyMessage = jackson.writeValueAsString(successWithEmptyMessage);
+ log.info("jacksonSuccessWithEmptyMessage: {}", jacksonSuccessWithEmptyMessage);
+ assertEquals("{\"status\":\"2000000\",\"message\":\"\"}", jacksonSuccessWithEmptyMessage);
}
// success with empty message and null data
@@ -190,22 +193,297 @@ class UnifiedResponseTests {
assertEquals("{status: \"2000000\", message: \"\", data: null}", successWithEmptyMessageAndNullData.toString());
}
+ // success with empty message and data
@Test
- void testError_Status_And_Message() throws Exception {
+ void testSuccess_WithEmptyMessageAndData() throws Exception {
+ final User user = new User("zhouxy", "zhouxy@gmail.com");
+ final UnifiedResponse successWithEmptyMessageAndData = UnifiedResponse.success("", user);
+ assertEquals(SuccessResult.SUCCESS_STATUS, successWithEmptyMessageAndData.getStatus());
+ assertEquals("", successWithEmptyMessageAndData.getMessage());
+ assertEquals(user, successWithEmptyMessageAndData.getData());
+
+ final String jacksonSuccessWithEmptyMessageAndData = jackson.writeValueAsString(successWithEmptyMessageAndData);
+ log.info("jacksonSuccessWithEmptyMessageAndData: {}", jacksonSuccessWithEmptyMessageAndData);
+ assertEquals("{\"status\":\"2000000\",\"message\":\"\",\"data\":{\"username\":\"zhouxy\",\"email\":\"zhouxy@gmail.com\"}}", jacksonSuccessWithEmptyMessageAndData);
+ }
+
+ @Test
+ void testError_WithMessage() throws Exception {
+ UnifiedResponse errorWithMessage = UnifiedResponse.error("查询失败");
+ assertEquals("9999999", errorWithMessage.getStatus());
+ assertEquals("查询失败", errorWithMessage.getMessage());
+ assertNull(errorWithMessage.getData());
+
+ final String jacksonErrorWithMessage = jackson.writeValueAsString(errorWithMessage);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"查询失败\"}", jacksonErrorWithMessage);
+ final String gsonErrorWithMessage = gson.toJson(errorWithMessage);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"查询失败\"}", gsonErrorWithMessage);
+ }
+
+ @Test
+ void testError_WithMessage_AndNullData() throws Exception {
+ UnifiedResponse errorWithMessageAndNullData = UnifiedResponse.error("查询失败", (Object) null);
+ assertEquals("9999999", errorWithMessageAndNullData.getStatus());
+ assertEquals("查询失败", errorWithMessageAndNullData.getMessage());
+ assertNull(errorWithMessageAndNullData.getData());
+
+ final String jacksonErrorWithMessageAndNullData = jackson.writeValueAsString(errorWithMessageAndNullData);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"查询失败\"}", jacksonErrorWithMessageAndNullData);
+ final String gsonErrorWithMessageAndNullData = gson.toJson(errorWithMessageAndNullData);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"查询失败\"}", gsonErrorWithMessageAndNullData);
+ }
+
+ @Test
+ void testError_WithMessage_AndData() throws Exception {
+ final User user = new User("zhouxy", "zhouxy@gmail.com");
+ UnifiedResponse errorWithMessageAndData = UnifiedResponse.error("查询失败", user);
+ assertEquals("9999999", errorWithMessageAndData.getStatus());
+ assertEquals("查询失败", errorWithMessageAndData.getMessage());
+ assertEquals(user, errorWithMessageAndData.getData());
+
+ final String jacksonErrorWithMessageAndData = jackson.writeValueAsString(errorWithMessageAndData);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"查询失败\",\"data\":{\"username\":\"zhouxy\",\"email\":\"zhouxy@gmail.com\"}}",
+ jacksonErrorWithMessageAndData);
+ final String gsonErrorWithMessageAndData = gson.toJson(errorWithMessageAndData);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"查询失败\",\"data\":{\"username\":\"zhouxy\",\"email\":\"zhouxy@gmail.com\"}}",
+ gsonErrorWithMessageAndData);
+ }
+
+ @Test
+ void testError_WithNullMessage() throws Exception {
+ UnifiedResponse errorWithNullMessage = UnifiedResponse.error((String) null);
+ assertEquals("9999999", errorWithNullMessage.getStatus());
+ assertEquals("", errorWithNullMessage.getMessage());
+ assertNull(errorWithNullMessage.getData());
+
+ final String jacksonErrorWithNullMessage = jackson.writeValueAsString(errorWithNullMessage);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"\"}", jacksonErrorWithNullMessage);
+ final String gsonErrorWithNullMessage = gson.toJson(errorWithNullMessage);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"\"}", gsonErrorWithNullMessage);
+ }
+
+ @Test
+ void testError_WithNullMessage_AndNullData() throws Exception {
+ UnifiedResponse errorWithNullMessageAndNullData = UnifiedResponse.error((String) null, (User) null);
+ assertEquals("9999999", errorWithNullMessageAndNullData.getStatus());
+ assertEquals("", errorWithNullMessageAndNullData.getMessage());
+ assertNull(errorWithNullMessageAndNullData.getData());
+
+ final String jacksonErrorWithNullMessageAndNullData = jackson.writeValueAsString(errorWithNullMessageAndNullData);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"\"}", jacksonErrorWithNullMessageAndNullData);
+ final String gsonErrorWithNullMessageAndNullData = gson.toJson(errorWithNullMessageAndNullData);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"\"}", gsonErrorWithNullMessageAndNullData);
+ }
+
+ @Test
+ void testError_WithNullMessage_AndData() throws Exception {
+ final User user = new User("zhouxy1", "zhouxy1@gmail.com");
+ UnifiedResponse errorWithNullMessageAndData = UnifiedResponse.error((String) null, user);
+ assertEquals("9999999", errorWithNullMessageAndData.getStatus());
+ assertEquals("", errorWithNullMessageAndData.getMessage());
+ assertEquals(user, errorWithNullMessageAndData.getData());
+
+ final String jacksonErrorWithNullMessageAndData = jackson.writeValueAsString(errorWithNullMessageAndData);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"\",\"data\":{\"username\":\"zhouxy1\",\"email\":\"zhouxy1@gmail.com\"}}",
+ jacksonErrorWithNullMessageAndData);
+ final String gsonErrorWithNullMessageAndData = gson.toJson(errorWithNullMessageAndData);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"\",\"data\":{\"username\":\"zhouxy1\",\"email\":\"zhouxy1@gmail.com\"}}",
+ gsonErrorWithNullMessageAndData);
+ }
+
+ @Test
+ void testError_WithEmptyMessage() throws Exception {
+ UnifiedResponse errorWithEmptyMessage = UnifiedResponse.error("");
+ assertEquals("9999999", errorWithEmptyMessage.getStatus());
+ assertEquals("", errorWithEmptyMessage.getMessage());
+ assertNull(errorWithEmptyMessage.getData());
+ final String jacksonErrorWithEmptyMessage = jackson.writeValueAsString(errorWithEmptyMessage);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"\"}", jacksonErrorWithEmptyMessage);
+ final String gsonErrorWithEmptyMessage = gson.toJson(errorWithEmptyMessage);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"\"}", gsonErrorWithEmptyMessage);
+ }
+
+ @Test
+ void testError_WithEmptyMessage_AndNullData() throws Exception {
+ UnifiedResponse errorWithEmptyMessageAndNullData = UnifiedResponse.error("", (User) null);
+ assertEquals("9999999", errorWithEmptyMessageAndNullData.getStatus());
+ assertEquals("", errorWithEmptyMessageAndNullData.getMessage());
+ assertNull(errorWithEmptyMessageAndNullData.getData());
+
+ final String jacksonErrorEmptyNullMessageAndNullData = jackson.writeValueAsString(errorWithEmptyMessageAndNullData);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"\"}", jacksonErrorEmptyNullMessageAndNullData);
+ final String gsonErrorWithEmptyMessageAndNullData = gson.toJson(errorWithEmptyMessageAndNullData);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"\"}", gsonErrorWithEmptyMessageAndNullData);
+ }
+
+ @Test
+ void testError_WithEmptyMessage_AndData() throws Exception {
+ final User user = new User("zhouxy1", "zhouxy1@gmail.com");
+ UnifiedResponse errorWithEmptyMessageAndData = UnifiedResponse.error("", user);
+ assertEquals("9999999", errorWithEmptyMessageAndData.getStatus());
+ assertEquals("", errorWithEmptyMessageAndData.getMessage());
+ assertEquals(user, errorWithEmptyMessageAndData.getData());
+
+ final String jacksonErrorWithEmptyMessageAndData = jackson.writeValueAsString(errorWithEmptyMessageAndData);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"\",\"data\":{\"username\":\"zhouxy1\",\"email\":\"zhouxy1@gmail.com\"}}",
+ jacksonErrorWithEmptyMessageAndData);
+ final String gsonErrorWithEmptyMessageAndData = gson.toJson(errorWithEmptyMessageAndData);
+ assertEquals("{\"status\":\"9999999\",\"message\":\"\",\"data\":{\"username\":\"zhouxy1\",\"email\":\"zhouxy1@gmail.com\"}}",
+ gsonErrorWithEmptyMessageAndData);
+ }
+
+ @Test
+ void testError_WithStatusAndMessage() throws Exception {
final UnifiedResponse errorWithStatusAndMessage = UnifiedResponse.error(108, "查询失败");
assertEquals(108, errorWithStatusAndMessage.getStatus());
assertEquals("查询失败", errorWithStatusAndMessage.getMessage());
assertNull(errorWithStatusAndMessage.getData());
+ assertEquals("{status: 108, message: \"查询失败\", data: null}", errorWithStatusAndMessage.toString());
final String jacksonErrorWithStatusAndMessage = jackson.writeValueAsString(errorWithStatusAndMessage);
log.info("jacksonErrorWithStatusAndMessage: {}", jacksonErrorWithStatusAndMessage);
assertEquals("{\"status\":108,\"message\":\"查询失败\"}", jacksonErrorWithStatusAndMessage);
- assertEquals("{status: 108, message: \"查询失败\", data: null}", errorWithStatusAndMessage.toString());
+ final String gsonErrorWithStatusAndMessage = gson.toJson(errorWithStatusAndMessage);
+ assertEquals("{\"status\":108,\"message\":\"查询失败\"}", gsonErrorWithStatusAndMessage);
}
@Test
- void testError_NullStatus() {
+ void testError_WithStatusAndMessage_AndNullData() throws Exception {
+ final UnifiedResponse errorWithStatusAndMessageAndNullData = UnifiedResponse.error(108, "查询失败", null);
+ assertEquals(108, errorWithStatusAndMessageAndNullData.getStatus());
+ assertEquals("查询失败", errorWithStatusAndMessageAndNullData.getMessage());
+ assertNull(errorWithStatusAndMessageAndNullData.getData());
+ assertEquals("{status: 108, message: \"查询失败\", data: null}", errorWithStatusAndMessageAndNullData.toString());
+
+ final String jacksonErrorWithStatusAndMessageAndNullData = jackson.writeValueAsString(errorWithStatusAndMessageAndNullData);
+ log.info("jacksonErrorWithStatusAndMessage: {}", jacksonErrorWithStatusAndMessageAndNullData);
+ assertEquals("{\"status\":108,\"message\":\"查询失败\"}", jacksonErrorWithStatusAndMessageAndNullData);
+
+ final String gsonErrorWithStatusAndMessageAndNullData = gson.toJson(errorWithStatusAndMessageAndNullData);
+ assertEquals("{\"status\":108,\"message\":\"查询失败\"}", gsonErrorWithStatusAndMessageAndNullData);
+ }
+
+ @Test
+ void testError_WithStatusAndMessage_AndData() throws Exception {
+ final PageResult emptyPageResult = PageResult.empty();
+ final UnifiedResponse errorWithStatusAndMessageAndData = UnifiedResponse.error(108, "查询失败", emptyPageResult);
+ assertEquals(108, errorWithStatusAndMessageAndData.getStatus());
+ assertEquals("查询失败", errorWithStatusAndMessageAndData.getMessage());
+ assertEquals(emptyPageResult, errorWithStatusAndMessageAndData.getData());
+ assertEquals("{status: 108, message: \"查询失败\", data: PageResult [total=0, content=[]]}", errorWithStatusAndMessageAndData.toString());
+
+ final String jacksonErrorWithStatusAndMessageAndData = jackson.writeValueAsString(errorWithStatusAndMessageAndData);
+ assertEquals("{\"status\":108,\"message\":\"查询失败\",\"data\":{\"total\":0,\"content\":[]}}",
+ jacksonErrorWithStatusAndMessageAndData);
+
+ final String gsonErrorWithStatusAndMessageAndData = gson.toJson(errorWithStatusAndMessageAndData);
+ assertEquals("{\"status\":108,\"message\":\"查询失败\",\"data\":{\"total\":0,\"content\":[]}}",
+ gsonErrorWithStatusAndMessageAndData);
+ }
+
+ @Test
+ void testError_WithStatusAndNullMessage() throws Exception {
+ UnifiedResponse errorWithStatusAndNullMessage = UnifiedResponse.error(500, (String) null);
+ assertEquals(500, errorWithStatusAndNullMessage.getStatus());
+ assertEquals("", errorWithStatusAndNullMessage.getMessage());
+ assertNull(errorWithStatusAndNullMessage.getData());
+
+ final String jacksonErrorWithStatusAndNullMessage = jackson.writeValueAsString(errorWithStatusAndNullMessage);
+ assertEquals("{\"status\":500,\"message\":\"\"}", jacksonErrorWithStatusAndNullMessage);
+
+ final String gsonErrorWithStatusAndNullMessage = gson.toJson(errorWithStatusAndNullMessage);
+ assertEquals("{\"status\":500,\"message\":\"\"}", gsonErrorWithStatusAndNullMessage);
+ }
+
+ @Test
+ void testError_WithStatusAndNullMessage_AndNullData() throws Exception {
+ UnifiedResponse errorWithStatusAndNullMessageAndNullData = UnifiedResponse.error(500, (String) null, null);
+
+ assertEquals(500, errorWithStatusAndNullMessageAndNullData.getStatus());
+ assertEquals("", errorWithStatusAndNullMessageAndNullData.getMessage());
+ assertNull(errorWithStatusAndNullMessageAndNullData.getData());
+
+ final String jacksonErrorWithStatusAndNullMessageAndNullData = jackson.writeValueAsString(errorWithStatusAndNullMessageAndNullData);
+ assertEquals("{\"status\":500,\"message\":\"\"}", jacksonErrorWithStatusAndNullMessageAndNullData);
+
+ final String gsonErrorWithStatusAndNullMessageAndNullData = gson.toJson(errorWithStatusAndNullMessageAndNullData);
+ assertEquals("{\"status\":500,\"message\":\"\"}", gsonErrorWithStatusAndNullMessageAndNullData);
+ }
+
+ @Test
+ void testError_WithStatusAndNullMessage_AndData() throws Exception {
+ PageResult emptyPageResult = PageResult.empty();
+ UnifiedResponse errorWithStatusAndNullMessageAndData = UnifiedResponse.error(500, (String) null, emptyPageResult);
+ assertEquals(500, errorWithStatusAndNullMessageAndData.getStatus());
+ assertEquals("", errorWithStatusAndNullMessageAndData.getMessage());
+ assertEquals(emptyPageResult, errorWithStatusAndNullMessageAndData.getData());
+ final String jacksonErrorWithStatusAndNullMessageAndData = jackson.writeValueAsString(errorWithStatusAndNullMessageAndData);
+ assertEquals("{\"status\":500,\"message\":\"\",\"data\":{\"total\":0,\"content\":[]}}", jacksonErrorWithStatusAndNullMessageAndData);
+ final String gsonErrorWithStatusAndNullMessageAndData = gson.toJson(errorWithStatusAndNullMessageAndData);
+ assertEquals("{\"status\":500,\"message\":\"\",\"data\":{\"total\":0,\"content\":[]}}", gsonErrorWithStatusAndNullMessageAndData);
+ }
+
+ @Test
+ void testError_WithStatusAndEmptyMessage() throws Exception {
+ UnifiedResponse errorWithStatusAndEmptyMessage = UnifiedResponse.error(500, "");
+ assertEquals(500, errorWithStatusAndEmptyMessage.getStatus());
+ assertEquals("", errorWithStatusAndEmptyMessage.getMessage());
+ assertNull(errorWithStatusAndEmptyMessage.getData());
+
+ final String jacksonErrorWithStatusAndEmptyMessage = jackson.writeValueAsString(errorWithStatusAndEmptyMessage);
+ assertEquals("{\"status\":500,\"message\":\"\"}", jacksonErrorWithStatusAndEmptyMessage);
+
+ final String gsonErrorWithStatusAndEmptyMessage = gson.toJson(errorWithStatusAndEmptyMessage);
+ assertEquals("{\"status\":500,\"message\":\"\"}", gsonErrorWithStatusAndEmptyMessage);
+ }
+
+ @Test
+ void testError_WithStatusAndEmptyMessage_AndNullData() throws Exception {
+ UnifiedResponse errorWithStatusAndEmptyMessageAndNullData = UnifiedResponse.error(500, "", null);
+
+ assertEquals(500, errorWithStatusAndEmptyMessageAndNullData.getStatus());
+ assertEquals("", errorWithStatusAndEmptyMessageAndNullData.getMessage());
+ assertNull(errorWithStatusAndEmptyMessageAndNullData.getData());
+
+ final String jacksonErrorWithStatusAndEmptyMessageAndNullData = jackson.writeValueAsString(errorWithStatusAndEmptyMessageAndNullData);
+ assertEquals("{\"status\":500,\"message\":\"\"}", jacksonErrorWithStatusAndEmptyMessageAndNullData);
+
+ final String gsonErrorWithStatusAndEmptyMessageAndNullData = gson.toJson(errorWithStatusAndEmptyMessageAndNullData);
+ assertEquals("{\"status\":500,\"message\":\"\"}", gsonErrorWithStatusAndEmptyMessageAndNullData);
+ }
+
+ @Test
+ void testError_WithStatusAndEmptyMessage_AndData() throws Exception {
+ PageResult emptyPageResult = PageResult.empty();
+ UnifiedResponse errorWithStatusAndEmptyMessageAndData = UnifiedResponse.error(500, "", emptyPageResult);
+ assertEquals(500, errorWithStatusAndEmptyMessageAndData.getStatus());
+ assertEquals("", errorWithStatusAndEmptyMessageAndData.getMessage());
+ assertEquals(emptyPageResult, errorWithStatusAndEmptyMessageAndData.getData());
+ final String jacksonErrorWithStatusAndEmptyMessageAndData = jackson.writeValueAsString(errorWithStatusAndEmptyMessageAndData);
+ assertEquals("{\"status\":500,\"message\":\"\",\"data\":{\"total\":0,\"content\":[]}}", jacksonErrorWithStatusAndEmptyMessageAndData);
+ final String gsonErrorWithStatusAndEmptyMessageAndData = gson.toJson(errorWithStatusAndEmptyMessageAndData);
+ assertEquals("{\"status\":500,\"message\":\"\",\"data\":{\"total\":0,\"content\":[]}}", gsonErrorWithStatusAndEmptyMessageAndData);
+ }
+
+ @Test
+ void testError_WithStatusAndThrowable() throws Exception {
+ final IllegalArgumentException e = new IllegalArgumentException("ID cannot be null");
+ final UnifiedResponse errorWithStatusThrowable = UnifiedResponse.error(500, e);
+ assertEquals(500, errorWithStatusThrowable.getStatus());
+ assertEquals("ID cannot be null", errorWithStatusThrowable.getMessage());
+ assertNull(errorWithStatusThrowable.getData());
+ assertEquals("{\"status\":500,\"message\":\"ID cannot be null\"}", jackson.writeValueAsString(errorWithStatusThrowable));
+ assertEquals("{\"status\":500,\"message\":\"ID cannot be null\"}", gson.toJson(errorWithStatusThrowable));
+ }
+
+ @Test
+ void testError_WithStatusAndNullThrowable() {
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.error(500, (Throwable) null));
+ }
+
+ @Test
+ void testError_WithNullStatus() {
final Object nullStatus = null;
final String nullMessage = null;
final User user = new User("zhouxy", "zhouxy@gmail.com");
@@ -222,36 +500,172 @@ class UnifiedResponseTests {
// null message
assertThrows(NullPointerException.class, () -> UnifiedResponse.error(nullStatus, nullMessage));
- assertThrows(NullPointerException.class, () -> UnifiedResponse.error(nullStatus, "nullMessage", null));
- assertThrows(NullPointerException.class, () -> UnifiedResponse.error(nullStatus, "nullMessage", user));
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.error(nullStatus, "查询失败", null));
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.error(nullStatus, "查询失败", user));
// Throwable
- // TODO
+ BizException bizException = new BizException("业务异常");
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.error(nullStatus, bizException));
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.error(nullStatus, (Throwable) null));
+ }
+
+
+ @Test
+ void testOf_WithStatusAndMessage() throws Exception {
+ final UnifiedResponse ofWithStatusAndMessage = UnifiedResponse.of(108, "This is a message.");
+ assertEquals(108, ofWithStatusAndMessage.getStatus());
+ assertEquals("This is a message.", ofWithStatusAndMessage.getMessage());
+ assertNull(ofWithStatusAndMessage.getData());
+
+ final String jacksonOfWithStatusAndMessage = jackson.writeValueAsString(ofWithStatusAndMessage);
+ log.info("jacksonOfWithStatusAndMessage: {}", jacksonOfWithStatusAndMessage);
+ assertEquals("{\"status\":108,\"message\":\"This is a message.\"}", jacksonOfWithStatusAndMessage);
+
+ assertEquals("{status: 108, message: \"This is a message.\", data: null}", ofWithStatusAndMessage.toString());
+
+ final String gsonOfWithStatusAndMessage = gson.toJson(ofWithStatusAndMessage);
+ assertEquals("{\"status\":108,\"message\":\"This is a message.\"}", gsonOfWithStatusAndMessage);
}
@Test
- void testError_Status_And_NullMessage() throws Exception {
- // TODO
+ void testOf_WithStatusAndMessage_AndNullData() throws Exception {
+ final UnifiedResponse ofWithStatusAndMessageAndNullData = UnifiedResponse.of(108, "This is a message.", null);
+ assertEquals(108, ofWithStatusAndMessageAndNullData.getStatus());
+ assertEquals("This is a message.", ofWithStatusAndMessageAndNullData.getMessage());
+ assertNull(ofWithStatusAndMessageAndNullData.getData());
+
+ final String jacksonOfWithStatusAndMessageAndNullData = jackson.writeValueAsString(ofWithStatusAndMessageAndNullData);
+ log.info("jacksonOfWithStatusAndMessage: {}", jacksonOfWithStatusAndMessageAndNullData);
+ assertEquals("{\"status\":108,\"message\":\"This is a message.\"}", jacksonOfWithStatusAndMessageAndNullData);
+
+ assertEquals("{status: 108, message: \"This is a message.\", data: null}", ofWithStatusAndMessageAndNullData.toString());
+
+ final String gsonOfWithStatusAndMessageAndNullData = gson.toJson(ofWithStatusAndMessageAndNullData);
+ assertEquals("{\"status\":108,\"message\":\"This is a message.\"}", gsonOfWithStatusAndMessageAndNullData);
}
@Test
- void testError_Message() throws Exception {
- // TODO
+ void testOf_WithStatusAndMessage_AndData() throws Exception {
+ final PageResult emptyPageResult = PageResult.empty();
+ final UnifiedResponse ofWithStatusAndMessageAndData
+ = UnifiedResponse.of(108, "This is a message.", emptyPageResult);
+ assertEquals("{status: 108, message: \"This is a message.\", data: PageResult [total=0, content=[]]}",
+ ofWithStatusAndMessageAndData.toString());
+ assertEquals(108, ofWithStatusAndMessageAndData.getStatus());
+ assertEquals("This is a message.", ofWithStatusAndMessageAndData.getMessage());
+ assertEquals(emptyPageResult, ofWithStatusAndMessageAndData.getData());
+ final String jacksonOfWithStatusAndMessageAndData = jackson.writeValueAsString(ofWithStatusAndMessageAndData);
+ assertEquals("{\"status\":108,\"message\":\"This is a message.\",\"data\":{\"total\":0,\"content\":[]}}",
+ jacksonOfWithStatusAndMessageAndData);
+ final String gsonOfWithStatusAndMessageAndData = gson.toJson(ofWithStatusAndMessageAndData);
+ assertEquals("{\"status\":108,\"message\":\"This is a message.\",\"data\":{\"total\":0,\"content\":[]}}",
+ gsonOfWithStatusAndMessageAndData);
}
@Test
- void testError_NullMessage() throws Exception {
- // TODO
+ void testOf_WithStatusAndNullMessage() throws Exception {
+ UnifiedResponse ofWithStatusAndNullMessage = UnifiedResponse.of(108, (String) null);
+ assertEquals(108, ofWithStatusAndNullMessage.getStatus());
+ assertEquals("", ofWithStatusAndNullMessage.getMessage());
+ assertNull(ofWithStatusAndNullMessage.getData());
+
+ final String jacksonOfWithStatusAndNullMessage = jackson.writeValueAsString(ofWithStatusAndNullMessage);
+ assertEquals("{\"status\":108,\"message\":\"\"}", jacksonOfWithStatusAndNullMessage);
+
+ final String gsonOfWithStatusAndNullMessage = gson.toJson(ofWithStatusAndNullMessage);
+ assertEquals("{\"status\":108,\"message\":\"\"}", gsonOfWithStatusAndNullMessage);
}
@Test
- void testError_EmptyMessage() throws Exception {
- // TODO
+ void testOf_WithStatusAndNullMessage_AndNullData() throws Exception {
+ UnifiedResponse ofWithStatusAndNullMessageAndNullData = UnifiedResponse.of(108, (String) null, null);
+
+ assertEquals(108, ofWithStatusAndNullMessageAndNullData.getStatus());
+ assertEquals("", ofWithStatusAndNullMessageAndNullData.getMessage());
+ assertNull(ofWithStatusAndNullMessageAndNullData.getData());
+
+ final String jacksonOfWithStatusAndNullMessageAndNullData = jackson.writeValueAsString(ofWithStatusAndNullMessageAndNullData);
+ assertEquals("{\"status\":108,\"message\":\"\"}", jacksonOfWithStatusAndNullMessageAndNullData);
+
+ final String gsonOfWithStatusAndNullMessageAndNullData = gson.toJson(ofWithStatusAndNullMessageAndNullData);
+ assertEquals("{\"status\":108,\"message\":\"\"}", gsonOfWithStatusAndNullMessageAndNullData);
}
@Test
- void testOf() {
+ void testOf_WithStatusAndNullMessage_AndData() throws Exception {
+ PageResult emptyPageResult = PageResult.empty();
+ UnifiedResponse ofWithStatusAndNullMessageAndData = UnifiedResponse.of(108, (String) null, emptyPageResult);
+ assertEquals(108, ofWithStatusAndNullMessageAndData.getStatus());
+ assertEquals("", ofWithStatusAndNullMessageAndData.getMessage());
+ assertEquals(emptyPageResult, ofWithStatusAndNullMessageAndData.getData());
+ final String jacksonOfWithStatusAndNullMessageAndData = jackson.writeValueAsString(ofWithStatusAndNullMessageAndData);
+ assertEquals("{\"status\":108,\"message\":\"\",\"data\":{\"total\":0,\"content\":[]}}", jacksonOfWithStatusAndNullMessageAndData);
+ final String gsonOfWithStatusAndNullMessageAndData = gson.toJson(ofWithStatusAndNullMessageAndData);
+ assertEquals("{\"status\":108,\"message\":\"\",\"data\":{\"total\":0,\"content\":[]}}", gsonOfWithStatusAndNullMessageAndData);
+ }
+ @Test
+ void testOf_WithStatusAndEmptyMessage() throws Exception {
+ UnifiedResponse ofWithStatusAndEmptyMessage = UnifiedResponse.of(108, "");
+ assertEquals(108, ofWithStatusAndEmptyMessage.getStatus());
+ assertEquals("", ofWithStatusAndEmptyMessage.getMessage());
+ assertNull(ofWithStatusAndEmptyMessage.getData());
+
+ final String jacksonOfWithStatusAndEmptyMessage = jackson.writeValueAsString(ofWithStatusAndEmptyMessage);
+ assertEquals("{\"status\":108,\"message\":\"\"}", jacksonOfWithStatusAndEmptyMessage);
+
+ final String gsonOfWithStatusAndEmptyMessage = gson.toJson(ofWithStatusAndEmptyMessage);
+ assertEquals("{\"status\":108,\"message\":\"\"}", gsonOfWithStatusAndEmptyMessage);
+ }
+
+ @Test
+ void testOf_WithStatusAndEmptyMessage_AndNullData() throws Exception {
+ UnifiedResponse ofWithStatusAndEmptyMessageAndNullData = UnifiedResponse.of(108, "", null);
+
+ assertEquals(108, ofWithStatusAndEmptyMessageAndNullData.getStatus());
+ assertEquals("", ofWithStatusAndEmptyMessageAndNullData.getMessage());
+ assertNull(ofWithStatusAndEmptyMessageAndNullData.getData());
+
+ final String jacksonOfWithStatusAndEmptyMessageAndNullData = jackson.writeValueAsString(ofWithStatusAndEmptyMessageAndNullData);
+ assertEquals("{\"status\":108,\"message\":\"\"}", jacksonOfWithStatusAndEmptyMessageAndNullData);
+
+ final String gsonOfWithStatusAndEmptyMessageAndNullData = gson.toJson(ofWithStatusAndEmptyMessageAndNullData);
+ assertEquals("{\"status\":108,\"message\":\"\"}", gsonOfWithStatusAndEmptyMessageAndNullData);
+ }
+
+ @Test
+ void testOf_WithStatusAndEmptyMessage_AndData() throws Exception {
+ PageResult emptyPageResult = PageResult.empty();
+ UnifiedResponse ofWithStatusAndEmptyMessageAndData = UnifiedResponse.of(108, "", emptyPageResult);
+ assertEquals(108, ofWithStatusAndEmptyMessageAndData.getStatus());
+ assertEquals("", ofWithStatusAndEmptyMessageAndData.getMessage());
+ assertEquals(emptyPageResult, ofWithStatusAndEmptyMessageAndData.getData());
+ final String jacksonOfWithStatusAndEmptyMessageAndData = jackson.writeValueAsString(ofWithStatusAndEmptyMessageAndData);
+ assertEquals("{\"status\":108,\"message\":\"\",\"data\":{\"total\":0,\"content\":[]}}", jacksonOfWithStatusAndEmptyMessageAndData);
+ final String gsonOfWithStatusAndEmptyMessageAndData = gson.toJson(ofWithStatusAndEmptyMessageAndData);
+ assertEquals("{\"status\":108,\"message\":\"\",\"data\":{\"total\":0,\"content\":[]}}", gsonOfWithStatusAndEmptyMessageAndData);
+ }
+
+ @Test
+ void testOf_WithNullStatus() {
+ final Object nullStatus = null;
+ final String nullMessage = null;
+ final User user = new User("zhouxy", "zhouxy@gmail.com");
+
+ // message
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.of(nullStatus, "查询失败"));
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.of(nullStatus, "查询失败", null));
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.of(nullStatus, "查询失败", user));
+
+ // empty message
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.of(nullStatus, ""));
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.of(nullStatus, "", null));
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.of(nullStatus, "", user));
+
+ // null message
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.of(nullStatus, nullMessage));
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.of(nullStatus, "查询失败", null));
+ assertThrows(NullPointerException.class, () -> UnifiedResponse.of(nullStatus, "查询失败", user));
}
@Data
From 37263c69332f5d684969e95100666c92bd00a949 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Sun, 29 Dec 2024 00:29:28 +0800
Subject: [PATCH 13/24] =?UTF-8?q?=E8=A1=A5=E5=85=85=20copyright?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../commons/collection/CollectionToolsTests.java | 16 ++++++++++++++++
.../plusone/commons/util/EnumToolsTests.java | 16 ++++++++++++++++
.../plusone/commons/util/IdGeneratorTests.java | 16 ++++++++++++++++
.../plusone/commons/util/RandomToolsTests.java | 16 ++++++++++++++++
4 files changed, 64 insertions(+)
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/collection/CollectionToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/collection/CollectionToolsTests.java
index 0b54e2d..bcb53a6 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/collection/CollectionToolsTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/collection/CollectionToolsTests.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2024 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 xyz.zhouxy.plusone.commons.collection;
import static org.junit.jupiter.api.Assertions.assertFalse;
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/EnumToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/EnumToolsTests.java
index a4c83fb..d4442cd 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/util/EnumToolsTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/EnumToolsTests.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2024 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 xyz.zhouxy.plusone.commons.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java
index 55edba9..7447e48 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2024 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 xyz.zhouxy.plusone.commons.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/RandomToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/RandomToolsTests.java
index fcf5f44..2f63bc6 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/util/RandomToolsTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/RandomToolsTests.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2024 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 xyz.zhouxy.plusone.commons.util;
import static org.junit.jupiter.api.Assertions.assertAll;
From 1f8036e1703bcbc842ddc89a95fe1649c9ee78d7 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Sun, 29 Dec 2024 11:32:21 +0800
Subject: [PATCH 14/24] =?UTF-8?q?=E6=A3=80=E6=9F=A5=E5=B9=B6=E5=AE=8C?=
=?UTF-8?q?=E5=96=84=20BigDecimals=E3=80=81Numbers=E3=80=81OptionalTools?=
=?UTF-8?q?=20=E7=9A=84=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
---
.../commons/util/BigDecimalsTests.java | 7 ++--
.../plusone/commons/util/NumbersTests.java | 2 -
.../commons/util/OptionalToolsTests.java | 40 +++++++++++++++----
3 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/BigDecimalsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/BigDecimalsTests.java
index 9a85b06..2fc6a0c 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/util/BigDecimalsTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/BigDecimalsTests.java
@@ -27,8 +27,6 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class BigDecimalsTests {
- // TODO 【优化】 检查测试用例
-
@Test
void equalsValue_NullValues_ReturnsTrue() {
assertTrue(BigDecimals.equalsValue(null, null));
@@ -176,7 +174,8 @@ public class BigDecimalsTests {
BigDecimal bd1 = new BigDecimal("10");
BigDecimal bd2 = new BigDecimal("20");
BigDecimal bd3 = new BigDecimal("30");
- assertEquals(new BigDecimal("60"), BigDecimals.sum(bd1, bd2, bd3));
+ BigDecimal bd4 = null;
+ assertEquals(new BigDecimal("60"), BigDecimals.sum(bd1, bd2, bd3, bd4));
}
@Test
@@ -192,6 +191,8 @@ public class BigDecimalsTests {
@Test
void of_BlankString_ReturnsZero() {
+ assertEquals(BigDecimal.ZERO, BigDecimals.of(null));
+ assertEquals(BigDecimal.ZERO, BigDecimals.of(""));
assertEquals(BigDecimal.ZERO, BigDecimals.of(" "));
}
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/NumbersTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/NumbersTests.java
index d09300f..1e2435f 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/util/NumbersTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/NumbersTests.java
@@ -24,8 +24,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public
class NumbersTests {
- // TODO 【优化】 检查测试用例
-
@Test
public void sum_ShortArray_ReturnsCorrectSum() {
short[] numbers = {1, 2, 3, 4};
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/OptionalToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/OptionalToolsTests.java
index 47ba4db..79199e4 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/util/OptionalToolsTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/OptionalToolsTests.java
@@ -19,6 +19,7 @@ package xyz.zhouxy.plusone.commons.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
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.Optional;
@@ -28,11 +29,12 @@ import java.util.OptionalLong;
import org.junit.jupiter.api.Test;
+/**
+ * {@link OptionalTools} 单元测试
+ */
public
class OptionalToolsTests {
- // TODO 【优化】 检查测试用例
-
@Test
void optionalOf_NullInteger_ReturnsEmptyOptionalInt() {
OptionalInt result = OptionalTools.optionalOf((Integer) null);
@@ -112,8 +114,14 @@ class OptionalToolsTests {
}
@Test
- void orElseNull_NullOptional_ReturnsNull() {
- Object result = OptionalTools.orElseNull(Optional.ofNullable(null));
+ void orElseNull_NullOptional_ThrowsNullPointerException() {
+ assertThrows(NullPointerException.class,
+ () -> OptionalTools.orElseNull(null));
+ }
+
+ @Test
+ void orElseNull_EmptyOptional_ReturnsNull() {
+ Object result = OptionalTools.orElseNull(Optional.empty());
assertNull(result);
}
@@ -124,7 +132,13 @@ class OptionalToolsTests {
}
@Test
- void toInteger_NullOptionalInt_ReturnsNull() {
+ void toInteger_NullOptionalInt_ThrowsNullPointerException() {
+ assertThrows(NullPointerException.class,
+ () -> OptionalTools.toInteger(null));
+ }
+
+ @Test
+ void toInteger_EmptyOptionalInt_ReturnsNull() {
Integer result = OptionalTools.toInteger(OptionalInt.empty());
assertNull(result);
}
@@ -136,7 +150,13 @@ class OptionalToolsTests {
}
@Test
- void toLong_NullOptionalLong_ReturnsNull() {
+ void toLong_NullOptionalLong_ThrowsNullPointerException() {
+ assertThrows(NullPointerException.class,
+ () -> OptionalTools.toLong(null));
+ }
+
+ @Test
+ void toLong_EmptyOptionalLong_ReturnsNull() {
Long result = OptionalTools.toLong(OptionalLong.empty());
assertNull(result);
}
@@ -148,7 +168,13 @@ class OptionalToolsTests {
}
@Test
- void toDouble_NullOptionalDouble_ReturnsNull() {
+ void toDouble_NullOptionalDouble_ThrowsNullPointerException() {
+ assertThrows(NullPointerException.class,
+ () -> OptionalTools.toDouble(null));
+ }
+
+ @Test
+ void toDouble_EmptyOptionalDouble_ReturnsNull() {
Double result = OptionalTools.toDouble(OptionalDouble.empty());
assertNull(result);
}
From 8411e75274f373c519410bf5f7e26eb02c85600e Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Sun, 29 Dec 2024 11:37:15 +0800
Subject: [PATCH 15/24] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=84=8F=E4=B9=89?=
=?UTF-8?q?=E4=B8=8D=E5=A4=A7=E7=9A=84=20MapWrapper?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../collection/AbstractMapWrapper.java | 234 ------------------
.../commons/collection/MapWrapper.java | 95 -------
2 files changed, 329 deletions(-)
delete mode 100644 src/main/java/xyz/zhouxy/plusone/commons/collection/AbstractMapWrapper.java
delete mode 100644 src/main/java/xyz/zhouxy/plusone/commons/collection/MapWrapper.java
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/collection/AbstractMapWrapper.java b/src/main/java/xyz/zhouxy/plusone/commons/collection/AbstractMapWrapper.java
deleted file mode 100644
index 04a974b..0000000
--- a/src/main/java/xyz/zhouxy/plusone/commons/collection/AbstractMapWrapper.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright 2023-2024 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 xyz.zhouxy.plusone.commons.collection;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import com.google.common.annotations.Beta;
-
-import xyz.zhouxy.plusone.commons.util.AssertTools;
-
-/**
- * AbstractMapWrapper
- *
- *
- * 包装了一个 {@link Map}。
- * 主要在于获取值时,如果 Key 不存在,是抛出异常;如果 Key 存在,则将 value 包装在 {@link Optional} 中 返回。
- * 此外可以定义 Key 和 Value 的检查规则。
- *
- *
- * @author ZhouXY
- * @since 1.0
- */
-@Beta
-public abstract class AbstractMapWrapper> {
-
- private final Map map;
- private final Consumer keyChecker;
- private final Consumer valueChecker;
-
- protected AbstractMapWrapper(Map map,
- @Nullable Consumer keyChecker,
- @Nullable Consumer valueChecker) {
- this.map = map;
- this.keyChecker = keyChecker;
- this.valueChecker = valueChecker;
- }
-
- public final T put(K key, V value) {
- if (this.keyChecker != null) {
- this.keyChecker.accept(key);
- }
- if (this.valueChecker != null) {
- this.valueChecker.accept(value);
- }
- this.map.put(key, value);
- return getSelf();
- }
-
- public final T putAll(Map extends K, ? extends V> m) {
- m.forEach(this::put);
- return getSelf();
- }
-
- /**
- * 获取 {@code map} 中的值。如果 {@code key} 不存在,则抛出异常。
- * 将 {@code value}(可为 {@code null})装进 {@link Optional} 中后返回。
- * 为了这碟醋包的这盘饺子。
- *
- * @param key 键
- * @return 可缺失的值
- * @throws IllegalArgumentException key 不存在时抛出。
- */
- @Nonnull
- public Optional get(K key) {
- AssertTools.checkArgument(this.map.containsKey(key), "Key does not exist");
- return Optional.ofNullable(this.map.get(key));
- }
-
- @SuppressWarnings("unchecked")
- public final Optional getAndConvert(K key) {
- return get(key).map(v -> (R) v);
- }
-
- public final Optional getAndConvert(K key, Function mapper) {
- return get(key).map(mapper);
- }
-
- public final boolean containsKey(Object key) {
- return this.map.containsKey(key);
- }
-
- public final int size() {
- return this.map.size();
- }
-
- public final Set keySet() {
- return this.map.keySet();
- }
-
- public final Collection values() {
- return this.map.values();
- }
-
- public final Set> entrySet() {
- return this.map.entrySet();
- }
-
- public final void clear() {
- this.map.clear();
- }
-
- public final boolean containsValue(Object value) {
- return this.map.containsValue(value);
- }
-
- public final boolean isEmpty() {
- return this.map.isEmpty();
- }
-
- public final V remove(Object key) {
- return this.map.remove(key);
- }
-
- public final V putIfAbsent(K key, V value) {
- if (this.keyChecker != null) {
- this.keyChecker.accept(key);
- }
- if (this.valueChecker != null) {
- this.valueChecker.accept(value);
- }
- return this.map.putIfAbsent(key, value);
- }
-
- public final V computeIfAbsent(K key, Function super K, ? extends V> mappingFunction) {
- if (this.keyChecker != null) {
- this.keyChecker.accept(key);
- }
- Function super K, ? extends V> func = (K k) -> {
- V value = mappingFunction.apply(k);
- if (this.valueChecker != null) {
- this.valueChecker.accept(value);
- }
- return value;
- };
- return this.map.computeIfAbsent(key, func);
- }
-
- public final Map exportMap() {
- return this.map;
- }
-
- public final Map exportUnmodifiableMap() {
- return Collections.unmodifiableMap(this.map);
- }
-
- protected abstract T getSelf();
-
- @Override
- public String toString() {
- return this.map.toString();
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(map);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- AbstractMapWrapper, ?, ?> other = (AbstractMapWrapper, ?, ?>) obj;
- return Objects.equals(map, other.map);
- }
-
- public abstract static class Builder> {
- protected final Map map;
- protected Consumer keyChecker;
- protected Consumer valueChecker;
-
- protected Builder(Map map) {
- this.map = map;
- }
-
- public Builder keyChecker(@Nullable Consumer keyChecker) {
- this.keyChecker = keyChecker;
- return this;
- }
-
- public Builder valueChecker(@Nullable Consumer valueChecker) {
- this.valueChecker = valueChecker;
- return this;
- }
-
- public Builder put(K key, V value) {
- if (this.keyChecker != null) {
- this.keyChecker.accept(key);
- }
- if (this.valueChecker != null) {
- this.valueChecker.accept(value);
- }
- this.map.put(key, value);
- return this;
- }
-
- public Builder putAll(Map extends K, ? extends V> m) {
- m.forEach(this::put);
- return this;
- }
-
- public abstract T build();
-
- public abstract T buildUnmodifiableMap();
- }
-}
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/collection/MapWrapper.java b/src/main/java/xyz/zhouxy/plusone/commons/collection/MapWrapper.java
deleted file mode 100644
index 026bd9c..0000000
--- a/src/main/java/xyz/zhouxy/plusone/commons/collection/MapWrapper.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2023-2024 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 xyz.zhouxy.plusone.commons.collection;
-
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.function.Consumer;
-
-import com.google.common.annotations.Beta;
-
-/**
- * MapWrapper
- *
- *
- * Map 包装器的默认实现
- *
- *
- * @author ZhouXY
- * @since 0.1.0
- */
-@Beta
-public final class MapWrapper extends AbstractMapWrapper> {
-
- private MapWrapper(Map map, Consumer keyChecker, Consumer valueChecker) {
- super(map, keyChecker, valueChecker);
- }
-
- public static Builder wrap(Map map) {
- return new Builder<>(map);
- }
-
- public static Builder wrapHashMap() {
- return new Builder<>(new HashMap<>());
- }
-
- public static Builder wrapHashMap(int initialCapacity) {
- return new Builder<>(new HashMap<>(initialCapacity));
- }
-
- public static Builder wrapHashMap(int initialCapacity, float loadFactor) {
- return new Builder<>(new HashMap<>(initialCapacity, loadFactor));
- }
-
- public static , V> Builder wrapTreeMap() {
- return new Builder<>(new TreeMap<>());
- }
-
- public static Builder wrapTreeMap(SortedMap m) {
- return new Builder<>(new TreeMap<>(m));
- }
-
- public static Builder wrapTreeMap(Comparator super K> comparator) {
- return new Builder<>(new TreeMap<>(comparator));
- }
-
- public static final class Builder extends AbstractMapWrapper.Builder> {
-
- private Builder(Map map) {
- super(map);
- }
-
- @Override
- public MapWrapper build() {
- return new MapWrapper<>(map, keyChecker, valueChecker);
- }
-
- @Override
- public MapWrapper buildUnmodifiableMap() {
- return new MapWrapper<>(Collections.unmodifiableMap(map), keyChecker, valueChecker);
- }
- }
-
- @Override
- protected MapWrapper getSelf() {
- return this;
- }
-}
From 1727af5940de78f33b89bc3b5ced7b705af30a24 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Sun, 29 Dec 2024 11:41:28 +0800
Subject: [PATCH 16/24] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20ProgressOfTesting.tx?=
=?UTF-8?q?t?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ProgressOfTesting.txt | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt
index 4e65a24..cd77b87 100644
--- a/ProgressOfTesting.txt
+++ b/ProgressOfTesting.txt
@@ -1,7 +1,7 @@
-[ ] 未开始测试 - 5 (7.81%)
-[-] 测试未完成 - 5 (7.81%)
-[Y] 测试完成 - 32 (50.00%)
-[x] 无需测试 - 22 (34.38%)
+[ ] 未开始测试 - 3 (4.84%)
+[-] 测试未完成 - 5 (8.06%)
+[Y] 测试完成 - 32 (51.61%)
+[x] 无需测试 - 22 (35.48%)
xyz.zhouxy.plusone.commons
├───annotation
@@ -24,9 +24,7 @@ xyz.zhouxy.plusone.commons
│ Ref.java [Y]
│
├───collection
- │ AbstractMapWrapper.java [ ]
│ CollectionTools.java [Y]
- │ MapWrapper.java [ ]
│
├───constant
│ PatternConsts.java [ ]
From 979eedabb17153e9de669a271dbcf48d48dce008 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Sun, 29 Dec 2024 15:33:33 +0800
Subject: [PATCH 17/24] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=AD=A3=E5=88=99?=
=?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=9B=B8=E5=85=B3=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 | 68 ++---
.../commons/constant/PatternConsts.java | 57 ++++-
.../plusone/commons/constant/RegexConsts.java | 10 +-
.../plusone/commons/util/RegexTools.java | 17 --
.../commons/constant/PatternConstsTests.java | 235 ++++++++++++++++++
.../plusone/commons/util/RegexToolsTests.java | 165 ++++++++++++
6 files changed, 486 insertions(+), 66 deletions(-)
create mode 100644 src/test/java/xyz/zhouxy/plusone/commons/constant/PatternConstsTests.java
create mode 100644 src/test/java/xyz/zhouxy/plusone/commons/util/RegexToolsTests.java
diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt
index cd77b87..ff0f1b7 100644
--- a/ProgressOfTesting.txt
+++ b/ProgressOfTesting.txt
@@ -1,16 +1,16 @@
-[ ] 未开始测试 - 3 (4.84%)
-[-] 测试未完成 - 5 (8.06%)
-[Y] 测试完成 - 32 (51.61%)
-[x] 无需测试 - 22 (35.48%)
+[ ] 未开始测试 - 0 (0.00%)
+[*] 测试未完成 - 5 (8.06%)
+[Y] 测试完成 - 35 (56.45%)
+[-] 无需测试 - 22 (35.48%)
xyz.zhouxy.plusone.commons
├───annotation
- │ ReaderMethod.java [x]
- │ StaticFactoryMethod.java [x]
- │ UnsupportedOperation.java [x]
- │ ValueObject.java [x]
- │ Virtual.java [x]
- │ WriterMethod.java [x]
+ │ ReaderMethod.java [-]
+ │ StaticFactoryMethod.java [-]
+ │ UnsupportedOperation.java [-]
+ │ ValueObject.java [-]
+ │ Virtual.java [-]
+ │ WriterMethod.java [-]
│
├───base
│ BoolRef.java [Y]
@@ -27,46 +27,46 @@ xyz.zhouxy.plusone.commons
│ CollectionTools.java [Y]
│
├───constant
- │ PatternConsts.java [ ]
- │ RegexConsts.java [ ]
+ │ PatternConsts.java [Y]
+ │ RegexConsts.java [Y]
│
├───exception
- │ │ DataNotExistsException.java [x]
+ │ │ DataNotExistsException.java [-]
│ │ ParsingFailureException.java [Y]
│ │ ExceptionType.java [Y]
│ │
│ ├───business
- │ │ BizException.java [x]
+ │ │ BizException.java [-]
│ │ InvalidInputException.java [Y]
- │ │ RequestParamsException.java [x]
+ │ │ RequestParamsException.java [-]
│ │
│ └───system
- │ DataOperationResultException.java [x]
- │ NoAvailableMacFoundException.java [x]
- │ SysException.java [x]
+ │ DataOperationResultException.java [-]
+ │ NoAvailableMacFoundException.java [-]
+ │ SysException.java [-]
│
├───function
- │ BoolUnaryOperator.java [x]
- │ CharUnaryOperator.java [x]
- │ Executable.java [x]
- │ OptionalSupplier.java [x]
+ │ BoolUnaryOperator.java [-]
+ │ CharUnaryOperator.java [-]
+ │ Executable.java [-]
+ │ OptionalSupplier.java [-]
│ PredicateTools.java [Y]
- │ ThrowingConsumer.java [x]
- │ ThrowingPredicate.java [x]
- │ ThrowingSupplier.java [x]
- │ ToOptionalBiFunction.java [x]
- │ ToOptionalFunction.java [x]
+ │ ThrowingConsumer.java [-]
+ │ ThrowingPredicate.java [-]
+ │ ThrowingSupplier.java [-]
+ │ ToOptionalBiFunction.java [-]
+ │ ToOptionalFunction.java [-]
│
├───model
│ │ Chinese2ndGenIDCardNumber.java [Y]
- │ │ Gender.java [x]
+ │ │ Gender.java [-]
│ │ IDCardNumber.java [Y]
│ │ ValidatableStringRecord.java [Y]
│ │
│ └───dto
- │ PageResult.java [-]
- │ PagingAndSortingQueryParams.java [-]
- │ PagingParams.java [-]
+ │ PageResult.java [*]
+ │ PagingAndSortingQueryParams.java [*]
+ │ PagingParams.java [*]
│ UnifiedResponse.java [Y]
│
├───time
@@ -74,10 +74,10 @@ xyz.zhouxy.plusone.commons
│ YearQuarter.java [Y]
│
└───util
- ArrayTools.java [-]
+ ArrayTools.java [*] 61
AssertTools.java [Y]
BigDecimals.java [Y]
- DateTimeTools.java [-]
+ DateTimeTools.java [*] 83
Enumeration.java [Y]
EnumTools.java [Y]
IdGenerator.java [Y]
@@ -85,7 +85,7 @@ xyz.zhouxy.plusone.commons
Numbers.java [Y]
OptionalTools.java [Y]
RandomTools.java [Y]
- RegexTools.java [ ]
+ RegexTools.java [Y]
SnowflakeIdGenerator.java [Y]
StringTools.java [Y]
TreeBuilder.java [Y]
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/constant/PatternConsts.java b/src/main/java/xyz/zhouxy/plusone/commons/constant/PatternConsts.java
index ad5b555..4d8e03b 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/constant/PatternConsts.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/constant/PatternConsts.java
@@ -27,33 +27,70 @@ import java.util.regex.Pattern;
*/
public final class PatternConsts {
- /** yyyyMMdd */
+ /**
+ * yyyyMMdd
+ *
+ * @see RegexConsts#BASIC_ISO_DATE
+ *
+ */
public static final Pattern BASIC_ISO_DATE = Pattern.compile(RegexConsts.BASIC_ISO_DATE);
- /** yyyy-MM-dd */
+ /**
+ * yyyy-MM-dd
+ *
+ * @see RegexConsts#ISO_LOCAL_DATE
+ */
public static final Pattern ISO_LOCAL_DATE = Pattern.compile(RegexConsts.ISO_LOCAL_DATE);
- /** 密码 */
+ /**
+ * 密码
+ *
+ * @see RegexConsts#PASSWORD
+ */
public static final Pattern PASSWORD = Pattern.compile(RegexConsts.PASSWORD);
- /** 验证码 */
+ /**
+ * 验证码
+ *
+ * @see RegexConsts#CAPTCHA
+ */
public static final Pattern CAPTCHA = Pattern.compile(RegexConsts.CAPTCHA);
- /** 邮箱地址 */
+ /**
+ * 邮箱地址
+ *
+ * @see RegexConsts#EMAIL
+ */
public static final Pattern EMAIL = Pattern.compile(RegexConsts.EMAIL);
- /** 中国大陆手机号 */
+ /**
+ * 中国大陆手机号
+ *
+ * @see RegexConsts#MOBILE_PHONE
+ */
public static final Pattern MOBILE_PHONE = Pattern.compile(RegexConsts.MOBILE_PHONE);
- /** 用户名 */
+ /**
+ * 用户名
+ *
+ * @see RegexConsts#USERNAME
+ */
public static final Pattern USERNAME = Pattern.compile(RegexConsts.USERNAME);
- /** 昵称 */
+ /**
+ * 昵称
+ *
+ * @see RegexConsts#NICKNAME
+ */
public static final Pattern NICKNAME = Pattern.compile(RegexConsts.NICKNAME);
- /** 中国第二代居民身份证 */
+ /**
+ * 中国第二代居民身份证
+ *
+ * @see RegexConsts#CHINESE_2ND_ID_CARD_NUMBER
+ */
public static final Pattern CHINESE_2ND_ID_CARD_NUMBER
- = Pattern.compile(RegexConsts.CHINESE_2ND_ID_CARD_NUMBER);
+ = Pattern.compile(RegexConsts.CHINESE_2ND_ID_CARD_NUMBER, Pattern.CASE_INSENSITIVE);
private PatternConsts() {
throw new IllegalStateException("Utility class");
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/constant/RegexConsts.java b/src/main/java/xyz/zhouxy/plusone/commons/constant/RegexConsts.java
index f1bad7f..9730ce1 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/constant/RegexConsts.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/constant/RegexConsts.java
@@ -24,9 +24,9 @@ package xyz.zhouxy.plusone.commons.constant;
*/
public final class RegexConsts {
- public static final String BASIC_ISO_DATE = "^(?\\d{4})(?\\d{2})(?\\d{2})";
+ public static final String BASIC_ISO_DATE = "^(?\\d{4,9})(?\\d{2})(?\\d{2})";
- public static final String ISO_LOCAL_DATE = "^(?\\d{4})-(?\\d{2})-(?\\d{2})";
+ public static final String ISO_LOCAL_DATE = "^(?\\d{4,9})-(?\\d{2})-(?\\d{2})";
public static final String PASSWORD = "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])[\\w\\\\!#$%&'*\\+\\-/=?^`{|}~@\\(\\)\\[\\]\",\\.;':><]{8,32}$";
@@ -38,12 +38,12 @@ public final class RegexConsts {
public static final String MOBILE_PHONE = "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$";
- public static final String USERNAME = "^[\\w_.@\\\\]{4,36}$";
+ public static final String USERNAME = "^[\\w-_.@]{4,36}$";
- public static final String NICKNAME = "^[\\w_.@\\\\]{4,36}$";
+ public static final String NICKNAME = "^[\\w-_.@]{4,36}$";
public static final String CHINESE_2ND_ID_CARD_NUMBER
- = "^(?(?(?\\d{2})\\d{2})\\d{2})(?\\d{8})\\d{2}(?\\d)([\\dXx])$";
+ = "^(?(?(?\\d{2})\\d{2})\\d{2})(?\\d{8})\\d{2}(?\\d)([\\dX])$";
private RegexConsts() {
throw new IllegalStateException("Utility class");
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/RegexTools.java b/src/main/java/xyz/zhouxy/plusone/commons/util/RegexTools.java
index 34dfb5c..53551f8 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/util/RegexTools.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/util/RegexTools.java
@@ -89,22 +89,6 @@ public final class RegexTools {
return getPatternsInternal(patterns);
}
- /**
- * 手动缓存 Pattern 实例。
- *
- * @param pattern 要缓存的 {@link Pattern} 实例
- * @return 缓存的 Pattern 实例。如果缓存已满,则返回 {@code null}。
- */
- public static Pattern cachePattern(final Pattern pattern) {
- AssertTools.checkNotNull(pattern, "The pattern can not be null.");
- if (PATTERN_CACHE.size() >= MAX_CACHE_SIZE) {
- return null;
- }
- final String patternStr = pattern.pattern();
- final Pattern pre = PATTERN_CACHE.putIfAbsent(patternStr, pattern);
- return pre != null ? pre : pattern;
- }
-
/**
* 判断 {@code input} 是否匹配 {@code pattern}。
*
@@ -285,7 +269,6 @@ public final class RegexTools {
* 获取 {@link Pattern} 实例。
*
* @param pattern 正则表达式
- * @param cachePattern 是否缓存 {@link Pattern} 实例
* @return {@link Pattern} 实例
*/
@Nonnull
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/constant/PatternConstsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/constant/PatternConstsTests.java
new file mode 100644
index 0000000..88304d6
--- /dev/null
+++ b/src/test/java/xyz/zhouxy/plusone/commons/constant/PatternConstsTests.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2024 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 xyz.zhouxy.plusone.commons.constant;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.regex.Matcher;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public //
+class PatternConstsTests {
+
+ // ================================
+ // #region - BASIC_ISO_DATE
+ // ================================
+
+ @Test
+ void testBasicIsoDate_ValidDate() {
+ Matcher matcher = PatternConsts.BASIC_ISO_DATE.matcher("20241229");
+ assertTrue(matcher.matches());
+
+ assertEquals("2024", matcher.group(1));
+ assertEquals("12", matcher.group(2));
+ assertEquals("29", matcher.group(3));
+ assertEquals("2024", matcher.group("yyyy"));
+ assertEquals("12", matcher.group("MM"));
+ assertEquals("29", matcher.group("dd"));
+
+ // LeapYearFeb29()
+ assertTrue(PatternConsts.BASIC_ISO_DATE.matcher("20200229").matches());
+
+ // BoundaryMin()
+ assertTrue(PatternConsts.BASIC_ISO_DATE.matcher("00000101").matches());
+
+ // BoundaryMax()
+ assertTrue(PatternConsts.BASIC_ISO_DATE.matcher("9999999991231").matches());
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "20231301", // InvalidMonth
+ "20230230", // InvalidDay
+ "20210229", // NonLeapYearFeb29
+ })
+ void testBasicIsoDate_InvalidDate_butMatches(String date) {
+ // 虽然日期有误,但这个正则无法判断。实际工作中,应使用日期时间 API。
+ Matcher matcher = PatternConsts.BASIC_ISO_DATE.matcher(date);
+ assertTrue(matcher.matches());
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "2023041", // TooShort
+ "99999999990415", // TooLong
+ "2023-04-15", // NonNumeric
+ })
+ void testBasicIsoDate_InvalidDate_Mismatches(String date) {
+ Matcher matcher = PatternConsts.BASIC_ISO_DATE.matcher(date);
+ assertFalse(matcher.matches());
+ }
+
+ // ================================
+ // #endregion - BASIC_ISO_DATE
+ // ================================
+
+ // ================================
+ // #region - ISO_LOCAL_DATE
+ // ================================
+
+ @Test
+ void testIsoLocalDate_ValidDate() {
+ Matcher matcher = PatternConsts.ISO_LOCAL_DATE.matcher("2024-12-29");
+ assertTrue(matcher.matches());
+ assertEquals("2024", matcher.group("yyyy"));
+ assertEquals("12", matcher.group("MM"));
+ assertEquals("29", matcher.group("dd"));
+
+ // LeapYearFeb29()
+ assertTrue(PatternConsts.ISO_LOCAL_DATE.matcher("2020-02-29").matches());
+
+ // BoundaryMin()
+ assertTrue(PatternConsts.ISO_LOCAL_DATE.matcher("0000-01-01").matches());
+
+ // BoundaryMax()
+ assertTrue(PatternConsts.ISO_LOCAL_DATE.matcher("999999999-12-31").matches());
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "2023-13-01", // InvalidMonth
+ "2023-02-30", // InvalidDay
+ "2021-02-29", // NonLeapYearFeb29
+ })
+ void testIsoLocalDate_InvalidDate_butMatches(String date) {
+ // 虽然日期有误,但这个正则无法判断。实际工作中,应使用日期时间 API。
+ Matcher matcher = PatternConsts.ISO_LOCAL_DATE.matcher(date);
+ assertTrue(matcher.matches());
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "2023-04-1", // TooShort
+ "9999999999-04-15", // TooLong
+ "20230415",
+ })
+ void testIsoLocalDate_InvalidDate_Mismatches(String date) {
+ Matcher matcher = PatternConsts.ISO_LOCAL_DATE.matcher(date);
+ assertFalse(matcher.matches());
+ }
+
+ // ================================
+ // #endregion - ISO_LOCAL_DATE
+ // ================================
+
+ // ================================
+ // #region - PASSWORD
+ // ================================
+
+ @Test
+ void testPassword_ValidPassword_Matches() {
+ assertTrue(PatternConsts.PASSWORD.matcher("Abc123!@#").matches());
+ }
+
+ @Test
+ void testPassword_InvalidPassword_Mismatches() {
+ assertFalse(PatternConsts.PASSWORD.matcher("Abc123 !@#").matches()); // 带空格
+ assertFalse(PatternConsts.PASSWORD.matcher("Abc123!@# ").matches()); // 带空格
+ assertFalse(PatternConsts.PASSWORD.matcher(" Abc123!@#").matches()); // 带空格
+ assertFalse(PatternConsts.PASSWORD.matcher(" Abc123!@# ").matches()); // 带空格
+ assertFalse(PatternConsts.PASSWORD.matcher("77553366998844113322").matches()); // 纯数字
+ assertFalse(PatternConsts.PASSWORD.matcher("poiujhgbfdsazxcfvghj").matches()); // 纯小写字母
+ assertFalse(PatternConsts.PASSWORD.matcher("POIUJHGBFDSAZXCFVGHJ").matches()); // 纯大写字母
+ assertFalse(PatternConsts.PASSWORD.matcher("!#$%&'*\\+-/=?^`{|}~@()[]\",.;':").matches()); // 纯特殊字符
+ assertFalse(PatternConsts.PASSWORD.matcher("sdfrghbv525842582752").matches()); // 没有小写字母
+ assertFalse(PatternConsts.PASSWORD.matcher("SDFRGHBV525842582752").matches()); // 没有小写字母
+ assertFalse(PatternConsts.PASSWORD.matcher("sdfrghbvSDFRGHBV").matches()); // 没有数字
+ assertFalse(PatternConsts.PASSWORD.matcher("Abc1!").matches()); // 太短
+ assertFalse(PatternConsts.PASSWORD.matcher("Abc1!Abc1!Abc1!Abc1!Abc1!Abc1!Abc1!").matches()); // 太长
+ assertFalse(PatternConsts.PASSWORD.matcher("").matches());
+ assertFalse(PatternConsts.PASSWORD.matcher(" ").matches());
+ }
+
+ // ================================
+ // #endregion - PASSWORD
+ // ================================
+
+ // ================================
+ // #region - EMAIL
+ // ================================
+
+ @Test
+ public void testValidEmails() {
+ assertTrue(PatternConsts.EMAIL.matcher("test@example.com").matches());
+ assertTrue(PatternConsts.EMAIL.matcher("user.name+tag+sorting@example.com").matches());
+ assertTrue(PatternConsts.EMAIL.matcher("user@sub.example.com").matches());
+ assertTrue(PatternConsts.EMAIL.matcher("user@123.123.123.123").matches());
+ }
+
+ @Test
+ public void testInvalidEmails() {
+ assertFalse(PatternConsts.EMAIL.matcher(".username@example.com").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("@missingusername.com").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("plainaddress").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("username..username@example.com").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("username.@example.com").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("username@-example.com").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("username@-example.com").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("username@.com.com").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("username@.com.my").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("username@.com").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("username@com.").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("username@com").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("username@example..com").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("username@example.com-").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("username@example.com.").matches());
+ assertFalse(PatternConsts.EMAIL.matcher("username@example").matches());
+ }
+
+ // ================================
+ // #endregion - EMAIL
+ // ================================
+
+ // ================================
+ // #region - Chinese2ndIdCardNumber
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "44520019900101456X",
+ "44520019900101456x",
+ "445200199001014566",
+ })
+ void testChinese2ndIdCardNumber_ValidChinese2ndIdCardNumber(String value) {
+ Matcher matcher = PatternConsts.CHINESE_2ND_ID_CARD_NUMBER.matcher(value);
+ assertTrue(matcher.matches());
+ assertEquals("44", matcher.group("province"));
+ assertEquals("4452", matcher.group("city"));
+ assertEquals("445200", matcher.group("county"));
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "4452200199001014566",
+ "44520199001014566",
+ " ",
+ "",
+ })
+ void testChinese2ndIdCardNumber_InvalidChinese2ndIdCardNumber(String value) {
+ assertFalse(PatternConsts.CHINESE_2ND_ID_CARD_NUMBER.matcher(value).matches());
+ }
+
+ // ================================
+ // #endregion - Chinese2ndIdCardNumber
+ // ================================
+}
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/RegexToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/RegexToolsTests.java
new file mode 100644
index 0000000..3968a24
--- /dev/null
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/RegexToolsTests.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2024 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 xyz.zhouxy.plusone.commons.util;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.jupiter.api.Test;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public
+class RegexToolsTests {
+
+ @Test
+ void getPattern_CachePatternTrue_ReturnsCachedPattern() {
+ String pattern = "abc";
+ Pattern cachedPattern = RegexTools.getPattern(pattern, true);
+ Pattern patternFromCache = RegexTools.getPattern(pattern, true);
+ assertSame(cachedPattern, patternFromCache, "Pattern should be cached");
+ }
+
+ @Test
+ void getPattern_CachePatternFalse_ReturnsNewPattern() {
+ String pattern = "abc";
+ Pattern pattern1 = RegexTools.getPattern(pattern, false);
+ Pattern pattern2 = RegexTools.getPattern(pattern, false);
+ assertNotSame(pattern1, pattern2, "Pattern should not be cached");
+ }
+
+ @Test
+ void getPattern_NullPattern_ThrowsException() {
+ assertThrows(NullPointerException.class, () -> {
+ RegexTools.getPattern(null, true);
+ });
+ }
+
+ @Test
+ void getPatterns_CachePatternTrue_ReturnsCachedPatterns() {
+ String[] patterns = {"abc", "def"};
+ Pattern[] cachedPatterns = RegexTools.getPatterns(patterns, true);
+ Pattern[] patternsFromCache = RegexTools.getPatterns(patterns, true);
+ assertSame(cachedPatterns[0], patternsFromCache[0]);
+ assertSame(cachedPatterns[1], patternsFromCache[1]);
+ }
+
+ @Test
+ void getPatterns_CachePatternFalse_ReturnsNewPatterns() {
+ String[] patterns = {"abc", "def"};
+ Pattern[] patterns1 = RegexTools.getPatterns(patterns, false);
+ Pattern[] patterns2 = RegexTools.getPatterns(patterns, false);
+ assertNotSame(patterns1[0], patterns2[0]);
+ assertNotSame(patterns1[1], patterns2[1]);
+ }
+
+ @Test
+ void getPatterns_NullPatterns_ThrowsException() {
+ assertThrows(NullPointerException.class, () -> {
+ RegexTools.getPatterns(null, true);
+ });
+ }
+
+ @Test
+ void matches_InputMatchesPattern_ReturnsTrue() {
+ String pattern = "abc";
+ Pattern compiledPattern = Pattern.compile(pattern);
+ assertTrue(RegexTools.matches("abc", compiledPattern), "Input should match pattern");
+ }
+
+ @Test
+ void matches_InputDoesNotMatchPattern_ReturnsFalse() {
+ String pattern = "abc";
+ Pattern compiledPattern = Pattern.compile(pattern);
+ assertFalse(RegexTools.matches("abcd", compiledPattern), "Input should not match pattern");
+ }
+
+ @Test
+ void matches_NullInput_ReturnsFalse() {
+ String pattern = "abc";
+ Pattern compiledPattern = Pattern.compile(pattern);
+ assertFalse(RegexTools.matches(null, compiledPattern), "Null input should return false");
+ }
+
+ @Test
+ void matchesOne_InputMatchesOnePattern_ReturnsTrue() {
+ String[] patterns = {"abc", "def"};
+ Pattern[] compiledPatterns = new Pattern[patterns.length];
+ for (int i = 0; i < patterns.length; i++) {
+ compiledPatterns[i] = Pattern.compile(patterns[i]);
+ }
+ assertTrue(RegexTools.matchesOne("abc", compiledPatterns), "Input should match one pattern");
+ }
+
+ @Test
+ void matchesOne_InputDoesNotMatchAnyPattern_ReturnsFalse() {
+ String[] patterns = {"abc", "def"};
+ Pattern[] compiledPatterns = new Pattern[patterns.length];
+ for (int i = 0; i < patterns.length; i++) {
+ compiledPatterns[i] = Pattern.compile(patterns[i]);
+ }
+ assertFalse(RegexTools.matchesOne("xyz", compiledPatterns), "Input should not match any pattern");
+ }
+
+ @Test
+ void matchesAll_InputMatchesAllPatterns_ReturnsTrue() {
+ String[] patterns = {"abc", "abc"};
+ Pattern[] compiledPatterns = new Pattern[patterns.length];
+ for (int i = 0; i < patterns.length; i++) {
+ compiledPatterns[i] = Pattern.compile(patterns[i]);
+ }
+ assertTrue(RegexTools.matchesAll("abc", compiledPatterns), "Input should match all patterns");
+ }
+
+ @Test
+ void matchesAll_InputDoesNotMatchAllPatterns_ReturnsFalse() {
+ String[] patterns = {"abc", "def"};
+ Pattern[] compiledPatterns = new Pattern[patterns.length];
+ for (int i = 0; i < patterns.length; i++) {
+ compiledPatterns[i] = Pattern.compile(patterns[i]);
+ }
+ assertFalse(RegexTools.matchesAll("abc", compiledPatterns), "Input should not match all patterns");
+ }
+
+ @Test
+ void getMatcher_ValidInputAndPattern_ReturnsMatcher() {
+ String pattern = "abc";
+ Pattern compiledPattern = Pattern.compile(pattern);
+ Matcher matcher = RegexTools.getMatcher("abc", compiledPattern);
+ assertNotNull(matcher, "Matcher should not be null");
+ }
+
+ @Test
+ void getMatcher_NullInput_ThrowsException() {
+ String pattern = "abc";
+ Pattern compiledPattern = Pattern.compile(pattern);
+ assertThrows(NullPointerException.class, () -> {
+ RegexTools.getMatcher(null, compiledPattern);
+ });
+ }
+
+ @Test
+ void getMatcher_NullPattern_ThrowsException() {
+ final Pattern pattern = null;
+ assertThrows(NullPointerException.class, () -> {
+ RegexTools.getMatcher("abc", pattern);
+ });
+ }
+}
From a2482419e0960fe7aa05a4d234e5d27cc3ab84f3 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Sun, 29 Dec 2024 21:29:23 +0800
Subject: [PATCH 18/24] =?UTF-8?q?=E5=AE=8C=E6=88=90=20DateTimeTools=20?=
=?UTF-8?q?=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=E5=92=8C=E4=BF=AE?=
=?UTF-8?q?=E5=A4=8D=EF=BC=8C=E5=B9=B6=E4=BF=AE=E6=94=B9=E5=85=B6=E5=AE=83?=
=?UTF-8?q?=E4=B8=8D=E5=90=88=E9=80=82=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B?=
=?UTF-8?q?=E8=AF=95=E7=94=A8=E4=BE=8B=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../plusone/commons/util/DateTimeTools.java | 25 +-
.../commons/util/DateTimeToolsTests.java | 502 ++++++++++++++++--
.../commons/util/IdGeneratorTests.java | 13 +-
.../plusone/commons/util/RegexToolsTests.java | 4 +-
4 files changed, 466 insertions(+), 78 deletions(-)
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeTools.java b/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeTools.java
index 28e1989..e580706 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeTools.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeTools.java
@@ -16,6 +16,8 @@
package xyz.zhouxy.plusone.commons.util;
+import static java.time.temporal.ChronoField.*;
+
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
@@ -30,7 +32,6 @@ import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
-import com.google.common.base.Strings;
import com.google.common.collect.Range;
import xyz.zhouxy.plusone.commons.time.Quarter;
@@ -46,29 +47,27 @@ public class DateTimeTools {
// #region - toString
public static String toYearString(int year) {
- return Integer.toString(year);
+ return Integer.toString(YEAR.checkValidIntValue(year));
}
public static String toYearString(Year year) {
return year.toString();
}
- public static String toMonthString(int monthValue) {
- return Strings.padStart(Integer.toString(monthValue), 2, '0');
+ public static String toMonthStringM(int monthValue) {
+ return Integer.toString(MONTH_OF_YEAR.checkValidIntValue(monthValue));
}
- public static String toMonthString(int monthValue, boolean padStart) {
- return padStart ? toMonthString(monthValue) : Integer.toString(monthValue);
+ public static String toMonthStringMM(int monthValue) {
+ return String.format("%02d", MONTH_OF_YEAR.checkValidIntValue(monthValue));
}
- public static String toMonthString(Month month) {
- final int monthValue = month.getValue();
- return Strings.padStart(Integer.toString(monthValue), 2, '0');
+ public static String toMonthStringM(Month month) {
+ return Integer.toString(month.getValue());
}
- public static String toMonthString(Month month, boolean padStart) {
- final int monthValue = month.getValue();
- return padStart ? toMonthString(month) : Integer.toString(monthValue);
+ public static String toMonthStringMM(Month month) {
+ return String.format("%02d", month.getValue());
}
// #endregion
@@ -282,7 +281,7 @@ public class DateTimeTools {
* @param zone 时区
* @return 带时区的地区时间
*/
- public static ZonedDateTime toZonedDateTime(LocalDateTime localDateTime, ZoneId zone) { // NOSONAR
+ public static ZonedDateTime toZonedDateTime(LocalDateTime localDateTime, ZoneId zone) {
return ZonedDateTime.of(localDateTime, zone);
}
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java
index 370c0eb..a1796bf 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java
@@ -17,96 +17,480 @@
package xyz.zhouxy.plusone.commons.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import java.time.DateTimeException;
import java.time.Instant;
+import java.time.LocalDate;
import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.time.Month;
+import java.time.Year;
+import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.collect.Range;
+
+import xyz.zhouxy.plusone.commons.time.Quarter;
+import xyz.zhouxy.plusone.commons.time.YearQuarter;
+
class DateTimeToolsTests {
private static final Logger log = LoggerFactory.getLogger(DateTimeToolsTests.class);
- @Test
- void testToJoda() {
- LocalDateTime dt = LocalDateTime.of(2008, 8, 8, 20, 18, 59, 108000000);
- log.info("src: {}", dt);
- org.joda.time.LocalDateTime dt2 = DateTimeTools.toJodaLocalDateTime(dt);
- log.info("result: {}", dt2);
- org.joda.time.format.DateTimeFormatter f = org.joda.time.format.DateTimeFormat
- .forPattern("yyyy-MM-dd HH:mm:ss.SSS");
+ // Java
+ static final LocalDateTime LOCAL_DATE_TIME = LocalDateTime.of(2024, 12, 29, 12, 58, 30, 333000000);
+ static final LocalDate LOCAL_DATE = LOCAL_DATE_TIME.toLocalDate();
+ static final LocalTime LOCAL_TIME = LOCAL_DATE_TIME.toLocalTime();
- assertEquals("2008-08-08 20:18:59.108", f.print(dt2));
+ // Java - 2024-12-29 12:58:30.333333333 SystemDefaultZone
+ static final ZoneId SYS_ZONE_ID = ZoneId.systemDefault();
+ static final ZonedDateTime ZONED_DATE_TIME_WITH_SYS_ZONE = LOCAL_DATE_TIME.atZone(SYS_ZONE_ID);
+ static final Instant INSTANT_WITH_SYS_ZONE = ZONED_DATE_TIME_WITH_SYS_ZONE.toInstant();
+ static final long INSTANT_MILLIS = INSTANT_WITH_SYS_ZONE.toEpochMilli();
+
+ static final TimeZone SYS_TIME_ZONE = TimeZone.getDefault();
+ static final Date SYS_DATE = Date.from(INSTANT_WITH_SYS_ZONE);
+ static final Calendar SYS_CALENDAR = Calendar.getInstance(SYS_TIME_ZONE);
+ static {
+ SYS_CALENDAR.setTime(SYS_DATE);
+ }
+
+ // Java - 2024-12-29 12:58:30.333333333 GMT+04:00
+ static final ZoneId ZONE_ID = ZoneId.of("GMT+04:00");
+ static final ZonedDateTime ZONED_DATE_TIME = LOCAL_DATE_TIME.atZone(ZONE_ID);
+ static final Instant INSTANT = ZONED_DATE_TIME.toInstant();
+ static final long MILLIS = INSTANT.toEpochMilli();
+
+ static final TimeZone TIME_ZONE = TimeZone.getTimeZone(ZONE_ID);
+ static final Date DATE = Date.from(INSTANT);
+ static final Calendar CALENDAR = Calendar.getInstance(TIME_ZONE);
+ static {
+ CALENDAR.setTime(DATE);
+ }
+
+ // Joda
+ static final org.joda.time.LocalDateTime JODA_LOCAL_DATE_TIME
+ = new org.joda.time.LocalDateTime(2024, 12, 29, 12, 58, 30, 333);
+ static final org.joda.time.LocalDate JODA_LOCAL_DATE = JODA_LOCAL_DATE_TIME.toLocalDate();
+ static final org.joda.time.LocalTime JODA_LOCAL_TIME = JODA_LOCAL_DATE_TIME.toLocalTime();
+
+ // Joda - 2024-12-29 12:58:30.333 SystemDefaultZone
+ static final org.joda.time.DateTimeZone JODA_SYS_ZONE = org.joda.time.DateTimeZone.getDefault();
+ static final org.joda.time.DateTime JODA_DATE_TIME_WITH_SYS_ZONE = JODA_LOCAL_DATE_TIME.toDateTime(JODA_SYS_ZONE);
+ static final org.joda.time.Instant JODA_INSTANT_WITH_SYS_ZONE = JODA_DATE_TIME_WITH_SYS_ZONE.toInstant();
+ static final long JODA_INSTANT_MILLIS = JODA_INSTANT_WITH_SYS_ZONE.getMillis();
+
+ // Joda - 2024-12-29 12:58:30.333 GMT+04:00
+ static final org.joda.time.DateTimeZone JODA_ZONE = org.joda.time.DateTimeZone.forID("GMT+04:00");
+ static final org.joda.time.DateTime JODA_DATE_TIME = JODA_LOCAL_DATE_TIME.toDateTime(JODA_ZONE);
+ static final org.joda.time.Instant JODA_INSTANT = JODA_DATE_TIME.toInstant();
+ static final long JODA_MILLIS = JODA_INSTANT.getMillis();
+
+ // ================================
+ // #region - toDate
+ // ================================
+
+ @Test
+ void toDate_timeMillis() {
+ assertNotEquals(SYS_DATE, DATE);
+ log.info("SYS_DATE: {}, DATE: {}", SYS_DATE, DATE);
+ assertEquals(SYS_DATE, JODA_DATE_TIME_WITH_SYS_ZONE.toDate());
+ assertEquals(SYS_DATE, DateTimeTools.toDate(INSTANT_MILLIS));
+ assertEquals(DATE, JODA_DATE_TIME.toDate());
+ assertEquals(DATE, DateTimeTools.toDate(MILLIS));
}
@Test
- void testToInstant() {
- ZonedDateTime dt = ZonedDateTime.of(2008, 1, 8, 10, 23, 50, 108000000, ZoneId.systemDefault());
- Instant instant = DateTimeTools.toInstant(dt.toInstant().toEpochMilli());
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yy-M-d HH:mm:ss.SSS");
- String str = formatter.format(instant.atZone(ZoneId.systemDefault()));
- log.info(str);
- assertEquals("08-1-8 10:23:50.108", str);
+ void toDate_calendar() {
+ assertEquals(SYS_DATE, DateTimeTools.toDate(SYS_CALENDAR));
+ assertEquals(DATE, DateTimeTools.toDate(CALENDAR));
}
@Test
- void testToJodaDateTime() {
- ZonedDateTime dt = ZonedDateTime.of(2008, 1, 8, 10, 23, 50, 108000000, ZoneId.systemDefault());
- Instant instant = DateTimeTools.toInstant(dt.toInstant().toEpochMilli());
-
- org.joda.time.format.DateTimeFormatter f = org.joda.time.format.DateTimeFormat
- .forPattern("yyyy-MM-dd HH:mm:ss.SSS");
-
- org.joda.time.DateTime jodaDateTime = DateTimeTools.toJodaDateTime(instant, ZoneId.of("+08:00"));
- log.info("jodaDateTime: {}", jodaDateTime);
- assertEquals("2008-01-08 10:23:50.108", f.print(jodaDateTime));
-
- jodaDateTime = DateTimeTools.toJodaDateTime(instant, ZoneId.of("+02:00"));
- log.info("jodaDateTime: {}", jodaDateTime);
- assertEquals("2008-01-08 04:23:50.108", f.print(jodaDateTime));
+ void toDate_instant() {
+ assertEquals(SYS_DATE, DateTimeTools.toDate(INSTANT_WITH_SYS_ZONE));
+ assertEquals(DATE, DateTimeTools.toDate(INSTANT));
}
@Test
- void test() {
- java.time.Instant now = java.time.Instant.now();
- org.joda.time.DateTime jodaDateTime = DateTimeTools.toJodaDateTime(now, ZoneId.of("America/New_York"));
- org.joda.time.format.DateTimeFormatter formatter = org.joda.time.format.DateTimeFormat
- .forPattern("yyyy-MM-dd HH:mm:ss.SSS");
- log.info(formatter.print(jodaDateTime));
- log.info(jodaDateTime.getZone().toString());
- log.info(jodaDateTime.toString());
- log.info("==========================================");
- org.joda.time.Instant instant = new org.joda.time.Instant(System.currentTimeMillis() - 500000);
- log.info(instant.toString());
- log.info(DateTimeTools.toJavaInstant(instant).toString());
- log.info(DateTimeTools.toZonedDateTime(instant, org.joda.time.DateTimeZone.forID("America/New_York"))
- .toString());
+ void toDate_ZoneDateTime() {
+ assertEquals(SYS_DATE, DateTimeTools.toDate(ZONED_DATE_TIME_WITH_SYS_ZONE));
+ assertEquals(DATE, DateTimeTools.toDate(ZONED_DATE_TIME));
}
@Test
- void testToJodaInstant() {
- java.time.Instant javaInstant = java.time.Instant.now();
- log.info("javaInstant: {}", javaInstant);
-
- org.joda.time.Instant jodaInstant = DateTimeTools.toJodaInstant(javaInstant);
- log.info("jodaInstant: {}", jodaInstant);
-
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
- DateTimeFormatter formatter2 = formatter.withZone(ZoneId.systemDefault());
- log.info("{}", formatter);
- log.info("{}", formatter2);
+ void toDate_LocalDateTimeAndZoneId() {
+ assertEquals(SYS_DATE, DateTimeTools.toDate(LOCAL_DATE_TIME, SYS_ZONE_ID));
+ assertEquals(DATE, DateTimeTools.toDate(LOCAL_DATE_TIME, ZONE_ID));
+ assertEquals(SYS_DATE, DateTimeTools.toDate(LOCAL_DATE, LOCAL_TIME, SYS_ZONE_ID));
+ assertEquals(DATE, DateTimeTools.toDate(LOCAL_DATE, LOCAL_TIME, ZONE_ID));
}
+ // ================================
+ // #endregion - toDate
+ // ================================
+
+ // ================================
+ // #region - toInstant
+ // ================================
+
+ @Test
+ void toInstant_timeMillis() {
+ assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toInstant(INSTANT_MILLIS));
+ assertEquals(INSTANT, DateTimeTools.toInstant(MILLIS));
+ }
+
+ @Test
+ void toInstant_Date() {
+ assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toInstant(SYS_DATE));
+ assertEquals(INSTANT, DateTimeTools.toInstant(DATE));
+ }
+
+ @Test
+ void toInstant_Calendar() {
+ assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toInstant(SYS_CALENDAR));
+ assertEquals(INSTANT, DateTimeTools.toInstant(CALENDAR));
+ }
+
+ @Test
+ void toInstant_ZonedDateTime() {
+ assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toInstant(ZONED_DATE_TIME_WITH_SYS_ZONE));
+ assertEquals(INSTANT, DateTimeTools.toInstant(ZONED_DATE_TIME));
+ }
+
+ @Test
+ void toInstant_LocalDateTimeAndZone() {
+ assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toInstant(LOCAL_DATE_TIME, SYS_ZONE_ID));
+ assertEquals(INSTANT, DateTimeTools.toInstant(LOCAL_DATE_TIME, ZONE_ID));
+ }
+
+ // ================================
+ // #endregion - toInstant
+ // ================================
+
+ // ================================
+ // #region - toZonedDateTime
+ // ================================
+
+ @Test
+ void toZonedDateTime_TimeMillisAndZone() {
+ assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(INSTANT_MILLIS, SYS_ZONE_ID));
+ assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(MILLIS, ZONE_ID));
+ }
+
+ @Test
+ void toZonedDateTime_DateAndZoneId() {
+ assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(SYS_DATE, SYS_ZONE_ID));
+ assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(DATE, ZONE_ID));
+ }
+
+ @Test
+ void toZonedDateTime_DateAndTimeZone() {
+ assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(SYS_DATE, SYS_TIME_ZONE));
+ assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(DATE, TIME_ZONE));
+ }
+
+ @Test
+ void toZonedDateTime_Calendar() {
+ assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(SYS_CALENDAR));
+ assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(CALENDAR));
+ }
+
+ @Test
+ void toZonedDateTime_CalendarAndZoneId() {
+ assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(SYS_CALENDAR, SYS_ZONE_ID));
+ assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(CALENDAR, ZONE_ID));
+ }
+
+ @Test
+ void toZonedDateTime_CalendarAndTimeZone() {
+ assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(SYS_CALENDAR, SYS_TIME_ZONE));
+ assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(CALENDAR, TIME_ZONE));
+ }
+
+ @Test
+ void toZonedDateTime_LocalDateTimeAndZoneId() {
+ assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(LOCAL_DATE_TIME, SYS_ZONE_ID));
+ assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(LOCAL_DATE_TIME, ZONE_ID));
+ }
+
+ // ================================
+ // #endregion - toZonedDateTime
+ // ================================
+
+ // ================================
+ // #region - toLocalDateTime
+ // ================================
+
+ @Test
+ void toLocalDateTime_TimeMillisAndZoneId() {
+ assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(INSTANT_MILLIS, SYS_ZONE_ID));
+ assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(MILLIS, ZONE_ID));
+ }
+
+ @Test
+ void toLocalDateTime_DateAndZoneId() {
+ assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(SYS_DATE, SYS_ZONE_ID));
+ assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(DATE, ZONE_ID));
+ }
+
+ @Test
+ void toLocalDateTime_DateAndTimeZone() {
+ assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(SYS_DATE, SYS_TIME_ZONE));
+ assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(DATE, TIME_ZONE));
+ }
+
+ @Test
+ void toLocalDateTime_CalendarAndZoneId() {
+ assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(SYS_CALENDAR, SYS_ZONE_ID));
+ assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(CALENDAR, ZONE_ID));
+ }
+
+ @Test
+ void toLocalDateTime_CalendarAndTimeZone() {
+ assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(SYS_CALENDAR, SYS_TIME_ZONE));
+ assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(CALENDAR, TIME_ZONE));
+ }
+
+ @Test
+ void toLocalDateTime_ZonedDateTimeAndZoneId() {
+ assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(ZONED_DATE_TIME_WITH_SYS_ZONE, SYS_ZONE_ID));
+ assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(ZONED_DATE_TIME, ZONE_ID));
+ }
+
+ // ================================
+ // #endregion - toLocalDateTime
+ // ================================
+
+ // ================================
+ // #region - toJodaInstant
+ // ================================
+
+ @Test
+ void toJodaInstant_JavaInstant() {
+ assertEquals(JODA_INSTANT_WITH_SYS_ZONE, DateTimeTools.toJodaInstant(INSTANT_WITH_SYS_ZONE));
+ assertEquals(JODA_INSTANT, DateTimeTools.toJodaInstant(INSTANT));
+ }
+
+ @Test
+ void toJodaInstant_ZonedDateTime() {
+ assertEquals(JODA_INSTANT_WITH_SYS_ZONE, DateTimeTools.toJodaInstant(ZONED_DATE_TIME_WITH_SYS_ZONE));
+ assertEquals(JODA_INSTANT, DateTimeTools.toJodaInstant(ZONED_DATE_TIME));
+ }
+
+ @Test
+ void toJodaInstant_LocalDateTimeAndZoneId() {
+ assertEquals(JODA_INSTANT_WITH_SYS_ZONE, DateTimeTools.toJodaInstant(LOCAL_DATE_TIME, SYS_ZONE_ID));
+ assertEquals(JODA_INSTANT, DateTimeTools.toJodaInstant(LOCAL_DATE_TIME, ZONE_ID));
+ }
+
+ // ================================
+ // #endregion - toJodaInstant
+ // ================================
+
+ // ================================
+ // #region - toJavaInstant
+ // ================================
+
+ @Test
+ void toJavaInstant_JodaInstant() {
+ assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toJavaInstant(JODA_INSTANT_WITH_SYS_ZONE));
+ assertEquals(INSTANT, DateTimeTools.toJavaInstant(JODA_INSTANT));
+ }
+
+ @Test
+ void toJavaInstant_JodaDateTime() {
+ assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toJavaInstant(JODA_DATE_TIME_WITH_SYS_ZONE));
+ assertEquals(INSTANT, DateTimeTools.toJavaInstant(JODA_DATE_TIME));
+ }
+
+ @Test
+ void toJavaInstant_JodaLocalDateTimeAndJodaDateTimeZone() {
+ assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toJavaInstant(JODA_LOCAL_DATE_TIME, JODA_SYS_ZONE));
+ assertEquals(INSTANT, DateTimeTools.toJavaInstant(JODA_LOCAL_DATE_TIME, JODA_ZONE));
+ }
+
+ // ================================
+ // #endregion - toJavaInstant
+ // ================================
+
+ // ================================
+ // #region - toJodaDateTime
+ // ================================
+
+ @Test
+ void toJodaDateTime_ZonedDateTime() {
+ assertEquals(JODA_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toJodaDateTime(ZONED_DATE_TIME_WITH_SYS_ZONE));
+ assertEquals(JODA_DATE_TIME, DateTimeTools.toJodaDateTime(ZONED_DATE_TIME));
+ }
+
+ @Test
+ void toJodaDateTime_LocalDateTimeAndZoneId() {
+ assertEquals(JODA_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toJodaDateTime(LOCAL_DATE_TIME, SYS_ZONE_ID));
+ assertEquals(JODA_DATE_TIME, DateTimeTools.toJodaDateTime(LOCAL_DATE_TIME, ZONE_ID));
+ }
+
+ @Test
+ void toJodaDateTime_InstantAndZoneId() {
+ assertEquals(JODA_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toJodaDateTime(INSTANT_WITH_SYS_ZONE, SYS_ZONE_ID));
+ assertEquals(JODA_DATE_TIME, DateTimeTools.toJodaDateTime(INSTANT, ZONE_ID));
+ }
+
+ // ================================
+ // #endregion - toJodaDateTime
+ // ================================
+
+ // ================================
+ // #region - toZonedDateTime
+ // ================================
+
+ @Test
+ void toZonedDateTime_JodaDateTime() {
+ assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(JODA_DATE_TIME_WITH_SYS_ZONE));
+ assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(JODA_DATE_TIME));
+ }
+
+ @Test
+ void toZonedDateTime_JodaLocalDateTimeAndJodaDateTimeZone() {
+ assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(JODA_LOCAL_DATE_TIME, JODA_SYS_ZONE));
+ assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(JODA_LOCAL_DATE_TIME, JODA_ZONE));
+ }
+
+ @Test
+ void toZonedDateTime_JodaInstantAndJodaDateTimeZone() {
+ assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(JODA_INSTANT_WITH_SYS_ZONE, JODA_SYS_ZONE));
+ assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(JODA_INSTANT, JODA_ZONE));
+ }
+
+ // ================================
+ // #endregion - toZonedDateTime
+ // ================================
+
+ // ================================
+ // #region - toJodaLocalDateTime
+ // ================================
+
+ @Test
+ void toJodaLocalDateTime_JavaLocalDateTime() {
+ assertEquals(JODA_LOCAL_DATE_TIME, DateTimeTools.toJodaLocalDateTime(LOCAL_DATE_TIME));
+ }
+
+ @Test
+ void toJavaLocalDateTime_JodaLocalDateTime() {
+ assertEquals(LOCAL_DATE_TIME, DateTimeTools.toJavaLocalDateTime(JODA_LOCAL_DATE_TIME));
+ }
+
+ // ================================
+ // #endregion - toJodaLocalDateTime
+ // ================================
+
+ // ================================
+ // #region - ZondId <--> DateTimeZone
+ // ================================
+
+ @Test
+ void convertJavaZoneIdAndJodaDateTimeZone() {
+ assertEquals(SYS_ZONE_ID, DateTimeTools.toJavaZone(JODA_SYS_ZONE));
+ assertEquals(ZONE_ID, DateTimeTools.toJavaZone(JODA_ZONE));
+ assertEquals(JODA_SYS_ZONE, DateTimeTools.toJodaZone(SYS_ZONE_ID));
+ assertEquals(JODA_ZONE, DateTimeTools.toJodaZone(ZONE_ID));
+ }
+
+ // ================================
+ // #endregion - ZondId <--> DateTimeZone
+ // ================================
+
+ // ================================
+ // #region - YearQuarter & Quarter
+ // ================================
+
+ @Test
+ void getQuarter() {
+ YearQuarter expectedYearQuarter = YearQuarter.of(2024, 4);
+ assertEquals(expectedYearQuarter, DateTimeTools.getQuarter(SYS_DATE));
+ assertEquals(expectedYearQuarter, DateTimeTools.getQuarter(SYS_CALENDAR));
+ assertEquals(Quarter.Q4, DateTimeTools.getQuarter(Month.DECEMBER));
+ assertEquals(expectedYearQuarter, DateTimeTools.getQuarter(2024, Month.DECEMBER));
+ assertEquals(expectedYearQuarter, DateTimeTools.getQuarter(YearMonth.of(2024, Month.DECEMBER)));
+ assertEquals(expectedYearQuarter, DateTimeTools.getQuarter(LOCAL_DATE));
+ }
+
+ // ================================
+ // #endregion - YearQuarter & Quarter
+ // ================================
+
+ // ================================
+ // #region - others
+ // ================================
+
+ @Test
+ void startDateOfYear() {
+ assertEquals(LocalDate.of(2008, 1, 1), DateTimeTools.startDateOfYear(2008));
+ assertEquals(LocalDate.of(2008, 12, 31), DateTimeTools.endDateOfYear(2008));
+ assertEquals(LocalDateTime.of(2024, 12, 30, 0, 0, 0),
+ DateTimeTools.startOfNextDate(LOCAL_DATE));
+ assertEquals(LocalDateTime.of(2024, 12, 30, 0, 0, 0).atZone(SYS_ZONE_ID),
+ DateTimeTools.startOfNextDate(LOCAL_DATE, SYS_ZONE_ID));
+ assertEquals(LocalDateTime.of(2024, 12, 30, 0, 0, 0).atZone(ZONE_ID),
+ DateTimeTools.startOfNextDate(LOCAL_DATE, ZONE_ID));
+
+ Range localDateTimeRange = DateTimeTools.toDateTimeRange(LOCAL_DATE);
+ assertEquals(LOCAL_DATE.atStartOfDay(), localDateTimeRange.lowerEndpoint());
+ assertTrue(localDateTimeRange.contains(LOCAL_DATE.atStartOfDay()));
+ assertEquals(LocalDate.of(2024, 12, 30).atStartOfDay(), localDateTimeRange.upperEndpoint());
+ assertEquals(LocalDate.of(2024, 12, 30).atStartOfDay(), localDateTimeRange.upperEndpoint());
+ assertFalse(localDateTimeRange.contains(LocalDate.of(2024, 12, 30).atStartOfDay()));
+
+ Range zonedDateTimeRange = DateTimeTools.toDateTimeRange(LOCAL_DATE, SYS_ZONE_ID);
+ assertEquals(LOCAL_DATE.atStartOfDay().atZone(SYS_ZONE_ID), zonedDateTimeRange.lowerEndpoint());
+ assertTrue(zonedDateTimeRange.contains(LOCAL_DATE.atStartOfDay().atZone(SYS_ZONE_ID)));
+ assertEquals(ZonedDateTime.of(LocalDate.of(2024, 12, 30).atStartOfDay(), SYS_ZONE_ID), zonedDateTimeRange.upperEndpoint());
+ assertEquals(ZonedDateTime.of(LocalDate.of(2024, 12, 30).atStartOfDay(), SYS_ZONE_ID), zonedDateTimeRange.upperEndpoint());
+ assertFalse(zonedDateTimeRange.contains(LocalDate.of(2024, 12, 30).atStartOfDay().atZone(SYS_ZONE_ID)));
+ }
+
+ // ================================
+ // #endregion - others
+ // ================================
+
+ // ================================
+ // #region - toString
+ // ================================
+
@Test
void testToString() {
- assertEquals("04", DateTimeTools.toMonthString(Month.APRIL));
- assertEquals("04", DateTimeTools.toMonthString(Month.APRIL, true));
- assertEquals("4", DateTimeTools.toMonthString(Month.APRIL, false));
+ assertEquals("2024", DateTimeTools.toYearString(2024));
+ assertEquals("999999999", DateTimeTools.toYearString(Year.MAX_VALUE));
+ assertEquals("-999999999", DateTimeTools.toYearString(Year.MIN_VALUE));
+ assertThrows(DateTimeException.class, () -> DateTimeTools.toYearString(Year.MIN_VALUE - 1));
+ assertThrows(DateTimeException.class, () -> DateTimeTools.toYearString(Year.MAX_VALUE + 1));
+
+ assertEquals("01", DateTimeTools.toMonthStringMM(1));
+ assertEquals("02", DateTimeTools.toMonthStringMM(2));
+ assertEquals("3", DateTimeTools.toMonthStringM(3));
+ assertEquals("04", DateTimeTools.toMonthStringMM(Month.APRIL));
+ assertEquals("05", DateTimeTools.toMonthStringMM(Month.MAY));
+ assertEquals("6", DateTimeTools.toMonthStringM(Month.JUNE));
+
+ assertThrows(DateTimeException.class, () -> DateTimeTools.toMonthStringM(0));
+ assertThrows(DateTimeException.class, () -> DateTimeTools.toMonthStringMM(0));
+ assertThrows(DateTimeException.class, () -> DateTimeTools.toMonthStringM(13));
+ assertThrows(DateTimeException.class, () -> DateTimeTools.toMonthStringMM(13));
}
+
+ // ================================
+ // #endregion - toString
+ // ================================
}
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java
index 7447e48..ccc3f59 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java
@@ -25,6 +25,8 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import cn.hutool.core.collection.ConcurrentHashSet;
@@ -49,9 +51,12 @@ public class IdGeneratorTests {
}
}
- @Test
- void testIdWorker() { // NOSONAR
- final IdWorker idWorker = new IdWorker(0L);
+ @ParameterizedTest
+ @ValueSource(longs = { 0L, 1L, 108L, 300L })
+ void testIdWorker(long workerId) { // NOSONAR
+ // 如果使用 new IdWorker(0L) 创建,会和下面的 IdGenerator#nextSnowflakeId 使用相同 workerId 的不同 IdWorker 实例,造成 ID 重复
+ final IdWorker idWorker = IdGenerator.getSnowflakeIdGenerator(workerId);
+
final Set ids = new ConcurrentHashSet<>();
for (int i = 0; i < 10000; i++) {
executor.execute(() -> {
@@ -63,7 +68,7 @@ public class IdGeneratorTests {
});
executor.execute(() -> {
for (int j = 0; j < 50000; j++) {
- if (false == ids.add(IdGenerator.nextSnowflakeId(0))) {
+ if (false == ids.add(IdGenerator.nextSnowflakeId(workerId))) {
throw new RuntimeException("重复ID!");
}
}
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/RegexToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/RegexToolsTests.java
index 3968a24..0d3fb8d 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/util/RegexToolsTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/RegexToolsTests.java
@@ -39,7 +39,7 @@ class RegexToolsTests {
@Test
void getPattern_CachePatternFalse_ReturnsNewPattern() {
- String pattern = "abc";
+ String pattern = "getPattern_CachePatternFalse_ReturnsNewPattern";
Pattern pattern1 = RegexTools.getPattern(pattern, false);
Pattern pattern2 = RegexTools.getPattern(pattern, false);
assertNotSame(pattern1, pattern2, "Pattern should not be cached");
@@ -63,7 +63,7 @@ class RegexToolsTests {
@Test
void getPatterns_CachePatternFalse_ReturnsNewPatterns() {
- String[] patterns = {"abc", "def"};
+ String[] patterns = {"getPatterns_CachePatternFalse_ReturnsNewPatterns1", "getPatterns_CachePatternFalse_ReturnsNewPatterns2"};
Pattern[] patterns1 = RegexTools.getPatterns(patterns, false);
Pattern[] patterns2 = RegexTools.getPatterns(patterns, false);
assertNotSame(patterns1[0], patterns2[0]);
From f1412d6eead85d14ff798ff2c4b05fb9b0fbe022 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Sun, 29 Dec 2024 21:32:19 +0800
Subject: [PATCH 19/24] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=B5=8B=E8=AF=95?=
=?UTF-8?q?=E8=BF=9B=E5=BA=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ProgressOfTesting.txt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt
index ff0f1b7..07efbfc 100644
--- a/ProgressOfTesting.txt
+++ b/ProgressOfTesting.txt
@@ -1,6 +1,6 @@
[ ] 未开始测试 - 0 (0.00%)
-[*] 测试未完成 - 5 (8.06%)
-[Y] 测试完成 - 35 (56.45%)
+[*] 测试未完成 - 4 (06.45%)
+[Y] 测试完成 - 36 (58.06%)
[-] 无需测试 - 22 (35.48%)
xyz.zhouxy.plusone.commons
@@ -77,7 +77,7 @@ xyz.zhouxy.plusone.commons
ArrayTools.java [*] 61
AssertTools.java [Y]
BigDecimals.java [Y]
- DateTimeTools.java [*] 83
+ DateTimeTools.java [Y]
Enumeration.java [Y]
EnumTools.java [Y]
IdGenerator.java [Y]
From 8a60f4db66bad9b13e5be243a1a1acfe979240ca Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Sun, 29 Dec 2024 22:35:53 +0800
Subject: [PATCH 20/24] =?UTF-8?q?=E4=BF=9D=E5=AD=98=20CollectionTools#null?=
=?UTF-8?q?ToEmptyXXX=20=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?=
=?UTF-8?q?=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../collection/CollectionToolsTests.java | 23 +++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/collection/CollectionToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/collection/CollectionToolsTests.java
index bcb53a6..97fdef5 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/collection/CollectionToolsTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/collection/CollectionToolsTests.java
@@ -16,16 +16,24 @@
package xyz.zhouxy.plusone.commons.collection;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.junit.jupiter.api.Test;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
public class CollectionToolsTests {
@Test
void testIsEmpty() {
@@ -46,4 +54,19 @@ public class CollectionToolsTests {
assertFalse(CollectionTools.isEmpty(map));
assertTrue(CollectionTools.isNotEmpty(map));
}
+
+ @Test
+ void testNullToEmpty() {
+ List list = Lists.newArrayList("Java", "C", "C++", "C#");
+ assertSame(list, CollectionTools.nullToEmptyList(list));
+ assertEquals(Collections.emptyList(), CollectionTools.nullToEmptyList(null));
+
+ Set set = Sets.newHashSet("Java", "C", "C++", "C#");
+ assertSame(set, CollectionTools.nullToEmptySet(set));
+ assertEquals(Collections.emptySet(), CollectionTools.nullToEmptySet(null));
+
+ Map map = ImmutableMap.of("K1", 1, "K2", 2, "K3", 3);
+ assertSame(map, CollectionTools.nullToEmptyMap(map));
+ assertEquals(Collections.emptyMap(), CollectionTools.nullToEmptyMap(null));
+ }
}
From 8f588c25b5b8db8ad6abff9f0fc1292018867284 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Sun, 29 Dec 2024 22:40:35 +0800
Subject: [PATCH 21/24] =?UTF-8?q?=E6=9E=84=E9=80=A0=20PageResult=20?=
=?UTF-8?q?=E6=97=B6=EF=BC=8C=E5=A6=82=E6=9E=9C=20list=20=E6=98=AF=20null?=
=?UTF-8?q?=EF=BC=8C=E5=88=99=E8=87=AA=E5=8A=A8=E8=BD=AC=E4=B8=BA=E7=A9=BA?=
=?UTF-8?q?=E5=88=97=E8=A1=A8=EF=BC=8C=E4=B8=8D=E6=8A=9B=E5=BC=82=E5=B8=B8?=
=?UTF-8?q?=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../xyz/zhouxy/plusone/commons/model/dto/PageResult.java | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PageResult.java b/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PageResult.java
index b73d0a0..353d86f 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PageResult.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PageResult.java
@@ -20,7 +20,7 @@ import java.util.Collections;
import java.util.List;
import xyz.zhouxy.plusone.commons.annotation.StaticFactoryMethod;
-import xyz.zhouxy.plusone.commons.util.AssertTools;
+import xyz.zhouxy.plusone.commons.collection.CollectionTools;
/**
* 返回分页查询的结果
@@ -37,8 +37,7 @@ public class PageResult {
private final List content;
private PageResult(List content, long total) {
- AssertTools.checkNotNull(content, "Content must not be null.");
- this.content = content;
+ this.content = CollectionTools.nullToEmptyList(content);
this.total = total;
}
From 9f96db1a0bcaa667ee0aaacd07654223ba28d52f Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Wed, 1 Jan 2025 17:17:50 +0800
Subject: [PATCH 22/24] =?UTF-8?q?=E5=AE=8C=E6=88=90=20ArrayTools=20?=
=?UTF-8?q?=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
---
.../plusone/commons/util/ArrayTools.java | 60 +-
.../plusone/commons/util/ArrayToolsTests.java | 1102 +++++++++++++----
2 files changed, 915 insertions(+), 247 deletions(-)
diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/ArrayTools.java b/src/main/java/xyz/zhouxy/plusone/commons/util/ArrayTools.java
index d547ade..8ad67ee 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/util/ArrayTools.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/util/ArrayTools.java
@@ -18,6 +18,7 @@ package xyz.zhouxy.plusone.commons.util;
import java.math.BigDecimal;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -260,12 +261,7 @@ public class ArrayTools {
*/
public static boolean isAllElementsNotNull(@Nonnull final T[] arr) {
AssertTools.checkArgument(arr != null, "The array cannot be null.");
- for (T element : arr) {
- if (element == null) {
- return false;
- }
- }
- return true;
+ return Arrays.stream(arr).allMatch(Objects::nonNull);
}
// #endregion
@@ -626,7 +622,7 @@ public class ArrayTools {
// fill - char
- public static void fill(char[] a, char... values) {
+ public static void fill(char[] a, char[] values) {
fill(a, 0, a.length, values);
}
@@ -634,9 +630,9 @@ public class ArrayTools {
fill(a, 0, a.length, values != null ? values.toCharArray() : EMPTY_CHAR_ARRAY);
}
- public static void fill(char[] a, int fromIndex, int toIndex, char... values) {
+ public static void fill(char[] a, int fromIndex, int toIndex, char[] values) {
AssertTools.checkArgument(Objects.nonNull(a));
- if (values.length == 0) {
+ if (values == null || values.length == 0) {
return;
}
final int start = Integer.max(fromIndex, 0);
@@ -659,13 +655,13 @@ public class ArrayTools {
// fill - byte
- public static void fill(byte[] a, byte... values) {
+ public static void fill(byte[] a, byte[] values) {
fill(a, 0, a.length, values);
}
- public static void fill(byte[] a, int fromIndex, int toIndex, byte... values) {
+ public static void fill(byte[] a, int fromIndex, int toIndex, byte[] values) {
AssertTools.checkArgument(Objects.nonNull(a));
- if (values.length == 0) {
+ if (values == null || values.length == 0) {
return;
}
final int start = Integer.max(fromIndex, 0);
@@ -688,13 +684,13 @@ public class ArrayTools {
// fill - short
- public static void fill(short[] a, short... values) {
+ public static void fill(short[] a, short[] values) {
fill(a, 0, a.length, values);
}
- public static void fill(short[] a, int fromIndex, int toIndex, short... values) {
+ public static void fill(short[] a, int fromIndex, int toIndex, short[] values) {
AssertTools.checkArgument(Objects.nonNull(a));
- if (values.length == 0) {
+ if (values == null || values.length == 0) {
return;
}
final int start = Integer.max(fromIndex, 0);
@@ -717,13 +713,13 @@ public class ArrayTools {
// fill - int
- public static void fill(int[] a, int... values) {
+ public static void fill(int[] a, int[] values) {
fill(a, 0, a.length, values);
}
- public static void fill(int[] a, int fromIndex, int toIndex, int... values) {
+ public static void fill(int[] a, int fromIndex, int toIndex, int[] values) {
AssertTools.checkArgument(Objects.nonNull(a));
- if (values.length == 0) {
+ if (values == null || values.length == 0) {
return;
}
final int start = Integer.max(fromIndex, 0);
@@ -746,13 +742,13 @@ public class ArrayTools {
// fill - long
- public static void fill(long[] a, long... values) {
+ public static void fill(long[] a, long[] values) {
fill(a, 0, a.length, values);
}
- public static void fill(long[] a, int fromIndex, int toIndex, long... values) {
+ public static void fill(long[] a, int fromIndex, int toIndex, long[] values) {
AssertTools.checkArgument(Objects.nonNull(a));
- if (values.length == 0) {
+ if (values == null || values.length == 0) {
return;
}
final int start = Integer.max(fromIndex, 0);
@@ -775,13 +771,13 @@ public class ArrayTools {
// fill - float
- public static void fill(float[] a, float... values) {
+ public static void fill(float[] a, float[] values) {
fill(a, 0, a.length, values);
}
- public static void fill(float[] a, int fromIndex, int toIndex, float... values) {
+ public static void fill(float[] a, int fromIndex, int toIndex, float[] values) {
AssertTools.checkArgument(Objects.nonNull(a));
- if (values.length == 0) {
+ if (values == null || values.length == 0) {
return;
}
final int start = Integer.max(fromIndex, 0);
@@ -804,13 +800,13 @@ public class ArrayTools {
// fill - double
- public static void fill(double[] a, double... values) {
+ public static void fill(double[] a, double[] values) {
fill(a, 0, a.length, values);
}
- public static void fill(double[] a, int fromIndex, int toIndex, double... values) {
+ public static void fill(double[] a, int fromIndex, int toIndex, double[] values) {
AssertTools.checkArgument(Objects.nonNull(a));
- if (values.length == 0) {
+ if (values == null || values.length == 0) {
return;
}
final int start = Integer.max(fromIndex, 0);
@@ -868,7 +864,7 @@ public class ArrayTools {
// #region - indexOf
- public static int indexOf(T[] arr, Predicate super T> predicate) {
+ public static int indexOfWithPredicate(T[] arr, Predicate super T> predicate) {
AssertTools.checkNotNull(predicate);
if (isNullOrEmpty(arr)) {
return NOT_FOUND_INDEX;
@@ -882,7 +878,7 @@ public class ArrayTools {
}
public static int indexOf(T[] arr, T obj) {
- return indexOf(arr, item -> Objects.equals(item, obj));
+ return indexOfWithPredicate(arr, item -> Objects.equals(item, obj));
}
public static int indexOf(char[] arr, char value) {
@@ -973,7 +969,7 @@ public class ArrayTools {
// #region - lastIndexOf
- public static int lastIndexOf(T[] arr, @Nonnull Predicate super T> predicate) {
+ public static int lastIndexOfWithPredicate(T[] arr, @Nonnull Predicate super T> predicate) {
AssertTools.checkNotNull(predicate);
if (isNullOrEmpty(arr)) {
return NOT_FOUND_INDEX;
@@ -987,7 +983,7 @@ public class ArrayTools {
}
public static int lastIndexOf(T[] arr, T obj) {
- return lastIndexOf(arr, item -> Objects.equals(item, obj));
+ return lastIndexOfWithPredicate(arr, item -> Objects.equals(item, obj));
}
public static int lastIndexOf(char[] arr, char value) {
@@ -1111,7 +1107,7 @@ public class ArrayTools {
}
public static boolean containsValue(BigDecimal[] arr, BigDecimal obj) {
- return indexOf(arr, item -> BigDecimals.equalsValue(item, obj)) > NOT_FOUND_INDEX;
+ return indexOfWithPredicate(arr, item -> BigDecimals.equalsValue(item, obj)) > NOT_FOUND_INDEX;
}
// #endregion
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/ArrayToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/ArrayToolsTests.java
index ceafaf1..32423a1 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/util/ArrayToolsTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/util/ArrayToolsTests.java
@@ -27,44 +27,63 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.function.Predicate;
-import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.function.Executable;
@SuppressWarnings("null")
public class ArrayToolsTests {
- // TODO 【优化】 检查、完善测试用例
+ static final String[] NULL_STRING_ARRAY = null;
+ static final Integer[] NULL_INTEGER_ARRAY = null;
+ static final char[] NULL_CHAR_ARRAY = null;
+ static final byte[] NULL_BYTE_ARRAY = null;
+ static final short[] NULL_SHORT_ARRAY = null;
+ static final int[] NULL_INT_ARRAY = null;
+ static final long[] NULL_LONG_ARRAY = null;
+ static final float[] NULL_FLOAT_ARRAY = null;
+ static final double[] NULL_DOUBLE_ARRAY = null;
- //#region null or empty
+ static final String[] EMPTY_STRING_ARRAY = {};
+ static final Integer[] EMPTY_INTEGER_ARRAY = {};
+ static final char[] EMPTY_CHAR_ARRAY = {};
+ static final byte[] EMPTY_BYTE_ARRAY = {};
+ static final short[] EMPTY_SHORT_ARRAY = {};
+ static final int[] EMPTY_INT_ARRAY = {};
+ static final long[] EMPTY_LONG_ARRAY = {};
+ static final float[] EMPTY_FLOAT_ARRAY = {};
+ static final double[] EMPTY_DOUBLE_ARRAY = {};
+
+ // ================================
+ // #region - isNullOrEmpty
+ // ================================
@Test
void isNullOrEmpty_NullArray_ReturnsTrue() {
assertAll(
- () -> assertTrue(ArrayTools.isNullOrEmpty((String[]) null)),
- () -> assertTrue(ArrayTools.isNullOrEmpty((Integer[]) null)),
- () -> assertTrue(ArrayTools.isNullOrEmpty((char[]) null)),
- () -> assertTrue(ArrayTools.isNullOrEmpty((byte[]) null)),
- () -> assertTrue(ArrayTools.isNullOrEmpty((short[]) null)),
- () -> assertTrue(ArrayTools.isNullOrEmpty((int[]) null)),
- () -> assertTrue(ArrayTools.isNullOrEmpty((long[]) null)),
- () -> assertTrue(ArrayTools.isNullOrEmpty((float[]) null)),
- () -> assertTrue(ArrayTools.isNullOrEmpty((double[]) null)));
+ () -> assertTrue(ArrayTools.isNullOrEmpty(NULL_STRING_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(NULL_INTEGER_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(NULL_CHAR_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(NULL_BYTE_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(NULL_SHORT_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(NULL_INT_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(NULL_LONG_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(NULL_FLOAT_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(NULL_DOUBLE_ARRAY)));
}
@Test
void isNullOrEmpty_EmptyArray_ReturnsTrue() {
assertAll(
- () -> assertTrue(ArrayTools.isNullOrEmpty(new String[] {})),
- () -> assertTrue(ArrayTools.isNullOrEmpty(new Integer[] {})),
- () -> assertTrue(ArrayTools.isNullOrEmpty(new char[] {})),
- () -> assertTrue(ArrayTools.isNullOrEmpty(new byte[] {})),
- () -> assertTrue(ArrayTools.isNullOrEmpty(new short[] {})),
- () -> assertTrue(ArrayTools.isNullOrEmpty(new int[] {})),
- () -> assertTrue(ArrayTools.isNullOrEmpty(new long[] {})),
- () -> assertTrue(ArrayTools.isNullOrEmpty(new float[] {})),
- () -> assertTrue(ArrayTools.isNullOrEmpty(new double[] {})));
+ () -> assertTrue(ArrayTools.isNullOrEmpty(EMPTY_STRING_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(EMPTY_INTEGER_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(EMPTY_CHAR_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(EMPTY_BYTE_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(EMPTY_SHORT_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(EMPTY_INT_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(EMPTY_LONG_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(EMPTY_FLOAT_ARRAY)),
+ () -> assertTrue(ArrayTools.isNullOrEmpty(EMPTY_DOUBLE_ARRAY)));
}
@Test
@@ -81,32 +100,40 @@ public class ArrayToolsTests {
() -> assertFalse(ArrayTools.isNullOrEmpty(new double[] { 1 })));
}
+ // ================================
+ // #endregion - isNullOrEmpty
+ // ================================
+
+ // ================================
+ // #region - isNotEmpty
+ // ================================
+
@Test
void isNotEmpty_NullArray_ReturnsFalse() {
assertAll(
- () -> assertFalse(ArrayTools.isNotEmpty((String[]) null)),
- () -> assertFalse(ArrayTools.isNotEmpty((Integer[]) null)),
- () -> assertFalse(ArrayTools.isNotEmpty((char[]) null)),
- () -> assertFalse(ArrayTools.isNotEmpty((byte[]) null)),
- () -> assertFalse(ArrayTools.isNotEmpty((short[]) null)),
- () -> assertFalse(ArrayTools.isNotEmpty((int[]) null)),
- () -> assertFalse(ArrayTools.isNotEmpty((long[]) null)),
- () -> assertFalse(ArrayTools.isNotEmpty((float[]) null)),
- () -> assertFalse(ArrayTools.isNotEmpty((double[]) null)));
+ () -> assertFalse(ArrayTools.isNotEmpty(NULL_STRING_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(NULL_INTEGER_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(NULL_CHAR_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(NULL_BYTE_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(NULL_SHORT_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(NULL_INT_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(NULL_LONG_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(NULL_FLOAT_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(NULL_DOUBLE_ARRAY)));
}
@Test
void isNotEmpty_EmptyArray_ReturnsFalse() {
assertAll(
- () -> assertFalse(ArrayTools.isNotEmpty(new String[] {})),
- () -> assertFalse(ArrayTools.isNotEmpty(new Integer[] {})),
- () -> assertFalse(ArrayTools.isNotEmpty(new char[] {})),
- () -> assertFalse(ArrayTools.isNotEmpty(new byte[] {})),
- () -> assertFalse(ArrayTools.isNotEmpty(new short[] {})),
- () -> assertFalse(ArrayTools.isNotEmpty(new int[] {})),
- () -> assertFalse(ArrayTools.isNotEmpty(new long[] {})),
- () -> assertFalse(ArrayTools.isNotEmpty(new float[] {})),
- () -> assertFalse(ArrayTools.isNotEmpty(new double[] {})));
+ () -> assertFalse(ArrayTools.isNotEmpty(EMPTY_STRING_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(EMPTY_INTEGER_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(EMPTY_CHAR_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(EMPTY_BYTE_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(EMPTY_SHORT_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(EMPTY_INT_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(EMPTY_LONG_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(EMPTY_FLOAT_ARRAY)),
+ () -> assertFalse(ArrayTools.isNotEmpty(EMPTY_DOUBLE_ARRAY)));
}
@Test
@@ -123,16 +150,24 @@ public class ArrayToolsTests {
() -> assertTrue(ArrayTools.isNotEmpty(new double[] { 1 })));
}
+ // ================================
+ // #endregion - isNotEmpty
+ // ================================
+
+ // ================================
+ // #region - isAllElementsNotNull
+ // ================================
+
@Test
void isAllElementsNotNull_NullArray_ThrowsException() {
- assertThrows(IllegalArgumentException.class, () -> ArrayTools.isAllElementsNotNull((String[]) null));
- assertThrows(IllegalArgumentException.class, () -> ArrayTools.isAllElementsNotNull((Integer[]) null));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.isAllElementsNotNull(NULL_STRING_ARRAY));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.isAllElementsNotNull(NULL_INTEGER_ARRAY));
}
@Test
void isAllElementsNotNull_EmptyArray_ReturnsTrue() {
- assertTrue(ArrayTools.isAllElementsNotNull(new String[] {}));
- assertTrue(ArrayTools.isAllElementsNotNull(new Integer[] {}));
+ assertTrue(ArrayTools.isAllElementsNotNull(EMPTY_STRING_ARRAY));
+ assertTrue(ArrayTools.isAllElementsNotNull(EMPTY_INTEGER_ARRAY));
}
@Test
@@ -147,155 +182,122 @@ public class ArrayToolsTests {
assertTrue(ArrayTools.isAllElementsNotNull(new Integer[] { 1, 2 }));
}
- // #endregion
+ // ================================
+ // #endregion - isAllElementsNotNull
+ // ================================
+ // ================================
// #region - concat
+ // ================================
- private static List charArrays;
- private static List byteArrays;
- private static List shortArrays;
- private static List intArrays;
- private static List longArrays;
- private static List floatArrays;
- private static List doubleArrays;
+ static final List charArrays;
+ static final List byteArrays;
+ static final List shortArrays;
+ static final List intArrays;
+ static final List longArrays;
+ static final List floatArrays;
+ static final List doubleArrays;
- @BeforeAll
- public static void setUp() {
+ static {
charArrays = new ArrayList<>();
+ charArrays.add(null);
+ charArrays.add(new char[0]);
charArrays.add(new char[] { 'a', 'b' });
charArrays.add(new char[] { 'c', 'd', 'e' });
- charArrays.add(null);
byteArrays = new ArrayList<>();
+ byteArrays.add(null);
+ byteArrays.add(new byte[0]);
byteArrays.add(new byte[] { 1, 2 });
byteArrays.add(new byte[] { 3, 4, 5 });
- byteArrays.add(null);
shortArrays = new ArrayList<>();
+ shortArrays.add(null);
+ shortArrays.add(new short[0]);
shortArrays.add(new short[] { 10, 20 });
shortArrays.add(new short[] { 30, 40, 50 });
- shortArrays.add(null);
intArrays = new ArrayList<>();
+ intArrays.add(null);
+ intArrays.add(new int[0]);
intArrays.add(new int[] { 100, 200 });
intArrays.add(new int[] { 300, 400, 500 });
- intArrays.add(null);
longArrays = new ArrayList<>();
+ longArrays.add(null);
+ longArrays.add(new long[0]);
longArrays.add(new long[] { 1000L, 2000L });
longArrays.add(new long[] { 3000L, 4000L, 5000L });
- longArrays.add(null);
floatArrays = new ArrayList<>();
+ floatArrays.add(null);
+ floatArrays.add(new float[0]);
floatArrays.add(new float[] { 1000.1f, 2000.2f });
floatArrays.add(new float[] { 3000.3f, 4000.4f, 5000.5f });
- floatArrays.add(null);
doubleArrays = new ArrayList<>();
+ doubleArrays.add(null);
+ doubleArrays.add(new double[0]);
doubleArrays.add(new double[] { 1000.1d, 2000.2d });
doubleArrays.add(new double[] { 3000.3d, 4000.4d, 5000.5d });
- doubleArrays.add(null);
}
@Test
- public void testConcatCharArray_NullOrEmptyCollection_ReturnsEmptyArray() {
- assertArrayEquals(new char[] {}, ArrayTools.concatCharArray(null));
+ void concat_NullOrEmptyCollection_ReturnsEmptyArray() {
+ assertEquals(0, ArrayTools.concatCharArray(null).length);
assertEquals(0, ArrayTools.concatCharArray(Collections.emptyList()).length);
- }
- @Test
- public void testConcatCharArray_ValidCollection_ReturnsConcatenatedArray() {
- char[] expected = { 'a', 'b', 'c', 'd', 'e' };
- char[] result = ArrayTools.concatCharArray(charArrays);
- assertArrayEquals(expected, result);
- }
-
- @Test
- public void testConcatByteArray_NullOrEmptyCollection_ReturnsEmptyArray() {
- assertArrayEquals(new byte[0], ArrayTools.concatByteArray(null));
+ assertEquals(0, ArrayTools.concatByteArray(null).length);
assertEquals(0, ArrayTools.concatByteArray(Collections.emptyList()).length);
- }
- @Test
- public void testConcatByteArray_ValidCollection_ReturnsConcatenatedArray() {
- byte[] expected = { 1, 2, 3, 4, 5 };
- byte[] result = ArrayTools.concatByteArray(byteArrays);
- assertArrayEquals(expected, result);
- }
-
- @Test
- public void testConcatShortArray_NullOrEmptyCollection_ReturnsEmptyArray() {
- assertArrayEquals(new short[0], ArrayTools.concatShortArray(null));
+ assertEquals(0, ArrayTools.concatShortArray(null).length);
assertEquals(0, ArrayTools.concatShortArray(Collections.emptyList()).length);
- }
- @Test
- public void testConcatShortArray_ValidCollection_ReturnsConcatenatedArray() {
- short[] expected = { 10, 20, 30, 40, 50 };
- short[] result = ArrayTools.concatShortArray(shortArrays);
- assertArrayEquals(expected, result);
- }
-
- @Test
- public void testConcatIntArray_NullOrEmptyCollection_ReturnsEmptyArray() {
- assertArrayEquals(new int[0], ArrayTools.concatIntArray(null));
+ assertEquals(0, ArrayTools.concatIntArray(null).length);
assertEquals(0, ArrayTools.concatIntArray(Collections.emptyList()).length);
- }
- @Test
- public void testConcatIntArray_ValidCollection_ReturnsConcatenatedArray() {
- int[] expected = { 100, 200, 300, 400, 500 };
- int[] result = ArrayTools.concatIntArray(intArrays);
- assertArrayEquals(expected, result);
- }
-
- @Test
- public void testConcatLongArray_NullOrEmptyCollection_ReturnsEmptyArray() {
- assertArrayEquals(new long[0], ArrayTools.concatLongArray(null));
+ assertEquals(0, ArrayTools.concatLongArray(null).length);
assertEquals(0, ArrayTools.concatLongArray(Collections.emptyList()).length);
- }
- @Test
- public void testConcatLongArray_ValidCollection_ReturnsConcatenatedArray() {
- long[] expected = { 1000L, 2000L, 3000L, 4000L, 5000L };
- long[] result = ArrayTools.concatLongArray(longArrays);
- assertArrayEquals(expected, result);
- }
-
- @Test
- public void testConcatFloatArray_NullOrEmptyCollection_ReturnsEmptyArray() {
- assertArrayEquals(new float[0], ArrayTools.concatFloatArray(null));
+ assertEquals(0, ArrayTools.concatFloatArray(null).length);
assertEquals(0, ArrayTools.concatFloatArray(Collections.emptyList()).length);
- }
- @Test
- public void testConcatFloatArray_ValidCollection_ReturnsConcatenatedArray() {
- float[] expected = { 1000.1f, 2000.2f, 3000.3f, 4000.4f, 5000.5f };
- float[] result = ArrayTools.concatFloatArray(floatArrays);
- assertArrayEquals(expected, result);
- }
-
- @Test
- public void testConcatDoubleArray_NullOrEmptyCollection_ReturnsEmptyArray() {
- assertArrayEquals(new double[] {}, ArrayTools.concatDoubleArray(null));
+ assertEquals(0, ArrayTools.concatDoubleArray(null).length);
assertEquals(0, ArrayTools.concatDoubleArray(Collections.emptyList()).length);
}
@Test
- public void testConcatDoubleArray_ValidCollection_ReturnsConcatenatedArray() {
- double[] expected = { 1000.1d, 2000.2d, 3000.3d, 4000.4d, 5000.5d };
- double[] result = ArrayTools.concatDoubleArray(doubleArrays);
- assertArrayEquals(expected, result);
+ void concat_ValidCollection_ReturnsConcatenatedArray() {
+ assertArrayEquals(new char[] { 'a', 'b', 'c', 'd', 'e' },
+ ArrayTools.concatCharArray(charArrays));
+
+ assertArrayEquals(new byte[] { 1, 2, 3, 4, 5 },
+ ArrayTools.concatByteArray(byteArrays));
+
+ assertArrayEquals(new short[] { 10, 20, 30, 40, 50 },
+ ArrayTools.concatShortArray(shortArrays));
+
+ assertArrayEquals(new int[] { 100, 200, 300, 400, 500 },
+ ArrayTools.concatIntArray(intArrays));
+
+ assertArrayEquals(new long[] { 1000L, 2000L, 3000L, 4000L, 5000L },
+ ArrayTools.concatLongArray(longArrays));
+
+ assertArrayEquals(new float[] { 1000.1f, 2000.2f, 3000.3f, 4000.4f, 5000.5f },
+ ArrayTools.concatFloatArray(floatArrays));
+
+ assertArrayEquals(new double[] { 1000.1d, 2000.2d, 3000.3d, 4000.4d, 5000.5d },
+ ArrayTools.concatDoubleArray(doubleArrays));
}
@Test
- public void testConcatToList_NullOrEmptyCollection_ReturnsEmptyList() {
+ void concatToList_NullOrEmptyCollection_ReturnsEmptyList() {
assertTrue(ArrayTools.concatToList(null).isEmpty());
assertTrue(ArrayTools.concatToList(Collections.emptyList()).isEmpty());
}
@Test
- public void testConcatToList_ValidCollection_ReturnsConcatenatedList() {
+ void concatToList_ValidCollection_ReturnsConcatenatedList() {
Character[] charArray1 = { 'a', 'b' };
Character[] charArray2 = { 'c', 'd', 'e' };
List expected = Arrays.asList('a', 'b', 'c', 'd', 'e');
@@ -303,116 +305,786 @@ public class ArrayToolsTests {
assertEquals(expected, result);
}
+ // ================================
// #endregion
+ // ================================
+ // ================================
// #region - repeat
+ // ================================
@Test
- void repeat_CharArray_TimesZero_ReturnsEmptyArray() {
- char[] input = { 'a', 'b', 'c' };
- char[] result = ArrayTools.repeat(input, 0);
- assertArrayEquals(ArrayTools.EMPTY_CHAR_ARRAY, result);
+ void repeat_NullArray_ThrowsException() {
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_CHAR_ARRAY, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_BYTE_ARRAY, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_SHORT_ARRAY, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_INT_ARRAY, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_LONG_ARRAY, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_FLOAT_ARRAY, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_DOUBLE_ARRAY, 2));
+
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_CHAR_ARRAY, 2, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_BYTE_ARRAY, 2, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_SHORT_ARRAY, 2, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_INT_ARRAY, 2, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_LONG_ARRAY, 2, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_FLOAT_ARRAY, 2, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(NULL_DOUBLE_ARRAY, 2, 2));
}
@Test
- void repeat_CharArray_TimesOne_ReturnsSameArray() {
- char[] input = { 'a', 'b', 'c' };
- char[] result = ArrayTools.repeat(input, 1);
- assertArrayEquals(input, result);
+ void repeat_NegativeTimes_ThrowsException() {
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new char[]{ 'a' }, -1));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new byte[]{ 1 }, -1));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new short[]{ 1 }, -1));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new int[]{ 1 }, -1));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new long[]{ 1 }, -1));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new float[]{ 1 }, -1));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new double[]{ 1 }, -1));
+
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new char[]{ 'a' }, -1, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new byte[]{ 1 }, -1, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new short[]{ 1 }, -1, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new int[]{ 1 }, -1, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new long[]{ 1 }, -1, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new float[]{ 1 }, -1, 2));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new double[]{ 1 }, -1, 2));
}
@Test
- void repeat_CharArray_TimesTwo_ReturnsRepeatedArray() {
- char[] input = { 'a', 'b', 'c' };
- char[] expected = { 'a', 'b', 'c', 'a', 'b', 'c' };
- char[] result = ArrayTools.repeat(input, 2);
- assertArrayEquals(expected, result);
+ void repeat_NegativeMaxLength_ThrowsException() {
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new char[]{ 'a' }, 2, -1));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new byte[]{ 1 }, 2, -1));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new short[]{ 1 }, 2, -1));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new int[]{ 1 }, 2, -1));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new long[]{ 1 }, 2, -1));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new float[]{ 1 }, 2, -1));
+ assertThrows(IllegalArgumentException.class, () -> ArrayTools.repeat(new double[]{ 1 }, 2, -1));
}
@Test
- void repeat_CharArray_WithMaxLength_ReturnsTruncatedArray() {
- char[] input = { 'a', 'b', 'c' };
- char[] expected = { 'a', 'b', 'c', 'a', 'b' };
- char[] result = ArrayTools.repeat(input, 2, 5);
- assertArrayEquals(expected, result);
+ void repeat_ZeroTimes_ReturnsEmptyArray() {
+ assertEquals(0, ArrayTools.repeat(new char[]{ 'a' }, 0).length);
+ assertEquals(0, ArrayTools.repeat(new byte[]{ 1 }, 0).length);
+ assertEquals(0, ArrayTools.repeat(new short[]{ 1 }, 0).length);
+ assertEquals(0, ArrayTools.repeat(new int[]{ 1 }, 0).length);
+ assertEquals(0, ArrayTools.repeat(new long[]{ 1 }, 0).length);
+ assertEquals(0, ArrayTools.repeat(new float[]{ 1 }, 0).length);
+ assertEquals(0, ArrayTools.repeat(new double[]{ 1 }, 0).length);
}
@Test
- void repeat_ByteArray_TimesZero_ReturnsEmptyArray() {
- byte[] input = { 1, 2, 3 };
- byte[] result = ArrayTools.repeat(input, 0);
- assertArrayEquals(ArrayTools.EMPTY_BYTE_ARRAY, result);
+ void repeat_NormalCase_RepeatsArray() {
+ assertArrayEquals(new char[] { 'a', 'b', 'a', 'b', 'a', 'b' }, ArrayTools.repeat(new char[] { 'a', 'b' }, 3));
+ assertArrayEquals(new byte[] { 1, 2, 1, 2, 1, 2 }, ArrayTools.repeat(new byte[] { 1, 2 }, 3));
+ assertArrayEquals(new short[] { 1, 2, 1, 2, 1, 2 }, ArrayTools.repeat(new short[] { 1, 2 }, 3));
+ assertArrayEquals(new int[] { 1, 2, 1, 2, 1, 2 }, ArrayTools.repeat(new int[] { 1, 2 }, 3));
+ assertArrayEquals(new long[] { 1L, 2L, 1L, 2L, 1L, 2L }, ArrayTools.repeat(new long[] { 1L, 2L }, 3));
+ assertArrayEquals(new float[] { 1.1F, 2.2F, 1.1F, 2.2F, 1.1F, 2.2F }, ArrayTools.repeat(new float[] { 1.1F, 2.2F }, 3));
+ assertArrayEquals(new double[] { 1.12, 2.23, 1.12, 2.23, 1.12, 2.23 }, ArrayTools.repeat(new double[] { 1.12, 2.23 }, 3));
}
@Test
- void repeat_ShortArray_TimesZero_ReturnsEmptyArray() {
- short[] input = { 1, 2, 3 };
- short[] result = ArrayTools.repeat(input, 0);
- assertArrayEquals(ArrayTools.EMPTY_SHORT_ARRAY, result);
- }
-
- @Test
- void repeat_IntArray_TimesZero_ReturnsEmptyArray() {
- int[] input = { 1, 2, 3 };
- int[] result = ArrayTools.repeat(input, 0);
- assertArrayEquals(ArrayTools.EMPTY_INT_ARRAY, result);
- }
-
- @Test
- void repeat_LongArray_TimesZero_ReturnsEmptyArray() {
- long[] input = { 1, 2, 3 };
- long[] result = ArrayTools.repeat(input, 0);
- assertArrayEquals(ArrayTools.EMPTY_LONG_ARRAY, result);
- }
-
- @Test
- void repeat_FloatArray_TimesZero_ReturnsEmptyArray() {
- float[] input = { 1, 2, 3 };
- float[] result = ArrayTools.repeat(input, 0);
- assertArrayEquals(ArrayTools.EMPTY_FLOAT_ARRAY, result);
- }
-
- @Test
- void repeat_DoubleArray_TimesZero_ReturnsEmptyArray() {
- double[] input = { 1, 2, 3 };
- double[] result = ArrayTools.repeat(input, 0);
- assertArrayEquals(ArrayTools.EMPTY_DOUBLE_ARRAY, result);
- }
-
- @Test
- void repeat_CharArray_ThrowsExceptionForNullArray() {
- Executable executable = () -> ArrayTools.repeat((char[]) null, 2);
- assertThrows(IllegalArgumentException.class, executable);
- }
-
- @Test
- void repeat_CharArray_ThrowsExceptionForNegativeTimes() {
- char[] input = { 'a', 'b', 'c' };
- Executable executable = () -> ArrayTools.repeat(input, -1);
- assertThrows(IllegalArgumentException.class, executable);
- }
-
- @Test
- void repeat_CharArray_ThrowsExceptionForNegativeMaxLength() {
- char[] input = { 'a', 'b', 'c' };
- Executable executable = () -> ArrayTools.repeat(input, 2, -1);
- assertThrows(IllegalArgumentException.class, executable);
+ void repeat_WithMaxLength_TruncatesResult() {
+ assertArrayEquals(new char[] { 'a', 'b', 'a', 'b', 'a' }, ArrayTools.repeat(new char[] { 'a', 'b' }, 3, 5));
+ assertArrayEquals(new byte[] { 1, 2, 1, 2, 1 }, ArrayTools.repeat(new byte[] { 1, 2 }, 3, 5));
+ assertArrayEquals(new short[] { 1, 2, 1, 2, 1 }, ArrayTools.repeat(new short[] { 1, 2 }, 3, 5));
+ assertArrayEquals(new int[] { 1, 2, 1, 2, 1 }, ArrayTools.repeat(new int[] { 1, 2 }, 3, 5));
+ assertArrayEquals(new long[] { 1L, 2L, 1L, 2L, 1L }, ArrayTools.repeat(new long[] { 1L, 2L }, 3, 5));
+ assertArrayEquals(new float[] { 1.1F, 2.2F, 1.1F, 2.2F, 1.1F }, ArrayTools.repeat(new float[] { 1.1F, 2.2F }, 3, 5));
+ assertArrayEquals(new double[] { 1.12, 2.23, 1.12, 2.23, 1.12 }, ArrayTools.repeat(new double[] { 1.12, 2.23 }, 3, 5));
}
+ // ================================
// #endregion
+ // ================================
- // TODO 【添加】 补充测试用例
-
+ // ================================
// #region - fill
- // #endregion
+ // ================================
+ @Test
+ void fill_WithValues() {
+ // fill - char
+ char[] charArray = new char[10];
+ ArrayTools.fill(charArray, new char[] {'a', 'b', 'c'});
+ assertArrayEquals(new char[] { 'a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c', 'a' }, charArray);
+ ArrayTools.fill(charArray, "abcd");
+ assertArrayEquals(new char[] { 'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'a', 'b' }, charArray);
+
+ // fill - byte
+ byte[] byteArray = new byte[10];
+ ArrayTools.fill(byteArray, new byte[] { 1, 2, 3 });
+ assertArrayEquals(new byte[] { 1, 2, 3, 1, 2, 3, 1, 2, 3, 1 }, byteArray);
+
+ // fill - short
+ short[] shortArray = new short[10];
+ ArrayTools.fill(shortArray, new short[] { 1, 2, 3 });
+ assertArrayEquals(new short[] { 1, 2, 3, 1, 2, 3, 1, 2, 3, 1 }, shortArray);
+
+ // fill - int
+ int[] intArray = new int[10];
+ ArrayTools.fill(intArray, new int[] { 1, 2, 3 });
+ assertArrayEquals(new int[] { 1, 2, 3, 1, 2, 3, 1, 2, 3, 1 }, intArray);
+
+ // fill - long
+ long[] longArray = new long[10];
+ ArrayTools.fill(longArray, new long[] { 1, 2, 3 });
+ assertArrayEquals(new long[] { 1, 2, 3, 1, 2, 3, 1, 2, 3, 1 }, longArray);
+
+ // fill - float
+ float[] floatArray = new float[10];
+ ArrayTools.fill(floatArray, new float[] { 1.1F, 2.2F, 3.3F });
+ assertArrayEquals(new float[] { 1.1F, 2.2F, 3.3F, 1.1F, 2.2F, 3.3F, 1.1F, 2.2F, 3.3F, 1.1F }, floatArray);
+
+ // fill - double
+ double[] doubleArray = new double[10];
+ ArrayTools.fill(doubleArray, new double[] { 1.1, 2.2, 3.3 });
+ assertArrayEquals(new double[] { 1.1, 2.2, 3.3, 1.1, 2.2, 3.3, 1.1, 2.2, 3.3, 1.1 }, doubleArray);
+
+ // fill - T
+ String[] stringArray = new String[10];
+ ArrayTools.fill(stringArray, new String[] { "aa", "bb", "cc" });
+ assertArrayEquals(new String[] { "aa", "bb", "cc", "aa", "bb", "cc", "aa", "bb", "cc", "aa" }, stringArray);
+ }
+
+ @Test
+ void fill_WithEmptyValues() {
+ // fill - char
+ char[] charArray = new char[10];
+ ArrayTools.fill(charArray, EMPTY_CHAR_ARRAY);
+ assertArrayEquals(new char[10], charArray);
+ ArrayTools.fill(charArray, "");
+ assertArrayEquals(new char[10], charArray);
+
+ // fill - byte
+ byte[] byteArray = new byte[10];
+ ArrayTools.fill(byteArray, EMPTY_BYTE_ARRAY);
+ assertArrayEquals(new byte[10], byteArray);
+
+ // fill - short
+ short[] shortArray = new short[10];
+ ArrayTools.fill(shortArray, EMPTY_SHORT_ARRAY);
+ assertArrayEquals(new short[10], shortArray);
+
+ // fill - int
+ int[] intArray = new int[10];
+ ArrayTools.fill(intArray, EMPTY_INT_ARRAY);
+ assertArrayEquals(new int[10], intArray);
+
+ // fill - long
+ long[] longArray = new long[10];
+ ArrayTools.fill(longArray, EMPTY_LONG_ARRAY);
+ assertArrayEquals(new long[10], longArray);
+
+ // fill - float
+ float[] floatArray = new float[10];
+ ArrayTools.fill(floatArray, EMPTY_FLOAT_ARRAY);
+ assertArrayEquals(new float[10], floatArray);
+
+ // fill - double
+ double[] doubleArray = new double[10];
+ ArrayTools.fill(doubleArray, EMPTY_DOUBLE_ARRAY);
+ assertArrayEquals(new double[10], doubleArray);
+
+ // fill - T
+ String[] stringArray = new String[10];
+ ArrayTools.fill(stringArray, EMPTY_STRING_ARRAY);
+ assertArrayEquals(new String[10], stringArray);
+ }
+
+ @Test
+ void fill_WithNullValues() {
+ // fill - char
+ char[] charArray = new char[10];
+ ArrayTools.fill(charArray, NULL_CHAR_ARRAY);
+ assertArrayEquals(new char[10], charArray);
+ ArrayTools.fill(charArray, (String) null);
+ assertArrayEquals(new char[10], charArray);
+
+ // fill - byte
+ byte[] byteArray = new byte[10];
+ ArrayTools.fill(byteArray, NULL_BYTE_ARRAY);
+ assertArrayEquals(new byte[10], byteArray);
+
+ // fill - short
+ short[] shortArray = new short[10];
+ ArrayTools.fill(shortArray, NULL_SHORT_ARRAY);
+ assertArrayEquals(new short[10], shortArray);
+
+ // fill - int
+ int[] intArray = new int[10];
+ ArrayTools.fill(intArray, NULL_INT_ARRAY);
+ assertArrayEquals(new int[10], intArray);
+
+ // fill - long
+ long[] longArray = new long[10];
+ ArrayTools.fill(longArray, NULL_LONG_ARRAY);
+ assertArrayEquals(new long[10], longArray);
+
+ // fill - float
+ float[] floatArray = new float[10];
+ ArrayTools.fill(floatArray, NULL_FLOAT_ARRAY);
+ assertArrayEquals(new float[10], floatArray);
+
+ // fill - double
+ double[] doubleArray = new double[10];
+ ArrayTools.fill(doubleArray, NULL_DOUBLE_ARRAY);
+ assertArrayEquals(new double[10], doubleArray);
+
+ // fill - T
+ String[] stringArray = new String[10];
+ ArrayTools.fill(stringArray, NULL_STRING_ARRAY);
+ assertArrayEquals(new String[10], stringArray);
+ }
+
+ @Test
+ void fill_WithValuesInRange() {
+ // fill - char
+ char[] charArray = new char[10];
+ ArrayTools.fill(charArray, 2, 8, new char[] { 'x', 'y' });
+ assertArrayEquals(new char[] { '\0', '\0', 'x', 'y', 'x', 'y', 'x', 'y', '\0', '\0' }, charArray);
+ // fill - byte
+ byte[] byteArray = new byte[10];
+ ArrayTools.fill(byteArray, 2, 8, new byte[] { 1, 2 });
+ assertArrayEquals(new byte[] { 0, 0, 1, 2, 1, 2, 1, 2, 0, 0 }, byteArray);
+ // fill - short
+ short[] shortArray = new short[10];
+ ArrayTools.fill(shortArray, 2, 8, new short[] { 1, 2 });
+ assertArrayEquals(new short[] { 0, 0, 1, 2, 1, 2, 1, 2, 0, 0 }, shortArray);
+ // fill - int
+ int[] intArray = new int[10];
+ ArrayTools.fill(intArray, 2, 8, new int[] { 1, 2 });
+ assertArrayEquals(new int[] { 0, 0, 1, 2, 1, 2, 1, 2, 0, 0 }, intArray);
+ // fill - long
+ long[] longArray = new long[10];
+ ArrayTools.fill(longArray, 2, 8, new long[] { 1, 2 });
+ assertArrayEquals(new long[] { 0, 0, 1, 2, 1, 2, 1, 2, 0, 0 }, longArray);
+ // fill - float
+ float[] floatArray = new float[10];
+ ArrayTools.fill(floatArray, 2, 8, new float[] { 1.1F, 2.2F });
+ assertArrayEquals(new float[] { 0F, 0F, 1.1F, 2.2F, 1.1F, 2.2F, 1.1F, 2.2F, 0F, 0F }, floatArray);
+ // fill - double
+ double[] doubleArray = new double[10];
+ ArrayTools.fill(doubleArray, 2, 8, new double[] { 0.1, 0.2 });
+ assertArrayEquals(new double[] { 0.0, 0.0, 0.1, 0.2, 0.1, 0.2, 0.1, 0.2, 0.0, 0.0 }, doubleArray);
+ // fill - T
+ String[] stringArray = new String[10];
+ ArrayTools.fill(stringArray, 2, 8, new String[] { "Java", "C++" });
+ assertArrayEquals(new String[] { null, null, "Java", "C++", "Java", "C++", "Java", "C++", null, null },
+ stringArray);
+ }
+
+ @Test
+ void fill_WithValues_OutOfRange() {
+ // fill - char
+ char[] charArray = new char[10];
+ ArrayTools.fill(charArray, 10, 20, new char[] { 'x', 'y' });
+ assertArrayEquals(new char[10], charArray);
+ // fill - byte
+ byte[] byteArray = new byte[10];
+ ArrayTools.fill(byteArray, 10, 20, new byte[] { 1, 2 });
+ assertArrayEquals(new byte[10], byteArray);
+ // fill - short
+ short[] shortArray = new short[10];
+ ArrayTools.fill(shortArray, 10, 20, new short[] { 1, 2 });
+ assertArrayEquals(new short[10], shortArray);
+ // fill - int
+ int[] intArray = new int[10];
+ ArrayTools.fill(intArray, 10, 20, new int[] { 1, 2 });
+ assertArrayEquals(new int[10], intArray);
+ // fill - long
+ long[] longArray = new long[10];
+ ArrayTools.fill(longArray, 10, 20, new long[] { 1, 2 });
+ assertArrayEquals(new long[10], longArray);
+ // fill - float
+ float[] floatArray = new float[10];
+ ArrayTools.fill(floatArray, 10, 20, new float[] { 1.1F, 2.2F });
+ assertArrayEquals(new float[10], floatArray);
+ // fill - double
+ double[] doubleArray = new double[10];
+ ArrayTools.fill(doubleArray, 10, 20, new double[] { 0.1, 0.2 });
+ assertArrayEquals(new double[10], doubleArray);
+ // fill - T
+ String[] stringArray = new String[10];
+ ArrayTools.fill(stringArray, 10, 20, new String[] { "Java", "C++" });
+ assertArrayEquals(new String[10], stringArray);
+ }
+
+ @Test
+ void fill_WithValues_NegativeRange() {
+ // fill - char
+ char[] charArray = new char[10];
+ ArrayTools.fill(charArray, -5, 5, new char[] {'w'});
+ assertArrayEquals(new char[]{'w', 'w', 'w', 'w', 'w', '\0', '\0', '\0', '\0', '\0'}, charArray);
+ // fill - byte
+ byte[] byteArray = new byte[10];
+ ArrayTools.fill(byteArray, -5, 5, new byte[] {108});
+ assertArrayEquals(new byte[]{108, 108, 108, 108, 108, 0, 0, 0, 0, 0}, byteArray);
+ // fill - short
+ short[] shortArray = new short[10];
+ ArrayTools.fill(shortArray, -5, 5, new short[] {108});
+ assertArrayEquals(new short[]{108, 108, 108, 108, 108, 0, 0, 0, 0, 0}, shortArray);
+ // fill - int
+ int[] intArray = new int[10];
+ ArrayTools.fill(intArray, -5, 5, new int[] {108});
+ assertArrayEquals(new int[]{108, 108, 108, 108, 108, 0, 0, 0, 0, 0}, intArray);
+ // fill - long
+ long[] longArray = new long[10];
+ ArrayTools.fill(longArray, -5, 5, new long[] {108L});
+ assertArrayEquals(new long[]{108L, 108L, 108L, 108L, 108L, 0L, 0L, 0L, 0L, 0L}, longArray);
+ // fill - float
+ float[] floatArray = new float[10];
+ ArrayTools.fill(floatArray, -5, 5, new float[] {108.01F});
+ assertArrayEquals(new float[]{108.01F, 108.01F, 108.01F, 108.01F, 108.01F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F}, floatArray);
+ // fill - double
+ double[] doubleArray = new double[10];
+ ArrayTools.fill(doubleArray, -5, 5, new double[] {108.01});
+ assertArrayEquals(new double[]{108.01, 108.01, 108.01, 108.01, 108.01, 0.0, 0.0, 0.0, 0.0, 0.0}, doubleArray);
+ // fill - T
+ String[] stringArray = new String[10];
+ ArrayTools.fill(stringArray, -5, 5, new String[] {"test"});
+ assertArrayEquals(new String[]{"test", "test", "test", "test", "test", null, null, null, null, null}, stringArray);
+ }
+
+ @Test
+ void fill_WithValues_ExactRange() {
+ // fill - char
+ char[] charArray = new char[10];
+ ArrayTools.fill(charArray, 0, 10, new char[] {'w'});
+ assertArrayEquals(new char[]{'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w', 'w'}, charArray);
+ // fill - byte
+ byte[] byteArray = new byte[10];
+ ArrayTools.fill(byteArray, 0, 10, new byte[] {108});
+ assertArrayEquals(new byte[]{108, 108, 108, 108, 108, 108, 108, 108, 108, 108}, byteArray);
+ // fill - short
+ short[] shortArray = new short[10];
+ ArrayTools.fill(shortArray, 0, 10, new short[] {108});
+ assertArrayEquals(new short[]{108, 108, 108, 108, 108, 108, 108, 108, 108, 108}, shortArray);
+ // fill - int
+ int[] intArray = new int[10];
+ ArrayTools.fill(intArray, 0, 10, new int[] {108});
+ assertArrayEquals(new int[]{108, 108, 108, 108, 108, 108, 108, 108, 108, 108}, intArray);
+ // fill - long
+ long[] longArray = new long[10];
+ ArrayTools.fill(longArray, 0, 10, new long[] {108L});
+ assertArrayEquals(new long[]{108L, 108L, 108L, 108L, 108L, 108L, 108L, 108L, 108L, 108L}, longArray);
+ // fill - float
+ float[] floatArray = new float[10];
+ ArrayTools.fill(floatArray, 0, 10, new float[] {108.01F});
+ assertArrayEquals(new float[]{108.01F, 108.01F, 108.01F, 108.01F, 108.01F, 108.01F, 108.01F, 108.01F, 108.01F, 108.01F}, floatArray);
+ // fill - double
+ double[] doubleArray = new double[10];
+ ArrayTools.fill(doubleArray, 0, 10, new double[] {108.01});
+ assertArrayEquals(new double[]{108.01, 108.01, 108.01, 108.01, 108.01, 108.01, 108.01, 108.01, 108.01, 108.01}, doubleArray);
+ // fill - T
+ String[] stringArray = new String[10];
+ ArrayTools.fill(stringArray, 0, 10, new String[] {"test"});
+ assertArrayEquals(new String[]{"test", "test", "test", "test", "test", "test", "test", "test", "test", "test"}, stringArray);
+ }
+
+ @Test
+ void fill_WithValues_Overlap() {
+ // fill - char
+ char[] charArray = new char[10];
+ ArrayTools.fill(charArray, 0, 5, new char[] {'a', 'b', 'c', 'd', 'e', 'f'});
+ assertArrayEquals(new char[]{'a', 'b', 'c', 'd', 'e', '\0', '\0', '\0', '\0', '\0'}, charArray);
+ // fill - byte
+ byte[] byteArray = new byte[10];
+ ArrayTools.fill(byteArray, 0, 5, new byte[] {1, 2, 3, 4, 5, 6});
+ assertArrayEquals(new byte[]{1, 2, 3, 4, 5, 0, 0, 0, 0, 0}, byteArray);
+ // fill - short
+ short[] shortArray = new short[10];
+ ArrayTools.fill(shortArray, 0, 5, new short[] {1, 2, 3, 4, 5, 6});
+ assertArrayEquals(new short[]{1, 2, 3, 4, 5, 0, 0, 0, 0, 0}, shortArray);
+ // fill - int
+ int[] intArray = new int[10];
+ ArrayTools.fill(intArray, 0, 5, new int[] {1, 2, 3, 4, 5, 6});
+ assertArrayEquals(new int[]{1, 2, 3, 4, 5, 0, 0, 0, 0, 0}, intArray);
+ // fill - long
+ long[] longArray = new long[10];
+ ArrayTools.fill(longArray, 0, 5, new long[] {1L, 2L, 3L, 4L, 5L, 6L});
+ assertArrayEquals(new long[]{1L, 2L, 3L, 4L, 5L, 0L, 0L, 0L, 0L, 0L}, longArray);
+ // fill - float
+ float[] floatArray = new float[10];
+ ArrayTools.fill(floatArray, 0, 5, new float[] {1.1F, 2.2F, 3.3F, 4.4F, 5.5F, 6.6F});
+ assertArrayEquals(new float[]{1.1F, 2.2F, 3.3F, 4.4F, 5.5F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F}, floatArray);
+ // fill - double
+ double[] doubleArray = new double[10];
+ ArrayTools.fill(doubleArray, 0, 5, new double[] {1.1, 2.2, 3.3, 4.4, 5.5, 6.6});
+ assertArrayEquals(new double[]{1.1, 2.2, 3.3, 4.4, 5.5, 0.0, 0.0, 0.0, 0.0, 0.0}, doubleArray);
+ // fill - T
+ String[] stringArray = new String[10];
+ ArrayTools.fill(stringArray, 0, 5, new String[] {"aaa", "bbb", "ccc", "ddd", "eee", "fff"});
+ assertArrayEquals(new String[]{"aaa", "bbb", "ccc", "ddd", "eee", null, null, null, null, null}, stringArray);
+ }
+
+ // ================================
+ // #endregion
+ // ================================
+
+ // ================================
// #region - indexOf
- // #endregion
+ // ================================
+ @Test
+ void indexOfWithPredicate_NullPredicate_ThrowsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> ArrayTools.indexOfWithPredicate(new String[] {}, null));
+ }
+
+ @Test
+ void indexOfWithPredicate_NullArray_ReturnsNotFoundIndex() {
+ Predicate predicate = s -> s.equals("test");
+ int result = ArrayTools.indexOfWithPredicate(null, predicate);
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, result);
+ }
+
+ @Test
+ void indexOfWithPredicate_EmptyArray_ReturnsNotFoundIndex() {
+ Predicate predicate = s -> s.equals("test");
+ int result = ArrayTools.indexOfWithPredicate(new String[] {}, predicate);
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, result);
+ }
+
+ @Test
+ void indexOfWithPredicate_ArrayContainsMatchingElement_ReturnsIndex() {
+ String[] array = { "apple", "banana", "cherry" };
+ Predicate predicate = s -> s.equals("banana");
+ int result = ArrayTools.indexOfWithPredicate(array, predicate);
+ assertEquals(1, result);
+ }
+
+ @Test
+ void indexOfWithPredicate_ArrayDoesNotContainMatchingElement_ReturnsNotFoundIndex() {
+ String[] array = { "apple", "banana", "cherry" };
+ Predicate predicate = s -> s.equals("orange");
+ int result = ArrayTools.indexOfWithPredicate(array, predicate);
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, result);
+ }
+
+ @Test
+ void indexOf_NullArray_ReturnsNotFound() {
+ // T
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf((String[]) null, "test"));
+ // char
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf((char[]) null, 'a'));
+ // byte
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf((byte[]) null, (byte) 1));
+ // short
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf((short[]) null, (short) 1));
+ // int
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf((int[]) null, 1));
+ // long
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf((long[]) null, 1L));
+ // float
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf((float[]) null, 1.23F));
+ // double
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf((double[]) null, 1.23));
+ }
+
+ @Test
+ void indexOf_EmptyArray_ReturnsNotFound() {
+ // T
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new String[] {}, "test"));
+ // char
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new char[] {}, 'a'));
+ // byte
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new byte[] {}, (byte) 1));
+ // short
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new short[] {}, (short) 1));
+ // int
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new int[] {}, 1));
+ // long
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new long[] {}, 1L));
+ // float
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new float[] {}, 1.23F));
+ // double
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new double[] {}, 1.23));
+ }
+
+ @Test
+ void indexOf_ObjectFound_ReturnsIndex() {
+ // T
+ assertEquals(1, ArrayTools.indexOf(new String[] { "a", "b", "c" }, "b"));
+ // char
+ assertEquals(1, ArrayTools.indexOf(new char[] { 'a', 'b', 'c' }, 'b'));
+ // byte
+ assertEquals(1, ArrayTools.indexOf(new byte[] { 1, 2, 3 }, (byte) 2));
+ // short
+ assertEquals(1, ArrayTools.indexOf(new short[] { 1, 2, 3 }, (short) 2));
+ // int
+ assertEquals(1, ArrayTools.indexOf(new int[] { 1, 2, 3 }, 2));
+ // long
+ assertEquals(1, ArrayTools.indexOf(new long[] { 1000000L, 2000000L, 3000000L }, 2000000L));
+ // float
+ assertEquals(1, ArrayTools.indexOf(new float[] { 1.11F, 2.22F, 3.33F }, 2.22F));
+ // double
+ assertEquals(1, ArrayTools.indexOf(new double[] { 1.11, 2.22, 3.33 }, 2.22));
+ }
+
+ @Test
+ void indexOf_ObjectNotFound_ReturnsNotFound() {
+ // T
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new String[] { "a", "b", "c" }, "d"));
+ // char
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new char[] { 'a', 'b', 'c' }, 'd'));
+ // byte
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new byte[] { 1, 2, 3 }, (byte) 4));
+ // short
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new short[] { 1, 2, 3 }, (short) 4));
+ // int
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new int[] { 1, 2, 3 }, 4));
+ // long
+ assertEquals(ArrayTools.NOT_FOUND_INDEX,
+ ArrayTools.indexOf(new long[] { 1000000L, 2000000L, 3000000L }, 4000000L));
+ // float
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new float[] { 1.11F, 2.22F, 3.33F }, 4.44F));
+ // double
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new double[] { 1.11, 2.22, 3.33 }, 4.44));
+ }
+
+ @Test
+ void indexOf_NullObject_ReturnsNotFound() {
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.indexOf(new String[] { "a", "b", "c" }, null));
+ }
+
+ @Test
+ void indexOf_ArrayContainsNull_ReturnsIndex() {
+ assertEquals(1, ArrayTools.indexOf(new String[] { "a", null, "c" }, null));
+ }
+
+ // ================================
+ // #endregion
+ // ================================
+
+ // ================================
// #region - lastIndexOf
- // #endregion
+ // ================================
- // #region - contains
+ @Test
+ void lastIndexOfWithPredicate_NullPredicate_ThrowsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> ArrayTools.lastIndexOfWithPredicate(new String[] {}, null));
+ }
+
+ @Test
+ void lastIndexOfWithPredicate_NullArray_ReturnsNotFoundIndex() {
+ Predicate predicate = s -> s.equals("test");
+ int result = ArrayTools.lastIndexOfWithPredicate(null, predicate);
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, result);
+ }
+
+ @Test
+ void lastIndexOfWithPredicate_EmptyArray_ReturnsNotFoundIndex() {
+ Predicate predicate = s -> s.equals("test");
+ int result = ArrayTools.lastIndexOfWithPredicate(new String[] {}, predicate);
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, result);
+ }
+
+ @Test
+ void lastIndexOfWithPredicate_ArrayContainsMatchingElement_ReturnsIndex() {
+ String[] array = { "apple", "banana", "banana", "cherry" };
+ Predicate predicate = s -> s.equals("banana");
+ int result = ArrayTools.lastIndexOfWithPredicate(array, predicate);
+ assertEquals(2, result);
+ }
+
+ @Test
+ void lastIndexOfWithPredicate_ArrayDoesNotContainMatchingElement_ReturnsNotFoundIndex() {
+ String[] array = { "apple", "banana", "cherry" };
+ Predicate predicate = s -> s.equals("orange");
+ int result = ArrayTools.lastIndexOfWithPredicate(array, predicate);
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, result);
+ }
+
+ @Test
+ void lastIndexOf_NullArray_ReturnsNotFound() {
+ // T
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf((String[]) null, "test"));
+ // char
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf((char[]) null, 'a'));
+ // byte
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf((byte[]) null, (byte) 1));
+ // short
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf((short[]) null, (short) 1));
+ // int
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf((int[]) null, 1));
+ // long
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf((long[]) null, 1L));
+ // float
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf((float[]) null, 1.23F));
+ // double
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf((double[]) null, 1.23));
+ }
+
+ @Test
+ void lastIndexOf_EmptyArray_ReturnsNotFound() {
+ // T
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new String[] {}, "test"));
+ // char
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new char[] {}, 'a'));
+ // byte
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new byte[] {}, (byte) 1));
+ // short
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new short[] {}, (short) 1));
+ // int
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new int[] {}, 1));
+ // long
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new long[] {}, 1L));
+ // float
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new float[] {}, 1.23F));
+ // double
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new double[] {}, 1.23));
+ }
+
+ @Test
+ void lastIndexOf_ObjectFound_ReturnsIndex() {
+ // T
+ assertEquals(3, ArrayTools.lastIndexOf(new String[] { "a", "b", "c", "b", "c" }, "b"));
+ // char
+ assertEquals(3, ArrayTools.lastIndexOf(new char[] { 'a', 'b', 'c', 'b', 'c' }, 'b'));
+ // byte
+ assertEquals(3, ArrayTools.lastIndexOf(new byte[] { 1, 2, 3, 2, 3 }, (byte) 2));
+ // short
+ assertEquals(3, ArrayTools.lastIndexOf(new short[] { 1, 2, 3, 2, 3 }, (short) 2));
+ // int
+ assertEquals(3, ArrayTools.lastIndexOf(new int[] { 1, 2, 3, 2, 3 }, 2));
+ // long
+ assertEquals(3,
+ ArrayTools.lastIndexOf(new long[] { 1000000L, 2000000L, 3000000L, 2000000L, 3000000L }, 2000000L));
+ // float
+ assertEquals(3, ArrayTools.lastIndexOf(new float[] { 1.11F, 2.22F, 3.33F, 2.22F, 3.33F }, 2.22F));
+ // double
+ assertEquals(3, ArrayTools.lastIndexOf(new double[] { 1.11, 2.22, 3.33, 2.22, 3.33 }, 2.22));
+ }
+
+ @Test
+ void lastIndexOf_ObjectNotFound_ReturnsNotFound() {
+ // T
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new String[] { "a", "b", "c" }, "d"));
+ // char
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new char[] { 'a', 'b', 'c' }, 'd'));
+ // byte
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new byte[] { 1, 2, 3 }, (byte) 4));
+ // short
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new short[] { 1, 2, 3 }, (short) 4));
+ // int
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new int[] { 1, 2, 3 }, 4));
+ // long
+ assertEquals(ArrayTools.NOT_FOUND_INDEX,
+ ArrayTools.lastIndexOf(new long[] { 1000000L, 2000000L, 3000000L }, 4000000L));
+ // float
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new float[] { 1.11F, 2.22F, 3.33F }, 4.44F));
+ // double
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new double[] { 1.11, 2.22, 3.33 }, 4.44));
+ }
+
+ @Test
+ void lastIndexOf_NullObject_ReturnsNotFound() {
+ assertEquals(ArrayTools.NOT_FOUND_INDEX, ArrayTools.lastIndexOf(new String[] { "a", "b", "c" }, null));
+ }
+
+ @Test
+ void lastIndexOf_ArrayContainsNull_ReturnsIndex() {
+ assertEquals(3, ArrayTools.lastIndexOf(new String[] { "a", null, "c", null, "e" }, null));
+ }
+
+ // ================================
// #endregion
+ // ================================
+
+ // ================================
+ // #region - contains
+ // ================================
+
+ @Test
+ void contains_NullArray_ReturnsFalse() {
+ assertFalse(ArrayTools.contains((String[]) null, "test"));
+ // char
+ assertFalse(ArrayTools.contains((char[]) null, 'a'));
+ // byte
+ assertFalse(ArrayTools.contains((byte[]) null, (byte) 1));
+ // short
+ assertFalse(ArrayTools.contains((short[]) null, (short) 1));
+ // int
+ assertFalse(ArrayTools.contains((int[]) null, 1));
+ // long
+ assertFalse(ArrayTools.contains((long[]) null, 1L));
+ // float
+ assertFalse(ArrayTools.contains((float[]) null, 1.2F));
+ // double
+ assertFalse(ArrayTools.contains((double[]) null, 1.2));
+ }
+
+ @Test
+ void contains_EmptyArray_ReturnsFalse() {
+ assertFalse(ArrayTools.contains(new String[] {}, "test"));
+ // char
+ assertFalse(ArrayTools.contains(new char[] {}, 'a'));
+ // byte
+ assertFalse(ArrayTools.contains(new byte[] {}, (byte) 1));
+ // short
+ assertFalse(ArrayTools.contains(new short[] {}, (short) 1));
+ // int
+ assertFalse(ArrayTools.contains(new int[] {}, 1));
+ // long
+ assertFalse(ArrayTools.contains(new long[] {}, 1L));
+ // float
+ assertFalse(ArrayTools.contains(new float[] {}, 1.2F));
+ // double
+ assertFalse(ArrayTools.contains(new double[] {}, 1.2));
+ }
+
+ @Test
+ void contains_ArrayContainsObject_ReturnsTrue() {
+ assertTrue(ArrayTools.contains(new String[] { "test", "example" }, "test"));
+ // char
+ assertTrue(ArrayTools.contains(new char[] { 'a', 'b', 'c' }, 'a'));
+ // byte
+ assertTrue(ArrayTools.contains(new byte[] { 1, 2, 3 }, (byte) 1));
+ // short
+ assertTrue(ArrayTools.contains(new short[] { 1, 2, 3 }, (short) 1));
+ // int
+ assertTrue(ArrayTools.contains(new int[] { 1, 2, 3 }, 1));
+ // long
+ assertTrue(ArrayTools.contains(new long[] { 1000000L, 2000000L, 3000000L }, 1000000L));
+ // float
+ assertTrue(ArrayTools.contains(new float[] { 1.11F, 2.22F, 3.33F }, 2.22F));
+ // double
+ assertTrue(ArrayTools.contains(new double[] { 1.11, 2.22, 3.33 }, 2.22));
+ }
+
+ @Test
+ void contains_ArrayDoesNotContainObject_ReturnsFalse() {
+ // T
+ assertFalse(ArrayTools.contains(new String[] { "a", "b", "c" }, "d"));
+ // char
+ assertFalse(ArrayTools.contains(new char[] { 'a', 'b', 'c' }, 'd'));
+ // byte
+ assertFalse(ArrayTools.contains(new byte[] { 1, 2, 3 }, (byte) 4));
+ // short
+ assertFalse(ArrayTools.contains(new short[] { 1, 2, 3 }, (short) 4));
+ // int
+ assertFalse(ArrayTools.contains(new int[] { 1, 2, 3 }, 4));
+ // long
+ assertFalse(ArrayTools.contains(new long[] { 1000000L, 2000000L, 3000000L }, 4000000L));
+ // float
+ assertFalse(ArrayTools.contains(new float[] { 1.11F, 2.22F, 3.33F }, 4.44F));
+ // double
+ assertFalse(ArrayTools.contains(new double[] { 1.11, 2.22, 3.33 }, 4.44));
+ }
+
+ @Test
+ void contains_ObjectIsNull_ReturnsFalse() {
+ assertFalse(ArrayTools.contains(new String[] { "test", "example" }, null));
+ }
+
+ @Test
+ void contains_ArrayContainsNull_ReturnsTrue() {
+ assertTrue(ArrayTools.contains(new String[] { "test", null }, null));
+ }
+
+ // ================================
+ // #endregion
+ // ================================
}
From 6c225513cad3b9d5b31aa39ce4891cbcaccd95f7 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Wed, 1 Jan 2025 17:22:42 +0800
Subject: [PATCH 23/24] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8D=95=E5=85=83?=
=?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=BF=9B=E5=BA=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ProgressOfTesting.txt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt
index 07efbfc..f0a6c78 100644
--- a/ProgressOfTesting.txt
+++ b/ProgressOfTesting.txt
@@ -1,6 +1,6 @@
[ ] 未开始测试 - 0 (0.00%)
-[*] 测试未完成 - 4 (06.45%)
-[Y] 测试完成 - 36 (58.06%)
+[*] 测试未完成 - 3 (04.84%)
+[Y] 测试完成 - 37 (59.68%)
[-] 无需测试 - 22 (35.48%)
xyz.zhouxy.plusone.commons
@@ -74,7 +74,7 @@ xyz.zhouxy.plusone.commons
│ YearQuarter.java [Y]
│
└───util
- ArrayTools.java [*] 61
+ ArrayTools.java [Y]
AssertTools.java [Y]
BigDecimals.java [Y]
DateTimeTools.java [Y]
From 25161044e970bf88f7974808018557ad0c3c2e09 Mon Sep 17 00:00:00 2001
From: ZhouXY108
Date: Wed, 1 Jan 2025 20:37:21 +0800
Subject: [PATCH 24/24] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=88=86=E9=A1=B5?=
=?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=8F=82=E6=95=B0=E7=9A=84=E5=8D=95=E5=85=83?=
=?UTF-8?q?=E6=B5=8B=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ProgressOfTesting.txt | 10 +-
pom.xml | 14 ++
.../PagingAndSortingQueryParamsTests.java | 235 ++++++++++++++----
src/test/resources/mybatis-config.xml | 20 ++
.../test/AccountQueries/AccountQueries.xml | 77 ++++++
5 files changed, 298 insertions(+), 58 deletions(-)
create mode 100644 src/test/resources/mybatis-config.xml
create mode 100644 src/test/resources/xyz/zhouxy/plusone/commons/model/dto/test/AccountQueries/AccountQueries.xml
diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt
index f0a6c78..ec459a2 100644
--- a/ProgressOfTesting.txt
+++ b/ProgressOfTesting.txt
@@ -1,6 +1,6 @@
[ ] 未开始测试 - 0 (0.00%)
-[*] 测试未完成 - 3 (04.84%)
-[Y] 测试完成 - 37 (59.68%)
+[*] 测试未完成 - 0 (0.00%)
+[Y] 测试完成 - 40 (64.52%)
[-] 无需测试 - 22 (35.48%)
xyz.zhouxy.plusone.commons
@@ -64,9 +64,9 @@ xyz.zhouxy.plusone.commons
│ │ ValidatableStringRecord.java [Y]
│ │
│ └───dto
- │ PageResult.java [*]
- │ PagingAndSortingQueryParams.java [*]
- │ PagingParams.java [*]
+ │ PageResult.java [Y]
+ │ PagingAndSortingQueryParams.java [Y]
+ │ PagingParams.java [Y]
│ UnifiedResponse.java [Y]
│
├───time
diff --git a/pom.xml b/pom.xml
index d71a63a..e21f4e1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,6 +82,20 @@
test
+
+ org.mybatis
+ mybatis
+ 3.5.17
+ test
+
+
+
+ com.h2database
+ h2
+ 2.2.224
+ test
+
+
com.fasterxml.jackson.core
diff --git a/src/test/java/xyz/zhouxy/plusone/commons/model/dto/test/PagingAndSortingQueryParamsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/model/dto/test/PagingAndSortingQueryParamsTests.java
index e94c7d5..2810acc 100644
--- a/src/test/java/xyz/zhouxy/plusone/commons/model/dto/test/PagingAndSortingQueryParamsTests.java
+++ b/src/test/java/xyz/zhouxy/plusone/commons/model/dto/test/PagingAndSortingQueryParamsTests.java
@@ -16,88 +16,217 @@
package xyz.zhouxy.plusone.commons.model.dto.test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.Statement;
import java.time.LocalDate;
+import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
+import java.util.List;
import java.util.Map;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.io.Resources;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.session.SqlSessionFactoryBuilder;
+import org.h2.jdbcx.JdbcDataSource;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
import lombok.Getter;
+import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
+import xyz.zhouxy.plusone.commons.model.dto.PageResult;
import xyz.zhouxy.plusone.commons.model.dto.PagingAndSortingQueryParams;
import xyz.zhouxy.plusone.commons.model.dto.PagingParams;
@Slf4j
-public //
-class PagingAndSortingQueryParamsTests {
+public class PagingAndSortingQueryParamsTests {
+
+ static SqlSessionFactory sqlSessionFactory;
+
+ @BeforeAll
+ static void setUp() throws Exception {
+ initDatabase();
+
+ String resource = "mybatis-config.xml";
+ InputStream inputStream = Resources.getResourceAsStream(resource);
+ sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
+ }
+
+ static void initDatabase() throws Exception {
+ JdbcDataSource dataSource = new JdbcDataSource();
+ dataSource.setURL("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=FALSE;MODE=MySQL");
+ dataSource.setUser("sa");
+ dataSource.setPassword("");
+
+ List data = Lists.newArrayList(
+ new AccountVO(1L, "zhouxy01", "zhouxy01@qq.com", 0, 108L, LocalDateTime.of(2020, 1, 1, 13, 15), 0L),
+ new AccountVO(2L, "zhouxy02", "zhouxy02@qq.com", 0, 108L, LocalDateTime.of(2020, 1, 2, 13, 15), 0L),
+ new AccountVO(3L, "zhouxy03", "zhouxy03@qq.com", 0, 108L, LocalDateTime.of(2020, 1, 3, 13, 15), 0L),
+ new AccountVO(4L, "zhouxy04", "zhouxy04@qq.com", 0, 108L, LocalDateTime.of(2020, 1, 4, 13, 15), 0L),
+ new AccountVO(5L, "zhouxy05", "zhouxy05@qq.com", 0, 108L, LocalDateTime.of(2020, 1, 5, 13, 15), 0L),
+ new AccountVO(6L, "zhouxy06", "zhouxy06@qq.com", 0, 108L, LocalDateTime.of(2024, 1, 6, 13, 15), 0L),
+ new AccountVO(7L, "zhouxy07", "zhouxy07@qq.com", 0, 108L, LocalDateTime.of(2024, 1, 7, 13, 15), 0L),
+ new AccountVO(8L, "zhouxy08", "zhouxy08@qq.com", 1, 108L, LocalDateTime.of(2024, 5, 8, 13, 15), 0L),
+ new AccountVO(9L, "zhouxy09", "zhouxy09@qq.com", 1, 108L, LocalDateTime.of(2024, 5, 9, 13, 15), 0L),
+ new AccountVO(10L, "zhouxy10", "zhouxy10@qq.com", 1, 108L, LocalDateTime.of(2024, 5, 10, 13, 15), 0L),
+ new AccountVO(11L, "zhouxy11", "zhouxy11@qq.com", 1, 108L, LocalDateTime.of(2024, 5, 11, 13, 15), 0L),
+ new AccountVO(12L, "zhouxy12", "zhouxy12@qq.com", 1, 108L, LocalDateTime.of(2024, 5, 12, 13, 15), 0L),
+ new AccountVO(13L, "zhouxy13", "zhouxy13@qq.com", 1, 108L, LocalDateTime.of(2024, 5, 13, 13, 15), 0L),
+ new AccountVO(14L, "zhouxy14", "zhouxy14@qq.com", 1, 108L, LocalDateTime.of(2024, 8, 14, 13, 15), 0L),
+ new AccountVO(15L, "zhouxy15", "zhouxy15@qq.com", 1, 108L, LocalDateTime.of(2024, 8, 15, 13, 15), 0L),
+ new AccountVO(16L, "zhouxy16", "zhouxy16@qq.com", 1, 108L, LocalDateTime.of(2024, 8, 16, 13, 15), 0L),
+ new AccountVO(17L, "zhouxy17", "zhouxy17@qq.com", 1, 108L, LocalDateTime.of(2024, 8, 17, 13, 15), 0L),
+ new AccountVO(18L, "zhouxy18", "zhouxy18@qq.com", 1, 108L, LocalDateTime.of(2024, 10, 18, 13, 15), 0L),
+ new AccountVO(19L, "zhouxy19", "zhouxy19@qq.com", 1, 108L, LocalDateTime.of(2024, 11, 19, 13, 15), 0L),
+ new AccountVO(20L, "zhouxy20", "zhouxy20@qq.com", 1, 108L, LocalDateTime.of(2024, 12, 20, 13, 15), 0L)
+ );
+
+ try (Connection conn = dataSource.getConnection()) {
+ try (Statement statement = conn.createStatement()) {
+ String ddl = "CREATE TABLE sys_account ("
+ + "\n" + " id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY"
+ + "\n" + " ,username VARCHAR(255) NOT NULL"
+ + "\n" + " ,email VARCHAR(255) NOT NULL"
+ + "\n" + " ,status VARCHAR(2) NOT NULL"
+ + "\n" + " ,create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP"
+ + "\n" + " ,created_by BIGINT NOT NULL"
+ + "\n" + " ,version BIGINT NOT NULL DEFAULT 0"
+ + "\n" + ")";
+ statement.execute(ddl);
+ }
+
+ String sql = "INSERT INTO sys_account(id, username, email, status, create_time, created_by, version) VALUES"
+ + "\n" + "(?, ?, ?, ?, ?, ?, ?)";
+ try (PreparedStatement statement = conn.prepareStatement(sql)) {
+ for (AccountVO a : data) {
+ statement.setObject(1, a.getId());
+ statement.setObject(2, a.getUsername());
+ statement.setObject(3, a.getEmail());
+ statement.setObject(4, a.getStatus());
+ statement.setObject(5, a.getCreateTime());
+ statement.setObject(6, a.getCreatedBy());
+ statement.setObject(7, a.getVersion());
+ statement.addBatch();
+ }
+ statement.executeBatch();
+ statement.clearBatch();
+ }
+ }
+ }
+
static final String JSON_STR = "" +
"{\n" +
- " \"size\": 15,\n" +
+ " \"pageNum\": 3,\n" +
+ " \"size\": 3,\n" +
" \"orderBy\": [\"username-asc\"],\n" +
" \"createTimeStart\": \"2024-05-06\",\n" +
- " \"createTimeEnd\": \"2024-07-06\",\n" +
- " \"updateTimeStart\": \"2024-08-06\",\n" +
- " \"updateTimeEnd\": \"2024-10-06\",\n" +
- " \"mobilePhone\": \"13169053215\"\n" +
+ " \"createTimeEnd\": \"2030-07-06\"" +
+ "}";
+
+ static final String WRONG_JSON_STR = "" +
+ "{\n" +
+ " \"pageNum\": 3,\n" +
+ " \"size\": 3,\n" +
+ " \"orderBy\": [\"status-asc\"],\n" +
+ " \"createTimeStart\": \"2024-05-06\",\n" +
+ " \"createTimeEnd\": \"2030-07-06\"" +
"}";
@Test
void testJackson() throws Exception {
- try {
- ObjectMapper om = new ObjectMapper();
- om.registerModule(new JavaTimeModule());
- AccountQueryParams params = om.readValue(JSON_STR, AccountQueryParams.class);
- log.info(params.toString());
+ ObjectMapper jackson = new ObjectMapper();
+ jackson.registerModule(new JavaTimeModule());
+ try (SqlSession session = sqlSessionFactory.openSession()) {
+ AccountQueryParams params = jackson.readValue(JSON_STR, AccountQueryParams.class);
PagingParams pagingParams = params.buildPagingParams();
- log.info("pagingParams: {}", pagingParams);
+
+ AccountQueries accountQueries = session.getMapper(AccountQueries.class);
+ List list = accountQueries.queryAccountList(params, pagingParams);
+ long count = accountQueries.countAccount(params);
+ PageResult accountPageResult = PageResult.of(list, count);
+ log.info(jackson.writeValueAsString(accountPageResult));
+
+ assertEquals(Lists.newArrayList(
+ new AccountVO(14L, "zhouxy14", "zhouxy14@qq.com", 1, 108L, LocalDateTime.of(2024, 8, 14, 13, 15), 0L),
+ new AccountVO(15L, "zhouxy15", "zhouxy15@qq.com", 1, 108L, LocalDateTime.of(2024, 8, 15, 13, 15), 0L),
+ new AccountVO(16L, "zhouxy16", "zhouxy16@qq.com", 1, 108L, LocalDateTime.of(2024, 8, 16, 13, 15), 0L)
+ ), accountPageResult.getContent());
+ assertEquals(13, accountPageResult.getTotal());
} catch (Exception e) {
log.error("测试不通过", e);
throw e;
}
+
+ AccountQueryParams queryParams = jackson.readValue(WRONG_JSON_STR, AccountQueryParams.class);
+ assertThrows(IllegalArgumentException.class, () -> queryParams.buildPagingParams()); // NOSONAR
}
static final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
- static final TypeAdapter dateAdapter = new TypeAdapter() {
-
- @Override
- public void write(JsonWriter out, LocalDate value) throws IOException {
- out.value(dateFormatter.format(value));
- }
-
- @Override
- public LocalDate read(JsonReader in) throws IOException {
- return LocalDate.parse(in.nextString(), dateFormatter);
- }
-
- };
-
@Test
void testGson() throws Exception {
- try {
- Gson gson = new GsonBuilder()
- .registerTypeAdapter(LocalDate.class, dateAdapter)
- .create();
+ Gson gson = new GsonBuilder()
+ .registerTypeAdapter(LocalDate.class, new TypeAdapter() {
+
+ @Override
+ public void write(JsonWriter out, LocalDate value) throws IOException {
+ out.value(dateFormatter.format(value));
+ }
+
+ @Override
+ public LocalDate read(JsonReader in) throws IOException {
+ return LocalDate.parse(in.nextString(), dateFormatter);
+ }
+
+ })
+ .create();
+ try (SqlSession session = sqlSessionFactory.openSession()) {
AccountQueryParams params = gson.fromJson(JSON_STR, AccountQueryParams.class);
log.info(params.toString());
PagingParams pagingParams = params.buildPagingParams();
log.info("pagingParams: {}", pagingParams);
+ AccountQueries accountQueries = session.getMapper(AccountQueries.class);
+ List list = accountQueries.queryAccountList(params, pagingParams);
+ long count = accountQueries.countAccount(params);
+ PageResult accountPageResult = PageResult.of(list, count);
+ log.info(gson.toJson(accountPageResult));
+
+ assertEquals(Lists.newArrayList(
+ new AccountVO(14L, "zhouxy14", "zhouxy14@qq.com", 1, 108L, LocalDateTime.of(2024, 8, 14, 13, 15), 0L),
+ new AccountVO(15L, "zhouxy15", "zhouxy15@qq.com", 1, 108L, LocalDateTime.of(2024, 8, 15, 13, 15), 0L),
+ new AccountVO(16L, "zhouxy16", "zhouxy16@qq.com", 1, 108L, LocalDateTime.of(2024, 8, 16, 13, 15), 0L)
+ ), accountPageResult.getContent());
+ assertEquals(13, accountPageResult.getTotal());
} catch (Exception e) {
log.error("测试不通过", e);
throw e;
}
+
+ AccountQueryParams queryParams = gson.fromJson(WRONG_JSON_STR, AccountQueryParams.class);
+ assertThrows(IllegalArgumentException.class, () -> queryParams.buildPagingParams()); // NOSONAR
}
}
@@ -113,15 +242,7 @@ class AccountQueryParams extends PagingAndSortingQueryParams {
private static final Map PROPERTY_COLUMN_MAP = ImmutableMap.builder()
.put("id", "id")
.put("username", "username")
- .put("email", "email")
- .put("mobilePhone", "mobile_phone")
- .put("status", "status")
- .put("nickname", "nickname")
- .put("sex", "sex")
- .put("createdBy", "created_by")
.put("createTime", "create_time")
- .put("updatedBy", "updated_by")
- .put("updateTime", "update_time")
.build();
public AccountQueryParams() {
@@ -131,17 +252,10 @@ class AccountQueryParams extends PagingAndSortingQueryParams {
private @Getter @Setter Long id;
private @Getter @Setter String username;
private @Getter @Setter String email;
- private @Getter @Setter String mobilePhone;
private @Getter @Setter Integer status;
- private @Getter @Setter String nickname;
- private @Getter @Setter Integer sex;
private @Getter @Setter Long createdBy;
private @Getter @Setter LocalDate createTimeStart;
private @Setter LocalDate createTimeEnd;
- private @Getter @Setter Long updatedBy;
- private @Getter @Setter LocalDate updateTimeStart;
- private @Setter LocalDate updateTimeEnd;
- private @Getter @Setter Long roleId;
public LocalDate getCreateTimeEnd() {
if (this.createTimeEnd == null) {
@@ -149,11 +263,26 @@ class AccountQueryParams extends PagingAndSortingQueryParams {
}
return this.createTimeEnd.plusDays(1);
}
-
- public LocalDate getUpdateTimeEnd() {
- if (this.updateTimeEnd == null) {
- return null;
- }
- return this.updateTimeEnd.plusDays(1);
- }
+}
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode
+class AccountVO {
+ private Long id;
+ private String username;
+ private String email;
+ private Integer status;
+ private Long createdBy;
+ private LocalDateTime createTime;
+ private Long version;
+}
+
+interface AccountQueries {
+
+ List queryAccountList(@Param("query") AccountQueryParams query,
+ @Param("page") PagingParams page);
+
+ long countAccount(@Param("query") AccountQueryParams query);
}
diff --git a/src/test/resources/mybatis-config.xml b/src/test/resources/mybatis-config.xml
new file mode 100644
index 0000000..903a7bb
--- /dev/null
+++ b/src/test/resources/mybatis-config.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/xyz/zhouxy/plusone/commons/model/dto/test/AccountQueries/AccountQueries.xml b/src/test/resources/xyz/zhouxy/plusone/commons/model/dto/test/AccountQueries/AccountQueries.xml
new file mode 100644
index 0000000..af25f08
--- /dev/null
+++ b/src/test/resources/xyz/zhouxy/plusone/commons/model/dto/test/AccountQueries/AccountQueries.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SELECT id, username, email, status, created_by, create_time, version
+ FROM sys_account a
+
+
+ AND a.id = #{query.id}
+
+
+ AND a.username = #{query.username}
+
+
+ AND a.email = #{query.email}
+
+
+ AND a.status = #{query.status}
+
+
+ AND a.created_by = #{query.createdBy}
+
+
+ AND a.create_time >= #{query.createTimeStart}
+
+
+ AND a.create_time < #{query.createTimeEnd}
+
+
+ ORDER BY
+
+ ${property.sqlSnippet},
+
+ id ASC
+ LIMIT #{page.size} OFFSET #{page.offset}
+
+
+
+ SELECT count(*)
+ FROM sys_account a
+
+
+ AND a.id = #{query.id}
+
+
+ AND a.username = #{query.username}
+
+
+ AND a.email = #{query.email}
+
+
+ AND a.status = #{query.status}
+
+
+ AND a.created_by = #{query.createdBy}
+
+
+ AND a.create_time >= #{query.createTimeStart}
+
+
+ AND a.create_time < #{query.createTimeEnd}
+
+
+
+
+