diff --git a/README.md b/README.md
index 59f02e8..dc7c8d0 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,23 @@
+
# uid.tools
+[](http://www.apache.org/licenses/LICENSE-2.0.html)
+
pom.xml:
1. in repositories section:
@@ -15,5 +32,5 @@
ua.net.uid
uid.tools
- 1.0.0
+ 1.0.2
diff --git a/pom.xml b/pom.xml
index 4a494b5..5e60fa6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,4 +1,20 @@
+
4.0.0
ua.net.uid
diff --git a/pom.xml.releaseBackup b/pom.xml.releaseBackup
deleted file mode 100644
index 39a14c5..0000000
--- a/pom.xml.releaseBackup
+++ /dev/null
@@ -1,116 +0,0 @@
-
-
- 4.0.0
- ua.net.uid
- uid.tools
- 1.0.1-SNAPSHOT
- jar
-
-
-
- ASL
- http://www.apache.org/licenses/LICENSE-2.0.txt
- repo
-
-
-
-
-
- org.junit.jupiter
- junit-jupiter-engine
- 5.5.1
- test
-
-
-
- com.h2database
- h2
- [1.4.193, 1.5.0)
- test
-
-
-
-
-
-
- .
-
- LICENSE
- NOTICE.txt
- RELEASE.txt
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.8.0
-
- 1.8
- 1.8
- true
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- 2.22.2
-
-
- maven-failsafe-plugin
- 2.22.2
-
-
- org.apache.maven.plugins
- maven-release-plugin
- 2.5.3
-
- true
- @{project.version}
-
- false
-
-
-
-
-
-
- UTF-8
- 1.8
- 1.8
- uid-releases
-
-
-
-
- ua.net.uid-releases
- https://git.uid.net.ua/maven/releases/
-
-
- ua.net.uid-snapshots
- https://git.uid.net.ua/maven/snapshots/
-
-
-
-
- scm:git:https://git.uid.net.ua/git/uid/uid.tools.git
- scm:git:https://git.uid.net.ua/git/uid/uid.tools.git
- https://git.uid.net.ua/git/uid/uid.tools.git
- HEAD
-
-
-
-
- uid-releases
- Release repository
- https://git.uid.net.ua/maven/releases/
-
-
- uid-snapshots
- Snapshots repository
- https://git.uid.net.ua/maven/snapshots/
-
-
-
\ No newline at end of file
diff --git a/release.properties b/release.properties
deleted file mode 100644
index dd20bf4..0000000
--- a/release.properties
+++ /dev/null
@@ -1,20 +0,0 @@
-#release configuration
-#Fri Sep 27 18:54:45 EEST 2019
-scm.commentPrefix=[maven-release-plugin]
-project.scm.ua.net.uid\:uid.tools.tag=HEAD
-pushChanges=true
-project.dev.ua.net.uid\:uid.tools=1.0.2-SNAPSHOT
-project.scm.ua.net.uid\:uid.tools.url=https\://git.uid.net.ua/git/uid/uid.tools.git
-scm.tag=1.0.1
-remoteTagging=true
-projectVersionPolicyId=default
-scm.id=uid-releases
-scm.url=scm\:git\:https\://git.uid.net.ua/git/uid/uid.tools.git
-scm.tagNameFormat=@{project.version}
-preparationGoals=clean verify
-project.scm.ua.net.uid\:uid.tools.developerConnection=scm\:git\:https\://git.uid.net.ua/git/uid/uid.tools.git
-exec.snapshotReleasePluginAllowed=false
-project.scm.ua.net.uid\:uid.tools.connection=scm\:git\:https\://git.uid.net.ua/git/uid/uid.tools.git
-project.scm.ua.net.uid\:uid.tools.id=uid-releases
-completedPhase=end-release
-project.rel.ua.net.uid\:uid.tools=1.0.1
diff --git a/src/main/java/ua/net/uid/utils/helpers/Cast.java b/src/main/java/ua/net/uid/utils/helpers/Cast.java
index f646a9e..e62b3a9 100644
--- a/src/main/java/ua/net/uid/utils/helpers/Cast.java
+++ b/src/main/java/ua/net/uid/utils/helpers/Cast.java
@@ -139,4 +139,8 @@
public static > T toEnum(Class enumType, String value, T defaults) {
return EnumHelper.valueOf(enumType, value, defaults);
}
+
+ public static > T toEnumIgnoreCase(Class enumType, String value, T defaults) {
+ return EnumHelper.valueOfIgnoreCase(enumType, value, defaults);
+ }
}
diff --git a/src/main/java/ua/net/uid/utils/helpers/CharsetHelper.java b/src/main/java/ua/net/uid/utils/helpers/CharsetHelper.java
new file mode 100644
index 0000000..5a7b62d
--- /dev/null
+++ b/src/main/java/ua/net/uid/utils/helpers/CharsetHelper.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 nightfall.
+ *
+ * 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
+ *
+ * http://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 ua.net.uid.utils.helpers;
+
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+
+public class CharsetHelper {
+ private CharsetHelper() {}
+
+ public static boolean isSupported(String charset) {
+ if (charset != null) {
+ try {
+ return Charset.isSupported(charset);
+ } catch (IllegalCharsetNameException ex) {}
+ }
+ return false;
+ }
+
+ public static Charset toCharset(String charsetName) {
+ return charsetName == null ? Charset.defaultCharset() : Charset.forName(charsetName);
+ }
+
+ public static String toCharsetName(String charsetName) {
+ return toCharset(charsetName).name();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ua/net/uid/utils/helpers/CommonHelper.java b/src/main/java/ua/net/uid/utils/helpers/CommonHelper.java
index efd07d8..8a5f816 100644
--- a/src/main/java/ua/net/uid/utils/helpers/CommonHelper.java
+++ b/src/main/java/ua/net/uid/utils/helpers/CommonHelper.java
@@ -15,8 +15,10 @@
*/
package ua.net.uid.utils.helpers;
+import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -54,6 +56,76 @@
return array == null || array.length == 0;
}
+ public static boolean isEmpty(Object object) {
+ if (object == null) return true;
+ if (object instanceof CharSequence) return ((CharSequence) object).length() == 0;
+ if (object.getClass().isArray()) return Array.getLength(object) == 0;
+ if (object instanceof Collection>) return ((Collection>) object).isEmpty();
+ if (object instanceof Map, ?>) return ((Map, ?>) object).isEmpty();
+ return false;
+ }
+
+ @SafeVarargs
+ public static T coalesce(T ... items) {
+ if (!isEmpty(items)) {
+ for (T item : items)
+ if (item != null)
+ return item;
+ }
+ return null;
+ }
+
+ public static > int compare(T v1, T v2, boolean nullGreater) {
+ if (v1 == v2) return 0;
+ if (v1 == null) return nullGreater ? 1 : -1;
+ if (v2 == null) return nullGreater ? -1 : 1;
+ return v1.compareTo(v2);
+ }
+
+ @SafeVarargs
+ public static > T min(T ... items) {
+ T result = null;
+ if (!isEmpty(items)) {
+ for (T item : items)
+ if (compare(item, result, true) < 0)
+ result = item;
+ }
+ return result;
+ }
+
+ @SafeVarargs
+ public static > T max(T ... items) {
+ T result = null;
+ if (!isEmpty(items)) {
+ for (T item : items)
+ if (compare(item, result, false) > 0)
+ result = item;
+ }
+ return result;
+ }
+
+ @SafeVarargs
+ public static T minBy(Comparator super T> comparator, T ... items) {
+ T result = null;
+ if (!isEmpty(items)) {
+ for (T item : items)
+ if (comparator.compare(result, item) > 0)
+ result = item;
+ }
+ return result;
+ }
+
+ @SafeVarargs
+ public static T maxBy(Comparator super T> comparator, T ... items) {
+ T result = null;
+ if (!isEmpty(items)) {
+ for (T item : items)
+ if (comparator.compare(result, item) < 0)
+ result = item;
+ }
+ return result;
+ }
+
@SafeVarargs
public static Set setOf(T ... items) {
if (!isEmpty(items)) {
diff --git a/src/main/java/ua/net/uid/utils/helpers/EnumHelper.java b/src/main/java/ua/net/uid/utils/helpers/EnumHelper.java
index 2735fd1..805340b 100644
--- a/src/main/java/ua/net/uid/utils/helpers/EnumHelper.java
+++ b/src/main/java/ua/net/uid/utils/helpers/EnumHelper.java
@@ -33,10 +33,22 @@
}
}
+ public static > T valueOfIgnoreCase(Class enumType, String value, T defValue) {
+ if (value == null) return defValue;
+ for (T item : enumType.getEnumConstants())
+ if (item.name().equalsIgnoreCase(value))
+ return item;
+ return defValue;
+ }
+
public static > T valueOf(Class enumType, String value) {
return valueOf(enumType, value, null);
}
+ public static > T valueOfIgnoreCase(Class enumType, String value) {
+ return valueOfIgnoreCase(enumType, value, null);
+ }
+
public static > List toList(final Class enumType) {
return Arrays.asList(enumType.getEnumConstants());
}
diff --git a/src/main/java/ua/net/uid/utils/helpers/IOHelper.java b/src/main/java/ua/net/uid/utils/helpers/IOHelper.java
new file mode 100644
index 0000000..86acd26
--- /dev/null
+++ b/src/main/java/ua/net/uid/utils/helpers/IOHelper.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2019 nightfall.
+ *
+ * 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
+ *
+ * http://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 ua.net.uid.utils.helpers;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+
+public class IOHelper {
+ public static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
+
+ public static long copy(InputStream input, OutputStream output, byte[] buffer) throws IOException {
+ long result = 0;
+ int readed;
+ while ((readed = input.read(buffer)) != -1) {
+ output.write(buffer, 0, readed);
+ result += readed;
+ }
+ return result;
+ }
+
+ public static long copy(InputStream input, OutputStream output, int buffer) throws IOException {
+ return copy(input, output, new byte[buffer]);
+ }
+
+ public static long copy(InputStream input, OutputStream output) throws IOException {
+ return copy(input, output, DEFAULT_BUFFER_SIZE);
+ }
+
+ public static long copy(Reader reader, Writer writer, char[] buffer) throws IOException {
+ long result = 0;
+ int readed;
+ while ((readed = reader.read(buffer)) != -1) {
+ writer.write(buffer, 0, readed);
+ result += readed;
+ }
+ return result;
+ }
+
+ public static long copy(Reader reader, Writer writer, int buffer) throws IOException {
+ return copy(reader, writer, new char[buffer]);
+ }
+
+ public static long copy(Reader reader, Writer writer) throws IOException {
+ return copy(reader, writer, DEFAULT_BUFFER_SIZE);
+ }
+
+ public static byte[] toByteArray(final InputStream input, byte[] buffer) throws IOException {
+ try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
+ copy(input, output, buffer);
+ return output.toByteArray();
+ }
+ }
+
+ public static byte[] toByteArray(final InputStream input, int buffer) throws IOException {
+ return toByteArray(input, new byte[buffer]);
+ }
+
+ public static byte[] toByteArray(final InputStream input) throws IOException {
+ return toByteArray(input, DEFAULT_BUFFER_SIZE);
+ }
+
+ public static BufferedInputStream buffered(InputStream input) {
+ if (input == null) return null;
+ return input instanceof BufferedInputStream ? (BufferedInputStream) input : new BufferedInputStream(input);
+ }
+
+ public static BufferedOutputStream buffered(OutputStream output) {
+ if (output == null) return null;
+ return output instanceof BufferedOutputStream ? (BufferedOutputStream) output : new BufferedOutputStream(output);
+ }
+
+ public static BufferedReader buffered(Reader reader) {
+ return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
+ }
+
+ public static BufferedWriter buffered(Writer writer) {
+ return writer instanceof BufferedWriter ? (BufferedWriter) writer : new BufferedWriter(writer);
+ }
+
+ private IOHelper() {}
+}
\ No newline at end of file
diff --git a/src/main/java/ua/net/uid/utils/helpers/NumberHelper.java b/src/main/java/ua/net/uid/utils/helpers/NumberHelper.java
index e8224aa..93137f6 100644
--- a/src/main/java/ua/net/uid/utils/helpers/NumberHelper.java
+++ b/src/main/java/ua/net/uid/utils/helpers/NumberHelper.java
@@ -15,8 +15,9 @@
*/
package ua.net.uid.utils.helpers;
-public class NumberHelper {
+import java.text.ParsePosition;
+public class NumberHelper {
private NumberHelper() {
}
@@ -38,13 +39,452 @@
return result;
}
+ public static Number smallest(long value) {
+ if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) return (byte)value;
+ if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) return (short)value;
+ if (value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE) return (int)value;
+ return value;
+ }
- /*public static Number parse(CharSequence source, ParsePosition position) {
+ public static Number parse(CharSequence source, ParsePosition position) {
int offset = StringHelper.skipWhitespace(source, position.getIndex());
- if (offset < source.length()) {
-
+ int length = source.length();
+ if (offset < length) {
+ char chr = source.charAt(offset);
+ if (chr == '0') {
+ return nextZeroDigit(source, position, offset + 1, length);
+ } else if (chr > '0' && chr <= '9') {
+ return nextDigit(chr, source, position, offset + 1, length);
+ } else if (chr == '.'){
+ return nextDot(source, position, offset + 1, length);
+ }
+
}
position.setErrorIndex(offset);
return null;
- }*/
+ }
+
+ public static Number parse(CharSequence source) {
+ return parse(source, new ParsePosition(0));
+ }
+
+ public static byte min(byte ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ byte first = items[0];
+ if (first > Byte.MIN_VALUE) {
+ final int length = items.length;
+ for(int i = 1; i < length; ++i) {
+ final byte other = items[i];
+ if (other == Byte.MIN_VALUE) return other;
+ if (other < first) first = other;
+ }
+ }
+ return first;
+ }
+
+ public static byte max(byte ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ byte first = items[0];
+ if (first < Byte.MAX_VALUE) {
+ final int length = items.length;
+ for(int i = 1; i < length; ++i) {
+ final byte other = items[i];
+ if (other == Byte.MAX_VALUE) return other;
+ if (other > first) first = other;
+ }
+ }
+ return first;
+ }
+
+ public static short min(short ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ short first = items[0];
+ if (first > Short.MIN_VALUE) {
+ final int length = items.length;
+ for(int i = 1; i < length; ++i) {
+ final short other = items[i];
+ if (other == Short.MIN_VALUE) return other;
+ if (other < first) first = other;
+ }
+ }
+ return first;
+ }
+
+ public static short max(short ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ short first = items[0];
+ if (first < Short.MAX_VALUE) {
+ final int length = items.length;
+ for(int i = 1; i < length; ++i) {
+ final short other = items[i];
+ if (other == Short.MAX_VALUE) return other;
+ if (other > first) first = other;
+ }
+ }
+ return first;
+ }
+
+ public static int min(int ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ int first = items[0];
+ if (first > Integer.MIN_VALUE) {
+ final int length = items.length;
+ for(int i = 1; i < length; ++i) {
+ final int other = items[i];
+ if (other == Integer.MIN_VALUE) return other;
+ if (other < first) first = other;
+ }
+ }
+ return first;
+ }
+
+ public static int max(int ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ int first = items[0];
+ if (first < Integer.MAX_VALUE) {
+ final int length = items.length;
+ for(int i = 1; i < length; ++i) {
+ final int other = items[i];
+ if (other == Integer.MAX_VALUE) return other;
+ if (other > first) first = other;
+ }
+ }
+ return first;
+ }
+
+ public static long min(long ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ long first = items[0];
+ if (first > Long.MIN_VALUE) {
+ final int length = items.length;
+ for(int i = 1; i < length; ++i) {
+ final long other = items[i];
+ if (other == Long.MIN_VALUE) return other;
+ if (other < first) first = other;
+ }
+ }
+ return first;
+ }
+
+ public static long max(long ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ long first = items[0];
+ if (first < Long.MAX_VALUE) {
+ final int length = items.length;
+ for(int i = 1; i < length; ++i) {
+ final long other = items[i];
+ if (other == Long.MAX_VALUE) return other;
+ if (other > first) first = other;
+ }
+ }
+ return first;
+ }
+
+ public static float min(float ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ float first = items[0];
+ if (first == first && Float.NEGATIVE_INFINITY != first) {
+ final int length = items.length;
+ for(int i = 1; i < length; ++i) {
+ final float other = items[i];
+ if (other != other || Float.NEGATIVE_INFINITY == other) return other;
+ if (other < first) first = other;
+ }
+ }
+ return first;
+ }
+
+ public static float max(float ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ final int length = items.length;
+ int i = 1;
+ float first = items[0];
+ while (first != first && i < length) first = items[++i]; // first not nan
+ if (first != Float.POSITIVE_INFINITY) {
+ for(; i < length; ++i) {
+ final float other = items[i];
+ if (other == Float.POSITIVE_INFINITY) return other;
+ if (other == other && other > first) first = other;
+ }
+ }
+ return first;
+ }
+
+ public static double min(double ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ double first = items[0];
+ if (first == first && Float.NEGATIVE_INFINITY != first) {
+ final int length = items.length;
+ for(int i = 1; i < length; ++i) {
+ final double other = items[i];
+ if (other != other || Double.NEGATIVE_INFINITY == other) return other;
+ if (other < first) first = other;
+ }
+ }
+ return first;
+ }
+
+ public static double max(double ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ final int length = items.length;
+ int i = 1;
+ double first = items[0];
+ while (first != first && i < length) first = items[++i];
+ if (first != Double.POSITIVE_INFINITY) {
+ for(; i < length; ++i) {
+ final double other = items[i];
+ if (other == Double.POSITIVE_INFINITY) return other;
+ if (other == other && other > first) first = other;
+ }
+ }
+ return first;
+ }
+
+ @SafeVarargs
+ public static > T min(T ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ final int length = items.length;
+ T first = items[0];
+ for(int i = 1; i < length; ++i) {
+ final T other = items[i];
+ if (other != null && other.compareTo(first) < 0)
+ first = other;
+ }
+ return first;
+ }
+
+ @SafeVarargs
+ public static > T max(T ... items) {
+ if (items == null || items.length == 0)
+ throw new IllegalArgumentException("the arguments array must not be null or empty");
+ final int length = items.length;
+ T first = items[0];
+ for(int i = 1; i < length; ++i) {
+ final T other = items[i];
+ if (other != null && other.compareTo(first) > 0)
+ first = other;
+ }
+ return first;
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////////
+ private static Number nextZeroDigit(CharSequence source, ParsePosition position, int end, int length) {
+ if (end < source.length()) {
+ char chr = source.charAt(end);
+ switch (chr) {
+ case 'x': case 'X':
+ return nextHexNumeric(source, position, end, length);
+ case 'b': case 'B':
+ return nextBinNumeric(source, position, end, length);
+ default:
+ long value = 0;
+ while (chr >= '0' && chr <= '7') {
+ value = (value << 3) | (chr - '0');
+ ++end;
+ if (end < length) {
+ chr = source.charAt(end);
+ } else {
+ break;
+ }
+ }
+ position.setIndex(end);
+ return smallest(value);
+ }
+ }
+ position.setIndex(end);
+ return (byte)0;
+ }
+
+ private static Number nextHexNumeric(CharSequence source, ParsePosition position, int end, int length) {
+ boolean real = false;
+ long main = 0;
+ int base = 0;
+ if (++end < length) {
+ do {
+ char chr = source.charAt(end);
+ if (chr >= '0' && chr <= '9') {
+ main = (main << 4) | (chr - '0');
+ } else if (chr >= 'A' && chr <= 'F') {
+ main = (main << 4) | (chr - 'A' + 10);
+ } else if (chr >= 'a' && chr <= 'f') {
+ main = (main << 4) | (chr - 'a' + 10);
+ } else if (!real && chr == '.') {
+ real = true;
+ continue;
+ } else {
+ if (chr == 'p' || chr == 'P') {
+ if (++end == length) {
+ position.setErrorIndex(end);
+ return null;
+ }
+ int sig = 1;
+ chr = source.charAt(end);
+ switch (chr) {
+ case '-':
+ sig = -1;
+ case '+':
+ if (++end == length) {
+ position.setErrorIndex(end);
+ return null;
+ }
+ chr = source.charAt(end);
+ }
+ if (chr < '0' || chr > '9') {
+ position.setErrorIndex(end);
+ return null;
+ }
+ int pow = chr - '0';
+ while (++end < length) {
+ chr = source.charAt(end);
+ if (chr < '0' || chr > '9') break;
+ pow = (pow * 10) + chr - '0';
+ }
+ base += (sig * pow);
+ real = true;
+ }
+ break;
+ }
+ if (real) base -= 4;
+ } while (++end < length);
+ position.setIndex(end);
+ if (real) {
+ if (main > 0 && (main & -2L) == main) {
+ do {
+ main >>>= 1;
+ ++base;
+ } while ((main & -2L) == main);
+ }
+ return (double)main * Math.pow(2, base);
+ } else {
+ return smallest(main);
+ }
+ }
+ position.setErrorIndex(end);
+ return null;
+ }
+
+ private static Number nextBinNumeric(CharSequence source, ParsePosition position, int end, int length) {
+ if (++end < length) {
+ char chr = source.charAt(end++);
+ if (chr == '0' || chr == '1') {
+ long value = chr - '0';
+ while (end < length) {
+ chr = source.charAt(end);
+ if (chr == '0' || chr == '1') {
+ value = (value << 1) | (chr - '0');
+ } else {
+ break;
+ }
+ ++end;
+ }
+ position.setIndex(end);
+ return smallest(value);
+ }
+ }
+ position.setErrorIndex(end);
+ return null;
+ }
+
+ private static Number nextDigit(char chr, CharSequence source, ParsePosition position, int end, int length) {
+ long main = chr - '0';
+ boolean real = false;
+ int base = 0;
+ while (end < length) {
+ chr = source.charAt(end);
+ if (chr >= '0' && chr <= '9') {
+ main = (main * 10) + (chr - '0');
+ ++end;
+ if (real) --base;
+ } else if (!real && chr == '.') {
+ real = true;
+ ++end;
+ } else if (chr == 'e' || chr == 'E') {
+ return nextDecExp(main, base, source, position, end, length);
+ } else {
+ break;
+ }
+ }
+ position.setIndex(end);
+ if (real) {
+ return (double)main * Math.pow(10, base);
+ } else {
+ return smallest(main);
+ }
+ }
+
+ private static Number nextDecExp(long main, int base, CharSequence source, ParsePosition position, int end, int length) {
+ int sig = 1;
+ if (++end == length) {
+ position.setErrorIndex(end);
+ return null;
+ }
+ char chr = source.charAt(end);
+ switch (chr) {
+ case '-':
+ sig = -1;
+ case '+':
+ if (++end == length) {
+ position.setErrorIndex(end);
+ return null;
+ }
+ chr = source.charAt(end);
+ }
+ if (chr >= '0' && chr <= '9') {
+ int pow = chr - '0';
+ while (++end < length) {
+ chr = source.charAt(end);
+ if (chr >= '0' && chr <= '9') {
+ pow = (pow * 10) + (chr - '0');
+ } else {
+ break;
+ }
+ }
+ position.setIndex(end);
+ return (double)main * Math.pow(10, (sig * pow) + base);
+ } else {
+ ++end;
+ position.setErrorIndex(end);
+ return null;
+ }
+ }
+
+ private static Number nextDot(CharSequence source, ParsePosition position, int end, int length) {
+ if (end < length) {
+ char chr = source.charAt(end);
+ if (chr >= '0' && chr <= '9') {
+ long main = chr - '0';
+ int base = -1;
+ while (++end < length) {
+ chr = source.charAt(end);
+ if (chr >= '0' && chr <= '9') {
+ main = (main * 10) + (chr - '0');
+ --base;
+ } else if (chr == 'e' || chr == 'E') {
+ return nextDecExp(main, base, source, position, end, length);
+ } else {
+ break;
+ }
+ }
+ position.setIndex(end);
+ return (double)main * Math.pow(10, base);
+ }
+ }
+ position.setIndex(end);
+ return null;
+ }
+
}
diff --git a/src/main/java/ua/net/uid/utils/helpers/StringHelper.java b/src/main/java/ua/net/uid/utils/helpers/StringHelper.java
index 2b9e512..1b9dbd1 100644
--- a/src/main/java/ua/net/uid/utils/helpers/StringHelper.java
+++ b/src/main/java/ua/net/uid/utils/helpers/StringHelper.java
@@ -18,6 +18,8 @@
import java.io.IOException;
import java.util.Iterator;
+import ua.net.uid.utils.iterators.ArrayIterator;
+
public class StringHelper {
private static final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
@@ -46,24 +48,12 @@
for (int e = start; e < end; ++e) {
char chr = string.charAt(e);
switch (chr) {
- case '"':
- case '\\':
- break;
- case '\t':
- chr = 't';
- break;
- case '\b':
- chr = 'b';
- break;
- case '\n':
- chr = 'n';
- break;
- case '\r':
- chr = 'r';
- break;
- case '\f':
- chr = 'f';
- break;
+ case '"': case '\\': break;
+ case '\t': chr = 't'; break;
+ case '\b': chr = 'b'; break;
+ case '\n': chr = 'n'; break;
+ case '\r': chr = 'r'; break;
+ case '\f': chr = 'f'; break;
default:
if (chr < 32) {
if (start < e) builder.append(string, start, e);
@@ -103,24 +93,12 @@
if (start < end) builder.append(string, start, end);
chr = string.charAt(++end);
switch (chr) {
- case '"':
- case '\\':
- break;
- case 't':
- chr = '\t';
- break;
- case 'b':
- chr = '\b';
- break;
- case 'n':
- chr = '\n';
- break;
- case 'r':
- chr = '\r';
- break;
- case 'f':
- chr = '\f';
- break;
+ case '"': case '\\': break;
+ case 't': chr = '\t'; break;
+ case 'b': chr = '\b'; break;
+ case 'n': chr = '\n'; break;
+ case 'r': chr = '\r'; break;
+ case 'f': chr = '\f'; break;
case 'u':
chr = 0;
for (int i = 1; i <= 4; ++i) {
@@ -183,42 +161,57 @@
return offset;
}
- public static void join(Appendable builder, CharSequence div, Iterator> iterator) throws IOException {
- join(builder, div, iterator, true, true);
- }
-
- public static void join(Appendable builder, CharSequence div, Iterator> iterator, boolean skipEmpty) throws IOException {
- join(builder, div, iterator, skipEmpty, skipEmpty);
- }
-
- public static void join(Appendable builder, CharSequence div, Iterator> iterator, boolean skipEmpty, boolean skipNull) throws IOException {
+ public static void joinTo(Appendable builder, CharSequence separator, Iterator> iterator, CharSequence emptyAs, CharSequence nullAs) throws IOException {
boolean first = true;
while (iterator.hasNext()) {
Object item = iterator.next();
- if (!skipNull || item != null) {
- String str = String.valueOf(item);
- if (!(skipEmpty && CommonHelper.isEmpty(str))) {
- if (first) first = false; else builder.append(div);
- builder.append(item.toString());
+ if (item == null) {
+ if (nullAs != null) {
+ if (first) first = false; else builder.append(separator);
+ builder.append(nullAs);
}
+ } else if (CommonHelper.isEmpty(item)) {
+ if (emptyAs != null) {
+ if (first) first = false; else builder.append(separator);
+ builder.append(emptyAs);
+ }
+ } else {
+ if (first) first = false; else builder.append(separator);
+ builder.append(item.toString());
}
}
}
- public static CharSequence join(CharSequence div, Iterator> iterator) {
- return join(div, iterator, true, true);
+ public static void joinTo(Appendable builder, CharSequence separator, Iterator> iterator, CharSequence emptyAs) throws IOException {
+ joinTo(builder, separator, iterator, emptyAs, emptyAs);
}
- public static CharSequence join(CharSequence div, Iterator> iterator, boolean skipEmpty) {
- return join(div, iterator, skipEmpty, skipEmpty);
+ public static void joinTo(Appendable builder, CharSequence separator, Iterator> iterator) throws IOException {
+ joinTo(builder, separator, iterator, "", "");
}
- public static CharSequence join(CharSequence div, Iterator> iterator, boolean skipEmpty, boolean skipNull) {
+ public static void joinItemsTo(Appendable builder, CharSequence separator, Object ... items) throws IOException {
+ joinTo(builder, separator, new ArrayIterator<>(items), "", "");
+ }
+
+ public static CharSequence join(CharSequence separator, Iterator> iterator, CharSequence emptyAs, CharSequence nullAs) {
StringBuilder builder = new StringBuilder();
- try { join(builder, div, iterator, skipEmpty, skipNull); } catch (IOException ignore) {}
+ try { joinTo(builder, separator, iterator, emptyAs, nullAs); } catch (IOException ignore) {}
return builder;
}
+ public static CharSequence join(CharSequence separator, Iterator> iterator, CharSequence emptyAs) {
+ return join(separator, iterator, emptyAs, emptyAs);
+ }
+
+ public static CharSequence join(CharSequence separator, Iterator> iterator) {
+ return join(separator, iterator, "", "");
+ }
+
+ public static CharSequence joinItems(CharSequence separator, Object ... items) {
+ return join(separator, new ArrayIterator<>(items), "", "");
+ }
+
public static boolean isAscii(int chr) {
return ((chr & 0xFFFFFF80) == 0);
}
@@ -234,4 +227,32 @@
public static boolean isAsciiDigit(int chr) {
return chr >= '0' && chr <= '9';
}
+
+ public static boolean isBlank(CharSequence str) {
+ if (!CommonHelper.isEmpty(str)) {
+ final int len = str.length();
+ for (int i = 0; i < len; ++i) {
+ char chr = str.charAt(i);
+ if ((Character.isHighSurrogate(chr) && !Character.isWhitespace(Character.toCodePoint(chr, str.charAt(++i)))) || !Character.isWhitespace(chr))
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static int length(CharSequence str) {
+ return str == null ? 0 : str.length();
+ }
+
+ public static int[] toCodePoints(String str) {
+ if (str == null) return null;
+ int length = str.codePointCount(0, str.length());
+ int[] result = new int[length];
+ for (int i = 0, j = 0; i < length; ++i) {
+ int chr = str.codePointAt(j);
+ j += Character.charCount(chr);
+ result[i] = chr;
+ }
+ return result;
+ }
}
diff --git a/src/main/java/ua/net/uid/utils/time/DailyEquation.java b/src/main/java/ua/net/uid/utils/time/DailyEquation.java
index 4b31cdb..5bbcd95 100644
--- a/src/main/java/ua/net/uid/utils/time/DailyEquation.java
+++ b/src/main/java/ua/net/uid/utils/time/DailyEquation.java
@@ -20,8 +20,6 @@
*
* https://www.aa.quae.nl/en/reken/zonpositie.html
*
- * TODO: переделать под java.time
- *
* @author nightfall
*/
public class DailyEquation {
@@ -86,7 +84,8 @@
// UT = T - lngHour
return localMeanTime - baseLongitudeHour;
}
-
+
+ private static final int DAYMSEC = 24 * 60 * 60 * 1000;
protected static long convertDate(Calendar calendar, double utcTime) {
// localT = UT + localOffset
int time = (int)(utcTime * 3600000) + calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
@@ -101,5 +100,5 @@
return calendar.getTimeInMillis();
}
- private static final int DAYMSEC = 24 * 60 * 60 * 1000;
+ private DailyEquation() {}
}
diff --git a/src/main/java/ua/net/uid/utils/time/DailyEvents.java b/src/main/java/ua/net/uid/utils/time/DailyEvents.java
index a88e146..e75ba4e 100644
--- a/src/main/java/ua/net/uid/utils/time/DailyEvents.java
+++ b/src/main/java/ua/net/uid/utils/time/DailyEvents.java
@@ -1,5 +1,7 @@
package ua.net.uid.utils.time;
+import java.util.Objects;
+
public class DailyEvents {
private final Long sunrise;
private final Long sunset;
@@ -22,4 +24,21 @@
public DailyEventType getType() {
return type;
}
+
+ public boolean equals(DailyEvents other) {
+ return other == this || (other != null
+ && Objects.equals(sunrise, other.sunrise)
+ && Objects.equals(sunset, other.sunset)
+ && Objects.equals(type, other.type));
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(sunrise, sunset, type) ^ getClass().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other instanceof DailyEvents && equals((DailyEvents) other);
+ }
}
diff --git a/src/test/java/ua/net/uid/utils/helpers/CastTest.java b/src/test/java/ua/net/uid/utils/helpers/CastTest.java
index ff0a055..a76294e 100644
--- a/src/test/java/ua/net/uid/utils/helpers/CastTest.java
+++ b/src/test/java/ua/net/uid/utils/helpers/CastTest.java
@@ -164,8 +164,19 @@
assertEquals(TestEnum.zero, Cast.toEnum(TestEnum.class, "zero", TestEnum.one));
}
+ @Test
+ void testToEnumIgnoreCase() {
+ assertNull(Cast.toEnumIgnoreCase(TestEnum.class, null, null));
+ assertNull(Cast.toEnumIgnoreCase(TestEnum.class, "", null));
+ assertNull(Cast.toEnumIgnoreCase(TestEnum.class, "qwe", null));
+ assertEquals(TestEnum.three, Cast.toEnumIgnoreCase(TestEnum.class, null, TestEnum.three));
+ assertEquals(TestEnum.two, Cast.toEnumIgnoreCase(TestEnum.class, "", TestEnum.two));
+ assertEquals(TestEnum.one, Cast.toEnumIgnoreCase(TestEnum.class, "qwe", TestEnum.one));
+ assertEquals(TestEnum.zero, Cast.toEnumIgnoreCase(TestEnum.class, "zero", TestEnum.one));
+ assertEquals(TestEnum.one, Cast.toEnumIgnoreCase(TestEnum.class, "One", TestEnum.zero));
+ assertEquals(TestEnum.two, Cast.toEnumIgnoreCase(TestEnum.class, "tWo", TestEnum.zero));
+ assertEquals(TestEnum.three, Cast.toEnumIgnoreCase(TestEnum.class, "THREE", TestEnum.zero));
+ }
enum TestEnum {zero, one, two, three}
-
-
}
diff --git a/src/test/java/ua/net/uid/utils/helpers/CharsetHelperTest.java b/src/test/java/ua/net/uid/utils/helpers/CharsetHelperTest.java
new file mode 100644
index 0000000..5e98a44
--- /dev/null
+++ b/src/test/java/ua/net/uid/utils/helpers/CharsetHelperTest.java
@@ -0,0 +1,34 @@
+package ua.net.uid.utils.helpers;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.charset.UnsupportedCharsetException;
+
+class CharsetHelperTest {
+ @Test
+ void testIsSupported() {
+ assertFalse(CharsetHelper.isSupported(null));
+ assertFalse(CharsetHelper.isSupported(""));
+ assertFalse(CharsetHelper.isSupported("Unknown"));
+ assertTrue(CharsetHelper.isSupported("UTF-8"));
+ assertTrue(CharsetHelper.isSupported("UTF-16"));
+ }
+
+ @Test
+ void testToCharset() {
+ assertEquals(Charset.defaultCharset(), CharsetHelper.toCharset(null));
+ assertEquals(StandardCharsets.UTF_8, CharsetHelper.toCharset("UTF-8"));
+ assertThrows(UnsupportedCharsetException.class, () -> CharsetHelper.toCharset("Unknown"));
+ }
+
+ @Test
+ void testToCharsetName() {
+ assertEquals(Charset.defaultCharset().name(), CharsetHelper.toCharsetName(null));
+ assertEquals(StandardCharsets.UTF_8.name(), CharsetHelper.toCharsetName("UTF-8"));
+ assertThrows(UnsupportedCharsetException.class, () -> CharsetHelper.toCharsetName("Unknown"));
+ }
+}
diff --git a/src/test/java/ua/net/uid/utils/helpers/CommonHelperTest.java b/src/test/java/ua/net/uid/utils/helpers/CommonHelperTest.java
index 44db5fd..f5423c2 100644
--- a/src/test/java/ua/net/uid/utils/helpers/CommonHelperTest.java
+++ b/src/test/java/ua/net/uid/utils/helpers/CommonHelperTest.java
@@ -4,11 +4,18 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
+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.assertTrue;
class CommonHelperTest {
@@ -73,6 +80,85 @@
assertFalse(CommonHelper.isEmpty(src));
}
+ @Test
+ void testIsEmptyObject() {
+ assertTrue(CommonHelper.isEmpty((Object) null));
+ assertTrue(CommonHelper.isEmpty((Object) ""));
+ assertFalse(CommonHelper.isEmpty((Object) "0"));
+ assertTrue(CommonHelper.isEmpty((Object) new byte[] {}));
+ assertFalse(CommonHelper.isEmpty((Object) new int[] {1,2,3}));
+ assertTrue(CommonHelper.isEmpty((Object) Arrays.asList()));
+ assertFalse(CommonHelper.isEmpty((Object) Arrays.asList(1,2,3)));
+ assertTrue(CommonHelper.isEmpty((Object) Collections.emptyMap()));
+ Map map = new HashMap<>();
+ assertTrue(CommonHelper.isEmpty((Object) map));
+ map.put("q", 1);
+ assertFalse(CommonHelper.isEmpty((Object) map));
+ }
+
+ @Test
+ void testCoalesce() {
+ assertNull(CommonHelper.coalesce());
+ assertNull(CommonHelper.coalesce(null, null));
+ assertEquals(1, CommonHelper.coalesce(1, null, null));
+ assertEquals(2, CommonHelper.coalesce(null, 2, null));
+ assertEquals(3, CommonHelper.coalesce(null, null, 3));
+ assertEquals(1, CommonHelper.coalesce(1, null, 3));
+ }
+
+ @Test
+ void testCompareNullable() {
+ assertTrue(CommonHelper.compare(null, null, true) == 0);
+ assertTrue(CommonHelper.compare(null, null, false) == 0);
+ assertTrue(CommonHelper.compare(null, 1, false) < 0);
+ assertTrue(CommonHelper.compare(null, 1, true) > 0);
+ assertTrue(CommonHelper.compare(1, null, false) > 0);
+ assertTrue(CommonHelper.compare(1, null, true) < 0);
+ assertTrue(CommonHelper.compare(1, 1, false) == 0);
+ assertTrue(CommonHelper.compare(1, 1, true) == 0);
+ assertTrue(CommonHelper.compare(-1, 1, false) < 0);
+ assertTrue(CommonHelper.compare(-1, 1, true) < 0);
+ assertTrue(CommonHelper.compare(1, -1, false) > 0);
+ assertTrue(CommonHelper.compare(1, -1, true) > 0);
+ }
+
+ @Test
+ void testMinComparable() {
+ assertNull(CommonHelper.min());
+ assertNull(CommonHelper.min((Integer) null));
+ assertEquals(0, CommonHelper.min(null, 3, 1, 0, 2, 4, null));
+ }
+
+ @Test
+ void testMaxComparable() {
+ assertNull(CommonHelper.max());
+ assertNull(CommonHelper.max((Integer) null));
+ assertEquals(4, CommonHelper.max(null, 3, 1, 0, 2, 4, null));
+ }
+
+ @Test
+ void testMinByComparator() {
+ Comparator comparator = (a, b) -> CommonHelper.compare(a, b, true);
+ assertNull(CommonHelper.minBy(comparator));
+ assertNull(CommonHelper.minBy(comparator, (Integer) null));
+ assertEquals(0, CommonHelper.minBy(comparator, null, 3, 1, 0, 2, 4, null));
+ }
+
+ @Test
+ void testMaxByComparator() {
+ Comparator comparator = (a, b) -> CommonHelper.compare(a, b, false);
+ assertNull(CommonHelper.maxBy(comparator));
+ assertNull(CommonHelper.maxBy(comparator, (Integer) null));
+ assertEquals(4, CommonHelper.maxBy(comparator, null, 3, 1, 0, 2, 4, null));
+ }
+
+ @Test
+ void testSetOf() {
+ Set expected = new HashSet<>(Arrays.asList(3,1,5,7,3));
+ Set actual = CommonHelper.setOf(3,1,1,5,7,3,5);
+ assertEquals(expected, actual);
+ }
+
static class AutoCloseableImpl implements AutoCloseable {
boolean called = false;
diff --git a/src/test/java/ua/net/uid/utils/helpers/EnumHelperTest.java b/src/test/java/ua/net/uid/utils/helpers/EnumHelperTest.java
index daf02b7..a610878 100644
--- a/src/test/java/ua/net/uid/utils/helpers/EnumHelperTest.java
+++ b/src/test/java/ua/net/uid/utils/helpers/EnumHelperTest.java
@@ -17,6 +17,16 @@
}
@Test
+ void testStringToEnumIgnoreCaseWithDefault() {
+ assertNull(EnumHelper.valueOfIgnoreCase(Source.class, "Zero", null));
+ assertEquals(Source.four, EnumHelper.valueOfIgnoreCase(Source.class, "Zero", Source.four));
+ assertEquals(Source.one, EnumHelper.valueOfIgnoreCase(Source.class, "one", null));
+ assertEquals(Source.two, EnumHelper.valueOfIgnoreCase(Source.class, "Two", null));
+ assertEquals(Source.three, EnumHelper.valueOfIgnoreCase(Source.class, "thrEE", null));
+ assertEquals(Source.four, EnumHelper.valueOfIgnoreCase(Source.class, "FOUR", null));
+ }
+
+ @Test
void testStringToEnumDefaultNull() {
assertNull(EnumHelper.valueOf(Source.class, "zero"));
assertEquals(Source.two, EnumHelper.valueOf(Source.class, "two"));
@@ -24,7 +34,16 @@
}
@Test
- void toList() {
+ void testStringToEnumIgnoreCaseDefaultNull() {
+ assertNull(EnumHelper.valueOfIgnoreCase(Source.class, "Zero"));
+ assertEquals(Source.one, EnumHelper.valueOfIgnoreCase(Source.class, "one"));
+ assertEquals(Source.two, EnumHelper.valueOfIgnoreCase(Source.class, "Two"));
+ assertEquals(Source.three, EnumHelper.valueOfIgnoreCase(Source.class, "thrEE"));
+ assertEquals(Source.four, EnumHelper.valueOfIgnoreCase(Source.class, "FOUR"));
+ }
+
+ @Test
+ void testToList() {
assertEquals(
Arrays.asList(Source.one, Source.two, Source.three, Source.four, Source.five),
EnumHelper.toList(Source.class)
@@ -32,7 +51,7 @@
}
@Test
- void toMap() {
+ void testToMap() {
Map map = new HashMap<>();
map.put(Source.one.toString(), Source.one);
map.put(Source.two.toString(), Source.two);
diff --git a/src/test/java/ua/net/uid/utils/helpers/IOHelperTest.java b/src/test/java/ua/net/uid/utils/helpers/IOHelperTest.java
new file mode 100644
index 0000000..fe5d7dd
--- /dev/null
+++ b/src/test/java/ua/net/uid/utils/helpers/IOHelperTest.java
@@ -0,0 +1,251 @@
+package ua.net.uid.utils.helpers;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+
+public class IOHelperTest {
+ private static final byte[] dataEmpty = {};
+ private static final byte[] dataShort = RandomHelper.randomString(1024, 1024).getBytes(StandardCharsets.UTF_8);
+ private static final byte[] dataLong = RandomHelper.randomString(16 * 1024, 32 * 1024).getBytes(StandardCharsets.UTF_8);
+
+ @Test
+ void testCopyStreamWithBuffer() throws IOException {
+ byte[] buffer = new byte[2048];
+ try (InputStream input = new ByteArrayInputStream(dataEmpty)) {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ assertEquals(dataEmpty.length, IOHelper.copy(input, output, buffer));
+ assertArrayEquals(dataEmpty, output.toByteArray());
+ }
+ try (InputStream input = new ByteArrayInputStream(dataShort)) {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ assertEquals(dataShort.length, IOHelper.copy(input, output, buffer));
+ assertArrayEquals(dataShort, output.toByteArray());
+ }
+ try (InputStream input = new ByteArrayInputStream(dataLong)) {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ assertEquals(dataLong.length, IOHelper.copy(input, output, buffer));
+ assertArrayEquals(dataLong, output.toByteArray());
+ }
+ }
+
+ @Test
+ void testCopyStreamWithBufferSize() throws IOException {
+ try (InputStream input = new ByteArrayInputStream(dataEmpty)) {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ assertEquals(dataEmpty.length, IOHelper.copy(input, output, 4096));
+ assertArrayEquals(dataEmpty, output.toByteArray());
+ }
+ try (InputStream input = new ByteArrayInputStream(dataShort)) {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ assertEquals(dataShort.length, IOHelper.copy(input, output, 4096));
+ assertArrayEquals(dataShort, output.toByteArray());
+ }
+ try (InputStream input = new ByteArrayInputStream(dataLong)) {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ assertEquals(dataLong.length, IOHelper.copy(input, output, 4096));
+ assertArrayEquals(dataLong, output.toByteArray());
+ }
+ }
+
+ @Test
+ void testCopyStreamWithDefault() throws IOException {
+ try (InputStream input = new ByteArrayInputStream(dataEmpty)) {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ assertEquals(dataEmpty.length, IOHelper.copy(input, output));
+ assertArrayEquals(dataEmpty, output.toByteArray());
+ }
+ try (InputStream input = new ByteArrayInputStream(dataShort)) {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ assertEquals(dataShort.length, IOHelper.copy(input, output));
+ assertArrayEquals(dataShort, output.toByteArray());
+ }
+ try (InputStream input = new ByteArrayInputStream(dataLong)) {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ assertEquals(dataLong.length, IOHelper.copy(input, output));
+ assertArrayEquals(dataLong, output.toByteArray());
+ }
+ }
+
+ @Test
+ void testCopyReaderWithBuffer() throws IOException {
+ char[] buffer = new char[2048];
+ {
+ String source = new String(dataEmpty, StandardCharsets.UTF_8);
+ try (Reader reader = new StringReader(source)) {
+ StringWriter writer = new StringWriter();
+ assertEquals(source.length(), IOHelper.copy(reader, writer, buffer));
+ assertEquals(source, writer.toString());
+ }
+ }
+ {
+ String source = new String(dataShort, StandardCharsets.UTF_8);
+ try (Reader reader = new StringReader(source)) {
+ StringWriter writer = new StringWriter();
+ assertEquals(source.length(), IOHelper.copy(reader, writer, buffer));
+ assertEquals(source, writer.toString());
+ }
+ }
+ {
+ String source = new String(dataLong, StandardCharsets.UTF_8);
+ try (Reader reader = new StringReader(source)) {
+ StringWriter writer = new StringWriter();
+ assertEquals(source.length(), IOHelper.copy(reader, writer, buffer));
+ assertEquals(source, writer.toString());
+ }
+ }
+ }
+
+ @Test
+ void testCopyReaderWithBufferSize() throws IOException {
+ {
+ String source = new String(dataEmpty, StandardCharsets.UTF_8);
+ try (Reader reader = new StringReader(source)) {
+ StringWriter writer = new StringWriter();
+ assertEquals(source.length(), IOHelper.copy(reader, writer, 4000));
+ assertEquals(source, writer.toString());
+ }
+ }
+ {
+ String source = new String(dataShort, StandardCharsets.UTF_8);
+ try (Reader reader = new StringReader(source)) {
+ StringWriter writer = new StringWriter();
+ assertEquals(source.length(), IOHelper.copy(reader, writer, 4000));
+ assertEquals(source, writer.toString());
+ }
+ }
+ {
+ String source = new String(dataLong, StandardCharsets.UTF_8);
+ try (Reader reader = new StringReader(source)) {
+ StringWriter writer = new StringWriter();
+ assertEquals(source.length(), IOHelper.copy(reader, writer, 4000));
+ assertEquals(source, writer.toString());
+ }
+ }
+ }
+
+ @Test
+ void testCopyReaderWithDefault() throws IOException {
+ {
+ String source = new String(dataEmpty, StandardCharsets.UTF_8);
+ try (Reader reader = new StringReader(source)) {
+ StringWriter writer = new StringWriter();
+ assertEquals(source.length(), IOHelper.copy(reader, writer));
+ assertEquals(source, writer.toString());
+ }
+ }
+ {
+ String source = new String(dataShort, StandardCharsets.UTF_8);
+ try (Reader reader = new StringReader(source)) {
+ StringWriter writer = new StringWriter();
+ assertEquals(source.length(), IOHelper.copy(reader, writer));
+ assertEquals(source, writer.toString());
+ }
+ }
+ {
+ String source = new String(dataLong, StandardCharsets.UTF_8);
+ try (Reader reader = new StringReader(source)) {
+ StringWriter writer = new StringWriter();
+ assertEquals(source.length(), IOHelper.copy(reader, writer));
+ assertEquals(source, writer.toString());
+ }
+ }
+ }
+
+ @Test
+ void testToByteArrayWithBuffer() throws IOException {
+ assertArrayEquals(dataLong, IOHelper.toByteArray(new ByteArrayInputStream(dataLong), new byte[2048]));
+ }
+
+ @Test
+ void testToByteArrayWithBufferSize() throws IOException {
+ assertArrayEquals(dataLong, IOHelper.toByteArray(new ByteArrayInputStream(dataLong), 2048));
+ }
+
+ @Test
+ void testToByteArrayWithDefault() throws IOException {
+ assertArrayEquals(dataLong, IOHelper.toByteArray(new ByteArrayInputStream(dataLong)));
+ }
+
+ @Test
+ void testBufferedInput() {
+ InputStream src = null;
+ BufferedInputStream dst = null;
+
+ assertNull(IOHelper.buffered(src));
+
+ src = new ByteArrayInputStream(dataLong);
+ dst = IOHelper.buffered(src);
+ assertNotNull(dst);
+ assertNotSame(src, dst);
+
+ src = dst;
+ dst = IOHelper.buffered(src);
+ assertNotNull(dst);
+ assertSame(src, dst);
+ }
+
+ @Test
+ void testBufferedOutput() {
+ OutputStream src = null;
+ BufferedOutputStream dst = null;
+
+ assertNull(IOHelper.buffered(src));
+
+ src = new ByteArrayOutputStream();
+ dst = IOHelper.buffered(src);
+ assertNotNull(dst);
+ assertNotSame(src, dst);
+
+ src = dst;
+ dst = IOHelper.buffered(src);
+ assertNotNull(dst);
+ assertSame(src, dst);
+ }
+
+ @Test
+ void testBufferedReader() {
+ Reader src = null;
+ BufferedReader dst = null;
+
+ assertThrows(NullPointerException.class, () -> IOHelper.buffered((Reader) null));
+
+ src = new StringReader("");
+ dst = IOHelper.buffered(src);
+ assertNotSame(src, dst);
+
+ src = dst;
+ dst = IOHelper.buffered(src);
+ assertSame(src, dst);
+ }
+
+ @Test
+ void testBufferedWriter() {
+ Writer src = null;
+ BufferedWriter dst = null;
+
+ assertThrows(NullPointerException.class, () -> IOHelper.buffered((Writer) null));
+
+ src = new StringWriter();
+ dst = IOHelper.buffered(src);
+ assertNotSame(src, dst);
+
+ src = dst;
+ dst = IOHelper.buffered(src);
+ assertSame(src, dst);
+ }
+}
diff --git a/src/test/java/ua/net/uid/utils/helpers/NumberHelperTest.java b/src/test/java/ua/net/uid/utils/helpers/NumberHelperTest.java
index e68b59e..219b3f6 100644
--- a/src/test/java/ua/net/uid/utils/helpers/NumberHelperTest.java
+++ b/src/test/java/ua/net/uid/utils/helpers/NumberHelperTest.java
@@ -4,6 +4,10 @@
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.text.ParsePosition;
class NumberHelperTest {
private final long LONG_VALUE = 0x12345678a1b2c3d4L;
@@ -21,4 +25,317 @@
void testBytesToLong() {
assertEquals(LONG_VALUE, NumberHelper.bytesToLong(BYTE_ARRAY));
}
+
+ @Test
+ void testSmallest() {
+ Number val = NumberHelper.smallest(0);
+ assertEquals(Byte.class, val.getClass());
+ assertEquals(Byte.valueOf((byte)0), val);
+
+ val = NumberHelper.smallest(Byte.MAX_VALUE);
+ assertEquals(Byte.class, val.getClass());
+ assertEquals(Byte.valueOf(Byte.MAX_VALUE), val);
+ val = NumberHelper.smallest(Byte.MIN_VALUE);
+ assertEquals(Byte.class, val.getClass());
+ assertEquals(Byte.valueOf(Byte.MIN_VALUE), val);
+
+ val = NumberHelper.smallest(Byte.MAX_VALUE + 1);
+ assertEquals(Short.class, val.getClass());
+ assertEquals(Short.valueOf((short) (Byte.MAX_VALUE + 1)), val);
+ val = NumberHelper.smallest(Byte.MIN_VALUE - 1);
+ assertEquals(Short.class, val.getClass());
+ assertEquals(Short.valueOf((short) (Byte.MIN_VALUE - 1)), val);
+
+ val = NumberHelper.smallest(Short.MAX_VALUE);
+ assertEquals(Short.class, val.getClass());
+ assertEquals(Short.valueOf(Short.MAX_VALUE), val);
+ val = NumberHelper.smallest(Short.MIN_VALUE);
+ assertEquals(Short.class, val.getClass());
+ assertEquals(Short.valueOf(Short.MIN_VALUE), val);
+
+ val = NumberHelper.smallest(Short.MAX_VALUE + 1);
+ assertEquals(Integer.class, val.getClass());
+ assertEquals(Integer.valueOf((int) (Short.MAX_VALUE + 1)), val);
+ val = NumberHelper.smallest(Short.MIN_VALUE - 1);
+ assertEquals(Integer.class, val.getClass());
+ assertEquals(Integer.valueOf((int) (Short.MIN_VALUE - 1)), val);
+
+ val = NumberHelper.smallest(Integer.MAX_VALUE);
+ assertEquals(Integer.class, val.getClass());
+ assertEquals(Integer.valueOf(Integer.MAX_VALUE), val);
+ val = NumberHelper.smallest(Integer.MIN_VALUE);
+ assertEquals(Integer.class, val.getClass());
+ assertEquals(Integer.valueOf(Integer.MIN_VALUE), val);
+
+ val = NumberHelper.smallest((long)Integer.MAX_VALUE + 1);
+ assertEquals(Long.class, val.getClass());
+ assertEquals(Long.valueOf((long) Integer.MAX_VALUE + 1), val);
+ val = NumberHelper.smallest((long)Integer.MIN_VALUE - 1);
+ assertEquals(Long.class, val.getClass());
+ assertEquals(Long.valueOf((long) Integer.MIN_VALUE - 1), val);
+
+ val = NumberHelper.smallest(Long.MAX_VALUE);
+ assertEquals(Long.class, val.getClass());
+ assertEquals(Long.valueOf(Long.MAX_VALUE), val);
+ val = NumberHelper.smallest(Long.MIN_VALUE);
+ assertEquals(Long.class, val.getClass());
+ assertEquals(Long.valueOf(Long.MIN_VALUE), val);
+ }
+
+ @Test
+ void testParseHexDigit() {
+ ParsePosition position = new ParsePosition(0);
+ String source =
+ "0 0x0 0x7a 0x1f9c 0x00000ffffff 0x10000ffffff 0x0. 0x7.a 0x1f.9c 0x00000.ffffff 0x10000.ffffff "+
+ "0x0p0 0x1000P+256 0x1000P-256 0x1.fffffffffffffp1023 0x0.0000000000001P-1022 0x1.0P-1074 0x1.8p+1";
+
+ assertEquals((byte)0, NumberHelper.parse(source, position));
+ assertEquals(1, position.getIndex());
+
+ assertEquals((byte)0, NumberHelper.parse(source, position));
+ assertEquals(5, position.getIndex());
+
+ assertEquals((byte)0x7a, NumberHelper.parse(source, position));
+ assertEquals(10, position.getIndex());
+
+ assertEquals((short)0x1f9c, NumberHelper.parse(source, position));
+ assertEquals(17, position.getIndex());
+
+ assertEquals(0xffffff, NumberHelper.parse(source, position));
+ assertEquals(31, position.getIndex());
+
+ assertEquals(0x10000ffffffL, NumberHelper.parse(source, position));
+ assertEquals(45, position.getIndex());
+
+ assertEquals(0., NumberHelper.parse(source, position));
+ assertEquals(50, position.getIndex());
+
+ assertEquals(0x7.ap0, NumberHelper.parse(source, position));
+ assertEquals(56, position.getIndex());
+
+ assertEquals(0x1f.9cp0, NumberHelper.parse(source, position));
+ assertEquals(64, position.getIndex());
+
+ assertEquals(0x0.ffffffp0, NumberHelper.parse(source, position));
+ assertEquals(79, position.getIndex());
+
+ assertEquals(0x10000.ffffffp0, NumberHelper.parse(source, position));
+ assertEquals(94, position.getIndex());
+
+ assertEquals(0x0p0, NumberHelper.parse(source, position));
+ assertEquals(100, position.getIndex());
+
+ assertEquals(0x1000p256, NumberHelper.parse(source, position));
+ assertEquals(112, position.getIndex());
+
+ assertEquals(0x1000p-256, NumberHelper.parse(source, position));
+ assertEquals(124, position.getIndex());
+
+ assertEquals(0x1.fffffffffffffp1023, NumberHelper.parse(source, position));
+ assertEquals(147, position.getIndex());
+
+ assertEquals(0x0.0000000000001P-1022, NumberHelper.parse(source, position));
+ assertEquals(171, position.getIndex());
+
+ assertEquals(0x1P-1074, NumberHelper.parse(source, position));
+ assertEquals(183, position.getIndex());
+
+ assertEquals(3., NumberHelper.parse(source, position));
+ assertEquals(192, position.getIndex());
+
+ assertNull(NumberHelper.parse(source, position));
+ assertEquals(192, position.getIndex());
+ assertEquals(192, position.getErrorIndex());
+ }
+
+ @Test
+ public void testParseOctDigits() {
+ ParsePosition position = new ParsePosition(0);
+ String source = "0 01 077 06666 01234567 0123456701234567";
+
+ assertEquals((byte)0, NumberHelper.parse(source, position));
+ assertEquals(1, position.getIndex());
+
+ assertEquals((byte)01, NumberHelper.parse(source, position));
+ assertEquals(4, position.getIndex());
+
+ assertEquals((byte)077, NumberHelper.parse(source, position));
+ assertEquals(8, position.getIndex());
+
+ assertEquals((short)0_66_66, NumberHelper.parse(source, position));
+ assertEquals(14, position.getIndex());
+
+ assertEquals(01234567, NumberHelper.parse(source, position));
+ assertEquals(23, position.getIndex());
+
+ assertEquals(0123456701234567L, NumberHelper.parse(source, position));
+ assertEquals(40, position.getIndex());
+
+ assertNull(NumberHelper.parse(source, position));
+ assertEquals(40, position.getIndex());
+ assertEquals(40, position.getErrorIndex());
+ }
+ @Test
+ public void testParseBinDigits() {
+ ParsePosition position = new ParsePosition(0);
+ String source = "0b0 0b1 0b11111111 0b1111111111111111111111111111111111111111111111111111111111111111 0ba";
+
+ assertEquals((byte)0, NumberHelper.parse(source, position));
+ assertEquals(3, position.getIndex());
+
+ assertEquals((byte)1, NumberHelper.parse(source, position));
+ assertEquals(7, position.getIndex());
+
+ assertEquals((short)0b11111111, NumberHelper.parse(source, position));
+ assertEquals(18, position.getIndex());
+
+ assertEquals((byte)-1, NumberHelper.parse(source, position));
+ assertEquals(85, position.getIndex());
+
+ assertNull(NumberHelper.parse(source, position));
+ assertEquals(85, position.getIndex());
+ assertEquals(89, position.getErrorIndex());
+ }
+
+
+ @Test
+ public void testParseDigits() {
+ ParsePosition position = new ParsePosition(0);
+ String source = "1 333 70000 465729124123444 .01 77. 3.333 .1e-3 222.e76 123.456e-78 888e+8 ";
+
+ assertEquals((byte)1, NumberHelper.parse(source, position));
+ assertEquals(1, position.getIndex());
+
+ assertEquals((short)333, NumberHelper.parse(source, position));
+ assertEquals(5, position.getIndex());
+
+ assertEquals(70000, NumberHelper.parse(source, position));
+ assertEquals(11, position.getIndex());
+
+ assertEquals(465729124123444l, NumberHelper.parse(source, position));
+ assertEquals(27, position.getIndex());
+
+ assertEquals(.01, NumberHelper.parse(source, position));
+ assertEquals(31, position.getIndex());
+
+ assertEquals(77., NumberHelper.parse(source, position));
+ assertEquals(35, position.getIndex());
+
+ assertEquals(3.333, NumberHelper.parse(source, position));
+ assertEquals(41, position.getIndex());
+
+ assertEquals(.1e-3, NumberHelper.parse(source, position));
+ assertEquals(47, position.getIndex());
+
+ assertEquals(222.e76, NumberHelper.parse(source, position));
+ assertEquals(55, position.getIndex());
+
+ assertEquals(123.456e-78, NumberHelper.parse(source, position));
+ assertEquals(67, position.getIndex());
+
+ assertEquals(888e+8, NumberHelper.parse(source, position));
+ assertEquals(74, position.getIndex());
+
+ assertNull(NumberHelper.parse(source, position));
+ assertEquals(74, position.getIndex());
+ assertEquals(75, position.getErrorIndex());
+ }
+
+ @Test
+ void testMinOfBytes() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min((byte[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min(new byte[0]));
+ assertEquals((byte)-55, NumberHelper.min(new byte[] {1,85,-4,6,3,-55}) );
+ }
+
+ @Test
+ void testMaxOfBytes() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max((byte[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max(new byte[0]));
+ assertEquals((byte)85, NumberHelper.max(new byte[] {1,85,-4,6,3,-55}) );
+ }
+
+ @Test
+ void testMinOfShorts() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min((short[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min(new short[0]));
+ assertEquals((short)-55, NumberHelper.min(new short[] {1,85,-4,6,3,-55}) );
+ }
+
+ @Test
+ void testMaxOfShorts() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max((short[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max(new short[0]));
+ assertEquals((short)85, NumberHelper.max(new short[] {1,85,-4,6,3,-55}) );
+ }
+
+ @Test
+ void testMinOfInts() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min((int[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min(new int[0]));
+ assertEquals((int)-55, NumberHelper.min(new int[] {1,85,-4,6,3,-55}) );
+ }
+
+ @Test
+ void testMaxOfInts() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max((int[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max(new int[0]));
+ assertEquals((int)85, NumberHelper.max(new int[] {1,85,-4,6,3,-55}) );
+ }
+
+ @Test
+ void testMinOfLongs() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min((long[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min(new long[0]));
+ assertEquals((long)-55, NumberHelper.min(new long[] {1,85,-4,6,3,-55}) );
+ }
+
+ @Test
+ void testMaxOfLongs() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max((long[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max(new long[0]));
+ assertEquals((long)85, NumberHelper.max(new long[] {1,85,-4,6,3,-55}) );
+ }
+
+ @Test
+ void testMinOfFloats() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min((float[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min(new float[0]));
+ assertEquals(-55.1f, NumberHelper.min(new float[] {1.1f,85.2f,-4.3f,6.3f,3.2f,-55.1f}) );
+ }
+
+ @Test
+ void testMaxOfFloats() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max((float[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max(new float[0]));
+ assertEquals(85.2f, NumberHelper.max(new float[] {1.1f,85.2f,-4.3f,6.3f,3.2f,-55.1f}) );
+ }
+
+ @Test
+ void testMinOfDoubles() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min((double[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min(new double[0]));
+ assertEquals(-55.1, NumberHelper.min(new double[] {1.1,85.2,-4.3,6.3,3.2,-55.1}) );
+ }
+
+ @Test
+ void testMaxOfDoubles() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max((double[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max(new double[0]));
+ assertEquals(85.2, NumberHelper.max(new double[] {1.1,85.2,-4.3,6.3,3.2,-55.1}) );
+ }
+
+ @Test
+ void testMinOfNumbers() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min((Double[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.min(new Double[0]));
+ assertEquals(-55.1, NumberHelper.min(new Double[] {1.1,85.2,-4.3,6.3,3.2,-55.1}) );
+ }
+
+ @Test
+ void testMaxOfNumbers() {
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max((Double[])null));
+ assertThrows(IllegalArgumentException.class, () -> NumberHelper.max(new Double[0]));
+ assertEquals(85.2, NumberHelper.max(new Double[] {1.1,85.2,-4.3,6.3,3.2,-55.1}) );
+ }
}
diff --git a/src/test/java/ua/net/uid/utils/helpers/RandomHelperTest.java b/src/test/java/ua/net/uid/utils/helpers/RandomHelperTest.java
index 751878c..e370374 100644
--- a/src/test/java/ua/net/uid/utils/helpers/RandomHelperTest.java
+++ b/src/test/java/ua/net/uid/utils/helpers/RandomHelperTest.java
@@ -7,7 +7,7 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
-class RandomHelperTest { //TODO RandomHelperTest
+class RandomHelperTest {
RandomHelperTest() {
}
diff --git a/src/test/java/ua/net/uid/utils/helpers/StringHelperTest.java b/src/test/java/ua/net/uid/utils/helpers/StringHelperTest.java
index 4ac9e70..4880448 100644
--- a/src/test/java/ua/net/uid/utils/helpers/StringHelperTest.java
+++ b/src/test/java/ua/net/uid/utils/helpers/StringHelperTest.java
@@ -4,6 +4,9 @@
import static org.junit.jupiter.api.Assertions.*;
+import java.io.IOException;
+import java.util.Arrays;
+
@SuppressWarnings("SpellCheckingInspection")
class StringHelperTest {
@@ -99,4 +102,158 @@
assertEquals(15, StringHelper.skipWhitespace(src, 15));
assertEquals(src.length(), StringHelper.skipWhitespace(src, 18));
}
+
+ @Test
+ void testJoinToBuilderWithEmptyAndNull() throws IOException {
+ StringBuilder builder = new StringBuilder();
+ Iterable