2 Commits

Author SHA1 Message Date
e15f4875af docs: 添加 SemVer 规范链接
在类注释中添加了指向 Semantic Versioning 2.0.0 规范的链接。
2025-10-13 21:14:45 +08:00
70225ca984 feat(model): 添加 SemVer 表示语义版本号
新增 `SemVer` 类用于解析和比较语义版本号,支持版本号的解析、比较、序列化等功能。

该实现遵循语义化版本规范(SemVer 2.0.0),包括主版本号、次版本号、修订号、先行版本号和构建元数据的处理。

同时添加了基础的单元测试,验证版本号之间的排序逻辑是否符合预期。

后续需完善正则表达式优化、补充完整单元测试以及相关文档说明。
2025-10-12 03:13:43 +08:00
8 changed files with 58 additions and 10295 deletions

View File

@@ -17,7 +17,6 @@
package xyz.zhouxy.plusone.commons.model;
import static xyz.zhouxy.plusone.commons.util.AssertTools.checkArgument;
import static xyz.zhouxy.plusone.commons.util.AssertTools.checkArgumentNotNull;
import java.util.Objects;
import java.util.function.Supplier;
@@ -76,8 +75,8 @@ public abstract class ValidatableStringRecord<T extends ValidatableStringRecord<
* @param errorMessage 正则不匹配时的错误信息
*/
protected ValidatableStringRecord(String value, Pattern pattern, String errorMessage) {
checkArgumentNotNull(value, "The value cannot be null.");
checkArgumentNotNull(pattern, "The pattern cannot be null.");
checkArgument(Objects.nonNull(value), "The value cannot be null.");
checkArgument(Objects.nonNull(pattern), "The pattern cannot be null.");
this.matcher = pattern.matcher(value);
checkArgument(this.matcher.matches(), errorMessage);
this.value = value;

View File

@@ -17,7 +17,6 @@
package xyz.zhouxy.plusone.commons.util;
import static xyz.zhouxy.plusone.commons.util.AssertTools.checkArgument;
import static xyz.zhouxy.plusone.commons.util.AssertTools.checkArgumentNotNull;
import static xyz.zhouxy.plusone.commons.util.AssertTools.checkNotNull;
import java.math.BigDecimal;
@@ -492,7 +491,7 @@ public class ArrayTools {
* @return 重复后的数组
*/
public static char[] repeat(char[] arr, int times, int maxLength) {
checkArgumentNotNull(arr);
checkArgument(Objects.nonNull(arr));
checkArgument(times >= 0,
"The number of times must be greater than or equal to zero");
checkArgument(maxLength >= 0,
@@ -527,7 +526,7 @@ public class ArrayTools {
* @return 重复后的数组
*/
public static byte[] repeat(byte[] arr, int times, int maxLength) {
checkArgumentNotNull(arr);
checkArgument(Objects.nonNull(arr));
checkArgument(times >= 0,
"The number of times must be greater than or equal to zero");
checkArgument(maxLength >= 0,
@@ -562,7 +561,7 @@ public class ArrayTools {
* @return 重复后的数组
*/
public static short[] repeat(short[] arr, int times, int maxLength) {
checkArgumentNotNull(arr);
checkArgument(Objects.nonNull(arr));
checkArgument(times >= 0,
"The number of times must be greater than or equal to zero");
checkArgument(maxLength >= 0,
@@ -597,7 +596,7 @@ public class ArrayTools {
* @return 重复后的数组
*/
public static int[] repeat(int[] arr, int times, int maxLength) {
checkArgumentNotNull(arr);
checkArgument(Objects.nonNull(arr));
checkArgument(times >= 0,
"The number of times must be greater than or equal to zero");
checkArgument(maxLength >= 0,
@@ -632,7 +631,7 @@ public class ArrayTools {
* @return 重复后的数组
*/
public static long[] repeat(long[] arr, int times, int maxLength) {
checkArgumentNotNull(arr);
checkArgument(Objects.nonNull(arr));
checkArgument(times >= 0,
"The number of times must be greater than or equal to zero");
checkArgument(maxLength >= 0,
@@ -667,7 +666,7 @@ public class ArrayTools {
* @return 重复后的数组
*/
public static float[] repeat(float[] arr, int times, int maxLength) {
checkArgumentNotNull(arr);
checkArgument(Objects.nonNull(arr));
checkArgument(times >= 0,
"The number of times must be greater than or equal to zero");
checkArgument(maxLength >= 0,
@@ -702,7 +701,7 @@ public class ArrayTools {
* @return 重复后的数组
*/
public static double[] repeat(double[] arr, int times, int maxLength) {
checkArgumentNotNull(arr);
checkArgument(Objects.nonNull(arr));
checkArgument(times >= 0,
"The number of times must be greater than or equal to zero");
checkArgument(maxLength >= 0,
@@ -751,7 +750,7 @@ public class ArrayTools {
* @param values 填充内容
*/
public static void fill(char[] a, int fromIndex, int toIndex, @Nullable char[] values) {
checkArgumentNotNull(a);
checkArgument(Objects.nonNull(a));
if (values == null || values.length == 0) {
return;
}
@@ -794,7 +793,7 @@ public class ArrayTools {
* @param values 填充内容
*/
public static void fill(byte[] a, int fromIndex, int toIndex, @Nullable byte[] values) {
checkArgumentNotNull(a);
checkArgument(Objects.nonNull(a));
if (values == null || values.length == 0) {
return;
}
@@ -837,7 +836,7 @@ public class ArrayTools {
* @param values 填充内容
*/
public static void fill(short[] a, int fromIndex, int toIndex, @Nullable short[] values) {
checkArgumentNotNull(a);
checkArgument(Objects.nonNull(a));
if (values == null || values.length == 0) {
return;
}
@@ -880,7 +879,7 @@ public class ArrayTools {
* @param values 填充内容
*/
public static void fill(int[] a, int fromIndex, int toIndex, @Nullable int[] values) {
checkArgumentNotNull(a);
checkArgument(Objects.nonNull(a));
if (values == null || values.length == 0) {
return;
}
@@ -923,7 +922,7 @@ public class ArrayTools {
* @param values 填充内容
*/
public static void fill(long[] a, int fromIndex, int toIndex, @Nullable long[] values) {
checkArgumentNotNull(a);
checkArgument(Objects.nonNull(a));
if (values == null || values.length == 0) {
return;
}
@@ -966,7 +965,7 @@ public class ArrayTools {
* @param values 填充内容
*/
public static void fill(float[] a, int fromIndex, int toIndex, @Nullable float[] values) {
checkArgumentNotNull(a);
checkArgument(Objects.nonNull(a));
if (values == null || values.length == 0) {
return;
}
@@ -1009,7 +1008,7 @@ public class ArrayTools {
* @param values 填充内容
*/
public static void fill(double[] a, int fromIndex, int toIndex, @Nullable double[] values) {
checkArgumentNotNull(a);
checkArgument(Objects.nonNull(a));
if (values == null || values.length == 0) {
return;
}
@@ -1064,7 +1063,7 @@ public class ArrayTools {
* @param values 填充内容
*/
private static <T> void fillInternal(T[] a, int fromIndex, int toIndex, @Nullable T[] values) {
checkArgumentNotNull(a);
checkArgument(Objects.nonNull(a));
if (values == null || values.length == 0) {
return;
}

View File

@@ -54,9 +54,7 @@ public class AssertTools {
* @throws IllegalArgumentException 当条件不满足时抛出
*/
public static void checkArgument(boolean condition) {
if (!condition) {
throw new IllegalArgumentException();
}
checkCondition(condition, IllegalArgumentException::new);
}
/**
@@ -67,9 +65,7 @@ public class AssertTools {
* @throws IllegalArgumentException 当条件不满足时抛出
*/
public static void checkArgument(boolean condition, @Nullable String errorMessage) {
if (!condition) {
throw new IllegalArgumentException(errorMessage);
}
checkCondition(condition, () -> new IllegalArgumentException(errorMessage));
}
/**
@@ -80,9 +76,7 @@ public class AssertTools {
* @throws IllegalArgumentException 当条件不满足时抛出
*/
public static void checkArgument(boolean condition, Supplier<String> errorMessageSupplier) {
if (!condition) {
throw new IllegalArgumentException(errorMessageSupplier.get());
}
checkCondition(condition, () -> new IllegalArgumentException(errorMessageSupplier.get()));
}
/**
@@ -95,9 +89,8 @@ public class AssertTools {
*/
public static void checkArgument(boolean condition,
String errorMessageTemplate, Object... errorMessageArgs) {
if (!condition) {
throw new IllegalArgumentException(String.format(errorMessageTemplate, errorMessageArgs));
}
checkCondition(condition,
() -> new IllegalArgumentException(String.format(errorMessageTemplate, errorMessageArgs)));
}
// ================================
@@ -116,9 +109,7 @@ public class AssertTools {
* @throws IllegalArgumentException 当 {@code obj} 为 {@code null} 时抛出
*/
public static <T> T checkArgumentNotNull(@Nullable T obj) {
if (obj == null) {
throw new IllegalArgumentException();
}
checkCondition(obj != null, IllegalArgumentException::new);
return obj;
}
@@ -131,9 +122,7 @@ public class AssertTools {
* @throws IllegalArgumentException 当 {@code obj} 为 {@code null} 时抛出
*/
public static <T> T checkArgumentNotNull(@Nullable T obj, String errorMessage) {
if (obj == null) {
throw new IllegalArgumentException(errorMessage);
}
checkCondition(obj != null, () -> new IllegalArgumentException(errorMessage));
return obj;
}
@@ -146,9 +135,7 @@ public class AssertTools {
* @throws IllegalArgumentException 当 {@code obj} 为 {@code null} 时抛出
*/
public static <T> T checkArgumentNotNull(@Nullable T obj, Supplier<String> errorMessageSupplier) {
if (obj == null) {
throw new IllegalArgumentException(errorMessageSupplier.get());
}
checkCondition(obj != null, () -> new IllegalArgumentException(errorMessageSupplier.get()));
return obj;
}
@@ -163,9 +150,8 @@ public class AssertTools {
*/
public static <T> T checkArgumentNotNull(@Nullable T obj,
String errorMessageTemplate, Object... errorMessageArgs) {
if (obj == null) {
throw new IllegalArgumentException(String.format(errorMessageTemplate, errorMessageArgs));
}
checkCondition(obj != null,
() -> new IllegalArgumentException(String.format(errorMessageTemplate, errorMessageArgs)));
return obj;
}
@@ -184,9 +170,7 @@ public class AssertTools {
* @throws IllegalStateException 当条件不满足时抛出
*/
public static void checkState(boolean condition) {
if (!condition) {
throw new IllegalStateException();
}
checkCondition(condition, IllegalStateException::new);
}
/**
@@ -197,9 +181,7 @@ public class AssertTools {
* @throws IllegalStateException 当条件不满足时抛出
*/
public static void checkState(boolean condition, @Nullable String errorMessage) {
if (!condition) {
throw new IllegalStateException(errorMessage);
}
checkCondition(condition, () -> new IllegalStateException(errorMessage));
}
/**
@@ -210,9 +192,7 @@ public class AssertTools {
* @throws IllegalStateException 当条件不满足时抛出
*/
public static void checkState(boolean condition, Supplier<String> errorMessageSupplier) {
if (!condition) {
throw new IllegalStateException(errorMessageSupplier.get());
}
checkCondition(condition, () -> new IllegalStateException(errorMessageSupplier.get()));
}
/**
@@ -225,9 +205,8 @@ public class AssertTools {
*/
public static void checkState(boolean condition,
String errorMessageTemplate, Object... errorMessageArgs) {
if (!condition) {
throw new IllegalStateException(String.format(errorMessageTemplate, errorMessageArgs));
}
checkCondition(condition,
() -> new IllegalStateException(String.format(errorMessageTemplate, errorMessageArgs)));
}
// ================================
@@ -246,9 +225,7 @@ public class AssertTools {
* @throws NullPointerException 当 {@code obj} 为 {@code null} 时抛出
*/
public static <T> void checkNotNull(@Nullable T obj) {
if (obj == null) {
throw new NullPointerException();
}
checkCondition(obj != null, NullPointerException::new);
}
/**
@@ -260,9 +237,7 @@ public class AssertTools {
* @throws NullPointerException 当 {@code obj} 为 {@code null} 时抛出
*/
public static <T> void checkNotNull(@Nullable T obj, String errorMessage) {
if (obj == null) {
throw new NullPointerException(errorMessage);
}
checkCondition(obj != null, () -> new NullPointerException(errorMessage));
}
/**
@@ -274,9 +249,7 @@ public class AssertTools {
* @throws NullPointerException 当 {@code obj} 为 {@code null} 时抛出
*/
public static <T> void checkNotNull(@Nullable T obj, Supplier<String> errorMessageSupplier) {
if (obj == null) {
throw new NullPointerException(errorMessageSupplier.get());
}
checkCondition(obj != null, () -> new NullPointerException(errorMessageSupplier.get()));
}
/**
@@ -290,9 +263,8 @@ public class AssertTools {
*/
public static <T> void checkNotNull(@Nullable T obj,
String errorMessageTemplate, Object... errorMessageArgs) {
if (obj == null) {
throw new NullPointerException(String.format(errorMessageTemplate, errorMessageArgs));
}
checkCondition(obj != null,
() -> new NullPointerException(String.format(errorMessageTemplate, errorMessageArgs)));
}
// ================================
@@ -313,9 +285,7 @@ public class AssertTools {
*/
public static <T> T checkExists(@Nullable T obj)
throws DataNotExistsException {
if (obj == null) {
throw new DataNotExistsException();
}
checkCondition(obj != null, DataNotExistsException::new);
return obj;
}
@@ -330,9 +300,7 @@ public class AssertTools {
*/
public static <T> T checkExists(@Nullable T obj, String errorMessage)
throws DataNotExistsException {
if (obj == null) {
throw new DataNotExistsException(errorMessage);
}
checkCondition(obj != null, () -> new DataNotExistsException(errorMessage));
return obj;
}
@@ -347,9 +315,7 @@ public class AssertTools {
*/
public static <T> T checkExists(@Nullable T obj, Supplier<String> errorMessageSupplier)
throws DataNotExistsException {
if (obj == null) {
throw new DataNotExistsException(errorMessageSupplier.get());
}
checkCondition(obj != null, () -> new DataNotExistsException(errorMessageSupplier.get()));
return obj;
}
@@ -366,9 +332,8 @@ public class AssertTools {
public static <T> T checkExists(@Nullable T obj,
String errorMessageTemplate, Object... errorMessageArgs)
throws DataNotExistsException {
if (obj == null) {
throw new DataNotExistsException(String.format(errorMessageTemplate, errorMessageArgs));
}
checkCondition(obj != null,
() -> new DataNotExistsException(String.format(errorMessageTemplate, errorMessageArgs)));
return obj;
}
@@ -382,9 +347,7 @@ public class AssertTools {
*/
public static <T> T checkExists(Optional<T> optional)
throws DataNotExistsException {
if (!optional.isPresent()) {
throw new DataNotExistsException();
}
checkCondition(optional.isPresent(), DataNotExistsException::new);
return optional.get();
}
@@ -399,9 +362,7 @@ public class AssertTools {
*/
public static <T> T checkExists(Optional<T> optional, String errorMessage)
throws DataNotExistsException {
if (!optional.isPresent()) {
throw new DataNotExistsException(errorMessage);
}
checkCondition(optional.isPresent(), () -> new DataNotExistsException(errorMessage));
return optional.get();
}
@@ -416,9 +377,7 @@ public class AssertTools {
*/
public static <T> T checkExists(Optional<T> optional, Supplier<String> errorMessageSupplier)
throws DataNotExistsException {
if (!optional.isPresent()) {
throw new DataNotExistsException(errorMessageSupplier.get());
}
checkCondition(optional.isPresent(), () -> new DataNotExistsException(errorMessageSupplier.get()));
return optional.get();
}
@@ -435,9 +394,8 @@ public class AssertTools {
public static <T> T checkExists(Optional<T> optional,
String errorMessageTemplate, Object... errorMessageArgs)
throws DataNotExistsException {
if (!optional.isPresent()) {
throw new DataNotExistsException(String.format(errorMessageTemplate, errorMessageArgs));
}
checkCondition(optional.isPresent(),
() -> new DataNotExistsException(String.format(errorMessageTemplate, errorMessageArgs)));
return optional.get();
}

View File

@@ -17,10 +17,10 @@
package xyz.zhouxy.plusone.commons.util;
import static xyz.zhouxy.plusone.commons.util.AssertTools.checkArgument;
import static xyz.zhouxy.plusone.commons.util.AssertTools.checkArgumentNotNull;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
@@ -69,20 +69,20 @@ public final class RandomTools {
* @return 随机字符串
*/
public static String randomStr(Random random, char[] sourceCharacters, int length) {
checkArgumentNotNull(random, "Random cannot be null.");
checkArgumentNotNull(sourceCharacters, "Source characters cannot be null.");
checkArgument(Objects.nonNull(random), "Random cannot be null.");
checkArgument(Objects.nonNull(sourceCharacters), "Source characters cannot be null.");
checkArgument(length >= 0, "The length should be greater than or equal to zero.");
return randomStrInternal(random, sourceCharacters, length);
}
public static String randomStr(char[] sourceCharacters, int length) {
checkArgumentNotNull(sourceCharacters, "Source characters cannot be null.");
checkArgument(Objects.nonNull(sourceCharacters), "Source characters cannot be null.");
checkArgument(length >= 0, "The length should be greater than or equal to zero.");
return randomStrInternal(ThreadLocalRandom.current(), sourceCharacters, length);
}
public static String secureRandomStr(char[] sourceCharacters, int length) {
checkArgumentNotNull(sourceCharacters, "Source characters cannot be null.");
checkArgument(Objects.nonNull(sourceCharacters), "Source characters cannot be null.");
checkArgument(length >= 0, "The length should be greater than or equal to zero.");
return randomStrInternal(DEFAULT_SECURE_RANDOM, sourceCharacters, length);
}
@@ -98,20 +98,20 @@ public final class RandomTools {
* @return 随机字符串
*/
public static String randomStr(Random random, String sourceCharacters, int length) {
checkArgumentNotNull(random, "Random cannot be null.");
checkArgumentNotNull(sourceCharacters, "Source characters cannot be null.");
checkArgument(Objects.nonNull(random), "Random cannot be null.");
checkArgument(Objects.nonNull(sourceCharacters), "Source characters cannot be null.");
checkArgument(length >= 0, "The length should be greater than or equal to zero.");
return randomStrInternal(random, sourceCharacters, length);
}
public static String randomStr(String sourceCharacters, int length) {
checkArgumentNotNull(sourceCharacters, "Source characters cannot be null.");
checkArgument(Objects.nonNull(sourceCharacters), "Source characters cannot be null.");
checkArgument(length >= 0, "The length should be greater than or equal to zero.");
return randomStrInternal(ThreadLocalRandom.current(), sourceCharacters, length);
}
public static String secureRandomStr(String sourceCharacters, int length) {
checkArgumentNotNull(sourceCharacters, "Source characters cannot be null.");
checkArgument(Objects.nonNull(sourceCharacters), "Source characters cannot be null.");
checkArgument(length >= 0, "The length should be greater than or equal to zero.");
return randomStrInternal(DEFAULT_SECURE_RANDOM, sourceCharacters, length);
}

View File

@@ -17,10 +17,10 @@
package xyz.zhouxy.plusone.commons.util;
import static xyz.zhouxy.plusone.commons.util.AssertTools.checkArgument;
import static xyz.zhouxy.plusone.commons.util.AssertTools.checkArgumentNotNull;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Objects;
import javax.annotation.Nullable;
@@ -112,7 +112,7 @@ public class StringTools {
* @return 结果
*/
public static String repeat(final String str, int times, int maxLength) {
checkArgumentNotNull(str);
checkArgument(Objects.nonNull(str));
return String.valueOf(ArrayTools.repeat(str.toCharArray(), times, maxLength));
}

View File

@@ -1,108 +0,0 @@
/*
* Copyright 2025 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 xyz.zhouxy.plusone.commons.util.AssertTools.checkArgument;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterOutputStream;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
/**
* zip 工具类
*
* <p>
* 提供最基础的数据压缩/解压方法
*
* @author ZhouXY108 <luquanlion@outlook.com>
*
* @see Deflater
* @see Inflater
*/
public class ZipTools {
/**
* 使用默认压缩级别压缩数据
*
* @param input 输入
* @param level 压缩级别
* @return 压缩后的数据
*
* @throws IOException 发生 I/O 错误时抛出
*/
public static byte[] zip(@Nullable byte[] input) throws IOException {
return zipInternal(input, Deflater.DEFAULT_COMPRESSION);
}
/**
* 使用指定压缩级别压缩数据
*
* @param input 输入
* @param level 压缩级别
* @return 压缩后的数据
*
* @throws IOException 发生 I/O 错误时抛出
*/
public static byte[] zip(@Nullable byte[] input, int level) throws IOException {
checkArgument((level >= 0 && level <= 9) || level == Deflater.DEFAULT_COMPRESSION,
"invalid compression level");
return zipInternal(input, level);
}
@CheckForNull
private static byte[] zipInternal(@Nullable byte[] input, int level) throws IOException {
if (input == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (DeflaterOutputStream dos = new DeflaterOutputStream(baos, new Deflater(level))) {
dos.write(input);
dos.finish();
return baos.toByteArray();
}
}
/**
* 解压数据
*
* @param input 输入
* @return 解压后的数据
*
* @throws IOException 发生 I/O 错误时抛出
*/
@CheckForNull
public static byte[] unzip(@Nullable byte[] input) throws IOException {
if (input == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (InflaterOutputStream dos = new InflaterOutputStream(baos, new Inflater())) {
dos.write(input);
dos.finish();
return baos.toByteArray();
}
}
private ZipTools() {
throw new IllegalStateException("Utility class");
}
}

View File

@@ -1,86 +0,0 @@
package xyz.zhouxy.plusone.commons.util;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.util.Arrays;
import java.util.Random;
import java.util.zip.DataFormatException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import com.google.common.base.Stopwatch;
import com.google.common.io.Resources;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ZipToolsTests {
static byte[] bytes;
@BeforeAll
static void setup() throws IOException {
URL resource = Resources.getResource("xyz/zhouxy/plusone/commons/util/LoremIpsum.txt");
bytes = Resources.toByteArray(resource);
}
@Test
void zip_WithDefaultLevel() throws IOException, DataFormatException {
Stopwatch stopwatch = Stopwatch.createStarted();
byte[] zip = ZipTools.zip(bytes);
stopwatch.stop();
log.info("default level, size: {} ({})", zip.length, stopwatch);
assertArrayEquals(bytes, ZipTools.unzip(zip));
assertNull(ZipTools.zip(null));
assertNull(ZipTools.unzip(null));
}
@ParameterizedTest
@ValueSource(ints = { -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 })
void zip_WithLevel(int level) throws IOException, DataFormatException {
Stopwatch stopwatch = Stopwatch.createStarted();
byte[] zip = ZipTools.zip(bytes, level);
stopwatch.stop();
log.info("level: {}, size: {} ({})", level, zip.length, stopwatch);
assertArrayEquals(bytes, ZipTools.unzip(zip));
assertNull(ZipTools.zip(null, level));
assertNull(ZipTools.unzip(null));
}
@Test
void zip_WithWrongLevel() throws IOException, DataFormatException {
Random random = new Random();
final int levelGtMax = random.nextInt() + 9;
assertThrows(IllegalArgumentException.class, () -> ZipTools.zip(bytes, levelGtMax));
final int levelLtMin = -1 - random.nextInt();
assertThrows(IllegalArgumentException.class, () -> ZipTools.zip(bytes, levelLtMin));
}
@Test
void test_constructor_isNotAccessible_ThrowsIllegalStateException() {
Constructor<?>[] constructors = ZipTools.class.getDeclaredConstructors();
Arrays.stream(constructors)
.forEach(constructor -> {
assertFalse(constructor.isAccessible());
constructor.setAccessible(true);
Throwable cause = assertThrows(Exception.class, constructor::newInstance)
.getCause();
assertInstanceOf(IllegalStateException.class, cause);
assertEquals("Utility class", cause.getMessage());
});
}
}