move package name

This commit is contained in:
nkzawa
2015-08-31 03:23:03 +09:00
parent 742e824a49
commit d0039f7910
31 changed files with 60 additions and 60 deletions

View File

@@ -0,0 +1,35 @@
package io.socket.backo;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
public class BackoffTest {
@Test
public void durationShouldIncreaseTheBackoff() {
Backoff b = new Backoff();
assertTrue(100 == b.duration());
assertTrue(200 == b.duration());
assertTrue(400 == b.duration());
assertTrue(800 == b.duration());
b.reset();
assertTrue(100 == b.duration());
assertTrue(200 == b.duration());
}
@Test
public void durationOverflow() {
Backoff b = new Backoff();
b.setMin(100);
b.setMax(10000);
b.setJitter(1.0);
for (int i = 0; i < 100; i++) {
long duration = b.duration();
assertTrue(100 <= duration && duration <= 10000);
}
}
}

View File

@@ -0,0 +1,115 @@
package io.socket.client;
import org.junit.After;
import org.junit.Before;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;
import java.util.logging.Logger;
public abstract class Connection {
private static final Logger logger = Logger.getLogger(Connection.class.getName());
final static int TIMEOUT = 7000;
final static int PORT = 3000;
private Process serverProcess;
private ExecutorService serverService;
private Future serverOutput;
private Future serverError;
@Before
public void startServer() throws IOException, InterruptedException {
logger.fine("Starting server ...");
final CountDownLatch latch = new CountDownLatch(1);
serverProcess = Runtime.getRuntime().exec(
String.format("node src/test/resources/server.js %s", nsp()), createEnv());
serverService = Executors.newCachedThreadPool();
serverOutput = serverService.submit(new Runnable() {
@Override
public void run() {
BufferedReader reader = new BufferedReader(
new InputStreamReader(serverProcess.getInputStream()));
String line;
try {
line = reader.readLine();
latch.countDown();
do {
logger.fine("SERVER OUT: " + line);
} while ((line = reader.readLine()) != null);
} catch (IOException e) {
logger.warning(e.getMessage());
}
}
});
serverError = serverService.submit(new Runnable() {
@Override
public void run() {
BufferedReader reader = new BufferedReader(
new InputStreamReader(serverProcess.getErrorStream()));
String line;
try {
while ((line = reader.readLine()) != null) {
logger.fine("SERVER ERR: " + line);
}
} catch (IOException e) {
logger.warning(e.getMessage());
}
}
});
latch.await(3000, TimeUnit.MILLISECONDS);
}
@After
public void stopServer() throws InterruptedException {
logger.fine("Stopping server ...");
serverProcess.destroy();
serverOutput.cancel(false);
serverError.cancel(false);
serverService.shutdown();
serverService.awaitTermination(3000, TimeUnit.MILLISECONDS);
}
Socket client() throws URISyntaxException {
return client(createOptions());
}
Socket client(IO.Options opts) throws URISyntaxException {
return IO.socket(uri() + nsp(), opts);
}
String uri() {
return "http://localhost:" + PORT;
}
String nsp() {
return "/";
}
IO.Options createOptions() {
IO.Options opts = new IO.Options();
opts.forceNew = true;
return opts;
}
String[] createEnv() {
Map<String, String> env = new HashMap<String, String>(System.getenv());
env.put("DEBUG", "socket.io:*");
env.put("PORT", String.valueOf(PORT));
String[] _env = new String[env.size()];
int i = 0;
for (String key : env.keySet()) {
_env[i] = key + "=" + env.get(key);
i++;
}
return _env;
}
}

View File

@@ -0,0 +1,813 @@
package io.socket.client;
import com.github.nkzawa.emitter.Emitter;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
@RunWith(JUnit4.class)
public class ConnectionTest extends Connection {
private Socket socket;
@Test(timeout = TIMEOUT)
public void connectToLocalhost() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.emit("echo");
socket.on("echoBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer("done");
}
});
}
});
socket.connect();
values.take();
socket.close();
}
@Test(timeout = TIMEOUT)
public void workWithAcks() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.emit("callAck");
socket.on("ack", new Emitter.Listener() {
@Override
public void call(Object... args) {
Ack fn = (Ack) args[0];
JSONObject data = new JSONObject();
try {
data.put("test", true);
} catch (JSONException e) {
throw new AssertionError(e);
}
fn.call(5, data);
}
});
socket.on("ackBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
JSONObject data = (JSONObject)args[1];
try {
if ((Integer)args[0] == 5 && data.getBoolean("test")) {
values.offer("done");
}
} catch (JSONException e) {
throw new AssertionError(e);
}
}
});
}
});
socket.connect();
values.take();
socket.close();
}
@Test(timeout = TIMEOUT)
public void receiveDateWithAck() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
try {
socket.emit("getAckDate", new JSONObject("{test: true}"), new Ack() {
@Override
public void call(Object... args) {
values.offer(args[0]);
}
});
} catch (JSONException e) {
throw new AssertionError(e);
}
}
});
socket.connect();
assertThat(values.take(), instanceOf(String.class));
socket.close();
}
@Test(timeout = TIMEOUT)
public void workWithFalse() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.emit("echo", false);
socket.on("echoBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args[0]);
}
});
}
});
socket.connect();
assertThat((Boolean)values.take(), is(false));
socket.close();
}
@Test(timeout = TIMEOUT)
public void receiveUTF8MultibyteCharacters() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
final String[] correct = new String[] {
"てすと",
"Я Б Г Д Ж Й",
"Ä ä Ü ü ß",
"utf8 — string",
"utf8 — string"
};
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.on("echoBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args[0]);
}
});
for (String data : correct) {
socket.emit("echo", data);
}
}
});
socket.connect();
for (String expected : correct) {
assertThat((String)values.take(), is(expected));
}
socket.close();
}
@Test(timeout = TIMEOUT)
public void connectToNamespaceAfterConnectionEstablished() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
final Manager manager = new Manager(new URI(uri()));
socket = manager.socket("/");
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
final Socket foo = manager.socket("/foo");
foo.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
foo.close();
socket.close();
manager.close();
values.offer("done");
}
});
foo.open();
}
});
socket.open();
values.take();
}
@Test(timeout = TIMEOUT)
public void connectToNamespaceAfterConnectionGetsClosed() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
final Manager manager = new Manager(new URI(uri()));
socket = manager.socket("/");
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.close();
}
}).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
final Socket foo = manager.socket("/foo");
foo.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
foo.close();
manager.close();
values.offer("done");
}
});
foo.open();
}
});
socket.open();
values.take();
}
@Test(timeout = TIMEOUT)
public void reconnectByDefault() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.io().on(Manager.EVENT_RECONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.close();
values.offer("done");
}
});
socket.open();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
socket.io().engine.close();
}
}, 500);
values.take();
}
@Test(timeout = TIMEOUT)
public void reconnectManually() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.once(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
socket.disconnect();
}
}).once(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
socket.once(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
socket.disconnect();
values.offer("done");
}
});
socket.connect();
}
});
socket.connect();
values.take();
}
@Test(timeout = TIMEOUT)
public void reconnectAutomaticallyAfterReconnectingManually() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.once(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
socket.disconnect();
}
}).once(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
socket.on(Socket.EVENT_RECONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
socket.disconnect();
values.offer("done");
}
});
socket.connect();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
socket.io().engine.close();
}
}, 500);
}
});
socket.connect();
values.take();
}
@Test(timeout = TIMEOUT)
public void attemptReconnectsAfterAFailedReconnect() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
IO.Options opts = createOptions();
opts.reconnection = true;
opts.timeout = 0;
opts.reconnectionAttempts = 2;
opts.reconnectionDelay = 10;
final Manager manager = new Manager(new URI(uri()), opts);
socket = manager.socket("/timeout");
socket.once(Socket.EVENT_RECONNECT_FAILED, new Emitter.Listener() {
@Override
public void call(Object... args) {
final int[] reconnects = new int[] {0};
Emitter.Listener reconnectCb = new Emitter.Listener() {
@Override
public void call(Object... args) {
reconnects[0]++;
}
};
manager.on(Manager.EVENT_RECONNECT_ATTEMPT, reconnectCb);
manager.on(Manager.EVENT_RECONNECT_FAILED, new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(reconnects[0]);
}
});
socket.connect();
}
});
socket.connect();
assertThat((Integer)values.take(), is(2));
socket.close();
manager.close();
}
@Test(timeout = TIMEOUT)
public void reconnectDelayShouldIncreaseEveryTime() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
IO.Options opts = createOptions();
opts.reconnection = true;
opts.timeout = 0;
opts.reconnectionAttempts = 5;
opts.reconnectionDelay = 10;
opts.randomizationFactor = 0.2;
final Manager manager = new Manager(new URI(uri()), opts);
socket = manager.socket("/timeout");
final int[] reconnects = new int[] {0};
final boolean[] increasingDelay = new boolean[] {true};
final long[] startTime = new long[] {0};
final long[] prevDelay = new long[] {0};
socket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
@Override
public void call(Object... args) {
startTime[0] = new Date().getTime();
}
});
socket.on(Socket.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
@Override
public void call(Object... args) {
reconnects[0]++;
long currentTime = new Date().getTime();
long delay = currentTime - startTime[0];
if (delay <= prevDelay[0]) {
increasingDelay[0] = false;
}
prevDelay[0] = delay;
}
});
socket.on(Socket.EVENT_RECONNECT_FAILED, new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(true);
}
});
socket.connect();
values.take();
assertThat(reconnects[0], is(5));
// this fails sometimes
//assertThat(increasingDelay[0], is(true));
socket.close();
manager.close();
}
@Test(timeout = TIMEOUT)
public void reconnectEventFireInSocket() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_RECONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
values.offer("done");
}
});
socket.open();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
socket.io().engine.close();
}
}, 500);
values.take();
socket.close();
}
@Test(timeout = TIMEOUT)
public void notReconnectWhenForceClosed() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
IO.Options opts = createOptions();
opts.timeout = 0;
opts.reconnectionDelay = 10;
socket = IO.socket(uri() + "/invalid", opts);
socket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
@Override
public void call(Object... args) {
socket.on(Socket.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(false);
}
});
socket.disconnect();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
values.offer(true);
}
}, 500);
}
});
socket.connect();
assertThat((Boolean)values.take(), is(true));
}
@Test(timeout = TIMEOUT)
public void stopReconnectingWhenForceClosed() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
IO.Options opts = createOptions();
opts.timeout = 0;
opts.reconnectionDelay = 10;
socket = IO.socket(uri() + "/invalid", opts);
socket.once(Socket.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
@Override
public void call(Object... args) {
socket.on(Socket.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(false);
}
});
socket.disconnect();
// set a timer to let reconnection possibly fire
new Timer().schedule(new TimerTask() {
@Override
public void run() {
values.offer(true);
}
}, 500);
}
});
socket.connect();
assertThat((Boolean) values.take(), is(true));
}
@Test(timeout = TIMEOUT)
public void stopReconnectingOnASocketAndKeepToReconnectOnAnother() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
final Manager manager = new Manager(new URI(uri()));
final Socket socket1 = manager.socket("/");
final Socket socket2 = manager.socket("/asd");
manager.on(Manager.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
@Override
public void call(Object... args) {
socket1.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(false);
}
});
socket2.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
new Timer().schedule(new TimerTask() {
@Override
public void run() {
socket2.disconnect();
manager.close();
values.offer(true);
}
}, 500);
}
});
socket1.disconnect();
}
});
socket1.connect();
socket2.connect();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
manager.engine.close();
}
}, 1000);
assertThat((Boolean) values.take(), is(true));
}
@Test(timeout = TIMEOUT)
public void tryToReconnectTwiceAndFailWithIncorrectAddress() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
IO.Options opts = new IO.Options();
opts.reconnection = true;
opts.reconnectionAttempts = 2;
opts.reconnectionDelay = 10;
final Manager manager = new Manager(new URI("http://localhost:3940"), opts);
socket = manager.socket("/asd");
final int[] reconnects = new int[] {0};
Emitter.Listener cb = new Emitter.Listener() {
@Override
public void call(Object... objects) {
reconnects[0]++;
}
};
manager.on(Manager.EVENT_RECONNECT_ATTEMPT, cb);
manager.on(Manager.EVENT_RECONNECT_FAILED, new Emitter.Listener() {
@Override
public void call(Object... objects) {
values.offer(reconnects[0]);
}
});
socket.open();
assertThat((Integer)values.take(), is(2));
socket.close();
manager.close();
}
@Test(timeout = TIMEOUT)
public void tryToReconnectTwiceAndFailWithImmediateTimeout() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
IO.Options opts = new IO.Options();
opts.reconnection = true;
opts.timeout = 0;
opts.reconnectionAttempts = 2;
opts.reconnectionDelay = 10;
final Manager manager = new Manager(new URI(uri()), opts);
final int[] reconnects = new int[] {0};
Emitter.Listener reconnectCb = new Emitter.Listener() {
@Override
public void call(Object... objects) {
reconnects[0]++;
}
};
manager.on(Manager.EVENT_RECONNECT_ATTEMPT, reconnectCb);
manager.on(Manager.EVENT_RECONNECT_FAILED, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.close();
manager.close();
values.offer(reconnects[0]);
}
});
socket = manager.socket("/timeout");
socket.open();
assertThat((Integer)values.take(), is(2));
}
@Test(timeout = TIMEOUT)
public void notTryToReconnectWithIncorrectPortWhenReconnectionDisabled() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
IO.Options opts = new IO.Options();
opts.reconnection = false;
final Manager manager = new Manager(new URI("http://localhost:9823"), opts);
Emitter.Listener cb = new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.close();
throw new RuntimeException();
}
};
manager.on(Manager.EVENT_RECONNECT_ATTEMPT, cb);
manager.on(Manager.EVENT_CONNECT_ERROR, new Emitter.Listener() {
@Override
public void call(Object... objects) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
socket.close();
manager.close();
values.offer("done");
}
}, 1000);
}
});
socket = manager.socket("/invalid");
socket.open();
values.take();
}
@Test(timeout = TIMEOUT)
public void fireReconnectEventsOnSocket() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
Manager.Options opts = new Manager.Options();
opts.reconnection = true;
opts.timeout = 0;
opts.reconnectionAttempts = 2;
opts.reconnectionDelay = 10;
final Manager manager = new Manager(new URI(uri()), opts);
socket = manager.socket("/timeout_socket");
final int[] reconnects = new int[] {0};
Emitter.Listener reconnectCb = new Emitter.Listener() {
@Override
public void call(Object... args) {
reconnects[0]++;
values.offer(args[0]);
}
};
socket.on(Socket.EVENT_RECONNECT_ATTEMPT, reconnectCb);
socket.on(Socket.EVENT_RECONNECT_FAILED, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.close();
manager.close();
values.offer(reconnects[0]);
}
});
socket.open();
assertThat((Integer)values.take(), is(reconnects[0]));
assertThat((Integer)values.take(), is(2));
}
@Test(timeout = TIMEOUT)
public void fireReconnectingWithAttemptsNumberWhenReconnectingTwice() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
Manager.Options opts = new Manager.Options();
opts.reconnection = true;
opts.timeout = 0;
opts.reconnectionAttempts = 2;
opts.reconnectionDelay = 10;
final Manager manager = new Manager(new URI(uri()), opts);
socket = manager.socket("/timeout_socket");
final int[] reconnects = new int[] {0};
Emitter.Listener reconnectCb = new Emitter.Listener() {
@Override
public void call(Object... args) {
reconnects[0]++;
values.offer(args[0]);
}
};
socket.on(Socket.EVENT_RECONNECTING, reconnectCb);
socket.on(Socket.EVENT_RECONNECT_FAILED, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.close();
manager.close();
values.offer(reconnects[0]);
}
});
socket.open();
assertThat((Integer)values.take(), is(reconnects[0]));
assertThat((Integer)values.take(), is(2));
}
@Test(timeout = TIMEOUT)
public void emitDateAsString() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.emit("echo", new Date());
socket.on("echoBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
socket.close();
values.offer(args[0]);
}
});
}
});
socket.connect();
assertThat(values.take(), instanceOf(String.class));
}
@Test(timeout = TIMEOUT)
public void emitDateInObject() throws URISyntaxException, InterruptedException, JSONException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
JSONObject data = new JSONObject();
try {
data.put("date", new Date());
} catch (JSONException e) {
throw new AssertionError(e);
}
socket.emit("echo", data);
socket.on("echoBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args[0]);
}
});
}
});
socket.connect();
Object data = values.take();
assertThat(data, instanceOf(JSONObject.class));
assertThat(((JSONObject)data).get("date"), instanceOf(String.class));
socket.close();
}
@Test(timeout = TIMEOUT)
public void sendAndGetBinaryData() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
final byte[] buf = "asdfasdf".getBytes(Charset.forName("UTF-8"));
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
socket.emit("echo", buf);
socket.on("echoBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args[0]);
}
});
}
});
socket.open();
assertThat((byte[])values.take(), is(buf));
socket.close();
}
@Test(timeout = TIMEOUT)
public void sendBinaryDataMixedWithJson() throws URISyntaxException, InterruptedException, JSONException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
final byte[] buf = "howdy".getBytes(Charset.forName("UTF-8"));
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
JSONObject data = new JSONObject();
try {
data.put("hello", "lol");
data.put("message", buf);
data.put("goodbye", "gotcha");
} catch (JSONException e) {
throw new AssertionError(e);
}
socket.emit("echo", data);
socket.on("echoBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args[0]);
}
});
}
});
socket.open();
JSONObject a = (JSONObject)values.take();
assertThat(a.getString("hello"), is("lol"));
assertThat((byte[])a.get("message"), is(buf));
assertThat(a.getString("goodbye"), is("gotcha"));
socket.close();
}
@Test(timeout = TIMEOUT)
public void sendEventsWithByteArraysInTheCorrectOrder() throws Exception {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
final byte[] buf = "abuff1".getBytes(Charset.forName("UTF-8"));
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
socket.emit("echo", buf);
socket.emit("echo", "please arrive second");
socket.on("echoBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args[0]);
}
});
}
});
socket.open();
assertThat((byte[])values.take(), is(buf));
assertThat((String)values.take(), is("please arrive second"));
socket.close();
}
}

View File

@@ -0,0 +1,49 @@
package io.socket.client;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Logger;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
@RunWith(JUnit4.class)
public class ExecutionTest extends Connection {
private static final Logger logger = Logger.getLogger(ExecutionTest.class.getName());
final static int TIMEOUT = 30 * 1000;
@Test(timeout = TIMEOUT)
public void execConnection() throws InterruptedException, IOException {
exec("io.socket.client.executions.Connection");
}
@Test(timeout = TIMEOUT)
public void execConnectionFailure() throws InterruptedException, IOException {
exec("io.socket.client.executions.ConnectionFailure");
}
@Test(timeout = TIMEOUT)
public void execImmediateClose() throws InterruptedException, IOException {
exec("io.socket.client.executions.ImmediateClose");
}
private void exec(String mainClass) throws InterruptedException, IOException {
Process process = Runtime.getRuntime().exec(String.format("mvn --quiet exec:java" +
" -Dexec.mainClass=%s -Dexec.classpathScope=test", mainClass), createEnv());
BufferedReader input = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
logger.fine("EXEC OUT: " + line);
}
process.waitFor();
assertThat(process.exitValue(), is(0));
}
}

View File

@@ -0,0 +1,118 @@
package io.socket.client;
import com.github.nkzawa.emitter.Emitter;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@RunWith(JUnit4.class)
public class SSLConnectionTest extends Connection {
// for test on localhost
static HostnameVerifier hostnameVerifier = new javax.net.ssl.HostnameVerifier(){
public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
return hostname.equals("localhost");
}
};
private Socket socket;
@Override
String uri() {
return "https://localhost:" + PORT;
}
@Override
IO.Options createOptions() {
IO.Options opts = super.createOptions();
opts.secure = true;
return opts;
}
@Override
String[] createEnv() {
return new String[] {"DEBUG=socket.io:*", "PORT=" + PORT, "SSL=1"};
}
SSLContext createSSLContext() throws GeneralSecurityException, IOException {
KeyStore ks = KeyStore.getInstance("JKS");
File file = new File("src/test/resources/keystore.jks");
ks.load(new FileInputStream(file), "password".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "password".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ks);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return sslContext;
}
@After
public void tearDown() {
IO.setDefaultSSLContext(null);
IO.setDefaultHostnameVerifier(null);
}
@Test(timeout = TIMEOUT)
public void connect() throws Exception {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
IO.Options opts = createOptions();
opts.sslContext = createSSLContext();
opts.hostnameVerifier = hostnameVerifier;
socket = client(opts);
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.emit("echo");
socket.on("echoBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer("done");
}
});
}
});
socket.connect();
values.take();
socket.close();
}
@Test(timeout = TIMEOUT)
public void defaultSSLContext() throws Exception {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
IO.setDefaultSSLContext(createSSLContext());
IO.setDefaultHostnameVerifier(hostnameVerifier);
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.emit("echo");
socket.on("echoBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer("done");
}
});
}
});
socket.connect();
values.take();
socket.close();
}
}

View File

@@ -0,0 +1,12 @@
package io.socket.client;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class ServerConnectionNamespaceTest extends ServerConnectionTest {
protected String nsp() {
return "/foo";
}
}

View File

@@ -0,0 +1,361 @@
package io.socket.client;
import com.github.nkzawa.emitter.Emitter;
import com.github.nkzawa.engineio.client.Transport;
import com.github.nkzawa.engineio.client.transports.Polling;
import com.github.nkzawa.engineio.client.transports.WebSocket;
import org.json.JSONObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;
@RunWith(JUnit4.class)
public class ServerConnectionTest extends Connection {
private Socket socket;
private Socket socket2;
@Test(timeout = TIMEOUT)
public void openAndClose() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args);
socket.disconnect();
}
}).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args);
}
});
socket.connect();
assertThat(((Object[])values.take()).length, is(0));
Object[] args = (Object[] )values.take();
assertThat(args.length, is(1));
assertThat(args[0], is(instanceOf(String.class)));
}
@Test(timeout = TIMEOUT)
public void message() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.send("foo", "bar");
}
}).on(Socket.EVENT_MESSAGE, new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args);
}
});
socket.connect();
assertThat((Object[])values.take(), is(new Object[] {"hello client"}));
assertThat((Object[])values.take(), is(new Object[] {"foo", "bar"}));
socket.disconnect();
}
@Test(timeout = TIMEOUT)
public void event() throws Exception {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
final JSONObject obj = new JSONObject();
obj.put("foo", 1);
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.emit("echo", obj, null, "bar");
}
}).on("echoBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args);
}
});
socket.connect();
Object[] args = (Object[])values.take();
assertThat(args.length, is(3));
assertThat(args[0].toString(), is(obj.toString()));
assertThat(args[1], is(nullValue()));
assertThat((String)args[2], is("bar"));
socket.disconnect();
}
@Test(timeout = TIMEOUT)
public void ack() throws Exception {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
final JSONObject obj = new JSONObject();
obj.put("foo", 1);
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.emit("ack", new Object[] {obj, "bar"}, new Ack() {
@Override
public void call(Object... args) {
values.offer(args);
}
});
}
});
socket.connect();
Object[] args = (Object[])values.take();
assertThat(args.length, is(2));
assertThat(args[0].toString(), is(obj.toString()));
assertThat((String)args[1], is("bar"));
socket.disconnect();
}
@Test(timeout = TIMEOUT)
public void ackWithoutArgs() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.emit("ack", null, new Ack() {
@Override
public void call(Object... args) {
values.offer(args.length);
}
});
}
});
socket.connect();
assertThat((Integer)values.take(), is(0));
socket.disconnect();
}
@Test(timeout = TIMEOUT)
public void ackWithoutArgsFromClient() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.on("ack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args);
Ack ack = (Ack)args[0];
ack.call();
}
}).on("ackBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args);
socket.disconnect();
}
});
socket.emit("callAck");
}
});
socket.connect();
Object[] args = (Object[])values.take();
assertThat(args.length, is(1));
assertThat(args[0], is(instanceOf(Ack.class)));
args = (Object[])values.take();
assertThat(args.length, is(0));
socket.disconnect();
}
@Test(timeout = TIMEOUT)
public void closeEngineConnection() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
socket.io().engine.on(com.github.nkzawa.engineio.client.Socket.EVENT_CLOSE, new Emitter.Listener() {
@Override
public void call(Object... objects) {
values.offer("done");
}
});
socket.disconnect();
}
});
socket.connect();
values.take();
}
@Test(timeout = TIMEOUT)
public void broadcast() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
try {
socket2 = client();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
socket2.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket2.emit("broadcast", "hi");
}
});
socket2.connect();
}
}).on("broadcastBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args);
}
});
socket.connect();
Object[] args = (Object[])values.take();
assertThat(args.length, is(1));
assertThat((String)args[0], is("hi"));
socket.disconnect();
socket2.disconnect();
}
@Test(timeout = TIMEOUT)
public void room() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.emit("room", "hi");
}
}).on("roomBack", new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(args);
}
});
socket.connect();
Object[] args = (Object[])values.take();
assertThat(args.length, is(1));
assertThat((String)args[0], is("hi"));
socket.disconnect();
}
@Test(timeout = TIMEOUT)
public void pollingHeaders() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
IO.Options opts = createOptions();
opts.transports = new String[] {Polling.NAME};
socket = client(opts);
socket.io().on(Manager.EVENT_TRANSPORT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Transport transport = (Transport)args[0];
transport.on(Transport.EVENT_REQUEST_HEADERS, new Emitter.Listener() {
@Override
public void call(Object... args) {
@SuppressWarnings("unchecked")
Map<String, List<String>> headers = (Map<String, List<String>>)args[0];
headers.put("X-SocketIO", Arrays.asList("hi"));
}
}).on(Transport.EVENT_RESPONSE_HEADERS, new Emitter.Listener() {
@Override
public void call(Object... args) {
@SuppressWarnings("unchecked")
Map<String, List<String>> headers = (Map<String, List<String>>)args[0];
List<String> value = headers.get("X-SocketIO");
values.offer(value != null ? value.get(0) : "");
}
});
}
});
socket.open();
assertThat((String)values.take(), is("hi"));
socket.close();
}
@Test(timeout = TIMEOUT)
public void websocketHandshakeHeaders() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
IO.Options opts = createOptions();
opts.transports = new String[] {WebSocket.NAME};
socket = client(opts);
socket.io().on(Manager.EVENT_TRANSPORT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Transport transport = (Transport)args[0];
transport.on(Transport.EVENT_REQUEST_HEADERS, new Emitter.Listener() {
@Override
public void call(Object... args) {
@SuppressWarnings("unchecked")
Map<String, List<String>> headers = (Map<String, List<String>>)args[0];
headers.put("X-SocketIO", Arrays.asList("hi"));
}
}).on(Transport.EVENT_RESPONSE_HEADERS, new Emitter.Listener() {
@Override
public void call(Object... args) {
@SuppressWarnings("unchecked")
Map<String, List<String>> headers = (Map<String, List<String>>)args[0];
List<String> value = headers.get("X-SocketIO");
values.offer(value != null ? value.get(0) : "");
}
});
}
});
socket.open();
assertThat((String)values.take(), is("hi"));
socket.close();
}
@Test(timeout = TIMEOUT)
public void disconnectFromServer() throws URISyntaxException, InterruptedException {
final BlockingQueue<Object> values = new LinkedBlockingQueue<Object>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
socket.emit("requestDisconnect");
}
}).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer("disconnected");
}
});
socket.connect();
assertThat((String)values.take(), is("disconnected"));
}
}

View File

@@ -0,0 +1,103 @@
package io.socket.client;
import com.github.nkzawa.emitter.Emitter;
import io.socket.util.Optional;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.net.URISyntaxException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;
@RunWith(JUnit4.class)
public class SocketTest extends Connection {
private Socket socket;
@Test(timeout = TIMEOUT)
public void shouldHaveAnAccessibleSocketIdEqualToTheEngineIOSocketId() throws URISyntaxException, InterruptedException {
final BlockingQueue<Optional> values = new LinkedBlockingQueue<Optional>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
values.offer(Optional.ofNullable(socket.id()));
}
});
socket.connect();
@SuppressWarnings("unchecked")
Optional<String> id = values.take();
assertThat(id.isPresent(), is(true));
assertThat(id.get(), is(socket.io().engine.id()));
socket.disconnect();
}
@Test(timeout = TIMEOUT)
public void clearsSocketIdUponDisconnection() throws URISyntaxException, InterruptedException {
final BlockingQueue<Optional> values = new LinkedBlockingQueue<Optional>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
socket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
values.offer(Optional.ofNullable(socket.id()));
}
});
socket.disconnect();
}
});
socket.connect();
@SuppressWarnings("unchecked")
Optional<String> id = values.take();
assertThat(id.isPresent(), is(false));
}
@Test(timeout = TIMEOUT)
public void shouldChangeSocketIdUponReconnection() throws URISyntaxException, InterruptedException {
final BlockingQueue<Optional> values = new LinkedBlockingQueue<Optional>();
socket = client();
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
values.offer(Optional.ofNullable(socket.id()));
socket.on(Socket.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
values.offer(Optional.ofNullable(socket.id()));
}
});
socket.on(Socket.EVENT_RECONNECT, new Emitter.Listener() {
@Override
public void call(Object... objects) {
values.offer(Optional.ofNullable(socket.id()));
}
});
socket.io().engine.close();
}
});
socket.connect();
@SuppressWarnings("unchecked")
Optional<String> id1 = values.take();
@SuppressWarnings("unchecked")
Optional<String> id2 = values.take();
assertThat(id2.isPresent(), is(false));
@SuppressWarnings("unchecked")
Optional<String> id3 = values.take();
assertThat(id3.get(), is(not(id1.get())));
socket.disconnect();
}
}

View File

@@ -0,0 +1,62 @@
package io.socket.client;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
@RunWith(JUnit4.class)
public class UrlTest {
@Test
public void parse() throws URISyntaxException {
assertThat(Url.parse("http://username:password@host:8080/directory/file?query#ref").toString(),
is("http://username:password@host:8080/directory/file?query#ref"));
}
@Test
public void parseRelativePath() throws URISyntaxException {
URL url = Url.parse("https://woot.com/test");
assertThat(url.getProtocol(), is("https"));
assertThat(url.getHost(), is("woot.com"));
assertThat(url.getPath(), is("/test"));
}
@Test
public void parseNoProtocol() throws URISyntaxException {
URL url = Url.parse("//localhost:3000");
assertThat(url.getProtocol(), is("https"));
assertThat(url.getHost(), is("localhost"));
assertThat(url.getPort(), is(3000));
}
@Test
public void parseNamespace() throws URISyntaxException {
assertThat(Url.parse("http://woot.com/woot").getPath(), is("/woot"));
assertThat(Url.parse("http://google.com").getPath(), is("/"));
assertThat(Url.parse("http://google.com/").getPath(), is("/"));
}
@Test
public void parseDefaultPort() throws URISyntaxException {
assertThat(Url.parse("http://google.com/").toString(), is("http://google.com:80/"));
assertThat(Url.parse("https://google.com/").toString(), is("https://google.com:443/"));
}
@Test
public void extractId() throws MalformedURLException {
String id1 = Url.extractId("http://google.com:80/");
String id2 = Url.extractId("http://google.com/");
String id3 = Url.extractId("https://google.com/");
assertThat(id1, is(id2));
assertThat(id1, is(not(id3)));
assertThat(id2, is(not(id3)));
}
}

View File

@@ -0,0 +1,24 @@
package io.socket.client.executions;
import com.github.nkzawa.emitter.Emitter;
import io.socket.client.IO;
import io.socket.client.Socket;
import java.net.URISyntaxException;
public class Connection {
public static void main(String[] args) throws URISyntaxException {
IO.Options options = new IO.Options();
options.forceNew = true;
final Socket socket = IO.socket("http://localhost:" + System.getenv("PORT"), options);
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("connect");
socket.close();
}
});
socket.open();
}
}

View File

@@ -0,0 +1,36 @@
package io.socket.client.executions;
import com.github.nkzawa.emitter.Emitter;
import io.socket.client.IO;
import io.socket.client.Socket;
import java.net.URISyntaxException;
public class ConnectionFailure {
public static void main(String[] args) throws URISyntaxException {
int port = Integer.parseInt(System.getenv("PORT"));
port++;
IO.Options options = new IO.Options();
options.forceNew = true;
options.reconnection = false;
final Socket socket = IO.socket("http://localhost:" + port, options);
socket.on(Socket.EVENT_CONNECT_TIMEOUT, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("connect timeout");
}
}).on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("connect error");
}
}).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("disconnect");
}
});
socket.open();
}
}

View File

@@ -0,0 +1,29 @@
package io.socket.client.executions;
import com.github.nkzawa.emitter.Emitter;
import io.socket.client.IO;
import io.socket.client.Socket;
import java.net.URISyntaxException;
public class ImmediateClose {
public static void main(String[] args) throws URISyntaxException {
IO.Options options = new IO.Options();
options.forceNew = true;
final Socket socket = IO.socket("http://localhost:" + System.getenv("PORT"), options);
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("connect");
}
}).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("disconnect");
}
});
socket.connect();
socket.disconnect();
}
}

View File

@@ -0,0 +1,73 @@
package io.socket.hasbinary;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.nio.charset.Charset;
import static org.junit.Assert.assertTrue;
@RunWith(JUnit4.class)
public class HasBinaryTest {
@Test
public void byteArray() {
assertTrue(HasBinary.hasBinary(new byte[0]));
}
@Test
public void anArrayThatDoesNotContainByteArray() throws JSONException {
JSONArray arr = new JSONArray("[1, \"cool\", 2]");
assertTrue(!HasBinary.hasBinary(arr));
}
@Test
public void anArrayContainsByteArray() throws JSONException {
JSONArray arr = new JSONArray("[1, null, 2]");
arr.put(1, "asdfasdf".getBytes(Charset.forName("UTF-8")));
assertTrue(HasBinary.hasBinary(arr));
}
@Test
public void anObjectThatDoesNotContainByteArray() throws JSONException {
JSONObject ob = new JSONObject("{\"a\": \"a\", \"b\": [], \"c\": 1234}");
assertTrue(!HasBinary.hasBinary(ob));
}
@Test
public void anObjectThatContainsByteArray() throws JSONException {
JSONObject ob = new JSONObject("{\"a\": \"a\", \"b\": null, \"c\": 1234}");
ob.put("b", "abc".getBytes(Charset.forName("UTF-8")));
assertTrue(HasBinary.hasBinary(ob));
}
@Test
public void testNull() {
assertTrue(!HasBinary.hasBinary(null));
}
@Test
public void aComplexObjectThatContainsNoBinary() throws JSONException {
JSONObject ob = new JSONObject();
ob.put("x", new JSONArray("[\"a\", \"b\", 123]"));
ob.put("y", JSONObject.NULL);
ob.put("z", new JSONObject("{\"a\": \"x\", \"b\": \"y\", \"c\": 3, \"d\": null}"));
ob.put("w", new JSONArray());
assertTrue(!HasBinary.hasBinary(ob));
}
@Test
public void aComplexObjectThatContainsBinary() throws JSONException {
JSONObject ob = new JSONObject();
ob.put("x", new JSONArray("[\"a\", \"b\", 123]"));
ob.put("y", JSONObject.NULL);
ob.put("z", new JSONObject("{\"a\": \"x\", \"b\": \"y\", \"c\": 3, \"d\": null}"));
ob.put("w", new JSONArray());
ob.put("bin", "xxx".getBytes(Charset.forName("UTF-8")));
assertTrue(HasBinary.hasBinary(ob));
}
}

View File

@@ -0,0 +1,105 @@
package io.socket.parser;
import com.github.nkzawa.emitter.Emitter;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.nio.charset.Charset;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
@RunWith(JUnit4.class)
public class ByteArrayTest {
private static Parser.Encoder encoder = new Parser.Encoder();
@Test
public void encodeByteArray() {
Packet<byte[]> packet = new Packet<byte[]>(Parser.BINARY_EVENT);
packet.data = "abc".getBytes(Charset.forName("UTF-8"));
packet.id = 23;
packet.nsp = "/cool";
Helpers.testBin(packet);
}
@Test
public void encodeByteArray2() {
Packet<byte[]> packet = new Packet<byte[]>(Parser.BINARY_EVENT);
packet.data = new byte[2];
packet.id = 0;
packet.nsp = "/";
Helpers.testBin(packet);
}
@Test
public void encodeByteArrayDeepInJson() throws JSONException {
JSONObject data = new JSONObject("{a: \"hi\", b: {}, c: {a: \"bye\", b: {}}}");
data.getJSONObject("b").put("why", new byte[3]);
data.getJSONObject("c").getJSONObject("b").put("a", new byte[6]);
Packet<JSONObject> packet = new Packet<JSONObject>(Parser.BINARY_EVENT);
packet.data = data;
packet.id = 999;
packet.nsp = "/deep";
Helpers.testBin(packet);
}
@Test
public void encodeDeepBinaryJSONWithNullValue() throws JSONException {
JSONObject data = new JSONObject("{a: \"b\", c: 4, e: {g: null}, h: null}");
data.put("h", new byte[9]);
Packet<JSONObject> packet = new Packet<JSONObject>(Parser.BINARY_EVENT);
packet.data = data;
packet.nsp = "/";
packet.id = 600;
Helpers.testBin(packet);
}
@Test
public void encodeBinaryAckWithByteArray() throws JSONException {
JSONArray data = new JSONArray("[a, null, {}]");
data.put(1, "xxx".getBytes(Charset.forName("UTF-8")));
Packet<JSONArray> packet = new Packet<JSONArray>(Parser.BINARY_ACK);
packet.data = data;
packet.id = 127;
packet.nsp = "/back";
Helpers.testBin(packet);
}
@Test
public void cleanItselfUpOnClose() {
JSONArray data = new JSONArray();
data.put(new byte[2]);
data.put(new byte[3]);
Packet<JSONArray> packet = new Packet<JSONArray>(Parser.BINARY_EVENT);
packet.data = data;
packet.id = 0;
packet.nsp = "/";
encoder.encode(packet, new Parser.Encoder.Callback() {
@Override
public void call(final Object[] encodedPackets) {
final Parser.Decoder decoder = new Parser.Decoder();
decoder.on(Parser.Decoder.EVENT_DECODED, new Emitter.Listener() {
@Override
public void call(Object... args) {
throw new RuntimeException("received a packet when not all binary data was sent.");
}
});
decoder.add((String)encodedPackets[0]);
decoder.add((byte[]) encodedPackets[1]);
decoder.destroy();
assertThat(decoder.reconstructor.buffers.size(), is(0));
}
});
}
}

View File

@@ -0,0 +1,98 @@
package io.socket.parser;
import com.github.nkzawa.emitter.Emitter;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.skyscreamer.jsonassert.JSONAssert;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
@RunWith(JUnit4.class)
public class Helpers {
private static Parser.Encoder encoder = new Parser.Encoder();
private static Packet<String> errorPacket = new Packet<String>(Parser.ERROR, "parser error");
public static void test(final Packet obj) {
encoder.encode(obj, new Parser.Encoder.Callback() {
@Override
public void call(Object[] encodedPackets) {
Parser.Decoder decoder = new Parser.Decoder();
decoder.on(Parser.Decoder.EVENT_DECODED, new Emitter.Listener() {
@Override
public void call(Object... args) {
Packet packet = (Packet)args[0];
assertPacket(packet, obj);
}
});
decoder.add((String)encodedPackets[0]);
}
});
}
public static void testDecodeError(final String errorMessage) {
Parser.Decoder decoder = new Parser.Decoder();
decoder.on(Parser.Decoder.EVENT_DECODED, new Emitter.Listener() {
@Override
public void call(Object... args) {
Packet packet = (Packet)args[0];
assertPacket(errorPacket, packet);
}
});
decoder.add(errorMessage);
}
public static void testBin(final Packet obj) {
final Object originalData = obj.data;
encoder.encode(obj, new Parser.Encoder.Callback() {
@Override
public void call(Object[] encodedPackets) {
Parser.Decoder decoder = new Parser.Decoder();
decoder.on(Parser.Decoder.EVENT_DECODED, new Emitter.Listener() {
@Override
public void call(Object... args) {
Packet packet = (Packet)args[0];
obj.data = originalData;
obj.attachments = -1;
assertPacket(packet, obj);
}
});
for (Object packet : encodedPackets) {
if (packet instanceof String) {
decoder.add((String)packet);
} else if (packet instanceof byte[]) {
decoder.add((byte[])packet);
}
}
}
});
}
public static void assertPacket(Packet expected, Packet actual) {
assertThat(actual.type, is(expected.type));
assertThat(actual.id, is(expected.id));
assertThat(actual.nsp, is(expected.nsp));
assertThat(actual.attachments, is(expected.attachments));
if (expected.data instanceof JSONArray) {
try {
JSONAssert.assertEquals((JSONArray)expected.data, (JSONArray)actual.data, true);
} catch (JSONException e) {
throw new AssertionError(e);
}
} else if (expected.data instanceof JSONObject) {
try {
JSONAssert.assertEquals((JSONObject)expected.data, (JSONObject)actual.data, true);
} catch (JSONException e) {
throw new AssertionError(e);
}
} else {
assertThat(actual.data, is(expected.data));
}
}
}

View File

@@ -0,0 +1,67 @@
package io.socket.parser;
import org.json.JSONArray;
import org.json.JSONException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class ParserTest {
private static Parser.Encoder encoder = new Parser.Encoder();
@Test
public void encodeConnection() {
Packet packet = new Packet(Parser.CONNECT);
packet.nsp = "/woot";
Helpers.test(packet);
}
@Test
public void encodeDisconnection() {
Packet packet = new Packet(Parser.DISCONNECT);
packet.nsp = "/woot";
Helpers.test(packet);
}
@Test
public void encodeEvent() throws JSONException {
Packet<JSONArray> packet1 = new Packet<JSONArray>(Parser.EVENT);
packet1.data = new JSONArray("[\"a\", 1, {}]");
packet1.nsp = "/";
Helpers.test(packet1);
Packet<JSONArray> packet2 = new Packet<JSONArray>(Parser.EVENT);
packet2.data = new JSONArray("[\"a\", 1, {}]");
packet2.nsp = "/test";
Helpers.test(packet2);
}
@Test
public void encodeAck() throws JSONException {
Packet<JSONArray> packet = new Packet<JSONArray>(Parser.ACK);
packet.data = new JSONArray("[\"a\", 1, {}]");
packet.id = 123;
packet.nsp = "/";
Helpers.test(packet);
}
@Test
public void decodeInError() throws JSONException {
// Random string
Helpers.testDecodeError("asdf");
// Unknown type
Helpers.testDecodeError(Parser.types.length + "asdf");
// Binary event with no `-`
Helpers.testDecodeError(Parser.BINARY_EVENT + "asdf");
// Binary ack with no `-`
Helpers.testDecodeError(Parser.BINARY_ACK + "asdf");
// Binary event with no attachment
Helpers.testDecodeError(String.valueOf(Parser.BINARY_EVENT));
// event non numeric id
Helpers.testDecodeError(Parser.EVENT + "2sd");
// event with invalid json data
Helpers.testDecodeError(Parser.EVENT + "2[\"a\",1,{asdf}]");
}
}

View File

@@ -0,0 +1,44 @@
package io.socket.util;
import java.util.NoSuchElementException;
public class Optional<T> {
static final Optional EMPTY = Optional.ofNullable(null);
private T value;
public static <T> Optional<T> of(T value) {
if (value == null) {
throw new NullPointerException();
}
return new Optional<T>(value);
}
public static <T> Optional<T> ofNullable(T value) {
return new Optional<T>(value);
}
public static <T> Optional<T> empty() {
return EMPTY;
}
private Optional(T value) {
this.value = value;
}
public boolean isPresent() {
return this.value != null;
}
public T get() {
if (this.value == null) {
throw new NoSuchElementException();
}
return this.value;
}
public T orElse(T other) {
return this.value != null ? this.value : other;
}
}