react-native/IntegrationTests/WebSocketTest.js

169 lines
3.7 KiB
JavaScript

/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
'use strict';
const React = require('react');
const ReactNative = require('react-native');
const {View} = ReactNative;
const {TestModule} = ReactNative.NativeModules;
const DEFAULT_WS_URL = 'ws://localhost:5555/';
const WS_EVENTS = ['close', 'error', 'message', 'open'];
const WS_STATES = [
/* 0 */ 'CONNECTING',
/* 1 */ 'OPEN',
/* 2 */ 'CLOSING',
/* 3 */ 'CLOSED',
];
type State = {
url: string,
fetchStatus: ?string,
socket: ?WebSocket,
socketState: ?number,
lastSocketEvent: ?string,
lastMessage: ?string | ?ArrayBuffer,
testMessage: string,
testExpectedResponse: string,
};
class WebSocketTest extends React.Component<{}, State> {
state: State = {
url: DEFAULT_WS_URL,
fetchStatus: null,
socket: null,
socketState: null,
lastSocketEvent: null,
lastMessage: null,
testMessage: 'testMessage',
testExpectedResponse: 'testMessage_response',
};
_waitFor = (condition: any, timeout: any, callback: any) => {
let remaining = timeout;
let t;
const timeoutFunction = function() {
if (condition()) {
callback(true);
return;
}
remaining--;
if (remaining === 0) {
callback(false);
} else {
t = setTimeout(timeoutFunction, 1000);
}
};
t = setTimeout(timeoutFunction, 1000);
};
_connect = () => {
const socket = new WebSocket(this.state.url);
WS_EVENTS.forEach(ev => socket.addEventListener(ev, this._onSocketEvent));
this.setState({
socket,
socketState: socket.readyState,
});
};
_socketIsConnected = () => {
return this.state.socketState === 1; //'OPEN'
};
_socketIsDisconnected = () => {
return this.state.socketState === 3; //'CLOSED'
};
_disconnect = () => {
if (!this.state.socket) {
return;
}
this.state.socket.close();
};
_onSocketEvent = (event: any) => {
const state: any = {
socketState: event.target.readyState,
lastSocketEvent: event.type,
};
if (event.type === 'message') {
state.lastMessage = event.data;
}
this.setState(state);
};
_sendText = (text: string) => {
if (!this.state.socket) {
return;
}
this.state.socket.send(text);
};
_sendTestMessage = () => {
this._sendText(this.state.testMessage);
};
_receivedTestExpectedResponse = () => {
return this.state.lastMessage === this.state.testExpectedResponse;
};
componentDidMount() {
this.testConnect();
}
testConnect = () => {
const component = this;
component._connect();
component._waitFor(component._socketIsConnected, 5, function(
connectSucceeded,
) {
if (!connectSucceeded) {
TestModule.markTestPassed(false);
return;
}
component.testSendAndReceive();
});
};
testSendAndReceive = () => {
const component = this;
component._sendTestMessage();
component._waitFor(component._receivedTestExpectedResponse, 5, function(
messageReceived,
) {
if (!messageReceived) {
TestModule.markTestPassed(false);
return;
}
component.testDisconnect();
});
};
testDisconnect = () => {
const component = this;
component._disconnect();
component._waitFor(component._socketIsDisconnected, 5, function(
disconnectSucceeded,
) {
TestModule.markTestPassed(disconnectSucceeded);
});
};
render(): React.Node {
return <View />;
}
}
WebSocketTest.displayName = 'WebSocketTest';
module.exports = WebSocketTest;