From 0a7c6e52be0689674bf7e3f98e0e7d4b155f6a77 Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Mon, 10 Nov 2014 17:27:19 -0500 Subject: [PATCH] Added java api! --- java/build.gradle | 11 +- java/gradle/wrapper/gradle-wrapper.properties | 4 +- java/src/main/java/Library.java | 11 -- .../edu/wpi/cs/jsh/AbstractBaseStream.java | 27 ++++ .../main/java/edu/wpi/cs/jsh/BasicStream.java | 60 +++++++ .../edu/wpi/cs/jsh/BasicStreamSerializer.java | 24 +++ .../java/edu/wpi/cs/jsh/BasicTypeStream.java | 50 ++++++ .../wpi/cs/jsh/BasicTypeStreamSerializer.java | 18 +++ .../java/edu/wpi/cs/jsh/JshException.java | 14 ++ .../edu/wpi/cs/jsh/JshStreamController.java | 146 ++++++++++++++++++ .../java/edu/wpi/cs/jsh/JshStreamFactory.java | 54 +++++++ .../main/java/edu/wpi/cs/jsh/NamedStream.java | 25 +++ java/src/main/java/edu/wpi/cs/jsh/Stream.java | 49 ++++++ .../java/edu/wpi/cs/jsh/TopLevelStream.java | 10 ++ .../wpi/cs/jsh/TopLevelStreamSerializer.java | 18 +++ .../main/java/edu/wpi/cs/jsh/TypeStream.java | 15 ++ java/src/test/java/LibraryTest.java | 15 -- .../java/edu/wpi/cs/jsh/BasicStreamTest.java | 95 ++++++++++++ .../edu/wpi/cs/jsh/BasicTypeStreamTest.java | 76 +++++++++ 19 files changed, 685 insertions(+), 37 deletions(-) delete mode 100644 java/src/main/java/Library.java create mode 100644 java/src/main/java/edu/wpi/cs/jsh/AbstractBaseStream.java create mode 100644 java/src/main/java/edu/wpi/cs/jsh/BasicStream.java create mode 100644 java/src/main/java/edu/wpi/cs/jsh/BasicStreamSerializer.java create mode 100644 java/src/main/java/edu/wpi/cs/jsh/BasicTypeStream.java create mode 100644 java/src/main/java/edu/wpi/cs/jsh/BasicTypeStreamSerializer.java create mode 100644 java/src/main/java/edu/wpi/cs/jsh/JshException.java create mode 100644 java/src/main/java/edu/wpi/cs/jsh/JshStreamController.java create mode 100644 java/src/main/java/edu/wpi/cs/jsh/JshStreamFactory.java create mode 100644 java/src/main/java/edu/wpi/cs/jsh/NamedStream.java create mode 100644 java/src/main/java/edu/wpi/cs/jsh/Stream.java create mode 100644 java/src/main/java/edu/wpi/cs/jsh/TopLevelStream.java create mode 100644 java/src/main/java/edu/wpi/cs/jsh/TopLevelStreamSerializer.java create mode 100644 java/src/main/java/edu/wpi/cs/jsh/TypeStream.java delete mode 100644 java/src/test/java/LibraryTest.java create mode 100644 java/src/test/java/edu/wpi/cs/jsh/BasicStreamTest.java create mode 100644 java/src/test/java/edu/wpi/cs/jsh/BasicTypeStreamTest.java diff --git a/java/build.gradle b/java/build.gradle index cd6a506..ab3e8db 100644 --- a/java/build.gradle +++ b/java/build.gradle @@ -12,19 +12,12 @@ apply plugin: 'java' // In this section you declare where to find the dependencies of your project repositories { - // Use 'jcenter' for resolving your dependencies. - // You can declare any Maven/Ivy/file repository here. jcenter() + mavenCentral() } // In this section you declare the dependencies for your production and test code dependencies { - // The production code uses the SLF4J logging API at compile time - compile 'org.slf4j:slf4j-api:1.7.5' - - // Declare the dependency for your favourite test framework you want to use in your tests. - // TestNG is also supported by the Gradle Test task. Just change the - // testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add - // 'test.useTestNG()' to your build script. + compile 'com.google.code.gson:gson:2.3' testCompile 'junit:junit:4.11' } diff --git a/java/gradle/wrapper/gradle-wrapper.properties b/java/gradle/wrapper/gradle-wrapper.properties index 8e6c4e3..1793be4 100644 --- a/java/gradle/wrapper/gradle-wrapper.properties +++ b/java/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Nov 06 16:30:58 EST 2014 +#Thu Nov 06 16:36:42 EST 2014 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-all.zip diff --git a/java/src/main/java/Library.java b/java/src/main/java/Library.java deleted file mode 100644 index f022333..0000000 --- a/java/src/main/java/Library.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * This Java source file was auto generated by running 'gradle buildInit --type java-library' - * by 'fred' at '11/6/14 4:30 PM' with Gradle 2.1 - * - * @author fred, @date 11/6/14 4:30 PM - */ -public class Library { - public boolean someLibraryMethod() { - return true; - } -} diff --git a/java/src/main/java/edu/wpi/cs/jsh/AbstractBaseStream.java b/java/src/main/java/edu/wpi/cs/jsh/AbstractBaseStream.java new file mode 100644 index 0000000..7f5bb2b --- /dev/null +++ b/java/src/main/java/edu/wpi/cs/jsh/AbstractBaseStream.java @@ -0,0 +1,27 @@ +package edu.wpi.cs.jsh; + +import edu.wpi.cs.jsh.NamedStream; + +/** + * Abstract base class that takes care of all of the simple named stream code. + */ +abstract class AbstractBaseStream implements NamedStream { + + protected final String m_name; + protected final Class m_type; + + protected AbstractBaseStream(String name, Class type) { + m_name = name; + m_type = type; + } + + @Override + public String getName() { + return m_name; + } + + @Override + public Class getStreamClass() { + return m_type; + } +} diff --git a/java/src/main/java/edu/wpi/cs/jsh/BasicStream.java b/java/src/main/java/edu/wpi/cs/jsh/BasicStream.java new file mode 100644 index 0000000..ed629a5 --- /dev/null +++ b/java/src/main/java/edu/wpi/cs/jsh/BasicStream.java @@ -0,0 +1,60 @@ +package edu.wpi.cs.jsh; + +import java.util.*; + +/** + * Created by fred on 11/7/14. + */ +class BasicStream extends AbstractBaseStream implements Stream { + + private final Object m_lock; + private final Map m_subStreams = new HashMap<>(); + + public BasicStream(String name, Object lock) { + super(name, Stream.class); + m_lock = lock; + } + + @Override + public TypeStream getTypeStream(String streamName, Class streamType) throws JshException { + synchronized (m_lock) { + TypeStream stream = getStream(streamName, streamType); + if (stream == null) { + stream = JshStreamFactory.getInstance().makeTypeStream(streamName, streamType, m_lock); + m_subStreams.put(streamName, stream); + } + return stream; + } + } + + @Override + public Stream getSubStream(String streamName) throws JshException { + synchronized (m_lock) { + Stream stream = getStream(streamName, Stream.class); + if (stream == null) { + stream = JshStreamFactory.getInstance().makeStream(streamName, m_lock, JshStreamFactory.StreamLevel.NORMAL); + m_subStreams.put(streamName, stream); + } + return stream; + } + } + + @Override + public Map getSubStreams() { + return m_subStreams; + } + + private > S getStream(String name, T type) throws JshException { + S stream = null; + if (m_subStreams.containsKey(name)) { + NamedStream mapStream = m_subStreams.get(name); + if (mapStream.getStreamClass().equals(type)) { + stream = (S) mapStream; + } else { + throw new JshException("Stream " + name + " exists already, and is a different type! Original was " + + mapStream.getStreamClass() + ", requested was " + type); + } + } + return stream; + } +} diff --git a/java/src/main/java/edu/wpi/cs/jsh/BasicStreamSerializer.java b/java/src/main/java/edu/wpi/cs/jsh/BasicStreamSerializer.java new file mode 100644 index 0000000..57ab93c --- /dev/null +++ b/java/src/main/java/edu/wpi/cs/jsh/BasicStreamSerializer.java @@ -0,0 +1,24 @@ +package edu.wpi.cs.jsh; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.Map; + +/** + * Serializes a {@link BasicStream} according to the JshProtocol + */ +class BasicStreamSerializer implements JsonSerializer { + @Override + public JsonElement serialize(BasicStream basicStream, Type type, JsonSerializationContext jsonSerializationContext) { + JsonArray output = new JsonArray(); + output.add(jsonSerializationContext.serialize(basicStream.getSubStreams())); + return output; + } +} diff --git a/java/src/main/java/edu/wpi/cs/jsh/BasicTypeStream.java b/java/src/main/java/edu/wpi/cs/jsh/BasicTypeStream.java new file mode 100644 index 0000000..7f7ff88 --- /dev/null +++ b/java/src/main/java/edu/wpi/cs/jsh/BasicTypeStream.java @@ -0,0 +1,50 @@ +package edu.wpi.cs.jsh; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; + +/** + * Created by fred on 11/7/14. + */ +class BasicTypeStream extends AbstractBaseStream implements TypeStream { + + private final Object m_lock; + private final Collection m_objects; + + public BasicTypeStream(String name, Class type, Object lock) { + super(name, type); + m_lock = lock; + m_objects = new LinkedList(); + } + + @Override + public void output(T... values) { + if (values != null) { + synchronized (m_lock) { + Collections.addAll(m_objects, values); + try { + JshStreamController.getInstance().incrementCount(values.length); + } catch (JshException e) { + e.printStackTrace(); + } + } + } + } + + /** + * Gets the objects that have been buffered by this type stream + * + * @return The buffered objects + */ + Collection getObjects() { + return m_objects; + } + + /** + * Removes all of the objects currently buffered. + */ + void flushObjects() { + m_objects.clear(); + } +} diff --git a/java/src/main/java/edu/wpi/cs/jsh/BasicTypeStreamSerializer.java b/java/src/main/java/edu/wpi/cs/jsh/BasicTypeStreamSerializer.java new file mode 100644 index 0000000..3b97ee1 --- /dev/null +++ b/java/src/main/java/edu/wpi/cs/jsh/BasicTypeStreamSerializer.java @@ -0,0 +1,18 @@ +package edu.wpi.cs.jsh; + +import com.google.gson.*; +import com.sun.org.apache.bcel.internal.generic.RET; + +import java.lang.reflect.Type; + +/** + * Serializes a BasicTypeStream to the proper Jsh format + */ +class BasicTypeStreamSerializer implements JsonSerializer> { + @Override + public JsonElement serialize(BasicTypeStream basicTypeStream, Type type, JsonSerializationContext jsonSerializationContext) { + JsonElement serializedStream = jsonSerializationContext.serialize(basicTypeStream.getObjects()); + basicTypeStream.flushObjects(); + return serializedStream; + } +} diff --git a/java/src/main/java/edu/wpi/cs/jsh/JshException.java b/java/src/main/java/edu/wpi/cs/jsh/JshException.java new file mode 100644 index 0000000..e502813 --- /dev/null +++ b/java/src/main/java/edu/wpi/cs/jsh/JshException.java @@ -0,0 +1,14 @@ +package edu.wpi.cs.jsh; + +/** + * Created by fred on 11/6/14. + */ +public class JshException extends Exception { + + private String reason; + + public JshException(String reason) { + super(reason); + this.reason = reason; + } +} diff --git a/java/src/main/java/edu/wpi/cs/jsh/JshStreamController.java b/java/src/main/java/edu/wpi/cs/jsh/JshStreamController.java new file mode 100644 index 0000000..8dca743 --- /dev/null +++ b/java/src/main/java/edu/wpi/cs/jsh/JshStreamController.java @@ -0,0 +1,146 @@ +package edu.wpi.cs.jsh; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import sun.awt.X11.ToplevelStateListener; + +import java.io.PrintStream; + +/** + * This factory allows for getting and creation of new streams, getting access to the top level streams, and controlling + * output. + */ +public class JshStreamController { + + private static final Object _lock = new Object(); + private static final int DEFAULT_MAX_BUFFER = 10; + private static JshStreamController instance; + private static boolean initialized; + + /** + * Initializes the JshStream api with the given output sources for stdout and stderr, and the given max buffer size. + * If you want to just use the system default stdout and stderr, call {@link #initialize()} instead. If you want to + * control either the buffer size or the streams individually, call the appropriate initialize method. The + * controller cannot be reinitialized after it has been initialized once, and it will throw an exception if such + * an instance occurs + * + * @param stdOut The printstream to write stdout to + * @param stdErr The printstream to write stderr to + * @throws JshException If the controller is already initialized, or if there is an error setting up the streams + */ + public static void initialize(PrintStream stdOut, PrintStream stdErr, int maxBuffer) throws JshException { + // Argument guards + if (stdOut == null) { + throw new JshException("Given StdOut source was null!"); + } + if (stdErr == null) { + throw new JshException("Given StdErr source was null!"); + } + + synchronized (_lock) { + if (initialized) { + throw new JshException("JshStream is already initialized! Cannot reinitialize in the middle of output."); + } + + instance = new JshStreamController(stdOut, stdErr, maxBuffer); + initialized = true; + } + } + + /** + * Initializes the JshStream api with the default sysout and syserr, and a given buffer size. If the api has already + * been initialized, then it will throw a JshException + * + * @param maxBuffer The buffer size to use + * @throws JshException If the controller has already been initialized, or if there is an error setting up the stream + */ + public static void initialize(int maxBuffer) throws JshException { + initialize(System.out, System.err, maxBuffer); + } + + /** + * Initializes the JshStream api with the given sysout and syserr, and a default buffer size. If the api has already + * been initialized, then it will throw a JshException + * + * @param sysOut The printstream to write stdout to + * @param sysErr The printstream to write stderr to + * @throws JshException If the controller has already been initialized, or if there is an error setting up the stream + */ + public static void initialized(PrintStream sysOut, PrintStream sysErr) throws JshException { + initialize(sysOut, sysErr, DEFAULT_MAX_BUFFER); + } + + /** + * Initializes the JshStream api with the default sysout and syserr sources. If the api has already been initialized, + * then it will throw a JshException. + * + * @throws JshException If the controller has already been initialized, or if there is an error setting up the streams + */ + public static void initialize() throws JshException { + initialize(System.out, System.err, DEFAULT_MAX_BUFFER); + } + + public static JshStreamController getInstance() throws JshException { + if (!initialized) { + throw new JshException("The JshController has not been set up! Please call one of the initialize methods."); + } + return instance; + } + + /** + * Resets the JshStreamController. After calling this, initialize must be called again. + */ + public static void reset() { + synchronized (_lock) { + initialized = false; + instance = null; + } + } + + public final Stream StdOutStream; + public final Stream StdErrStream; + private final PrintStream m_stdOutPrinter; + private final PrintStream m_stdErrPrinter; + private final int m_maxBuffer; + private final Gson m_json; + private int m_bufferCount; + + private JshStreamController(PrintStream stdOutPrinter, PrintStream stdErrPrinter, int maxBuffer) throws JshException { + m_stdOutPrinter = stdOutPrinter; + m_stdErrPrinter = stdErrPrinter; + StdOutStream = JshStreamFactory.getInstance().makeStream("StdOut", _lock, JshStreamFactory.StreamLevel.TOP_LEVEL); + StdErrStream = JshStreamFactory.getInstance().makeStream("StdErr", _lock, JshStreamFactory.StreamLevel.TOP_LEVEL); + m_maxBuffer = maxBuffer; + GsonBuilder jsonBuilder = new GsonBuilder(); + jsonBuilder.registerTypeAdapter(BasicStream.class, new BasicStreamSerializer()); + jsonBuilder.registerTypeAdapter(BasicTypeStream.class, new BasicTypeStreamSerializer()); + jsonBuilder.registerTypeAdapter(TopLevelStream.class, new TopLevelStreamSerializer()); + m_json = jsonBuilder.create(); + } + + /** + * Increments the count of objects in the buffer. + * + * @param amount The number of objects that have been added to the buffer + */ + void incrementCount(int amount) { + synchronized (_lock) { + m_bufferCount += amount; + if (m_bufferCount >= m_maxBuffer) { + flush(); + } + } + } + + /** + * Writes all current buffered objects to the initialized stdout and stderr. + */ + public void flush() { + synchronized (_lock) { + m_stdOutPrinter.println(m_json.toJson(StdOutStream.getSubStreams())); + m_stdErrPrinter.println(m_json.toJson(StdErrStream.getSubStreams())); + m_bufferCount = 0; + } + } + +} diff --git a/java/src/main/java/edu/wpi/cs/jsh/JshStreamFactory.java b/java/src/main/java/edu/wpi/cs/jsh/JshStreamFactory.java new file mode 100644 index 0000000..0f66857 --- /dev/null +++ b/java/src/main/java/edu/wpi/cs/jsh/JshStreamFactory.java @@ -0,0 +1,54 @@ +package edu.wpi.cs.jsh; + +import javax.swing.plaf.basic.BasicTreeUI; + +/** + * This factory is internal to the jsh api. It is used to create new JshStreams at runtime. + */ +class JshStreamFactory { + + public static final JshStreamFactory instance = new JshStreamFactory(); + + public static JshStreamFactory getInstance() { + return instance; + } + + /** + * Creates a new instance of an {@link Stream} implementation with the given name. The type of the stream is + * {@link Stream} + * + * @param name The name of the new stream + * @return The stream instance + */ + public Stream makeStream(String name, Object lock, StreamLevel level) throws JshException { + Stream stream; + switch (level) { + case TOP_LEVEL: + stream = new TopLevelStream(name, lock); + break; + case NORMAL: + stream = new BasicStream(name, lock); + break; + default: + throw new JshException("Error, unrecognized stream level"); + } + return stream; + } + + /** + * Creates a new instace of an {@link TypeStream} implementation with the given name and base type. The type of + * the stream is the provided type. + * + * @param name The name of the type stream + * @param type The type of the stream. This is necessary because Java lacks reified generics + * @param The type of the stream to be made. + * @return The stream instance. + */ + public TypeStream makeTypeStream(String name, Class type, Object lock) { + return new BasicTypeStream(name, type, lock); + } + + public enum StreamLevel { + TOP_LEVEL, NORMAL + } +} diff --git a/java/src/main/java/edu/wpi/cs/jsh/NamedStream.java b/java/src/main/java/edu/wpi/cs/jsh/NamedStream.java new file mode 100644 index 0000000..d438a2e --- /dev/null +++ b/java/src/main/java/edu/wpi/cs/jsh/NamedStream.java @@ -0,0 +1,25 @@ +package edu.wpi.cs.jsh; + +import java.lang.reflect.Type; + +/** + * A named stream is a JshStream that has the concept of having a name and some value. NamedStream implementations should + * actually implement one of {@link Stream} or {@link TypeStream} + */ +public interface NamedStream { + + /** + * Gets the name associated with this named stream + * + * @return The stream name + */ + String getName(); + + /** + * Gets the class associated with this named stream for equality checking + * + * @return The class of the value of this stream + */ + Class getStreamClass(); + +} diff --git a/java/src/main/java/edu/wpi/cs/jsh/Stream.java b/java/src/main/java/edu/wpi/cs/jsh/Stream.java new file mode 100644 index 0000000..caf5bcf --- /dev/null +++ b/java/src/main/java/edu/wpi/cs/jsh/Stream.java @@ -0,0 +1,49 @@ +package edu.wpi.cs.jsh; + +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.Map; + +/** + * This is an interface for the idea of a JSH style stream or substream. Streams have the following concepts: + *
    + *
  • You can output types on a specific key
  • + *
  • You can create new substreams from this stream
  • + *
  • All types output on a specific key must be the same
  • + *
+ * A stream that implements this interface should not directly output values. It outputs the values of the substreams, + * which are either streams or substreams + */ +public interface Stream extends NamedStream { + + /** + * Gets a raw type stream of the specified generic type. This output stream can be of any type, but you should not use + * {@link edu.wpi.cs.jsh.Stream} as the type. If you need a new substream, use the {@link edu.wpi.cs.jsh.Stream#getSubStream(String)} + * method instead. + * + * @param The type of the substream. If the stream name is already a stream of a different type, an exception will be thrown + * @param streamName The name of the substream. + * @param streamType The type of T parameter. Due to Java generic limitations, this needs to passed in to be available at runtime + * @return The raw type stream with the given name and type + * @throws JshException Thrown if the stream name is not unique and has conflicting types + */ + TypeStream getTypeStream(String streamName, Class streamType) throws JshException; + + /** + * Gets a new Stream that allows for additional substreams. The stream name must be unique, ie this stream does not already + * have any other Streams or TypeStreams that have the same name. Streams do not output directly: if you need to directly output + * a type, use the {@link Stream#getTypeStream(String, Class)} method instead. + * + * @param streamName The name of the substream to create + * @return The substream with the given name + * @throws JshException Thrown if the stream name is not unique and has conflicting types + */ + Stream getSubStream(String streamName) throws JshException; + + /** + * Gets all currently created substreams. + * + * @return All substreams + */ + Map getSubStreams(); +} diff --git a/java/src/main/java/edu/wpi/cs/jsh/TopLevelStream.java b/java/src/main/java/edu/wpi/cs/jsh/TopLevelStream.java new file mode 100644 index 0000000..0869775 --- /dev/null +++ b/java/src/main/java/edu/wpi/cs/jsh/TopLevelStream.java @@ -0,0 +1,10 @@ +package edu.wpi.cs.jsh; + +/** + * Special case of a basic stream that is the top level. The only difference is the deserializers. + */ +public class TopLevelStream extends BasicStream { + public TopLevelStream(String name, Object lock) { + super(name, lock); + } +} diff --git a/java/src/main/java/edu/wpi/cs/jsh/TopLevelStreamSerializer.java b/java/src/main/java/edu/wpi/cs/jsh/TopLevelStreamSerializer.java new file mode 100644 index 0000000..af5df01 --- /dev/null +++ b/java/src/main/java/edu/wpi/cs/jsh/TopLevelStreamSerializer.java @@ -0,0 +1,18 @@ +package edu.wpi.cs.jsh; + +import com.google.gson.JsonElement; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +import java.lang.reflect.Type; + +/** + * Serializer for the top level stream, which is the same as the rest of the streams except that it does not wrap the stream + * in an array object. + */ +public class TopLevelStreamSerializer implements JsonSerializer { + @Override + public JsonElement serialize(BasicStream basicStream, Type type, JsonSerializationContext jsonSerializationContext) { + return jsonSerializationContext.serialize(basicStream.getSubStreams()); + } +} diff --git a/java/src/main/java/edu/wpi/cs/jsh/TypeStream.java b/java/src/main/java/edu/wpi/cs/jsh/TypeStream.java new file mode 100644 index 0000000..9398e8a --- /dev/null +++ b/java/src/main/java/edu/wpi/cs/jsh/TypeStream.java @@ -0,0 +1,15 @@ +package edu.wpi.cs.jsh; + +/** + * A type stream is a raw type stream that can output raw types. Type streams use generics to ensure that they are type + * safe. Type streams cannot have substreams, as they put out raw elements.s + */ +public interface TypeStream extends NamedStream { + + /** + * Outputs the given set of values on this stream. + * @param values + */ + void output(T... values); + +} diff --git a/java/src/test/java/LibraryTest.java b/java/src/test/java/LibraryTest.java deleted file mode 100644 index 4561740..0000000 --- a/java/src/test/java/LibraryTest.java +++ /dev/null @@ -1,15 +0,0 @@ -import org.junit.Test; -import static org.junit.Assert.*; - -/* - * This Java source file was auto generated by running 'gradle init --type java-library' - * by 'fred' at '11/6/14 4:30 PM' with Gradle 2.1 - * - * @author fred, @date 11/6/14 4:30 PM - */ -public class LibraryTest { - @Test public void testSomeLibraryMethod() { - Library classUnderTest = new Library(); - assertTrue("someLibraryMethod should return 'true'", classUnderTest.someLibraryMethod()); - } -} diff --git a/java/src/test/java/edu/wpi/cs/jsh/BasicStreamTest.java b/java/src/test/java/edu/wpi/cs/jsh/BasicStreamTest.java new file mode 100644 index 0000000..95549f5 --- /dev/null +++ b/java/src/test/java/edu/wpi/cs/jsh/BasicStreamTest.java @@ -0,0 +1,95 @@ +package edu.wpi.cs.jsh; + +import com.google.gson.*; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Created by fred on 11/10/14. + */ +public class BasicStreamTest { + + @Before + public void setup() throws JshException { + JshStreamController.reset(); + JshStreamController.initialize(); + } + + @Test + public void testEmptySubStream() throws JshException { + Stream superStream = JshStreamController.getInstance().StdOutStream; + superStream.getSubStream("TestSubStream"); + Gson json = new GsonBuilder() + .registerTypeAdapter(BasicTypeStream.class, new BasicTypeStreamSerializer()) + .registerTypeAdapter(BasicStream.class, new BasicStreamSerializer()) + .registerTypeAdapter(TopLevelStream.class, new TopLevelStreamSerializer()) + .create(); + JsonElement actual = json.toJsonTree(superStream); + JsonObject expected = new JsonObject(); + JsonArray array = new JsonArray(); + array.add(new JsonObject()); + expected.add("TestSubStream", array); + assertEquals(expected, actual); + } + + @Test + public void testIntSubStream() throws JshException { + Stream superStream = JshStreamController.getInstance().StdOutStream; + TypeStream subStream = superStream.getTypeStream("TestSubStream", Integer.class); + subStream.output(1, 2, 3); + Gson json = new GsonBuilder() + .registerTypeAdapter(BasicTypeStream.class, new BasicTypeStreamSerializer()) + .registerTypeAdapter(BasicStream.class, new BasicStreamSerializer()) + .registerTypeAdapter(TopLevelStream.class, new TopLevelStreamSerializer()) + .create(); + JsonElement actual = json.toJsonTree(superStream); + JsonObject expected = new JsonObject(); + JsonArray array = new JsonArray(); + array.add(new JsonPrimitive(1)); + array.add(new JsonPrimitive(2)); + array.add(new JsonPrimitive(3)); + expected.add("TestSubStream", array); + assertEquals(expected, actual); + } + + @Test + public void testStringSubStream() throws JshException { + Stream superStream = JshStreamController.getInstance().StdOutStream; + TypeStream subStream = superStream.getTypeStream("TestSubStream", String.class); + subStream.output("First", "Second", "Third"); + Gson json = new GsonBuilder() + .registerTypeAdapter(BasicTypeStream.class, new BasicTypeStreamSerializer()) + .registerTypeAdapter(BasicStream.class, new BasicStreamSerializer()) + .registerTypeAdapter(TopLevelStream.class, new TopLevelStreamSerializer()) + .create(); + JsonElement actual = json.toJsonTree(superStream); + JsonObject expected = new JsonObject(); + JsonArray array = new JsonArray(); + array.add(new JsonPrimitive("First")); + array.add(new JsonPrimitive("Second")); + array.add(new JsonPrimitive("Third")); + expected.add("TestSubStream", array); + assertEquals(expected, actual); + } + + @Test + public void testSubSubStream() throws JshException { + Stream superStream = JshStreamController.getInstance().StdOutStream; + superStream.getSubStream("SubStream").getTypeStream("SubSubStream", Integer.class); + Gson json = new GsonBuilder() + .registerTypeAdapter(BasicTypeStream.class, new BasicTypeStreamSerializer()) + .registerTypeAdapter(BasicStream.class, new BasicStreamSerializer()) + .registerTypeAdapter(TopLevelStream.class, new TopLevelStreamSerializer()) + .create(); + JsonElement actual = json.toJsonTree(superStream); + JsonObject expected = new JsonObject(); + JsonArray array = new JsonArray(); + JsonObject subSubObject = new JsonObject(); + subSubObject.add("SubSubStream", new JsonArray()); + array.add(subSubObject); + expected.add("SubStream", array); + assertEquals(expected, actual); + } +} diff --git a/java/src/test/java/edu/wpi/cs/jsh/BasicTypeStreamTest.java b/java/src/test/java/edu/wpi/cs/jsh/BasicTypeStreamTest.java new file mode 100644 index 0000000..7b11ff4 --- /dev/null +++ b/java/src/test/java/edu/wpi/cs/jsh/BasicTypeStreamTest.java @@ -0,0 +1,76 @@ +package edu.wpi.cs.jsh; + +import com.google.gson.*; +import org.junit.Before; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * Testing basic type stream serialization and output + */ +public class BasicTypeStreamTest { + + @Before + public void setup() { + try { + JshStreamController.reset(); + JshStreamController.initialize(); + } catch (JshException e) { + e.printStackTrace(); + } + } + + @Test + public void testIntStream() throws JshException { + TypeStream intStream = JshStreamController.getInstance().StdOutStream.getTypeStream("IntStream", Integer.class); + intStream.output(1, 2, 3); + Gson json = new GsonBuilder().registerTypeAdapter(BasicTypeStream.class, new BasicTypeStreamSerializer()).create(); + JsonElement output = json.toJsonTree(intStream); + JsonArray expected = new JsonArray(); + expected.add(new JsonPrimitive(1)); + expected.add(new JsonPrimitive(2)); + expected.add(new JsonPrimitive(3)); + assertEquals(output, expected); + } + + @Test + public void testStringStream() throws JshException { + TypeStream intStream = JshStreamController.getInstance().StdOutStream.getTypeStream("IntStream", String.class); + intStream.output("First", "Second", "Third"); + Gson json = new GsonBuilder().registerTypeAdapter(BasicTypeStream.class, new BasicTypeStreamSerializer()).create(); + JsonElement output = json.toJsonTree(intStream); + JsonArray expected = new JsonArray(); + expected.add(new JsonPrimitive("First")); + expected.add(new JsonPrimitive("Second")); + expected.add(new JsonPrimitive("Third")); + assertEquals(output, expected); + } + + @Test + public void testObjectStream() throws JshException { + TypeStream intStream = JshStreamController.getInstance().StdOutStream.getTypeStream("IntStream", TestClass.class); + TestClass firstElement = new TestClass(1 , 2, "three"); + TestClass secondElement = new TestClass(4, 5, "six"); + TestClass thirdElement = new TestClass(7, 8, "nine"); + intStream.output(firstElement, secondElement, thirdElement); + Gson json = new GsonBuilder().registerTypeAdapter(BasicTypeStream.class, new BasicTypeStreamSerializer()).create(); + JsonElement output = json.toJsonTree(intStream); + JsonArray expected = new JsonArray(); + expected.add(json.toJsonTree(firstElement)); + expected.add(json.toJsonTree(secondElement)); + expected.add(json.toJsonTree(thirdElement)); + assertEquals(output, expected); + } + + private class TestClass { + int value1; + int value2; + String value3; + + public TestClass(int value1, int value2, String value3) { + this.value1 = value1; + this.value2 = value2; + this.value3 = value3; + } + } +}