Skip to content

CP-1099 Add close() to client. Add integration tests. #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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