Skip to content

Commit 580f69a

Browse files
committed
fix(WebSocketSubject): resultSelector and protocols specifications work properly
- resultSelector errors will now be sent down the error path - protocol can now be specified properly with a config object argument
1 parent 3b1655e commit 580f69a

File tree

2 files changed

+164
-18
lines changed

2 files changed

+164
-18
lines changed

spec/observables/dom/webSocket-spec.js

Lines changed: 162 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22
var Rx = require('../../../dist/cjs/Rx.DOM');
33
var Observable = Rx.Observable;
44

5-
function noop() {
6-
// nope.
7-
}
8-
95
describe('Observable.webSocket', function () {
106
beforeEach(function () {
117
setupMockWebSocket();
@@ -32,7 +28,7 @@ describe('Observable.webSocket', function () {
3228
socket.open();
3329
expect(socket.lastMessageSent()).toBe('ping');
3430

35-
socket.triggerMessage('pong');
31+
socket.triggerMessage(JSON.stringify('pong'));
3632
expect(messageReceived).toBe(true);
3733
});
3834

@@ -50,7 +46,7 @@ describe('Observable.webSocket', function () {
5046
socket.open();
5147

5248
expected.forEach(function (x) {
53-
socket.triggerMessage(x);
49+
socket.triggerMessage(JSON.stringify(x));
5450
});
5551

5652
expect(results).toEqual(expected);
@@ -148,6 +144,165 @@ describe('Observable.webSocket', function () {
148144
expect(socket2).not.toBe(socket1);
149145
expect(socket2.lastMessageSent()).toBe('yo-ho! yo-ho!');
150146
});
147+
148+
it('should have a default resultSelector that parses message data as JSON', function () {
149+
var result;
150+
var expected = { mork: 'shazbot!' };
151+
var subject = Observable.webSocket('ws://mysocket');
152+
153+
subject.subscribe(function (x) {
154+
result = x;
155+
});
156+
157+
var socket = MockWebSocket.lastSocket();
158+
socket.open();
159+
socket.triggerMessage(JSON.stringify(expected));
160+
161+
expect(result).toEqual(expected);
162+
});
163+
164+
describe('with a config object', function () {
165+
it('should send and receive messages', function () {
166+
var messageReceived = false;
167+
var subject = Observable.webSocket({ url: 'ws://mysocket' });
168+
169+
subject.next('ping');
170+
171+
subject.subscribe(function (x) {
172+
expect(x).toBe('pong');
173+
messageReceived = true;
174+
});
175+
176+
var socket = MockWebSocket.lastSocket();
177+
expect(socket.url).toBe('ws://mysocket');
178+
179+
socket.open();
180+
expect(socket.lastMessageSent()).toBe('ping');
181+
182+
socket.triggerMessage(JSON.stringify('pong'));
183+
expect(messageReceived).toBe(true);
184+
});
185+
186+
it('should take a protocol and set it properly on the web socket', function () {
187+
var subject = Observable.webSocket({
188+
url: 'ws://mysocket',
189+
protocol: 'someprotocol'
190+
});
191+
192+
subject.subscribe();
193+
194+
var socket = MockWebSocket.lastSocket();
195+
expect(socket.protocol).toBe('someprotocol');
196+
});
197+
198+
it('should take a resultSelector', function () {
199+
var results = [];
200+
201+
var subject = Observable.webSocket({
202+
url: 'ws://mysocket',
203+
resultSelector: function (e) {
204+
return e.data + '!';
205+
}
206+
});
207+
208+
subject.subscribe(function (x) {
209+
results.push(x);
210+
});
211+
212+
var socket = MockWebSocket.lastSocket();
213+
socket.open();
214+
['ahoy', 'yarr', 'shove off'].forEach(function (x) {
215+
socket.triggerMessage(x);
216+
});
217+
218+
expect(results).toEqual(['ahoy!', 'yarr!', 'shove off!']);
219+
});
220+
221+
it('if the resultSelector fails it should go down the error path', function () {
222+
223+
var subject = Observable.webSocket({
224+
url: 'ws://mysocket',
225+
resultSelector: function (e) {
226+
throw new Error('I am a bad error');
227+
}
228+
});
229+
230+
subject.subscribe(function (x) {
231+
expect(x).toBe('this should not happen');
232+
}, function (err) {
233+
expect(err).toEqual(new Error('I am a bad error'));
234+
});
235+
236+
var socket = MockWebSocket.lastSocket();
237+
socket.open();
238+
socket.triggerMessage('weee!');
239+
});
240+
241+
it('should accept a closingObserver', function () {
242+
var calls = 0;
243+
var subject = Observable.webSocket({
244+
url: 'ws://mysocket',
245+
closingObserver: {
246+
next: function (x) {
247+
calls++;
248+
expect(x).toBe(undefined);
249+
}
250+
}
251+
});
252+
253+
subject.subscribe();
254+
var socket = MockWebSocket.lastSocket();
255+
socket.open();
256+
257+
expect(calls).toBe(0);
258+
259+
subject.complete();
260+
expect(calls).toBe(1);
261+
262+
subject.subscribe();
263+
socket = MockWebSocket.lastSocket();
264+
socket.open();
265+
266+
subject.error({ code: 1337 });
267+
expect(calls).toBe(2);
268+
});
269+
270+
it('should accept a closeObserver', function () {
271+
var expected = [{ wasClean: true }, { wasClean: false }];
272+
var closes = [];
273+
var subject = Observable.webSocket({
274+
url: 'ws://mysocket',
275+
closeObserver: {
276+
next: function (e) {
277+
closes.push(e);
278+
}
279+
}
280+
});
281+
282+
subject.subscribe();
283+
var socket = MockWebSocket.lastSocket();
284+
socket.open();
285+
286+
expect(closes.length).toBe(0);
287+
288+
socket.triggerClose(expected[0]);
289+
expect(closes.length).toBe(1);
290+
291+
292+
subject.subscribe(null, function (err) {
293+
expect(err).toBe(expected[1]);
294+
});
295+
296+
socket = MockWebSocket.lastSocket();
297+
socket.open();
298+
299+
socket.triggerClose(expected[1]);
300+
expect(closes.length).toBe(2);
301+
302+
expect(closes[0]).toBe(expected[0]);
303+
expect(closes[1]).toBe(expected[1]);
304+
});
305+
});
151306
});
152307

153308
var sockets = [];
@@ -175,15 +330,6 @@ MockWebSocket.prototype = {
175330
return sent.length > 0 ? sent[sent.length - 1] : undefined;
176331
},
177332

178-
closeDirty: function (code, reason) {
179-
if (this.readyState < 2) {
180-
this.readyState = 2;
181-
this.closeCode = code;
182-
this.closeReason = reason;
183-
this.triggerClose({ wasClean: false });
184-
}
185-
},
186-
187333
triggerClose: function (e) {
188334
this.readyState = 3;
189335
this.trigger('close', e);
@@ -196,7 +342,7 @@ MockWebSocket.prototype = {
196342

197343
triggerMessage: function (data) {
198344
var messageEvent = {
199-
data: JSON.stringify(data),
345+
data: data,
200346
origin: 'mockorigin',
201347
ports: undefined,
202348
source: __root__,

src/observable/dom/webSocket.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export class WebSocketSubject<T> extends Subject<T> {
9696
}
9797

9898
if (self.url && !self.socket) {
99-
const socket = new WebSocket(self.url);
99+
const socket = self.protocol ? new WebSocket(self.url, self.protocol) : new WebSocket(self.url);
100100
self.socket = socket;
101101

102102
socket.onopen = (e) => {
@@ -151,7 +151,7 @@ export class WebSocketSubject<T> extends Subject<T> {
151151

152152
socket.onmessage = (e: MessageEvent) => {
153153
const result = tryCatch(self.resultSelector)(e);
154-
if (result === errorObject.e) {
154+
if (result === errorObject) {
155155
self._finalError(errorObject.e);
156156
} else {
157157
self._finalNext(result);

0 commit comments

Comments
 (0)