diff --git a/README.md b/README.md index 59f02e8..dc7c8d0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,23 @@ + # uid.tools +[![License](http://img.shields.io/:license-apache-blue.svg)](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 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 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 src = Arrays.asList(1, 2, null, "q", "w", ""); + + StringHelper.joinTo(builder, ",", src.iterator(), "E", "N"); + assertEquals("1,2,N,q,w,E", builder.toString()); builder.setLength(0); + + StringHelper.joinTo(builder, ",", src.iterator(), "E", ""); + assertEquals("1,2,,q,w,E", builder.toString()); builder.setLength(0); + + StringHelper.joinTo(builder, ",", src.iterator(), "E", null); + assertEquals("1,2,q,w,E", builder.toString()); builder.setLength(0); + + StringHelper.joinTo(builder, ",", src.iterator(), "", "N"); + assertEquals("1,2,N,q,w,", builder.toString()); builder.setLength(0); + + StringHelper.joinTo(builder, ",", src.iterator(), null, "N"); + assertEquals("1,2,N,q,w", builder.toString()); builder.setLength(0); + } + + @Test + void testJoinToBuilderWithEmpty() throws IOException { + StringBuilder builder = new StringBuilder(); + Iterable src = Arrays.asList(1, 2, null, "q", "w", ""); + + StringHelper.joinTo(builder, ",", src.iterator(), "-"); + assertEquals("1,2,-,q,w,-", builder.toString()); builder.setLength(0); + + StringHelper.joinTo(builder, ",", src.iterator(), ""); + assertEquals("1,2,,q,w,", builder.toString()); builder.setLength(0); + + StringHelper.joinTo(builder, ",", src.iterator(), null); + assertEquals("1,2,q,w", builder.toString()); builder.setLength(0); + } + + @Test + void testJoinToBuilder() throws IOException { + StringBuilder builder = new StringBuilder(); + StringHelper.joinTo(builder, ",", Arrays.asList(1, 2, null, "q", "w", "").iterator()); + assertEquals("1,2,,q,w,", builder.toString()); builder.setLength(0); + } + + @Test + void testJoinItemsToBuilder() throws IOException { + StringBuilder builder = new StringBuilder(); + StringHelper.joinItemsTo(builder, ",", 1, 2, null, "q", "w", ""); + assertEquals("1,2,,q,w,", builder.toString()); builder.setLength(0); + } + + @Test + void testJoinWithEmptyAndNull() { + Iterable src = Arrays.asList(1, 2, null, "q", "w", ""); + assertEquals("1,2,N,q,w,E", StringHelper.join(",", src.iterator(), "E", "N").toString()); + assertEquals("1,2,,q,w,E", StringHelper.join(",", src.iterator(), "E", "").toString()); + assertEquals("1,2,q,w,E", StringHelper.join(",", src.iterator(), "E", null).toString()); + assertEquals("1,2,N,q,w,", StringHelper.join(",", src.iterator(), "", "N").toString()); + assertEquals("1,2,N,q,w", StringHelper.join(",", src.iterator(), null, "N").toString()); + } + + @Test + void testJoinWithEmpty() throws IOException { + Iterable src = Arrays.asList(1, 2, null, "q", "w", ""); + assertEquals("1,2,-,q,w,-", StringHelper.join(",", src.iterator(), "-").toString()); + assertEquals("1,2,,q,w,", StringHelper.join(",", src.iterator(), "").toString()); + assertEquals("1,2,q,w", StringHelper.join(",", src.iterator(), null).toString()); + } + + @Test + void testJoin() throws IOException { + Iterable src = Arrays.asList(1, 2, null, "q", "w", ""); + assertEquals("1,2,,q,w,", StringHelper.join(",", src.iterator()).toString()); + } + + @Test + void testJoinItems() throws IOException { + assertEquals("1,2,,q,w,", StringHelper.joinItems(",", 1, 2, null, "q", "w", "").toString()); + } + + @Test + void testIsAscii() { + for(int i = 0; i < 128; ++i) + assertTrue(StringHelper.isAscii(i)); + for(int i = 7; i < 32; ++i) + assertFalse(StringHelper.isAscii(1 + (1 << i))); + assertFalse(StringHelper.isAscii(0xffffffff)); + } + + @Test + void testisAsciiUpper() { + for(int i = 0; i < 'A'; ++i) + assertFalse(StringHelper.isAsciiUpper(i)); + for(int i = 'A'; i <= 'Z'; ++i) + assertTrue(StringHelper.isAsciiUpper(i)); + for(int i = 'Z' + 1; i <= 128; ++i) + assertFalse(StringHelper.isAsciiUpper(i)); + for(int i = 7; i < 32; ++i) + assertFalse(StringHelper.isAsciiUpper(1 + (1 << i))); + assertFalse(StringHelper.isAsciiUpper(0xffffffff)); + } + + @Test + void testIsAsciiLower() { + for(int i = 0; i < 'a'; ++i) + assertFalse(StringHelper.isAsciiLower(i)); + for(int i = 'a'; i <= 'z'; ++i) + assertTrue(StringHelper.isAsciiLower(i)); + for(int i = 'z' + 1; i <= 128; ++i) + assertFalse(StringHelper.isAsciiLower(i)); + for(int i = 7; i < 32; ++i) + assertFalse(StringHelper.isAsciiLower(1 + (1 << i))); + assertFalse(StringHelper.isAsciiLower(0xffffffff)); + } + + @Test + void testIsAsciiDigit() { + for(int i = 0; i < '0'; ++i) + assertFalse(StringHelper.isAsciiDigit(i)); + for(int i = '0'; i <= '9'; ++i) + assertTrue(StringHelper.isAsciiDigit(i)); + for(int i = '9' + 1; i <= 128; ++i) + assertFalse(StringHelper.isAsciiDigit(i)); + for(int i = 7; i < 32; ++i) + assertFalse(StringHelper.isAsciiDigit(1 + (1 << i))); + assertFalse(StringHelper.isAsciiDigit(0xffffffff)); + } + + @Test + void testIsBlank() { + assertTrue(StringHelper.isBlank(null)); + assertTrue(StringHelper.isBlank("")); + assertTrue(StringHelper.isBlank(" \t\r\n\u005Ct")); + assertFalse(StringHelper.isBlank("a")); + assertFalse(StringHelper.isBlank(" \t\r\n\u005Ctq")); + assertFalse(StringHelper.isBlank(" \t\r\n\0x2F81A")); + } + + @Test + void testLength() { + assertEquals(0, StringHelper.length(null)); + assertEquals(0, StringHelper.length("")); + assertEquals(3, StringHelper.length("123")); + } + + @Test + void testToCodePoints() { + assertNull(StringHelper.toCodePoints(null)); + assertEquals(0, StringHelper.toCodePoints("").length); + String src = "Пří視客øĥäΘい파ป็م♛"; + int[] codes = {1055, 345, 237, 35222, 23458, 248, 293, 228, 920, 12356, 54028, 3611, 3655, 1605, 9819}; + // String dst = new String(codes, 0, codes.length); + assertArrayEquals(codes, StringHelper.toCodePoints(src)); + } }