Skip to content

Commit

Permalink
Merge pull request #3 from Workiva/improvements-and-tests
Browse files Browse the repository at this point in the history
CP-1099 Add close() to client. Add integration tests.
  • Loading branch information
jayudey-wf committed Nov 11, 2015
2 parents 6b281d4 + 7e5c52e commit ac07d83
Show file tree
Hide file tree
Showing 13 changed files with 281 additions and 22 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.project
packages

.packages
.pub
packages
pubspec.lock
2 changes: 1 addition & 1 deletion lib/sockjs_client.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
library sockjs_client;

import "dart:html";
import "dart:html" as html;
import "dart:convert";
import "dart:async";
import "dart:js";
Expand Down
6 changes: 3 additions & 3 deletions lib/src/ajax.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ typedef AbstractXHRObject AjaxObjectFactory(String method, String baseUrl, [payl

class AbstractXHRObject extends Object with event.Emitter {

HttpRequest xhr;
html.HttpRequest xhr;
StreamSubscription changeSubscription;

Stream get onChunk => this["chunk"];
Expand All @@ -20,7 +20,7 @@ class AbstractXHRObject extends Object with event.Emitter {
_start(method, url, payload, {noCredentials: false, headers}) {

try {
xhr = new HttpRequest();
xhr = new html.HttpRequest();
} catch(x) {};

if ( xhr == null ) {
Expand Down Expand Up @@ -61,7 +61,7 @@ class AbstractXHRObject extends Object with event.Emitter {
xhr.send(payload);
}

_readyStateHandler(Event evt) {
_readyStateHandler(html.Event evt) {
switch (xhr.readyState) {
case 3:
var text, status;
Expand Down
20 changes: 18 additions & 2 deletions lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,22 @@ class Client extends Object with event.Emitter {
Stream get onClose => this["close"];
Stream get onHeartbeat => this["heartbeat"];

void close([int code, String reason]) {
if (_transport != null) {
if (_transport is WebSocketTransport) {
_transport.doClose(code, reason);
} else if (_transport is XhrStreamingTransport) {
if (code == null) {
code = 0;
}
if (reason == null) {
reason = '';
}
_didClose(code, reason);
}
}
}

send(data) {
if (readyState == CONNECTING) {
throw 'INVALID_STATE_ERR';
Expand Down Expand Up @@ -199,11 +215,11 @@ class Client extends Object with event.Emitter {
// the `head`?
if (PROTOCOLS.containsKey(protocol) &&
PROTOCOLS[protocol].needBody &&
( (document.body == null) || (document.readyState != null && document.readyState != 'complete'))
( (html.document.body == null) || (html.document.readyState != null && html.document.readyState != 'complete'))
) {
_protocols.insert(0, protocol);
this.protocol = 'waiting-for-load';
document.onLoad.listen( (_) => _tryNextProtocol());
html.document.onLoad.listen( (_) => _tryNextProtocol());
return true;
}

Expand Down
6 changes: 3 additions & 3 deletions lib/src/info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Info {
origins = json["origins"];
cookieNeeded = json["cookie_needed"];
entropy = json["entropy"];
nullOrigin = (document.domain == null);
nullOrigin = (html.document.domain == null);
}
}

Expand Down Expand Up @@ -84,8 +84,8 @@ class AjaxInfoReceiver extends InfoReceiver {
class InfoReceiverIframe extends InfoReceiver {

InfoReceiverIframe(base_url) : super._() {
if(document.body == null) {
document.onLoad.listen((_) => go());
if(html.document.body == null) {
html.document.onLoad.listen((_) => go());
} else {
go();
}
Expand Down
18 changes: 9 additions & 9 deletions lib/src/transport/sender.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,18 @@ class BufferedSender {
// postMessage communication */
class JsonPGenericSender {
FormElement _sendForm = null;
TextAreaElement _sendArea = null;
html.FormElement _sendForm = null;
html.TextAreaElement _sendArea = null;
var completed;
JsonPGenericSender(url, payload, callback) {
FormElement form;
TextAreaElement area;
html.FormElement form;
html.TextAreaElement area;
if (_sendForm == null) {
form = _sendForm = new Element.tag('form');
area = _sendArea = new Element.tag('textarea');
form = _sendForm = new html.Element.tag('form');
area = _sendArea = new html.Element.tag('textarea');
area.name = 'd';
form.style.display = 'none';
form.style.position = 'absolute';
Expand All @@ -93,12 +93,12 @@ class JsonPGenericSender {
form.target = id;
form.action = '$url/jsonp_send?i=$id';
IFrameElement iframe;
html.IFrameElement iframe;
try {
// ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
iframe = new Element.html('<iframe name="$id">');
iframe = new html.Element.html('<iframe name="$id">');
} catch(x) {
iframe = new Element.tag('iframe');
iframe = new html.Element.tag('iframe');
iframe.name = id;
}
iframe.id = id;
Expand Down
16 changes: 13 additions & 3 deletions lib/src/transport/websocket.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class WebSocketTransport {
Client ri;
String url;

WebSocket ws;
html.WebSocket ws;
StreamSubscription messageSubscription;
StreamSubscription closeSubscription;

Expand All @@ -20,7 +20,7 @@ class WebSocketTransport {

this.url = url;

ws = new WebSocket(url);
ws = new html.WebSocket(url);


messageSubscription = ws.onMessage.listen(_msgHandler);
Expand All @@ -37,7 +37,17 @@ class WebSocketTransport {

_msgHandler(m) => ri._didMessage(m.data);

_closeHandler(m) => ri._didMessage(utils.closeFrame(1006, "WebSocket connection broken"));
_closeHandler(html.CloseEvent c) {
var code = c.code != null ? c.code : 1006;
var reason = c.reason != null ? c.reason : 'WebSocket connection broken';
ri._didMessage(utils.closeFrame(code, reason));
}

doClose([int code, String reason]) {
if (ws != null) {
ws.close(code, reason);
}
}

doSend(data) => ws.send('[$data]');

Expand Down
17 changes: 17 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "sockjs-dart-client",
"version": "0.2.0",
"description": "A SockJS client in Dart",
"repository": {
"type": "git",
"url": "git://github.com/Workiva/sockjs-dart-client.git"
},
"bugs": {
"url": "https://github.com/Workiva/sockjs-dart-client/issues"
},
"homepage": "https://github.com/Workiva/sockjs-dart-client",
"devDependencies": {
"http": "0.0.0",
"sockjs": "^0.3.15"
}
}
5 changes: 5 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,10 @@ authors:
dependencies:
browser: '>=0.9.0 <1.0.0'
logging: '>=0.9.0 <1.0.0'
dev_dependencies:
coverage: '>=0.7.2'
dart_dev: '>=1.0.2'
dart_style: '>=0.2.0'
test: '>=0.12.5'
environment:
sdk: '>=1.0.0 <2.0.0'
104 changes: 104 additions & 0 deletions test/sockjs_client_integration_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
@TestOn('browser')
library sockjs_client.test.sockjs_client_test;

import 'dart:async';

import 'package:sockjs_client/sockjs_client.dart';
import 'package:test/test.dart';

const String echoUri = 'http://localhost:8000/echo';
const String corUri = 'http://localhost:8000/cor';
const String fofUri = 'http://localhost:8600/404';

void main() {
group('SockJS Client', () {
group('default', () {
Client createEchoClient() => new Client(echoUri);
Client createCorClient() => new Client(corUri);
Client create404Client() => new Client(fofUri);

integrationSuite(createEchoClient, createCorClient, create404Client);
});

group('web-socket', () {
Client createEchoClient() => new Client(echoUri, protocolsWhitelist: ['websocket']);
Client createCorClient() => new Client(corUri, protocolsWhitelist: ['websocket']);
Client create404Client() => new Client(fofUri, protocolsWhitelist: ['websocket']);

integrationSuite(createEchoClient, createCorClient, create404Client);
});

group('xhr-streaming', () {
Client createEchoClient() => new Client(echoUri, protocolsWhitelist: ['xhr-streaming']);
Client createCorClient() => new Client(corUri, protocolsWhitelist: ['xhr-streaming']);
Client create404Client() => new Client(fofUri, protocolsWhitelist: ['xhr-streaming']);

integrationSuite(createEchoClient, createCorClient, create404Client);
});
});
}

void integrationSuite(Client createEchoClient(), Client createCorClient(), Client create404Client()) {
test('connecting to a SockJS server', () async {
Client client = createEchoClient();
await client.onOpen.first;
});

test('sending and receiving messages', () async {
Client client = createEchoClient();
await client.onOpen.first;

Completer c = new Completer();
var echos = [];
client.onMessage.listen((MessageEvent message) {
echos.add(message.data);
if (echos.length == 2) {
c.complete();
}
});
client.send('message1');
client.send('message2');

await c.future;
client.close();

expect(echos, equals(['message1', 'message2']));
});

test('client closing the connection', () async {
Client client = createEchoClient();
await client.onOpen.first;
client.close();
await client.onClose.first;
});

test('client closing the connection with code and reason', () async {
Client client = createEchoClient();
await client.onOpen.first;
client.close(4001, 'Custom close.');
CloseEvent event = await client.onClose.first;
expect(event.code, equals(4001));
expect(event.reason, equals('Custom close.'));
});

test('server closing the connection', () async {
Client client = createCorClient();
await client.onOpen.first;
client.send('close');
await client.onClose.first;
});

test('server closing the connection with code and reason', () async {
Client client = createCorClient();
await client.onOpen.first;
client.send('close::4001::Custom close.');
CloseEvent event = await client.onClose.first;
expect(event.code, equals(4001));
expect(event.reason, equals('Custom close.'));
});

test('handle failed connection', () async {
Client client = create404Client();
await client.onClose.first;
});
}
1 change: 1 addition & 0 deletions test/sockjs_client_integration_test.dart.temp.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<script type="application/dart" src="sockjs_client_integration_test.dart"></script>
56 changes: 56 additions & 0 deletions tool/dev.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
library tool.dev;

import 'dart:async';
import 'dart:io';

import 'package:dart_dev/dart_dev.dart' show dev, config;
import 'package:dart_dev/util.dart' show TaskProcess, reporter;

main(List<String> args) async {
// https://github.com/Workiva/dart_dev

config.analyze.entryPoints = ['example/', 'lib/', 'tool/'];
config.format.directories = ['example/', 'lib/', 'tool/'];

config.coverage
..before = [_startServer]
..after = [_stopServer];
config.test
..before = [_startServer]
..after = [_stopServer]
..unitTests = []
..integrationTests = ['test/sockjs_client_integration_test.dart']
..platforms = ['content-shell', 'dartium'];

await dev(args);
}

/// Server needed for integration tests and examples.
TaskProcess _server;

/// Output from the server (only used if caching the output to dump at the end).
List<String> _serverOutput;

/// Start the server needed for integration tests and cache the server output
/// until the task requiring the server has finished. Then, the server output
/// will be dumped all at once.
Future _startServer() async {
_serverOutput = [];
_server = new TaskProcess('node', ['tool/server.js']);
_server.stdout.listen(_serverOutput.add);
_server.stderr.listen(_serverOutput.add);
// todo: wait for server to start
}

/// Stop the server needed for integration tests.
Future _stopServer() async {
if (_serverOutput != null) {
reporter.logGroup('HTTP Server Logs',
output: ' ${_serverOutput.join('\n')}');
}
if (_server != null) {
try {
_server.kill();
} catch (e) {}
}
}
Loading

0 comments on commit ac07d83

Please sign in to comment.