diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt index f6a9972..a8f53fc 100644 --- a/ProgressOfTesting.txt +++ b/ProgressOfTesting.txt @@ -1,7 +1,7 @@ -[x] 无需测试 - 6 -[ ] 未开始测试 - 34 -[-] 测试未完成 - 14 -[Y] 测试完成 - 16 +[ ] 未开始测试 - 25 (35.71%) +[-] 测试未完成 - 14 (20.00%) +[Y] 测试完成 - 19 (27.14%) +[x] 无需测试 - 12 (17.14%) xyz.zhouxy.plusone.commons ├───annotation @@ -35,18 +35,19 @@ xyz.zhouxy.plusone.commons │ RegexConsts.java [ ] │ ├───exception - │ │ DataNotExistsException.java [ ] - │ │ ParsingFailureException.java [ ] + │ │ DataNotExistsException.java [x] + │ │ ParsingFailureException.java [Y] + │ │ ExceptionType.java [Y] │ │ │ ├───business - │ │ BizException.java [ ] - │ │ InvalidInputException.java [ ] - │ │ RequestParamsException.java [ ] + │ │ BizException.java [x] + │ │ InvalidInputException.java [Y] + │ │ RequestParamsException.java [x] │ │ │ └───system - │ DataOperationResultException.java [ ] - │ NoAvailableMacFoundException.java [ ] - │ SysException.java [ ] + │ DataOperationResultException.java [x] + │ NoAvailableMacFoundException.java [x] + │ SysException.java [x] │ ├───function │ BoolUnaryOperator.java [ ] diff --git a/src/main/java/xyz/zhouxy/plusone/commons/exception/DataNotExistsException.java b/src/main/java/xyz/zhouxy/plusone/commons/exception/DataNotExistsException.java index b3dab24..5877a68 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/exception/DataNotExistsException.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/exception/DataNotExistsException.java @@ -27,10 +27,18 @@ public final class DataNotExistsException extends Exception { private static final long serialVersionUID = 6536955800679703111L; public DataNotExistsException() { - super("数据不存在"); + super(); } public DataNotExistsException(String message) { super(message); } + + public DataNotExistsException(Throwable cause) { + super(cause); + } + + public DataNotExistsException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/exception/ExceptionType.java b/src/main/java/xyz/zhouxy/plusone/commons/exception/ExceptionType.java new file mode 100644 index 0000000..f8ad83b --- /dev/null +++ b/src/main/java/xyz/zhouxy/plusone/commons/exception/ExceptionType.java @@ -0,0 +1,130 @@ +/* + * 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.exception; + +import javax.annotation.Nonnull; + +import xyz.zhouxy.plusone.commons.base.IWithCode; + +/** + * 异常类型 + * + *

+ * 异常在不同场景下被抛出,可以用不同的枚举值,表示不同的异常类型。 + * 该枚举实现本接口,用于基于不同类型创建异常。 + * + *

+ * public final class LoginException extends RuntimeException {
+ *     private final Type type;
+ *     private LoginException(Type type, String message) {
+ *         super(message);
+ *         this.type = type;
+ *     }
+ *
+ *     private LoginException(Type type, Throwable cause) {
+ *         super(cause);
+ *         this.type = type;
+ *     }
+ *
+ *     private LoginException(Type type, String message, Throwable cause) {
+ *         super(message, cause);
+ *         this.type = type;
+ *     }
+ *
+ *     // ...
+ *
+ *     public enum Type implements ExceptionType {
+ *         DEFAULT("00", "当前会话未登录"),
+ *         NOT_TOKEN("10", "未提供token"),
+ *         INVALID_TOKEN("20", "token无效"),
+ *         TOKEN_TIMEOUT("30", "token已过期"),
+ *         BE_REPLACED("40", "token已被顶下线"),
+ *         KICK_OUT("50", "token已被踢下线"),
+ *         ;
+ *
+ *         @Nonnull
+ *         private final String code;
+ *         @Nonnull
+ *         private final String defaultMessage;
+ *
+ *         Type(String code, String defaultMessage) {
+ *             this.code = code;
+ *             this.defaultMessage = defaultMessage;
+ *         }
+ *
+ *         @Override
+ *         @Nonnull
+ *         public String getCode() {
+ *             return code;
+ *         }
+ *
+ *         @Override
+ *         public String getDefaultMessage() {
+ *             return defaultMessage;
+ *         }
+ *
+ *         @Override
+ *         @Nonnull
+ *         public LoginException create() {
+ *             return new LoginException(this, this.defaultMessage);
+ *         }
+ *
+ *         @Override
+ *         @Nonnull
+ *         public LoginException create(String message) {
+ *             return new LoginException(this, message);
+ *         }
+ *
+ *         @Override
+ *         @Nonnull
+ *         public LoginException create(Throwable cause) {
+ *             return new LoginException(this, cause);
+ *         }
+ *
+ *         @Override
+ *         @Nonnull
+ *         public LoginException create(String message, Throwable cause) {
+ *             return new LoginException(this, message, cause);
+ *         }
+ *     }
+ * }
+ * 
+ * + * 使用时,可以使用这种方式创建并抛出异常: + *
+ * throw LoginException.Type.TOKEN_TIMEOUT.create();
+ * 
+ *

+ * + * @author ZhouXY + */ +public interface ExceptionType extends IWithCode { + + String getDefaultMessage(); + + @Nonnull + E create(); + + @Nonnull + E create(String message); + + @Nonnull + E create(Throwable cause); + + @Nonnull + E create(String message, Throwable cause); + +} diff --git a/src/main/java/xyz/zhouxy/plusone/commons/exception/ParsingFailureException.java b/src/main/java/xyz/zhouxy/plusone/commons/exception/ParsingFailureException.java index 343bc2b..0a86545 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/exception/ParsingFailureException.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/exception/ParsingFailureException.java @@ -20,7 +20,6 @@ import java.time.format.DateTimeParseException; import javax.annotation.Nonnull; -import xyz.zhouxy.plusone.commons.base.IWithCode; import xyz.zhouxy.plusone.commons.exception.business.RequestParamsException; /** @@ -42,13 +41,8 @@ public final class ParsingFailureException extends RuntimeException { private final Type type; - private ParsingFailureException(Type type) { - super(type.getDefaultMsg()); - this.type = type; - } - - private ParsingFailureException(Type type, String msg) { - super(msg); + private ParsingFailureException(Type type, String message) { + super(message); this.type = type; } @@ -57,64 +51,64 @@ public final class ParsingFailureException extends RuntimeException { this.type = type; } - private ParsingFailureException(Type type, String msg, Throwable cause) { - super(msg, cause); + private ParsingFailureException(Type type, String message, Throwable cause) { + super(message, cause); this.type = type; } public ParsingFailureException() { - this(Type.DEFAULT); + this(Type.DEFAULT, Type.DEFAULT.getDefaultMessage()); } - public ParsingFailureException(String msg) { - this(Type.DEFAULT, msg); + public ParsingFailureException(String message) { + this(Type.DEFAULT, message); } - public ParsingFailureException(Throwable e) { - this(Type.DEFAULT, e); + public ParsingFailureException(Throwable cause) { + this(Type.DEFAULT, cause); } - public ParsingFailureException(String msg, Throwable e) { - this(Type.DEFAULT, msg, e); + public ParsingFailureException(String message, Throwable cause) { + this(Type.DEFAULT, message, cause); } - public static ParsingFailureException of(Type type) { - return new ParsingFailureException(type); + public static ParsingFailureException of(DateTimeParseException cause) { + if (cause == null) { + return Type.DATE_TIME_PARSING_FAILURE.create(); + } + return Type.DATE_TIME_PARSING_FAILURE.create(cause.getMessage(), cause); } - public static ParsingFailureException of(Type type, String msg) { - return new ParsingFailureException(type, msg); + public static ParsingFailureException of(String message, DateTimeParseException cause) { + return Type.DATE_TIME_PARSING_FAILURE.create(message, cause); } - public static ParsingFailureException of(Type type, Throwable e) { - return new ParsingFailureException(type, e); + public static ParsingFailureException of(NumberFormatException cause) { + if (cause == null) { + return Type.NUMBER_PARSING_FAILURE.create(); + } + return Type.NUMBER_PARSING_FAILURE.create(cause.getMessage(), cause); } - public static ParsingFailureException of(Type type, String msg, Throwable e) { - return new ParsingFailureException(type, msg, e); - } - - public static ParsingFailureException of(DateTimeParseException e) { - return new ParsingFailureException(Type.DATE_TIME_PARSING_FAILURE, e.getMessage(), e); - } - - public static ParsingFailureException of(String msg, DateTimeParseException e) { - return new ParsingFailureException(Type.DATE_TIME_PARSING_FAILURE, msg, e); - } - - public static ParsingFailureException of(NumberFormatException e) { - return new ParsingFailureException(Type.NUMBER_PARSING_FAILURE, e.getMessage(), e); - } - - public static ParsingFailureException of(String msg, NumberFormatException e) { - return new ParsingFailureException(Type.NUMBER_PARSING_FAILURE, msg, e); + public static ParsingFailureException of(String message, NumberFormatException cause) { + return Type.NUMBER_PARSING_FAILURE.create(message, cause); } public Type getType() { return type; } - public enum Type implements IWithCode { + public String getCode() { + return this.type.code; + } + + public static final Type DEFAULT = Type.DEFAULT; + public static final Type NUMBER_PARSING_FAILURE = Type.NUMBER_PARSING_FAILURE; + public static final Type DATE_TIME_PARSING_FAILURE = Type.DATE_TIME_PARSING_FAILURE; + public static final Type JSON_PARSING_FAILURE = Type.JSON_PARSING_FAILURE; + public static final Type XML_PARSING_FAILURE = Type.XML_PARSING_FAILURE; + + public enum Type implements ExceptionType { DEFAULT("00", "解析失败"), NUMBER_PARSING_FAILURE("10", "数字转换失败"), DATE_TIME_PARSING_FAILURE("20", "时间解析失败"), @@ -123,13 +117,13 @@ public final class ParsingFailureException extends RuntimeException { ; @Nonnull - final String code; + private final String code; @Nonnull - final String defaultMsg; + private final String defaultMessage; - Type(String code, String defaultMsg) { + Type(String code, String defaultMessage) { this.code = code; - this.defaultMsg = defaultMsg; + this.defaultMessage = defaultMessage; } @Override @@ -138,8 +132,33 @@ public final class ParsingFailureException extends RuntimeException { return code; } - public String getDefaultMsg() { - return defaultMsg; + @Override + public String getDefaultMessage() { + return defaultMessage; + } + + @Override + @Nonnull + public ParsingFailureException create() { + return new ParsingFailureException(this, this.defaultMessage); + } + + @Override + @Nonnull + public ParsingFailureException create(String message) { + return new ParsingFailureException(this, message); + } + + @Override + @Nonnull + public ParsingFailureException create(Throwable cause) { + return new ParsingFailureException(this, cause); + } + + @Override + @Nonnull + public ParsingFailureException create(String message, Throwable cause) { + return new ParsingFailureException(this, message, cause); } } } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/exception/business/BizException.java b/src/main/java/xyz/zhouxy/plusone/commons/exception/business/BizException.java index eee5262..ed4b664 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/exception/business/BizException.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/exception/business/BizException.java @@ -37,16 +37,16 @@ public class BizException extends RuntimeException { super(DEFAULT_MSG); } - public BizException(String msg) { - super(msg); + public BizException(String message) { + super(message); } public BizException(Throwable cause) { super(cause); } - public BizException(String msg, Throwable cause) { - super(msg, cause); + public BizException(String message, Throwable cause) { + super(message, cause); } } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/exception/business/InvalidInputException.java b/src/main/java/xyz/zhouxy/plusone/commons/exception/business/InvalidInputException.java index 53c26ed..aacf7a6 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/exception/business/InvalidInputException.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/exception/business/InvalidInputException.java @@ -18,7 +18,7 @@ package xyz.zhouxy.plusone.commons.exception.business; import javax.annotation.Nonnull; -import xyz.zhouxy.plusone.commons.base.IWithCode; +import xyz.zhouxy.plusone.commons.exception.ExceptionType; /** * InvalidInputException @@ -38,12 +38,12 @@ public final class InvalidInputException extends RequestParamsException { private final Type type; private InvalidInputException(Type type) { - super(type.getDefaultMsg()); + super(type.getDefaultMessage()); this.type = type; } - private InvalidInputException(Type type, String msg) { - super(msg); + private InvalidInputException(Type type, String message) { + super(message); this.type = type; } @@ -52,8 +52,8 @@ public final class InvalidInputException extends RequestParamsException { this.type = type; } - private InvalidInputException(Type type, String msg, Throwable cause) { - super(msg, cause); + private InvalidInputException(Type type, String message, Throwable cause) { + super(message, cause); this.type = type; } @@ -61,47 +61,27 @@ public final class InvalidInputException extends RequestParamsException { this(Type.DEFAULT); } - public InvalidInputException(String msg) { - this(Type.DEFAULT, msg); + public InvalidInputException(String message) { + this(Type.DEFAULT, message); } - public InvalidInputException(Throwable e) { - this(Type.DEFAULT, e); + public InvalidInputException(Throwable cause) { + this(Type.DEFAULT, cause); } - public InvalidInputException(String msg, Throwable e) { - this(Type.DEFAULT, msg, e); - } - - public static InvalidInputException of(Type type) { - return new InvalidInputException(type); - } - - public static InvalidInputException of(Type type, String msg) { - return new InvalidInputException(type, msg); - } - - public static InvalidInputException of(Type type, Throwable e) { - return new InvalidInputException(type, e); - } - - public static InvalidInputException of(Type type, String msg, Throwable e) { - return new InvalidInputException(type, msg, e); - } - - public static InvalidInputException of(Throwable e) { - return new InvalidInputException(Type.DEFAULT, e.getMessage(), e); - } - - public static InvalidInputException of(String msg, Throwable e) { - return new InvalidInputException(Type.DEFAULT, msg, e); + public InvalidInputException(String message, Throwable cause) { + this(Type.DEFAULT, message, cause); } public Type getType() { - return type; + return this.type; } - public enum Type implements IWithCode { + public Object getCode() { + return this.type.code; + } + + public enum Type implements ExceptionType { DEFAULT("00", "用户输入内容非法"), CONTAINS_ILLEGAL_AND_MALICIOUS_LINKS("01", "包含非法恶意跳转链接"), CONTAINS_ILLEGAL_WORDS("02", "包含违禁敏感词"), @@ -109,12 +89,14 @@ public final class InvalidInputException extends RequestParamsException { INFRINGE_COPYRIGHT("04", "文件侵犯版权"), ; + @Nonnull final String code; - final String defaultMsg; + @Nonnull + final String defaultMessage; Type(String code, String defaultMsg) { this.code = code; - this.defaultMsg = defaultMsg; + this.defaultMessage = defaultMsg; } @Override @@ -123,8 +105,33 @@ public final class InvalidInputException extends RequestParamsException { return code; } - public String getDefaultMsg() { - return defaultMsg; + @Override + public String getDefaultMessage() { + return defaultMessage; + } + + @Override + @Nonnull + public InvalidInputException create() { + return new InvalidInputException(this); + } + + @Override + @Nonnull + public InvalidInputException create(String message) { + return new InvalidInputException(this, message); + } + + @Override + @Nonnull + public InvalidInputException create(Throwable cause) { + return new InvalidInputException(this, cause); + } + + @Override + @Nonnull + public InvalidInputException create(String message, Throwable cause) { + return new InvalidInputException(this, message, cause); } } } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/exception/business/RequestParamsException.java b/src/main/java/xyz/zhouxy/plusone/commons/exception/business/RequestParamsException.java index 8f4f383..4d9155a 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/exception/business/RequestParamsException.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/exception/business/RequestParamsException.java @@ -34,16 +34,16 @@ public class RequestParamsException extends BizException { super(DEFAULT_MSG); } - public RequestParamsException(String msg) { - super(msg); + public RequestParamsException(String message) { + super(message); } public RequestParamsException(Throwable cause) { super(cause); } - public RequestParamsException(String msg, Throwable cause) { - super(msg, cause); + public RequestParamsException(String message, Throwable cause) { + super(message, cause); } } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/exception/system/DataOperationResultException.java b/src/main/java/xyz/zhouxy/plusone/commons/exception/system/DataOperationResultException.java index 99db690..bbb49f6 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/exception/system/DataOperationResultException.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/exception/system/DataOperationResultException.java @@ -39,15 +39,15 @@ public final class DataOperationResultException extends SysException { super(DEFAULT_MSG); } - public DataOperationResultException(String msg) { - super(msg); + public DataOperationResultException(String message) { + super(message); } public DataOperationResultException(Throwable cause) { super(cause); } - public DataOperationResultException(String msg, Throwable cause) { - super(msg, cause); + public DataOperationResultException(String message, Throwable cause) { + super(message, cause); } } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/exception/system/NoAvailableMacFoundException.java b/src/main/java/xyz/zhouxy/plusone/commons/exception/system/NoAvailableMacFoundException.java index 7897b46..d7c76f8 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/exception/system/NoAvailableMacFoundException.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/exception/system/NoAvailableMacFoundException.java @@ -33,15 +33,15 @@ public class NoAvailableMacFoundException extends SysException { super(); } - public NoAvailableMacFoundException(String msg) { - super(msg); + public NoAvailableMacFoundException(String message) { + super(message); } - public NoAvailableMacFoundException(Throwable e) { - super(e); + public NoAvailableMacFoundException(Throwable cause) { + super(cause); } - public NoAvailableMacFoundException(String msg, Throwable e) { - super(msg, e); + public NoAvailableMacFoundException(String message, Throwable cause) { + super(message, cause); } } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/exception/system/SysException.java b/src/main/java/xyz/zhouxy/plusone/commons/exception/system/SysException.java index 877d43a..7480bd6 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/exception/system/SysException.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/exception/system/SysException.java @@ -30,19 +30,19 @@ public class SysException extends RuntimeException { private static final String DEFAULT_MSG = "系统异常"; - protected SysException() { + public SysException() { super(DEFAULT_MSG); } - public SysException(String msg) { - super(msg); + public SysException(String message) { + super(message); } public SysException(Throwable cause) { super(cause); } - public SysException(String msg, Throwable cause) { - super(msg, cause); + public SysException(String message, Throwable cause) { + super(message, cause); } } diff --git a/src/test/java/xyz/zhouxy/plusone/commons/base/IWithCodeTests.java b/src/test/java/xyz/zhouxy/plusone/commons/base/IWithCodeTests.java index bbd60a3..5d627ec 100644 --- a/src/test/java/xyz/zhouxy/plusone/commons/base/IWithCodeTests.java +++ b/src/test/java/xyz/zhouxy/plusone/commons/base/IWithCodeTests.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.base; import static org.junit.jupiter.api.Assertions.*; diff --git a/src/test/java/xyz/zhouxy/plusone/commons/exception/test/InvalidInputExceptionTests.java b/src/test/java/xyz/zhouxy/plusone/commons/exception/test/InvalidInputExceptionTests.java new file mode 100644 index 0000000..13b31bc --- /dev/null +++ b/src/test/java/xyz/zhouxy/plusone/commons/exception/test/InvalidInputExceptionTests.java @@ -0,0 +1,288 @@ +/* + * 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.exception.test; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import lombok.extern.slf4j.Slf4j; +import xyz.zhouxy.plusone.commons.exception.business.InvalidInputException; + +@Slf4j +public class InvalidInputExceptionTests { + + // ================================ + // #region - createByType + // ================================ + + @Test + void test_createByType() { + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw InvalidInputException.Type.CONTAINS_ILLEGAL_AND_MALICIOUS_LINKS.create(); + }); + assertEquals(InvalidInputException.Type.CONTAINS_ILLEGAL_AND_MALICIOUS_LINKS, e.getType()); + assertEquals(InvalidInputException.Type.CONTAINS_ILLEGAL_AND_MALICIOUS_LINKS.getCode(), e.getCode()); + assertEquals(InvalidInputException.Type.CONTAINS_ILLEGAL_AND_MALICIOUS_LINKS.getDefaultMessage(), e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByType_withMessage() { + final String message = "test_createByType_withMessage"; + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw InvalidInputException.Type.CONTAINS_ILLEGAL_WORDS.create(message); + }); + assertEquals(InvalidInputException.Type.CONTAINS_ILLEGAL_WORDS, e.getType()); + assertEquals(InvalidInputException.Type.CONTAINS_ILLEGAL_WORDS.getCode(), e.getCode()); + assertEquals(message, e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByType_withNullMessage() { + final String message = null; + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw InvalidInputException.Type.PICTURE_CONTAINS_ILLEGAL_INFORMATION.create(message); + }); + assertEquals(InvalidInputException.Type.PICTURE_CONTAINS_ILLEGAL_INFORMATION, e.getType()); + assertEquals(InvalidInputException.Type.PICTURE_CONTAINS_ILLEGAL_INFORMATION.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByType_withCause() { + Arrays.asList("test_createByType_withCause", null).forEach(message -> { + + NumberFormatException nfe = new NumberFormatException(message); + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw InvalidInputException.Type.INFRINGE_COPYRIGHT.create(nfe); + }); + + assertEquals(InvalidInputException.Type.INFRINGE_COPYRIGHT, e.getType()); + assertEquals(InvalidInputException.Type.INFRINGE_COPYRIGHT.getCode(), e.getCode()); + log.info("{}", e.getMessage()); + assertEquals(nfe.toString(), e.getMessage()); + assertEquals(nfe, e.getCause()); + }); + } + + @Test + void test_createByType_withNullCause() { + NumberFormatException nfe = null; + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw InvalidInputException.Type.DEFAULT.create(nfe); + }); + + assertEquals(InvalidInputException.Type.DEFAULT, e.getType()); + assertEquals(InvalidInputException.Type.DEFAULT.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByType_withMessageAndCause() { + final String message = "test_createByType_withMessageAndCause"; + final NumberFormatException nfe = new NumberFormatException("NumberFormatExceptionMessage"); + + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw InvalidInputException.Type.CONTAINS_ILLEGAL_AND_MALICIOUS_LINKS.create(message, nfe); + }); + assertEquals(InvalidInputException.Type.CONTAINS_ILLEGAL_AND_MALICIOUS_LINKS, e.getType()); + assertEquals(InvalidInputException.Type.CONTAINS_ILLEGAL_AND_MALICIOUS_LINKS.getCode(), e.getCode()); + assertEquals(message, e.getMessage()); + assertEquals(nfe, e.getCause()); + } + + @Test + void test_createByType_withNullMessageAndCause() { + final String message = null; + final NullPointerException nfe = new NullPointerException("Context is null."); + + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw InvalidInputException.Type.CONTAINS_ILLEGAL_WORDS.create(message, nfe); + }); + assertEquals(InvalidInputException.Type.CONTAINS_ILLEGAL_WORDS, e.getType()); + assertEquals(InvalidInputException.Type.CONTAINS_ILLEGAL_WORDS.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertEquals(nfe, e.getCause()); + } + + @Test + void test_createByType_withMessageAndNullCause() { + final String message = "test_createByType_withMessageAndNullCause"; + final NullPointerException npe = null; + + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw InvalidInputException.Type.CONTAINS_ILLEGAL_WORDS.create(message, npe); + }); + assertEquals(InvalidInputException.Type.CONTAINS_ILLEGAL_WORDS, e.getType()); + assertEquals(InvalidInputException.Type.CONTAINS_ILLEGAL_WORDS.getCode(), e.getCode()); + assertEquals(message, e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByType_withNullMessageAndNullCause() { + final String message = null; + final NullPointerException nfe = null; + + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw InvalidInputException.Type.CONTAINS_ILLEGAL_WORDS.create(message, nfe); + }); + assertEquals(InvalidInputException.Type.CONTAINS_ILLEGAL_WORDS, e.getType()); + assertEquals(InvalidInputException.Type.CONTAINS_ILLEGAL_WORDS.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertNull(e.getCause()); + } + + // ================================ + // #endregion - createByType + // ================================ + + // ================================ + // #region - constructor + // ================================ + + @Test + void testConstructor() { + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw new InvalidInputException(); + }); + assertEquals(InvalidInputException.Type.DEFAULT, e.getType()); + assertEquals(InvalidInputException.Type.DEFAULT.getCode(), e.getCode()); + assertEquals(InvalidInputException.Type.DEFAULT.getDefaultMessage(), e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void testConstructor_withMessage() { + final String message = "testConstructor_withMessage"; + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw new InvalidInputException(message); + }); + assertEquals(InvalidInputException.Type.DEFAULT, e.getType()); + assertEquals(InvalidInputException.Type.DEFAULT.getCode(), e.getCode()); + assertEquals(message, e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void testConstructor_withNullMessage() { + final String message = null; + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw new InvalidInputException(message); + }); + assertEquals(InvalidInputException.Type.DEFAULT, e.getType()); + assertEquals(InvalidInputException.Type.DEFAULT.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void testConstructor_withCause() { + Arrays.asList("testConstructor_withCause", null).forEach(message -> { + + NumberFormatException nfe = new NumberFormatException(message); + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw new InvalidInputException(nfe); + }); + + assertEquals(InvalidInputException.Type.DEFAULT, e.getType()); + assertEquals(InvalidInputException.Type.DEFAULT.getCode(), e.getCode()); + log.info("{}", e.getMessage()); + assertEquals(nfe.toString(), e.getMessage()); + assertEquals(nfe, e.getCause()); + }); + } + + @Test + void testConstructor_withNullCause() { + NumberFormatException nfe = null; + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw new InvalidInputException(nfe); + }); + + assertEquals(InvalidInputException.Type.DEFAULT, e.getType()); + assertEquals(InvalidInputException.Type.DEFAULT.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void testConstructor_withMessageAndCause() { + final String message = "testConstructor_withMessageAndCause"; + final NumberFormatException nfe = new NumberFormatException("NumberFormatExceptionMessage"); + + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw new InvalidInputException(message, nfe); + }); + assertEquals(InvalidInputException.Type.DEFAULT, e.getType()); + assertEquals(InvalidInputException.Type.DEFAULT.getCode(), e.getCode()); + assertEquals(message, e.getMessage()); + assertEquals(nfe, e.getCause()); + } + + @Test + void testConstructor_withNullMessageAndCause() { + final String message = null; + final NullPointerException nfe = new NullPointerException("Context is null."); + + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw new InvalidInputException(message, nfe); + }); + assertEquals(InvalidInputException.Type.DEFAULT, e.getType()); + assertEquals(InvalidInputException.Type.DEFAULT.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertEquals(nfe, e.getCause()); + } + + @Test + void testConstructor_withMessageAndNullCause() { + final String message = "testConstructor_withMessageAndNullCause"; + final NullPointerException npe = null; + + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw new InvalidInputException(message, npe); + }); + assertEquals(InvalidInputException.Type.DEFAULT, e.getType()); + assertEquals(InvalidInputException.Type.DEFAULT.getCode(), e.getCode()); + assertEquals(message, e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void testConstructor_withNullMessageAndNullCause() { + final String message = null; + final NullPointerException nfe = null; + + InvalidInputException e = assertThrows(InvalidInputException.class, () -> { + throw new InvalidInputException(message, nfe); + }); + assertEquals(InvalidInputException.Type.DEFAULT, e.getType()); + assertEquals(InvalidInputException.Type.DEFAULT.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertNull(e.getCause()); + } + + // ================================ + // #endregion - constructor + // ================================ +} diff --git a/src/test/java/xyz/zhouxy/plusone/commons/exception/test/ParsingFailureExceptionTests.java b/src/test/java/xyz/zhouxy/plusone/commons/exception/test/ParsingFailureExceptionTests.java new file mode 100644 index 0000000..9b1ba11 --- /dev/null +++ b/src/test/java/xyz/zhouxy/plusone/commons/exception/test/ParsingFailureExceptionTests.java @@ -0,0 +1,367 @@ +/* + * 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.exception.test; + +import static org.junit.jupiter.api.Assertions.*; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import lombok.extern.slf4j.Slf4j; +import xyz.zhouxy.plusone.commons.exception.ParsingFailureException; + +@Slf4j +public class ParsingFailureExceptionTests { + + // ================================ + // #region - createByType + // ================================ + + @Test + void test_createByType() { + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.DATE_TIME_PARSING_FAILURE.create(); + }); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE.getCode(), e.getCode()); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE.getDefaultMessage(), e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByType_withMessage() { + final String message = "test_createByType_withMessage"; + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.JSON_PARSING_FAILURE.create(message); + }); + assertEquals(ParsingFailureException.Type.JSON_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.Type.JSON_PARSING_FAILURE.getCode(), e.getCode()); + assertEquals(message, e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByType_withNullMessage() { + final String message = null; + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.XML_PARSING_FAILURE.create(message); + }); + assertEquals(ParsingFailureException.XML_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.XML_PARSING_FAILURE.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByType_withCause() { + Arrays.asList("test_createByType_withCause", null).forEach(message -> { + + NumberFormatException nfe = new NumberFormatException(message); + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.NUMBER_PARSING_FAILURE.create(nfe); + }); + + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE.getCode(), e.getCode()); + log.info("{}", e.getMessage()); + assertEquals(nfe.toString(), e.getMessage()); + assertEquals(nfe, e.getCause()); + }); + } + + @Test + void test_createByType_withNullCause() { + NumberFormatException nfe = null; + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.NUMBER_PARSING_FAILURE.create(nfe); + }); + + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByType_withMessageAndCause() { + final String message = "test_createByType_withMessageAndCause"; + final NumberFormatException nfe = new NumberFormatException("NumberFormatExceptionMessage"); + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.NUMBER_PARSING_FAILURE.create(message, nfe); + }); + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE.getCode(), e.getCode()); + assertEquals(message, e.getMessage()); + assertEquals(nfe, e.getCause()); + } + + @Test + void test_createByType_withNullMessageAndCause() { + final String message = null; + final NullPointerException nfe = new NullPointerException("Context is null."); + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.DATE_TIME_PARSING_FAILURE.create(message, nfe); + }); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertEquals(nfe, e.getCause()); + } + + @Test + void test_createByType_withMessageAndNullCause() { + final String message = "test_createByType_withMessageAndNullCause"; + final NullPointerException npe = null; + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.DATE_TIME_PARSING_FAILURE.create(message, npe); + }); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE.getCode(), e.getCode()); + assertEquals(message, e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByType_withNullMessageAndNullCause() { + final String message = null; + final NullPointerException nfe = null; + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.DATE_TIME_PARSING_FAILURE.create(message, nfe); + }); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertNull(e.getCause()); + } + + // ================================ + // #endregion - createByType + // ================================ + + // ================================ + // #region - of DateTimeParseException + // ================================ + + @Test + void test_createByOf_withDateTimeParseException() { + DateTimeParseException dtpe = assertThrows(DateTimeParseException.class, () -> { + LocalDateTime.parse("abcd", DateTimeFormatter.ISO_DATE_TIME); + }); + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.of(dtpe); + }); + + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE.getCode(), e.getCode()); + assertEquals(dtpe.getMessage(), e.getMessage()); + assertEquals(dtpe, e.getCause()); + } + + @Test + void test_createByOf_withNullDateTimeParseException() { + DateTimeParseException dtpe = null; + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.of(dtpe); + }); + + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE.getCode(), e.getCode()); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE.getDefaultMessage(), e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByOf_withDateTimeParseExceptionAndMessage() { + final String message = "test_createByOf_withDateTimeParseExceptionAndMessage"; + DateTimeParseException dtpe = assertThrows(DateTimeParseException.class, () -> { + LocalDateTime.parse("abcd", DateTimeFormatter.ISO_DATE_TIME); + }); + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.of(message, dtpe); + }); + + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE.getCode(), e.getCode()); + assertEquals(message, e.getMessage()); + assertEquals(dtpe, e.getCause()); + } + + @Test + void test_createByOf_withDateTimeParseExceptionAndNullMessage() { + final String message = null; + DateTimeParseException dtpe = assertThrows(DateTimeParseException.class, () -> { + LocalDateTime.parse("abcd", DateTimeFormatter.ISO_DATE_TIME); + }); + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.of(message, dtpe); + }); + + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertEquals(dtpe, e.getCause()); + } + + @Test + void test_createByOf_withNullDateTimeParseExceptionAndMessage() { + final String message = "test_createByOf_withDateTimeParseExceptionAndMessage"; + DateTimeParseException dtpe = null; + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.of(message, dtpe); + }); + + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE.getCode(), e.getCode()); + assertEquals(message, e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByOf_withNullDateTimeParseExceptionAndNullMessage() { + final String message = null; + DateTimeParseException dtpe = null; + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.of(message, dtpe); + }); + + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.DATE_TIME_PARSING_FAILURE.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertNull(e.getCause()); + } + + // ================================ + // #endregion - of DateTimeParseException + // ================================ + + // ================================ + // #region - of NumberFormatException + // ================================ + + @Test + void test_createByOf_withNumberFormatException() { + NumberFormatException dtpe = assertThrows(NumberFormatException.class, () -> { + LocalDateTime.parse("abcd", DateTimeFormatter.ISO_DATE_TIME); + }); + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.of(dtpe); + }); + + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE.getCode(), e.getCode()); + assertEquals(dtpe.getMessage(), e.getMessage()); + assertEquals(dtpe, e.getCause()); + } + + @Test + void test_createByOf_withNullNumberFormatException() { + NumberFormatException dtpe = null; + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.of(dtpe); + }); + + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE.getCode(), e.getCode()); + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE.getDefaultMessage(), e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByOf_withNumberFormatExceptionAndMessage() { + final String message = "test_createByOf_withNumberFormatExceptionAndMessage"; + NumberFormatException dtpe = assertThrows(NumberFormatException.class, () -> { + LocalDateTime.parse("abcd", DateTimeFormatter.ISO_DATE_TIME); + }); + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.of(message, dtpe); + }); + + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE.getCode(), e.getCode()); + assertEquals(message, e.getMessage()); + assertEquals(dtpe, e.getCause()); + } + + @Test + void test_createByOf_withNumberFormatExceptionAndNullMessage() { + final String message = null; + NumberFormatException dtpe = assertThrows(NumberFormatException.class, () -> { + LocalDateTime.parse("abcd", DateTimeFormatter.ISO_DATE_TIME); + }); + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.of(message, dtpe); + }); + + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertEquals(dtpe, e.getCause()); + } + + @Test + void test_createByOf_withNullNumberFormatExceptionAndMessage() { + final String message = "test_createByOf_withNumberFormatExceptionAndMessage"; + NumberFormatException dtpe = null; + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.of(message, dtpe); + }); + + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE.getCode(), e.getCode()); + assertEquals(message, e.getMessage()); + assertNull(e.getCause()); + } + + @Test + void test_createByOf_withNullNumberFormatExceptionAndNullMessage() { + final String message = null; + NumberFormatException dtpe = null; + + ParsingFailureException e = assertThrows(ParsingFailureException.class, () -> { + throw ParsingFailureException.of(message, dtpe); + }); + + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE, e.getType()); + assertEquals(ParsingFailureException.NUMBER_PARSING_FAILURE.getCode(), e.getCode()); + assertNull(e.getMessage()); + assertNull(e.getCause()); + } + + // ================================ + // #endregion - of NumberFormatException + // ================================ + +}