From 12fd03748431de4d1ee219693883a9f104a7d150 Mon Sep 17 00:00:00 2001 From: Major- Date: Sun, 31 Jan 2016 11:52:28 +0000 Subject: [PATCH] Add unit tests for all utility classes --- .../org/apollo/game/scheduling/Scheduler.java | 4 +- .../main/org/apollo/util/CollectionUtil.java | 12 +-- .../main/org/apollo/util/EnumerationUtil.java | 48 --------- util/src/main/org/apollo/util/NameUtil.java | 100 +++++++++++------- util/src/main/org/apollo/util/StreamUtil.java | 37 ++++--- util/src/main/org/apollo/util/ThreadUtil.java | 18 ++-- .../test/org/apollo/util/BufferUtilTests.java | 52 ++++----- .../org/apollo/util/CollectionUtilTests.java | 28 +++++ .../org/apollo/util/CompressionUtilTests.java | 38 +++---- .../org/apollo/util/LanguageUtilTests.java | 7 +- .../test/org/apollo/util/NameUtilTests.java | 59 +++++++++++ .../test/org/apollo/util/StreamUtilTests.java | 52 +++++++++ .../test/org/apollo/util/ThreadUtilTests.java | 44 ++++++++ 13 files changed, 325 insertions(+), 174 deletions(-) delete mode 100644 util/src/main/org/apollo/util/EnumerationUtil.java create mode 100644 util/src/test/org/apollo/util/CollectionUtilTests.java create mode 100644 util/src/test/org/apollo/util/NameUtilTests.java create mode 100644 util/src/test/org/apollo/util/StreamUtilTests.java create mode 100644 util/src/test/org/apollo/util/ThreadUtilTests.java diff --git a/game/src/main/org/apollo/game/scheduling/Scheduler.java b/game/src/main/org/apollo/game/scheduling/Scheduler.java index b3302077..f8191394 100644 --- a/game/src/main/org/apollo/game/scheduling/Scheduler.java +++ b/game/src/main/org/apollo/game/scheduling/Scheduler.java @@ -1,13 +1,13 @@ package org.apollo.game.scheduling; +import org.apollo.util.CollectionUtil; + import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Queue; -import org.apollo.util.CollectionUtil; - /** * A class which manages {@link ScheduledTask}s. * diff --git a/util/src/main/org/apollo/util/CollectionUtil.java b/util/src/main/org/apollo/util/CollectionUtil.java index 39f1431e..cf116e4b 100644 --- a/util/src/main/org/apollo/util/CollectionUtil.java +++ b/util/src/main/org/apollo/util/CollectionUtil.java @@ -1,11 +1,11 @@ package org.apollo.util; +import com.google.common.base.Preconditions; + import java.util.Collection; import java.util.Queue; import java.util.function.Consumer; -import com.google.common.base.Preconditions; - /** * A utility class containing helper methods for various {@link Collection} objects. * @@ -14,11 +14,11 @@ import com.google.common.base.Preconditions; public final class CollectionUtil { /** - * Polls every element within the specified {@link Queue} and performs the specified {@link Consumer} event for each - * element. + * Polls every element within the specified {@link Queue} and performs the specified {@link Consumer} event for + * each element. * - * @param queue The Queue to poll each element for, may not be {@code null}. - * @param consumer The Consumer event to execute for each polled element, may not be {@code null}. + * @param queue The {@link Queue} to poll elements from. Must not be {@code null}. + * @param consumer The {@link Consumer} to execute for each polled element. Must not be {@code null}. */ public static void pollAll(Queue queue, Consumer consumer) { Preconditions.checkNotNull(queue, "Queue may not be null"); diff --git a/util/src/main/org/apollo/util/EnumerationUtil.java b/util/src/main/org/apollo/util/EnumerationUtil.java deleted file mode 100644 index 6c75b51c..00000000 --- a/util/src/main/org/apollo/util/EnumerationUtil.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.apollo.util; - -import java.util.Enumeration; -import java.util.Iterator; - -/** - * A utility class for wrapping old {@link Enumeration} objects inside an {@link Iterator} to allow for greater - * compatibility. - * - * @author Graham - */ -public final class EnumerationUtil { - - /** - * Returns an {@link Iterator} which wraps around the specified {@link Enumeration}. - * - * @param enumeration The {@link Enumeration}. - * @return An {@link Iterator}. - */ - public static Iterator asIterator(final Enumeration enumeration) { - return new Iterator() { - - @Override - public boolean hasNext() { - return enumeration.hasMoreElements(); - } - - @Override - public E next() { - return enumeration.nextElement(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException("Cannot remove an element using this wrapper."); - } - - }; - } - - /** - * Default private constructor to prevent instantiation by other classes. - */ - private EnumerationUtil() { - - } - -} \ No newline at end of file diff --git a/util/src/main/org/apollo/util/NameUtil.java b/util/src/main/org/apollo/util/NameUtil.java index 8056a0ed..f65362c2 100644 --- a/util/src/main/org/apollo/util/NameUtil.java +++ b/util/src/main/org/apollo/util/NameUtil.java @@ -1,65 +1,89 @@ package org.apollo.util; -import com.google.common.base.Preconditions; - /** - * A class which contains name-related utility methods. + * Contains name-related utility methods. * * @author Graham */ public final class NameUtil { /** - * An array of valid characters in a player name encoded as a long. + * The name with the minimum possible value. */ - private static final char[] NAME_CHARS = { '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '+', '=', ':', ';', '.', '>', '<', ',', - '"', '[', ']', '|', '?', '/', '`' }; + private static final long FIRST_VALID_NAME = encodeBase37(""); /** - * Converts a long to a player name. - * - * @param l The long. - * @return The player name. + * The name with the maximum possible value. */ - public static String decodeBase37(long l) { - int i = 0; - char[] chars = new char[12]; - while (l != 0L) { - long tmp = l; - l /= 37L; - chars[11 - i++] = NAME_CHARS[(int) (tmp - l * 37L)]; + private static final long LAST_VALID_NAME = encodeBase37("999999999999"); + + /** + * Decodes a base-37 encoded String, from a {@code long}. + * + * @param value The encoded value. + * @return The decoded String. Will never be {@code null}. + * @throws IllegalArgumentException If the {@code value} does not represent a valid name. + */ + public static String decodeBase37(long value) { + if (value < FIRST_VALID_NAME || value > LAST_VALID_NAME) { + throw new IllegalArgumentException("Invalid name."); } - return new String(chars, 12 - i, i); + + char[] chars = new char[12]; + int length = 0; + + while (value != 0) { + int remainder = (int) (value % 37); + value /= 37; + char character; + + if (remainder >= 1 && remainder <= 26) { + character = (char) ('a' + remainder - 1); + } else if (remainder >= 27 && remainder <= 36) { + character = (char) ('0' + remainder - 27); + } else { + character = '_'; + } + + chars[chars.length - length++ - 1] = character; + } + + return new String(chars, chars.length - length, length); } /** - * Converts a player name to a long. + * Encodes a String into a {@code long}. * - * @param name The player name. - * @return The long. + * @param string The String to encode. Must not be {@code null}. Must be less than 12 characters in length. + * @return The encoded value, as a {@code long}. + * @throws IllegalArgumentException If the String is too long, or contains illegal characters ([^a-zA-Z0-9 _]). */ - public static long encodeBase37(String name) { - Preconditions.checkArgument(name.length() <= 12, "Name too long."); + public static long encodeBase37(String string) { + int length = string.length(); + if (length > 12) { + throw new IllegalArgumentException("String too long."); + } - long l = 0; - for (int index = 0; index < name.length(); index++) { - char c = name.charAt(index); - l *= 37; - if (c >= 'A' && c <= 'Z') { - l += 1 + c - 65; - } else if (c >= 'a' && c <= 'z') { - l += 1 + c - 97; - } else if (c >= '0' && c <= '9') { - l += 27 + c - 48; + long value = 0; + for (char character : string.toCharArray()) { + value *= 37; + + if (character >= 'A' && character <= 'Z') { + value += character - 'A' + 1; + } else if (character >= 'a' && character <= 'z') { + value += character - 'a' + 1; + } else if (character >= '0' && character <= '9') { + value += character - '0' + 27; + } else if (character != ' ' && character != '_') { + throw new IllegalArgumentException("Illegal character: " + character + "."); } } - for (; l % 37L == 0L && l != 0L; l /= 37L) { - ; + while (value != 0 && (value % 37) == 0) { + value /= 37; } - return l; + + return value; } /** diff --git a/util/src/main/org/apollo/util/StreamUtil.java b/util/src/main/org/apollo/util/StreamUtil.java index 685e9bce..e015b900 100644 --- a/util/src/main/org/apollo/util/StreamUtil.java +++ b/util/src/main/org/apollo/util/StreamUtil.java @@ -5,40 +5,43 @@ import java.io.InputStream; import java.io.OutputStream; /** - * A class which contains {@link InputStream}- and {@link OutputStream}-related utility methods. + * Contains utility methods for {@link InputStream}s and {@link OutputStream}s. * * @author Graham */ public final class StreamUtil { /** - * Reads a string from the specified input stream. + * Reads a String from the specified {@link InputStream}. * - * @param is The input stream. - * @return The string. - * @throws IOException If an I/O error occurs. + * @param input The {@link InputStream}. Must not be {@code null}. + * @return The String. Will never be {@code null}. May be empty. + * @throws IOException If an error occurs when reading from the {@link InputStream}. */ - public static String readString(InputStream is) throws IOException { + public static String readString(InputStream input) throws IOException { StringBuilder builder = new StringBuilder(); - char character; - while ((character = (char) is.read()) != -1 && character != '\0') { - builder.append(character); + int character; + + while ((character = input.read()) != -1 && character != '\0') { + builder.append((char) character); } + return builder.toString(); } /** - * Writes a string to the specified output stream. + * Writes an ASCII String to the specified {@link OutputStream}. * - * @param os The output stream. - * @param str The string. - * @throws IOException If an I/O error occurs. + * @param output The {@link OutputStream}. Must not be {@code null}. + * @param string The String. Must be ASCII. Must not be {@code null}. + * @throws IOException If an error occurs when writing to the {@link OutputStream}. */ - public static void writeString(OutputStream os, String str) throws IOException { - for (char c : str.toCharArray()) { - os.write(c); + public static void writeString(OutputStream output, String string) throws IOException { + for (char character : string.toCharArray()) { + output.write(character); } - os.write('\0'); + + output.write('\0'); } /** diff --git a/util/src/main/org/apollo/util/ThreadUtil.java b/util/src/main/org/apollo/util/ThreadUtil.java index 429f49e1..47c3d0a3 100644 --- a/util/src/main/org/apollo/util/ThreadUtil.java +++ b/util/src/main/org/apollo/util/ThreadUtil.java @@ -1,13 +1,13 @@ package org.apollo.util; +import com.google.common.util.concurrent.ThreadFactoryBuilder; + import java.lang.Thread.UncaughtExceptionHandler; import java.util.Objects; import java.util.concurrent.ThreadFactory; import java.util.logging.Level; import java.util.logging.Logger; -import com.google.common.util.concurrent.ThreadFactoryBuilder; - /** * A static utility class which provides ease of use functionality for {@link Thread}s * @@ -24,7 +24,7 @@ public final class ThreadUtil { /** * A {@link Logger} used to debug messages to the console. */ - private static final Logger LOGGER = Logger.getLogger(ThreadUtil.class.getSimpleName()); + private static final Logger logger = Logger.getLogger(ThreadUtil.class.getSimpleName()); /** * The default {@link UncaughtExceptionHandler} which raises an error from the logger with the exception and name @@ -32,15 +32,14 @@ public final class ThreadUtil { * the specified thread the exception occurred in. */ private static final UncaughtExceptionHandler DEFAULT_EXCEPTION_HANDLER = - (thread, exception) -> LOGGER.log(Level.SEVERE, "Exception in thread " + thread.getName(), exception); + (thread, exception) -> logger.log(Level.SEVERE, "Exception in thread " + thread.getName(), exception); /** * Builds a {@link ThreadFactory} using the specified {@code String} name-format, normal thread priority and the - * default {@link UncaughtExceptionHandler}. + * default {@link UncaughtExceptionHandler}, which simply logs exception messages. * * @param name The name-format used when creating threads. Must not be {@code null}. * @return The {@link ThreadFactory}. Will never be {@code null}. - * @see #DEFAULT_EXCEPTION_HANDLER */ public static ThreadFactory create(String name) { return create(name, Thread.NORM_PRIORITY, DEFAULT_EXCEPTION_HANDLER); @@ -51,7 +50,7 @@ public final class ThreadUtil { * {@link #DEFAULT_EXCEPTION_HANDLER}. * * @param name The name-format used when creating threads. Must not be {@code null}. - * @param priority The priority used when creating threads. + * @param priority The priority used when creating threads. Must be {@code 1 <= priority <= 10}. * @return The {@link ThreadFactory}. Will never be {@code null}. */ public static ThreadFactory create(String name, int priority) { @@ -59,11 +58,11 @@ public final class ThreadUtil { } /** - * Builds a {@link ThreadFactory} using the specified {@code String} name-format, priority and + * Creates a {@link ThreadFactory} using the specified {@code String} name-format, priority and * {@link UncaughtExceptionHandler}. * * @param name The name-format used when creating threads. Must not be {@code null}. - * @param priority The priority used when creating threads. + * @param priority The priority used when creating threads. Must be {@code 1 <= priority <= 10}. * @param handler The {@link UncaughtExceptionHandler} used when creating threads. Must not be {@code null}. * @return The {@link ThreadFactory}. Will never be {@code null}. */ @@ -75,6 +74,7 @@ public final class ThreadUtil { builder.setNameFormat(name); builder.setPriority(priority); builder.setUncaughtExceptionHandler(handler); + return builder.build(); } diff --git a/util/src/test/org/apollo/util/BufferUtilTests.java b/util/src/test/org/apollo/util/BufferUtilTests.java index 8f001282..d0f78b12 100644 --- a/util/src/test/org/apollo/util/BufferUtilTests.java +++ b/util/src/test/org/apollo/util/BufferUtilTests.java @@ -19,60 +19,46 @@ public final class BufferUtilTests { * Test the {@link BufferUtil#readString(ByteBuf)} method. */ @Test - public void readByteBufString() { - ByteBuf buf = Unpooled.buffer(6); - buf.writeBytes(new byte[]{ 'H', 'e', 'l', 'l', 'o', 10 }); - String str = BufferUtil.readString(buf); - assertEquals("Hello", str); + public void byteBufString() { + ByteBuf buffer = Unpooled.buffer(6 * Byte.BYTES); - buf = Unpooled.buffer(5); - buf.writeBytes(new byte[]{ 'W', 'o', 'r', 'l', 'd' }); - str = BufferUtil.readString(buf); - assertEquals("World", str); + buffer.writeBytes(new byte[]{ 'H', 'e', 'l', 'l', 'o', 10 }); + assertEquals("Hello", BufferUtil.readString(buffer)); - buf = Unpooled.buffer(3); - buf.writeByte('!'); - buf.writeByte(10); - buf.writeByte('.'); + buffer = Unpooled.buffer(2 * Byte.BYTES); + buffer.writeByte('!'); + buffer.writeByte(BufferUtil.STRING_TERMINATOR); - str = BufferUtil.readString(buf); - assertEquals("!", str); - - str = BufferUtil.readString(buf); - assertEquals(".", str); + assertEquals("!", BufferUtil.readString(buffer)); } /** * Tests the {@link BufferUtil#readString(ByteBuffer)} method. */ @Test - public void readByteBufferString() { - ByteBuffer buf = ByteBuffer.allocate(8); - buf.put((byte) 'h'); - buf.put((byte) 'e'); - buf.put((byte) 'l'); - buf.put((byte) 'l'); - buf.put((byte) 'o'); - buf.put((byte) BufferUtil.STRING_TERMINATOR); - buf.put((byte) 66); - buf.put((byte) 6); - buf.flip(); + public void byteBufferString() { + ByteBuffer buffer = ByteBuffer.allocate(4 * Byte.BYTES); + buffer.put((byte) 'h'); + buffer.put((byte) 'i'); + buffer.put((byte) BufferUtil.STRING_TERMINATOR); + buffer.put((byte) '!'); + buffer.flip(); - assertEquals("hello", BufferUtil.readString(buf)); + assertEquals("hi", BufferUtil.readString(buffer)); } /** * Tests the {@link BufferUtil#readUnsignedMedium} method. */ @Test - public void testReadUnsignedTriByte() { - ByteBuffer buf = ByteBuffer.allocate(3); + public void medium() { + ByteBuffer buf = ByteBuffer.allocate(3 * Byte.BYTES); buf.put((byte) 123); buf.put((byte) 45); buf.put((byte) 67); buf.flip(); - assertEquals(8072515, BufferUtil.readUnsignedMedium(buf)); + assertEquals(123 << 16 | 45 << 8 | 67, BufferUtil.readUnsignedMedium(buf)); } } \ No newline at end of file diff --git a/util/src/test/org/apollo/util/CollectionUtilTests.java b/util/src/test/org/apollo/util/CollectionUtilTests.java new file mode 100644 index 00000000..5ebd9ca1 --- /dev/null +++ b/util/src/test/org/apollo/util/CollectionUtilTests.java @@ -0,0 +1,28 @@ +package org.apollo.util; + +import org.junit.Test; + +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Queue; + +import static org.junit.Assert.assertTrue; + +/** + * Contains unit tests for {@link CollectionUtil}s. + * + * @author Major + */ +public final class CollectionUtilTests { + + /** + * Tests that {@link CollectionUtil#pollAll} functions correctly. + */ + @Test + public void poll() { + Queue queue = new ArrayDeque<>(Arrays.asList("hello", "world")); + CollectionUtil.pollAll(queue, String::length); + assertTrue(queue.isEmpty()); + } + +} diff --git a/util/src/test/org/apollo/util/CompressionUtilTests.java b/util/src/test/org/apollo/util/CompressionUtilTests.java index 68fd83ff..d33f7303 100644 --- a/util/src/test/org/apollo/util/CompressionUtilTests.java +++ b/util/src/test/org/apollo/util/CompressionUtilTests.java @@ -3,6 +3,7 @@ package org.apollo.util; import org.junit.Test; import java.io.IOException; +import java.nio.charset.StandardCharsets; import static org.junit.Assert.assertEquals; @@ -10,35 +11,34 @@ import static org.junit.Assert.assertEquals; * Contains unit tests for {@link CompressionUtil}s. * * @author Graham + * @author Major */ -public class CompressionUtilTests { +public final class CompressionUtilTests { /** - * Tests the {@link CompressionUtil#bzip2(byte[])} and {@link CompressionUtil#debzip2} methods. - * - * @throws IOException If an I/O error occurs. + * Tests the {@link CompressionUtil#bzip2} and {@link CompressionUtil#debzip2} methods. */ @Test - public void testBzip2() throws IOException { - String str = "Hello, World!"; - byte[] data = str.getBytes(); - byte[] compressed = CompressionUtil.bzip2(data); - CompressionUtil.debzip2(compressed, data); - assertEquals(str, new String(data)); + public void bzip2() throws IOException { + String string = "Hello, world!"; + + byte[] data = string.getBytes(StandardCharsets.UTF_8); + CompressionUtil.debzip2(CompressionUtil.bzip2(data), data); + + assertEquals(string, new String(data, StandardCharsets.UTF_8)); } /** - * Tests the {@link CompressionUtil#gzip(byte[])} and {@link CompressionUtil#degzip} methods. - * - * @throws IOException If an I/O error occurs. + * Tests the {@link CompressionUtil#gzip} and {@link CompressionUtil#degzip} methods. */ @Test - public void testGzip() throws IOException { - String str = "Hello, World!"; - byte[] data = str.getBytes(); - byte[] compressed = CompressionUtil.gzip(data); - CompressionUtil.degzip(compressed, data); - assertEquals(str, new String(data)); + public void gzip() throws IOException { + String string = "Hello, world!"; + + byte[] data = string.getBytes(StandardCharsets.UTF_8); + CompressionUtil.degzip(CompressionUtil.gzip(data), data); + + assertEquals(string, new String(data, StandardCharsets.UTF_8)); } } \ No newline at end of file diff --git a/util/src/test/org/apollo/util/LanguageUtilTests.java b/util/src/test/org/apollo/util/LanguageUtilTests.java index 8c3219e6..7d6a5909 100644 --- a/util/src/test/org/apollo/util/LanguageUtilTests.java +++ b/util/src/test/org/apollo/util/LanguageUtilTests.java @@ -9,17 +9,20 @@ import static org.junit.Assert.assertEquals; * * @author Graham */ -public class LanguageUtilTests { +public final class LanguageUtilTests { /** * Tests the {@link LanguageUtil#getIndefiniteArticle} method. */ @Test - public void testIndefiniteArticle() { + public void indefiniteArticle() { assertEquals("an", LanguageUtil.getIndefiniteArticle("apple")); assertEquals("an", LanguageUtil.getIndefiniteArticle("urn")); assertEquals("a", LanguageUtil.getIndefiniteArticle("nose")); assertEquals("a", LanguageUtil.getIndefiniteArticle("foot")); + + assertEquals("an", LanguageUtil.getIndefiniteArticle("NPC")); + assertEquals("an", LanguageUtil.getIndefiniteArticle("FC")); } } \ No newline at end of file diff --git a/util/src/test/org/apollo/util/NameUtilTests.java b/util/src/test/org/apollo/util/NameUtilTests.java new file mode 100644 index 00000000..4797eecc --- /dev/null +++ b/util/src/test/org/apollo/util/NameUtilTests.java @@ -0,0 +1,59 @@ +package org.apollo.util; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Contains unit tests for {@link NameUtil}s. + * + * @author Major + */ +public final class NameUtilTests { + + /** + * Tests that attempting to encode an illegal character results in an {@link IllegalArgumentException} being + * thrown. + */ + @Test(expected = IllegalArgumentException.class) + public void illegalCharacter() { + NameUtil.encodeBase37("!"); + } + + /** + * Tests that attempting to decode an illegal encoded value results in an {@link IllegalArgumentException} being + * thrown. + */ + @Test(expected = IllegalArgumentException.class) + public void invalidName() { + NameUtil.decodeBase37(NameUtil.encodeBase37("999999999999") + 1); + } + + /** + * Tests that attempting to encode a String longer than 12 characters results in an + * {@link IllegalArgumentException} being thrown. + */ + @Test(expected = IllegalArgumentException.class) + public void length() { + NameUtil.encodeBase37("LongerThan12Characters"); + } + + /** + * Tests that encoding a String containing a space (' ') results in the space being replaced with an underscore + * ('_'). + */ + @Test + public void space() { + assertEquals("hello_world", NameUtil.decodeBase37(NameUtil.encodeBase37("hello world"))); + } + + /** + * Tests that {@link NameUtil#decodeBase37} and {@link NameUtil#encodeBase37} perform as expected. + */ + @Test + public void test() { + assertEquals("a_b_c", NameUtil.decodeBase37(NameUtil.encodeBase37("a_b_c"))); + assertEquals("01234_56789", NameUtil.decodeBase37(NameUtil.encodeBase37("01234_56789"))); + } + +} diff --git a/util/src/test/org/apollo/util/StreamUtilTests.java b/util/src/test/org/apollo/util/StreamUtilTests.java new file mode 100644 index 00000000..130db401 --- /dev/null +++ b/util/src/test/org/apollo/util/StreamUtilTests.java @@ -0,0 +1,52 @@ +package org.apollo.util; + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.assertEquals; + +/** + * Contains unit tests for {@link StreamUtil}s. + * + * @author Major + */ +public final class StreamUtilTests { + + /** + * Tests that reading a String from an {@link InputStream} works as expected. + */ + @Test + public void read() throws IOException { + ByteArrayInputStream input = new ByteArrayInputStream("hello\0".getBytes(StandardCharsets.US_ASCII)); + assertEquals("hello", StreamUtil.readString(input)); + } + + /** + * Tests that attempting to read a String that is not terminated with {@code \0} will not cause + * an infinite loop. + */ + @Test(timeout = 10) + public void unterminated() throws IOException { + InputStream input = new ByteArrayInputStream("hello".getBytes(StandardCharsets.US_ASCII)); + StreamUtil.readString(input); + } + + /** + * Tests that writing a String to an {@link OutputStream} works as expected. + */ + @Test + public void write() throws IOException { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + StreamUtil.writeString(output, "hello"); + + String written = new String(output.toByteArray(), StandardCharsets.US_ASCII); + assertEquals("hello\0", written); + } + +} diff --git a/util/src/test/org/apollo/util/ThreadUtilTests.java b/util/src/test/org/apollo/util/ThreadUtilTests.java new file mode 100644 index 00000000..1f267576 --- /dev/null +++ b/util/src/test/org/apollo/util/ThreadUtilTests.java @@ -0,0 +1,44 @@ +package org.apollo.util; + +import org.junit.Test; + +/** + * Contains unit tests for {@link ThreadUtil}s. + * + * @author Major + */ +public final class ThreadUtilTests { + + /** + * Tests that trying to use an illegal name throws a {@link java.lang.Thread.UncaughtExceptionHandler}. + */ + @Test(expected = NullPointerException.class) + public void badHandler() { + ThreadUtil.create("factory", 1, null); + } + + /** + * Tests that trying to use an illegal name throws a {@link NullPointerException}. + */ + @Test(expected = NullPointerException.class) + public void badName() { + ThreadUtil.create(null); + } + + /** + * Tests that using a priority above 10 throws an {@link IllegalArgumentException}. + */ + @Test(expected = IllegalArgumentException.class) + public void largePriority() { + ThreadUtil.create("factory", 11); + } + + /** + * Tests that using a priority below 1 throws an {@link IllegalArgumentException}. + */ + @Test(expected = IllegalArgumentException.class) + public void smallPriority() { + ThreadUtil.create("factory", 0); + } + +}