package com.openxc.messages.streamers; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import com.openxc.messages.NamedVehicleMessage; import com.openxc.messages.SimpleVehicleMessage; import com.openxc.messages.VehicleMessage; @RunWith(RobolectricTestRunner.class) public class JsonStreamerTest { JsonStreamer streamer; SimpleVehicleMessage message = new SimpleVehicleMessage("foo", "bar"); @Before public void setup() { streamer = new JsonStreamer(); } @Test public void jsonContainsJson() { assertTrue(JsonStreamer.containsJson("{\"name\": \"foo\"}\u0000")); } @Test public void paritalJsonDoesntContainJson() { assertFalse(JsonStreamer.containsJson("{\"name\": \"foo\"}\u0000\u0001\u0002")); } @Test public void notJsonDoesntContainJson() { assertFalse(JsonStreamer.containsJson("\u0000\u0001\u0002")); } @Test public void emptyHasNoMessages() { assertThat(streamer.parseNextMessage(), nullValue()); } @Test public void receiveLessThanFullBufferDoesntGrabAll() { // When we receive bytes, we have a buffer with bytes but only part of // it may be valid. The streamer must only try and use the valid part of // the buffer. byte[] bytes = new String( "{\"name\": \"bar\"}\u0000{\"name\": \"bing\"}\u0000").getBytes(); // Tell the JsonStreamer that the buffer is only valid up to the end of // the first message. streamer.receive(bytes, 16); assertThat(streamer.parseNextMessage(), notNullValue()); // If we can parse both, it's broken. assertThat(streamer.parseNextMessage(), nullValue()); } @Test public void clearsDelimitersInFrontOfMessage() { byte[] bytes = new String("\u0000\u0000{\"name\": \"bar\"}\u0000").getBytes(); streamer.receive(bytes, bytes.length); assertThat(streamer.parseNextMessage(), notNullValue()); } @Test public void readWithOnlyExtras() { byte[] bytes = new String("{\"extras\": {\"foo\": \"bar\"}}\u0000").getBytes(); streamer.receive(bytes, bytes.length); assertThat(streamer.parseNextMessage(), notNullValue()); } @Test public void readUnrecognizedFields() { byte[] bytes = new String("{\"foo\": \"bar\"}\u0000").getBytes(); streamer.receive(bytes, bytes.length); assertThat(streamer.parseNextMessage(), nullValue()); } @Test public void readingGenericThenSpecific() { byte[] bytes = new String("{\"name\": \"bar\"}\u0000").getBytes(); streamer.receive(bytes, bytes.length); bytes = new String("{\"name\": \"foo\", \"value\": \"bar\"}\u0000").getBytes(); streamer.receive(bytes, bytes.length); assertThat(streamer.parseNextMessage(), notNullValue()); assertThat(streamer.parseNextMessage(), notNullValue()); } @Test public void readLinesOne() { byte[] bytes = new String("{\"name\": \"foo\"}\u0000").getBytes(); streamer.receive(bytes, bytes.length); VehicleMessage message = streamer.parseNextMessage(); assertThat(message, notNullValue()); assertThat(message, instanceOf(NamedVehicleMessage.class)); NamedVehicleMessage namedMessage = (NamedVehicleMessage) message; assertThat(namedMessage.getName(), equalTo("foo")); assertThat(streamer.parseNextMessage(), nullValue()); } @Test public void readLinesTwo() { byte[] bytes = new String("{\"name\": \"foo\"}\u0000").getBytes(); streamer.receive(bytes, bytes.length); bytes = new String("{\"name\": \"miracle\"}\u0000").getBytes(); streamer.receive(bytes, bytes.length); assertThat(streamer.parseNextMessage(), notNullValue()); assertThat(streamer.parseNextMessage(), notNullValue()); assertThat(streamer.parseNextMessage(), nullValue()); } @Test public void leavePartial() { byte[] bytes = new String("{\"name\": \"foo\"}\u0000").getBytes(); streamer.receive(bytes, bytes.length); bytes = new String("{\"name\": \"mira").getBytes(); streamer.receive(bytes, bytes.length); assertThat(streamer.parseNextMessage(), notNullValue()); assertThat(streamer.parseNextMessage(), nullValue()); } @Test public void completePartial() { byte[] bytes = new String("{\"name\": \"foo\"}\u0000").getBytes(); streamer.receive(bytes, bytes.length); bytes = new String("{\"name\": \"mira").getBytes(); streamer.receive(bytes, bytes.length); assertThat(streamer.parseNextMessage(), notNullValue()); assertThat(streamer.parseNextMessage(), nullValue()); bytes = new String("cle\"}\u0000").getBytes(); streamer.receive(bytes, bytes.length); assertThat(streamer.parseNextMessage(), notNullValue()); assertThat(streamer.parseNextMessage(), nullValue()); } @Test public void deserializeSerialized() { byte[] data = streamer.serializeForStream(message); streamer.receive(data, data.length); VehicleMessage deserialized = streamer.parseNextMessage(); assertEquals(message, deserialized); } @Test public void logTransferStatsAfterMegabyte() { byte[] data = streamer.serializeForStream(message); for(int i = 0; i < 10000; i++) { streamer.receive(data, data.length); } for(int i = 0; i < 10000; i++) { VehicleMessage deserialized = streamer.parseNextMessage(); assertEquals(message, deserialized); } } }