summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandy Abernethy <ra@apache.org>2015-02-16 01:25:53 -0800
committerRandy Abernethy <ra@apache.org>2015-02-16 01:25:53 -0800
commitd8187c5ff1d8b83d170cbce69282688be39df19c (patch)
tree00955bc1293272bd78ee22c4fd6e77ecc3caf543
parent3b9ff4de6e38eb2e0e17eacd22865e4b8ce27e37 (diff)
downloadthrift-d8187c5ff1d8b83d170cbce69282688be39df19c.tar.gz
THRIFT-2976: add browserify support and tests
Client: nodejs Patch: Andrew de Andrade
-rw-r--r--lib/nodejs/lib/thrift/browser.js34
-rw-r--r--lib/nodejs/lib/thrift/index.js5
-rw-r--r--lib/nodejs/lib/thrift/json_protocol.js15
-rw-r--r--lib/nodejs/lib/thrift/multiplexed_protocol.js1
-rw-r--r--lib/nodejs/lib/thrift/web_server.js2
-rw-r--r--lib/nodejs/lib/thrift/ws_connection.js4
-rw-r--r--lib/nodejs/lib/thrift/ws_transport.js204
-rw-r--r--lib/nodejs/lib/thrift/xhr_connection.js280
-rw-r--r--lib/nodejs/test/binary.test.js142
-rw-r--r--lib/nodejs/test/browser_client.js27
-rw-r--r--lib/nodejs/test/server.js5
-rw-r--r--lib/nodejs/test/test-cases.js14
-rwxr-xr-xlib/nodejs/test/testAll.sh21
-rw-r--r--lib/nodejs/test/test_driver.js296
-rw-r--r--lib/nodejs/test/test_handler.js28
-rw-r--r--[-rwxr-xr-x]package.json6
16 files changed, 836 insertions, 248 deletions
diff --git a/lib/nodejs/lib/thrift/browser.js b/lib/nodejs/lib/thrift/browser.js
new file mode 100644
index 000000000..4593a8fd1
--- /dev/null
+++ b/lib/nodejs/lib/thrift/browser.js
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+exports.Thrift = require('./thrift');
+
+var xhrConnection = require('./xhr_connection');
+exports.XHRConnection = xhrConnection.XHRConnection;
+exports.createXHRConnection = xhrConnection.createXHRConnection;
+exports.createXHRClient = xhrConnection.createXHRClient;
+
+exports.Multiplexer = require('./multiplexed_protocol').Multiplexer;
+
+exports.TWebSocketTransport = require('./ws_transport');
+exports.TBufferedTransport = require('./buffered_transport');
+exports.TFramedTransport = require('./framed_transport');
+
+exports.Protocol = exports.TJSONProtocol = require('./json_protocol');
+exports.TBinaryProtocol = require('./binary_protocol');
+exports.TCompactProtocol = require('./compact_protocol');
diff --git a/lib/nodejs/lib/thrift/index.js b/lib/nodejs/lib/thrift/index.js
index e313dbb57..61e5cbd01 100644
--- a/lib/nodejs/lib/thrift/index.js
+++ b/lib/nodejs/lib/thrift/index.js
@@ -36,6 +36,11 @@ exports.WSConnection = wsConnection.WSConnection;
exports.createWSConnection = wsConnection.createWSConnection;
exports.createWSClient = wsConnection.createWSClient;
+var xhrConnection = require('./xhr_connection');
+exports.XHRConnection = xhrConnection.XHRConnection;
+exports.createXHRConnection = xhrConnection.createXHRConnection;
+exports.createXHRClient = xhrConnection.createXHRClient;
+
var server = require('./server');
exports.createServer = server.createServer;
exports.createMultiplexServer = server.createMultiplexServer;
diff --git a/lib/nodejs/lib/thrift/json_protocol.js b/lib/nodejs/lib/thrift/json_protocol.js
index f4678f5d5..77339f7f1 100644
--- a/lib/nodejs/lib/thrift/json_protocol.js
+++ b/lib/nodejs/lib/thrift/json_protocol.js
@@ -39,6 +39,8 @@ module.exports = TJSONProtocol;
* var protocol = new Thrift.Protocol(transport);
*/
function TJSONProtocol(trans) {
+ this.tstack = [];
+ this.tpos = [];
this.trans = trans;
};
@@ -607,15 +609,7 @@ TJSONProtocol.prototype.readSetEnd = function() {
* False unless the next number in the protocol buffer
* is 1, in which case the value property is True */
TJSONProtocol.prototype.readBool = function() {
- var r = this.readI32();
-
- if (r !== null && r.value == '1') {
- r.value = true;
- } else {
- r.value = false;
- }
-
- return r;
+ return this.readI32() == '1';
};
/** Returns the an object with a value property set to the
@@ -685,8 +679,7 @@ TJSONProtocol.prototype.readBinary = function() {
/** Returns the an object with a value property set to the
next value found in the protocol buffer */
TJSONProtocol.prototype.readString = function() {
- var r = this.readI32();
- return r;
+ return this.readI32();
};
/**
diff --git a/lib/nodejs/lib/thrift/multiplexed_protocol.js b/lib/nodejs/lib/thrift/multiplexed_protocol.js
index 0745a1bd4..9caf6ab52 100644
--- a/lib/nodejs/lib/thrift/multiplexed_protocol.js
+++ b/lib/nodejs/lib/thrift/multiplexed_protocol.js
@@ -19,7 +19,6 @@
var util = require('util');
var Thrift = require('./thrift');
-exports.Wrapper = Wrapper;
exports.Multiplexer = Multiplexer;
function Wrapper(serviceName, protocol, connection) {
diff --git a/lib/nodejs/lib/thrift/web_server.js b/lib/nodejs/lib/thrift/web_server.js
index 68eb94d45..37159eafb 100644
--- a/lib/nodejs/lib/thrift/web_server.js
+++ b/lib/nodejs/lib/thrift/web_server.js
@@ -516,6 +516,8 @@ exports.createWebServer = function(options) {
"Upgrade: websocket\r\n" +
"Connection: Upgrade\r\n" +
"Sec-WebSocket-Accept: " + hash.digest("base64") + "\r\n" +
+ "Sec-WebSocket-Origin: " + request.headers.origin + "\r\n" +
+ "Sec-WebSocket-Location: ws://" + request.headers.host + request.url + "\r\n" +
"\r\n");
//Handle WebSocket traffic
var data = null;
diff --git a/lib/nodejs/lib/thrift/ws_connection.js b/lib/nodejs/lib/thrift/ws_connection.js
index 08129340a..052cbd4e9 100644
--- a/lib/nodejs/lib/thrift/ws_connection.js
+++ b/lib/nodejs/lib/thrift/ws_connection.js
@@ -29,6 +29,8 @@ var InputBufferUnderrunError = require('./input_buffer_underrun_error');
var createClient = require('./create_client');
+exports.WSConnection = WSConnection;
+
/**
* @class
* @name WSConnectOptions
@@ -73,7 +75,7 @@ var createClient = require('./create_client');
* semantics implemented using Websockets.
* @see {@link createWSConnection}
*/
-var WSConnection = exports.WSConnection = function(host, port, options) {
+function WSConnection(host, port, options) {
//Initialize the emitter base object
EventEmitter.call(this);
diff --git a/lib/nodejs/lib/thrift/ws_transport.js b/lib/nodejs/lib/thrift/ws_transport.js
new file mode 100644
index 000000000..8e750e233
--- /dev/null
+++ b/lib/nodejs/lib/thrift/ws_transport.js
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+module.exports = TWebSocketTransport;
+
+/**
+ * Constructor Function for the WebSocket transport.
+ * @constructor
+ * @param {string} [url] - The URL to connect to.
+ * @classdesc The Apache Thrift Transport layer performs byte level I/O
+ * between RPC clients and servers. The JavaScript TWebSocketTransport object
+ * uses the WebSocket protocol. Target servers must implement WebSocket.
+ * (see: node.js example server_http.js).
+ * @example
+ * var transport = new Thrift.TWebSocketTransport("http://localhost:8585");
+ */
+function TWebSocketTransport(url) {
+ this.__reset(url);
+};
+
+
+TWebSocketTransport.prototype.__reset = function(url) {
+ this.url = url; //Where to connect
+ this.socket = null; //The web socket
+ this.callbacks = []; //Pending callbacks
+ this.send_pending = []; //Buffers/Callback pairs waiting to be sent
+ this.send_buf = ''; //Outbound data, immutable until sent
+ this.recv_buf = ''; //Inbound data
+ this.rb_wpos = 0; //Network write position in receive buffer
+ this.rb_rpos = 0; //Client read position in receive buffer
+};
+
+/**
+ * Sends the current WS request and registers callback. The async
+ * parameter is ignored (WS flush is always async) and the callback
+ * function parameter is required.
+ * @param {object} async - Ignored.
+ * @param {object} callback - The client completion callback.
+ * @returns {undefined|string} Nothing (undefined)
+ */
+TWebSocketTransport.prototype.flush = function(async, callback) {
+ var self = this;
+ if (this.isOpen()) {
+ //Send data and register a callback to invoke the client callback
+ this.socket.send(this.send_buf);
+ this.callbacks.push((function() {
+ var clientCallback = callback;
+ return function(msg) {
+ self.setRecvBuffer(msg);
+ clientCallback();
+ };
+ }()));
+ } else {
+ //Queue the send to go out __onOpen
+ this.send_pending.push({
+ buf: this.send_buf,
+ cb: callback
+ });
+ }
+};
+
+TWebSocketTransport.prototype.__onOpen = function() {
+ var self = this;
+ if (this.send_pending.length > 0) {
+ //If the user made calls before the connection was fully
+ //open, send them now
+ this.send_pending.forEach(function(elem) {
+ this.socket.send(elem.buf);
+ this.callbacks.push((function() {
+ var clientCallback = elem.cb;
+ return function(msg) {
+ self.setRecvBuffer(msg);
+ clientCallback();
+ };
+ }()));
+ });
+ this.send_pending = [];
+ }
+};
+
+TWebSocketTransport.prototype.__onClose = function(evt) {
+ this.__reset(this.url);
+};
+
+TWebSocketTransport.prototype.__onMessage = function(evt) {
+ if (this.callbacks.length) {
+ this.callbacks.shift()(evt.data);
+ }
+};
+
+TWebSocketTransport.prototype.__onError = function(evt) {
+ console.log("Thrift WebSocket Error: " + evt.toString());
+ this.socket.close();
+};
+
+/**
+ * Sets the buffer to use when receiving server responses.
+ * @param {string} buf - The buffer to receive server responses.
+ */
+TWebSocketTransport.prototype.setRecvBuffer = function(buf) {
+ this.recv_buf = buf;
+ this.recv_buf_sz = this.recv_buf.length;
+ this.wpos = this.recv_buf.length;
+ this.rpos = 0;
+};
+
+/**
+ * Returns true if the transport is open
+ * @readonly
+ * @returns {boolean}
+ */
+TWebSocketTransport.prototype.isOpen = function() {
+ return this.socket && this.socket.readyState == this.socket.OPEN;
+};
+
+/**
+ * Opens the transport connection
+ */
+TWebSocketTransport.prototype.open = function() {
+ //If OPEN/CONNECTING/CLOSING ignore additional opens
+ if (this.socket && this.socket.readyState != this.socket.CLOSED) {
+ return;
+ }
+ //If there is no socket or the socket is closed:
+ this.socket = new WebSocket(this.url);
+ this.socket.onopen = this.__onOpen.bind(this);
+ this.socket.onmessage = this.__onMessage.bind(this);
+ this.socket.onerror = this.__onError.bind(this);
+ this.socket.onclose = this.__onClose.bind(this);
+};
+
+/**
+ * Closes the transport connection
+ */
+TWebSocketTransport.prototype.close = function() {
+ this.socket.close();
+};
+
+/**
+ * Returns the specified number of characters from the response
+ * buffer.
+ * @param {number} len - The number of characters to return.
+ * @returns {string} Characters sent by the server.
+ */
+TWebSocketTransport.prototype.read = function(len) {
+ var avail = this.wpos - this.rpos;
+
+ if (avail === 0) {
+ return '';
+ }
+
+ var give = len;
+
+ if (avail < len) {
+ give = avail;
+ }
+
+ var ret = this.read_buf.substr(this.rpos, give);
+ this.rpos += give;
+
+ //clear buf when complete?
+ return ret;
+};
+
+/**
+ * Returns the entire response buffer.
+ * @returns {string} Characters sent by the server.
+ */
+TWebSocketTransport.prototype.readAll = function() {
+ return this.recv_buf;
+};
+
+/**
+ * Sets the send buffer to buf.
+ * @param {string} buf - The buffer to send.
+ */
+TWebSocketTransport.prototype.write = function(buf) {
+ this.send_buf = buf;
+};
+
+/**
+ * Returns the send buffer.
+ * @readonly
+ * @returns {string} The send buffer.
+ */
+TWebSocketTransport.prototype.getSendBuffer = function() {
+ return this.send_buf;
+};
diff --git a/lib/nodejs/lib/thrift/xhr_connection.js b/lib/nodejs/lib/thrift/xhr_connection.js
new file mode 100644
index 000000000..6459c900c
--- /dev/null
+++ b/lib/nodejs/lib/thrift/xhr_connection.js
@@ -0,0 +1,280 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+var util = require('util');
+var EventEmitter = require("events").EventEmitter;
+var thrift = require('./thrift');
+
+var TBufferedTransport = require('./buffered_transport');
+var TJSONProtocol = require('./json_protocol');
+var InputBufferUnderrunError = require('./input_buffer_underrun_error');
+
+var createClient = require('./create_client');
+
+exports.XHRConnection = XHRConnection;
+
+/**
+ * Constructor Function for the XHR Connection.
+ * If you do not specify a host and port then XHRConnection will default to the
+ * host and port of the page from which this javascript is served.
+ * @constructor
+ * @param {string} [url] - The URL to connect to.
+ * @classdesc TXHRConnection objects provide Thrift end point transport
+ * semantics implemented using XHR.
+ * @example
+ * var transport = new Thrift.TXHRConnection('localhost', 9099, {});
+ */
+function XHRConnection(host, port, options) {
+ this.options = options || {};
+ this.wpos = 0;
+ this.rpos = 0;
+ this.useCORS = (options && options.useCORS);
+ this.send_buf = '';
+ this.recv_buf = '';
+ this.transport = options.transport || TBufferedTransport;
+ this.protocol = options.protocol || TJSONProtocol;
+ this.headers = options.headers || {};
+
+ host = host || window.location.host;
+ port = port || window.location.port;
+ var prefix = options.https ? 'https://' : 'http://';
+ var path = options.path || '/';
+
+ if (port === '') {
+ port = undefined;
+ }
+
+ if (!port || port === 80 || port === '80') {
+ this.url = prefix + host + path;
+ } else {
+ this.url = prefix + host + ':' + port + path;
+ }
+
+ //The sequence map is used to map seqIDs back to the
+ // calling client in multiplexed scenarios
+ this.seqId2Service = {};
+};
+
+util.inherits(XHRConnection, EventEmitter);
+
+/**
+* Gets the browser specific XmlHttpRequest Object.
+* @returns {object} the browser XHR interface object
+*/
+XHRConnection.prototype.getXmlHttpRequestObject = function() {
+ try { return new XMLHttpRequest(); } catch (e1) { }
+ try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch (e2) { }
+ try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e3) { }
+
+ throw "Your browser doesn't support XHR.";
+};
+
+/**
+ * Sends the current XRH request if the transport was created with a URL
+ * and the async parameter is false. If the transport was not created with
+ * a URL, or the async parameter is True and no callback is provided, or
+ * the URL is an empty string, the current send buffer is returned.
+ * @param {object} async - If true the current send buffer is returned.
+ * @param {object} callback - Optional async completion callback
+ * @returns {undefined|string} Nothing or the current send buffer.
+ * @throws {string} If XHR fails.
+ */
+XHRConnection.prototype.flush = function() {
+ var self = this;
+ if (this.url === undefined || this.url === '') {
+ return this.send_buf;
+ }
+
+ var xreq = this.getXmlHttpRequestObject();
+
+ if (xreq.overrideMimeType) {
+ xreq.overrideMimeType('application/json');
+ }
+
+ xreq.onreadystatechange = function() {
+ if (this.readyState == 4 && this.status == 200) {
+ self.setRecvBuffer(this.responseText);
+ }
+ };
+
+ xreq.open('POST', this.url, true);
+
+ Object.keys(this.headers).forEach(function(headerKey) {
+ xreq.setRequestHeader(headerKey, self.headers[headerKey]);
+ });
+
+ xreq.send(this.send_buf);
+};
+
+/**
+ * Sets the buffer to provide the protocol when deserializing.
+ * @param {string} buf - The buffer to supply the protocol.
+ */
+XHRConnection.prototype.setRecvBuffer = function(buf) {
+ this.recv_buf = buf;
+ this.recv_buf_sz = this.recv_buf.length;
+ this.wpos = this.recv_buf.length;
+ this.rpos = 0;
+
+ if (Object.prototype.toString.call(buf) == "[object ArrayBuffer]") {
+ var data = new Uint8Array(buf);
+ }
+ var thing = new Buffer(data || buf);
+
+ this.transport.receiver(this.__decodeCallback.bind(this))(thing);
+
+};
+
+XHRConnection.prototype.__decodeCallback = function(transport_with_data) {
+ var proto = new this.protocol(transport_with_data);
+ try {
+ while (true) {
+ var header = proto.readMessageBegin();
+ var dummy_seqid = header.rseqid * -1;
+ var client = this.client;
+ //The Multiplexed Protocol stores a hash of seqid to service names
+ // in seqId2Service. If the SeqId is found in the hash we need to
+ // lookup the appropriate client for this call.
+ // The client var is a single client object when not multiplexing,
+ // when using multiplexing it is a service name keyed hash of client
+ // objects.
+ //NOTE: The 2 way interdependencies between protocols, transports,
+ // connections and clients in the Node.js implementation are irregular
+ // and make the implementation difficult to extend and maintain. We
+ // should bring this stuff inline with typical thrift I/O stack
+ // operation soon.
+ // --ra
+ var service_name = this.seqId2Service[header.rseqid];
+ if (service_name) {
+ client = this.client[service_name];
+ delete this.seqId2Service[header.rseqid];
+ }
+ /*jshint -W083 */
+ client._reqs[dummy_seqid] = function(err, success) {
+ transport_with_data.commitPosition();
+ var clientCallback = client._reqs[header.rseqid];
+ delete client._reqs[header.rseqid];
+ if (clientCallback) {
+ clientCallback(err, success);
+ }
+ };
+ /*jshint +W083 */
+ if (client['recv_' + header.fname]) {
+ client['recv_' + header.fname](proto, header.mtype, dummy_seqid);
+ } else {
+ delete client._reqs[dummy_seqid];
+ this.emit("error",
+ new thrift.TApplicationException(
+ thrift.TApplicationExceptionType.WRONG_METHOD_NAME,
+ "Received a response to an unknown RPC function"));
+ }
+ }
+ } catch (e) {
+ if (e instanceof InputBufferUnderrunError) {
+ transport_with_data.rollbackPosition();
+ } else {
+ throw e;
+ }
+ }
+};
+
+/**
+ * Returns true if the transport is open, XHR always returns true.
+ * @readonly
+ * @returns {boolean} Always True.
+ */
+XHRConnection.prototype.isOpen = function() {
+ return true;
+};
+
+/**
+ * Opens the transport connection, with XHR this is a nop.
+ */
+XHRConnection.prototype.open = function() {};
+
+/**
+ * Closes the transport connection, with XHR this is a nop.
+ */
+XHRConnection.prototype.close = function() {};
+
+/**
+ * Returns the specified number of characters from the response
+ * buffer.
+ * @param {number} len - The number of characters to return.
+ * @returns {string} Characters sent by the server.
+ */
+XHRConnection.prototype.read = function(len) {
+ var avail = this.wpos - this.rpos;
+
+ if (avail === 0) {
+ return '';
+ }
+
+ var give = len;
+
+ if (avail < len) {
+ give = avail;
+ }
+
+ var ret = this.read_buf.substr(this.rpos, give);
+ this.rpos += give;
+
+ //clear buf when complete?
+ return ret;
+};
+
+/**
+ * Returns the entire response buffer.
+ * @returns {string} Characters sent by the server.
+ */
+XHRConnection.prototype.readAll = function() {
+ return this.recv_buf;
+};
+
+/**
+ * Sets the send buffer to buf.
+ * @param {string} buf - The buffer to send.
+ */
+XHRConnection.prototype.write = function(buf) {
+ this.send_buf = buf;
+ this.flush();
+};
+
+/**
+ * Returns the send buffer.
+ * @readonly
+ * @returns {string} The send buffer.
+ */
+XHRConnection.prototype.getSendBuffer = function() {
+ return this.send_buf;
+};
+
+/**
+ * Creates a new TXHRTransport object, used by Thrift clients to connect
+ * to Thrift HTTP based servers.
+ * @param {string} host - The host name or IP to connect to.
+ * @param {number} port - The TCP port to connect to.
+ * @param {XHRConnectOptions} options - The configuration options to use.
+ * @returns {XHRConnection} The connection object.
+ * @see {@link XHRConnectOptions}
+ */
+exports.createXHRConnection = function(host, port, options) {
+ return new XHRConnection(host, port, options);
+};
+
+exports.createXHRClient = createClient;
diff --git a/lib/nodejs/test/binary.test.js b/lib/nodejs/test/binary.test.js
index dacadef34..38ba63411 100644
--- a/lib/nodejs/test/binary.test.js
+++ b/lib/nodejs/test/binary.test.js
@@ -17,117 +17,121 @@
* under the License.
*/
-var testCase = require('nodeunit').testCase;
+var test = require('tape');
var binary = require('thrift/binary');
-module.exports = testCase({
- "Should read signed byte": function(test){
- test.strictEqual(1, binary.readByte(0x01));
- test.strictEqual(-1, binary.readByte(0xFF));
+var cases = {
+ "Should read signed byte": function(assert){
+ assert.equal(1, binary.readByte(0x01));
+ assert.equal(-1, binary.readByte(0xFF));
- test.strictEqual(127, binary.readByte(0x7F));
- test.strictEqual(-128, binary.readByte(0x80));
- test.done();
+ assert.equal(127, binary.readByte(0x7F));
+ assert.equal(-128, binary.readByte(0x80));
+ assert.end();
},
- "Should write byte": function(test){
- //Protocol simply writes to the buffer. Nothing to test.. yet.
- test.ok(true);
- test.done();
+ "Should write byte": function(assert){
+ //Protocol simply writes to the buffer. Nothing to test.. yet.
+ assert.ok(true);
+ assert.end();
},
- "Should read I16": function(test) {
- test.strictEqual(0, binary.readI16([0x00, 0x00]));
- test.strictEqual(1, binary.readI16([0x00, 0x01]));
- test.strictEqual(-1, binary.readI16([0xff, 0xff]));
+ "Should read I16": function(assert) {
+ assert.equal(0, binary.readI16([0x00, 0x00]));
+ assert.equal(1, binary.readI16([0x00, 0x01]));
+ assert.equal(-1, binary.readI16([0xff, 0xff]));
// Min I16
- test.strictEqual(-32768, binary.readI16([0x80, 0x00]));
+ assert.equal(-32768, binary.readI16([0x80, 0x00]));
// Max I16
- test.strictEqual(32767, binary.readI16([0x7f, 0xff]));
- test.done();
+ assert.equal(32767, binary.readI16([0x7f, 0xff]));
+ assert.end();
},
- "Should write I16": function(test) {
- test.deepEqual([0x00, 0x00], binary.writeI16([], 0));
- test.deepEqual([0x00, 0x01], binary.writeI16([], 1));
- test.deepEqual([0xff, 0xff], binary.writeI16([], -1));
+ "Should write I16": function(assert) {
+ assert.deepEqual([0x00, 0x00], binary.writeI16([], 0));
+ assert.deepEqual([0x00, 0x01], binary.writeI16([], 1));
+ assert.deepEqual([0xff, 0xff], binary.writeI16([], -1));
// Min I16
- test.deepEqual([0x80, 0x00], binary.writeI16([], -32768));
+ assert.deepEqual([0x80, 0x00], binary.writeI16([], -32768));
// Max I16
- test.deepEqual([0x7f, 0xff], binary.writeI16([], 32767));
- test.done();
+ assert.deepEqual([0x7f, 0xff], binary.writeI16([], 32767));
+ assert.end();
},
- "Should read I32": function(test) {
- test.strictEqual(0, binary.readI32([0x00, 0x00, 0x00, 0x00]));
- test.strictEqual(1, binary.readI32([0x00, 0x00, 0x00, 0x01]));
- test.strictEqual(-1, binary.readI32([0xff, 0xff, 0xff, 0xff]));
+ "Should read I32": function(assert) {
+ assert.equal(0, binary.readI32([0x00, 0x00, 0x00, 0x00]));
+ assert.equal(1, binary.readI32([0x00, 0x00, 0x00, 0x01]));
+ assert.equal(-1, binary.readI32([0xff, 0xff, 0xff, 0xff]));
// Min I32
- test.strictEqual(-2147483648, binary.readI32([0x80, 0x00, 0x00, 0x00]));
+ assert.equal(-2147483648, binary.readI32([0x80, 0x00, 0x00, 0x00]));
// Max I32
- test.strictEqual(2147483647, binary.readI32([0x7f, 0xff, 0xff, 0xff]));
- test.done();
+ assert.equal(2147483647, binary.readI32([0x7f, 0xff, 0xff, 0xff]));
+ assert.end();
},
- "Should write I32": function(test) {
- test.deepEqual([0x00, 0x00, 0x00, 0x00], binary.writeI32([], 0));
- test.deepEqual([0x00, 0x00, 0x00, 0x01], binary.writeI32([], 1));
- test.deepEqual([0xff, 0xff, 0xff, 0xff], binary.writeI32([], -1));
+ "Should write I32": function(assert) {
+ assert.deepEqual([0x00, 0x00, 0x00, 0x00], binary.writeI32([], 0));
+ assert.deepEqual([0x00, 0x00, 0x00, 0x01], binary.writeI32([], 1));
+ assert.deepEqual([0xff, 0xff, 0xff, 0xff], binary.writeI32([], -1));
// Min I32
- test.deepEqual([0x80, 0x00, 0x00, 0x00], binary.writeI32([], -2147483648));
+ assert.deepEqual([0x80, 0x00, 0x00, 0x00], binary.writeI32([], -2147483648));
// Max I32
- test.deepEqual([0x7f, 0xff, 0xff, 0xff], binary.writeI32([], 2147483647));
- test.done();
+ assert.deepEqual([0x7f, 0xff, 0xff, 0xff], binary.writeI32([], 2147483647));
+ assert.end();
},
- "Should read doubles": function(test) {
- test.strictEqual(0, binary.readDouble([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
- test.strictEqual(0, binary.readDouble([0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
- test.strictEqual(1, binary.readDouble([0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
- test.strictEqual(2, binary.readDouble([0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
- test.strictEqual(-2, binary.readDouble([0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
+ "Should read doubles": function(assert) {
+ assert.equal(0, binary.readDouble([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
+ assert.equal(0, binary.readDouble([0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
+ assert.equal(1, binary.readDouble([0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
+ assert.equal(2, binary.readDouble([0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
+ assert.equal(-2, binary.readDouble([0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
- test.strictEqual(Math.PI, binary.readDouble([0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18]))
+ assert.equal(Math.PI, binary.readDouble([0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18]))
- test.strictEqual(Infinity, binary.readDouble([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
- test.strictEqual(-Infinity, binary.readDouble([0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
+ assert.equal(Infinity, binary.readDouble([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
+ assert.equal(-Infinity, binary.readDouble([0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
- test.ok(isNaN(binary.readDouble([0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])))
+ assert.ok(isNaN(binary.readDouble([0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])))
- test.strictEqual(1/3, binary.readDouble([0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55]))
+ assert.equal(1/3, binary.readDouble([0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55]))
// Min subnormal positive double
- test.strictEqual(4.9406564584124654e-324, binary.readDouble([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]))
+ assert.equal(4.9406564584124654e-324, binary.readDouble([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]))
// Min normal positive double
- test.strictEqual(2.2250738585072014e-308, binary.readDouble([0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
+ assert.equal(2.2250738585072014e-308, binary.readDouble([0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
// Max positive double
- test.strictEqual(1.7976931348623157e308, binary.readDouble([0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]))
- test.done();
+ assert.equal(1.7976931348623157e308, binary.readDouble([0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]))
+ assert.end();
},
- "Should write doubles": function(test) {
- test.deepEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 0));
- test.deepEqual([0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 1));
- test.deepEqual([0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 2));
- test.deepEqual([0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], -2));
+ "Should write doubles": function(assert) {
+ assert.deepEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 0));
+ assert.deepEqual([0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 1));
+ assert.deepEqual([0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 2));
+ assert.deepEqual([0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], -2));
- test.deepEqual([0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18], binary.writeDouble([], Math.PI));
+ assert.deepEqual([0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18], binary.writeDouble([], Math.PI));
- test.deepEqual([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], Infinity));
- test.deepEqual([0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], -Infinity));
+ assert.deepEqual([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], Infinity));
+ assert.deepEqual([0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], -Infinity));
- test.deepEqual([0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], NaN));
+ assert.deepEqual([0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], NaN));
- test.deepEqual([0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55], binary.writeDouble([], 1/3));
+ assert.deepEqual([0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55], binary.writeDouble([], 1/3));
// Min subnormal positive double
- test.deepEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01], binary.writeDouble([], 4.9406564584124654e-324));
+ assert.deepEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01], binary.writeDouble([], 4.9406564584124654e-324));
// Min normal positive double
- test.deepEqual([0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 2.2250738585072014e-308));
+ assert.deepEqual([0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 2.2250738585072014e-308));
// Max positive double
- test.deepEqual([0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], binary.writeDouble([], 1.7976931348623157e308));
- test.done();
+ assert.deepEqual([0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], binary.writeDouble([], 1.7976931348623157e308));
+ assert.end();
}
+};
+
+Object.keys(cases).forEach(function(caseName) {
+ test(caseName, cases[caseName]);
});
diff --git a/lib/nodejs/test/browser_client.js b/lib/nodejs/test/browser_client.js
new file mode 100644
index 000000000..27db543be
--- /dev/null
+++ b/lib/nodejs/test/browser_client.js
@@ -0,0 +1,27 @@
+
+var assert = require('assert');
+var thrift = require('thrift');
+var helpers = require('./helpers');
+var ThriftTest = require('./gen-nodejs/ThriftTest');
+var ThriftTestDriver = require('./test_driver').ThriftTestDriver;
+
+// createXHRConnection createWSConnection
+var connection = thrift.createXHRConnection("localhost", 9090, {
+ transport: helpers.transports['buffered'],
+ protocol: helpers.protocols['json'],
+ path: '/test'
+});
+
+connection.on('error', function(err) {
+ assert(false, err);
+});
+
+// Uncomment the following line to start a websockets connection
+// connection.open();
+
+// createWSClient createXHRClient
+var client = thrift.createXHRClient(ThriftTest, connection);
+
+ThriftTestDriver(client, function (status) {
+ console.log('Browser:', status);
+});
diff --git a/lib/nodejs/test/server.js b/lib/nodejs/test/server.js
index 2d53e115c..b33e91b21 100644
--- a/lib/nodejs/test/server.js
+++ b/lib/nodejs/test/server.js
@@ -57,7 +57,10 @@ if (type === 'http' || type ==='websocket') {
options.processor = ThriftTest;
options = {
- services: { "/test": options }
+ services: { "/test": options },
+ cors: {
+ '*': true
+ }
}
}
diff --git a/lib/nodejs/test/test-cases.js b/lib/nodejs/test/test-cases.js
index 33866572d..0d13cddfc 100644
--- a/lib/nodejs/test/test-cases.js
+++ b/lib/nodejs/test/test-cases.js
@@ -1,6 +1,5 @@
'use strict';
-var assert = require('assert');
var ttypes = require('./gen-nodejs/ThriftTest_types');
//all Languages in UTF-8
@@ -55,17 +54,19 @@ var simple = [
['testByte', -1],
['testByte', -127],
['testI32', -1],
+ ['testDouble', -5.2098523],
+ ['testDouble', 7.012052175215044],
+ ['testEnum', ttypes.Numberz.ONE]
+];
+
+var simpleLoose = [
['testI64', 5],
['testI64', -5],
['testI64', 734359738368],
['testI64', -34359738368],
['testI64', -734359738368],
- ['testDouble', -5.2098523],
- ['testDouble', 7.012052175215044],
- ['testEnum', ttypes.Numberz.ONE],
['testTypedef', 69]
-];
-
+]
var mapout = {};
for (var i = 0; i < 5; ++i) {
@@ -118,6 +119,7 @@ var insanity = {
};
module.exports.simple = simple;
+module.exports.simpleLoose = simpleLoose;
module.exports.deep = deep;
module.exports.out = out;
diff --git a/lib/nodejs/test/testAll.sh b/lib/nodejs/test/testAll.sh
index 0d10758c5..fd1142585 100755
--- a/lib/nodejs/test/testAll.sh
+++ b/lib/nodejs/test/testAll.sh
@@ -24,7 +24,7 @@ fi
DIR="$( cd "$( dirname "$0" )" && pwd )"
ISTANBUL="$DIR/../../../node_modules/istanbul/lib/cli.js"
-NODEUNIT="${DIR}/../../../node_modules/nodeunit/bin/nodeunit"
+RUNBROWSER="$DIR/../../../node_modules/run-browser/bin/cli.js"
REPORT_PREFIX="${DIR}/../coverage/report"
@@ -54,6 +54,18 @@ testServer()
return $RET
}
+testBrowser()
+{
+ echo " Testing browser client with http server with json protocol and buffered transport";
+ RET=0
+ node ${DIR}/server.js --type http -p json -t buffered &
+ SERVERPID=$!
+ sleep 1
+ ${RUNBROWSER} ${DIR}/browser_client.js --phantom || RET=1
+ kill -2 $SERVERPID || RET=1
+ return $RET
+}
+
TESTOK=0
#generating thrift code
@@ -62,11 +74,11 @@ ${DIR}/../../../compiler/cpp/thrift -o ${DIR} --gen js:node ${DIR}/../../../test
#unit tests
-${NODEUNIT} ${DIR}/binary.test.js || TESTOK=1
+node ${DIR}/binary.test.js || TESTOK=1
#integration tests
-for type in tcp multiplex http websocket
+for type in tcp multiplex websocket http
do
for protocol in compact binary json
@@ -81,6 +93,9 @@ do
done
done
+# XHR only until phantomjs 2 is released.
+testBrowser
+
if [ -n "${COVER}" ]; then
${ISTANBUL} report --dir "${DIR}/../coverage" --include "${DIR}/../coverage/report*/coverage.json" lcov cobertura html
rm -r ${DIR}/../coverage/report*/*
diff --git a/lib/nodejs/test/test_driver.js b/lib/nodejs/test/test_driver.js
index 9f2b894e5..f79baa6d7 100644
--- a/lib/nodejs/test/test_driver.js
+++ b/lib/nodejs/test/test_driver.js
@@ -26,177 +26,195 @@
// supports an optional callback function which is called with
// a status message when the test is complete.
-var assert = require('assert');
+var test = require('tape');
+//var assert = require('assert');
var ttypes = require('./gen-nodejs/ThriftTest_types');
var Int64 = require('node-int64');
var testCases = require('./test-cases');
exports.ThriftTestDriver = function(client, callback) {
- function makeAsserter(assertionFn) {
- return function(c) {
- var fnName = c[0];
- var expected = c[1];
- client[fnName](expected, function(err, actual) {
- assert(!err);
- assertionFn(actual, expected);
- })
- };
- }
+ test('NodeJS Style Callback Client Tests', function(assert) {
- testCases.simple.forEach(makeAsserter(assert.equal));
- testCases.deep.forEach(makeAsserter(assert.deepEqual));
+ var checkRecursively = makeRecursiveCheck(assert);
- client.testStruct(testCases.out, function(err, response) {
- assert(!err);
- checkRecursively(testCases.out, response);
- });
+ function makeAsserter(assertionFn) {
+ return function(c) {
+ var fnName = c[0];
+ var expected = c[1];
+ client[fnName](expected, function(err, actual) {
+ assert.error(err, fnName + ': no callback error');
+ assertionFn(actual, expected, fnName);
+ })
+ };
+ }
- client.testNest(testCases.out2, function(err, response) {
- assert(!err);
- checkRecursively(testCases.out2, response);
- });
+ testCases.simple.forEach(makeAsserter(assert.equal));
+ testCases.simpleLoose.forEach(makeAsserter(function(a, e, m){
+ assert.ok(a == e, m);
+ }));
+ testCases.deep.forEach(makeAsserter(assert.deepEqual));
- client.testInsanity(testCases.crazy, function(err, response) {
- assert(!err);
- checkRecursively(testCases.insanity, response);
- });
+ client.testStruct(testCases.out, function(err, response) {
+ assert.error(err, 'testStruct: no callback error');
+ checkRecursively(testCases.out, response, 'testStruct');
+ });
- client.testException('TException', function(err, response) {
- assert(!err);
- assert(!response);
- });
+ client.testNest(testCases.out2, function(err, response) {
+ assert.error(err, 'testNest: no callback error');
+ checkRecursively(testCases.out2, response, 'testNest');
+ });
- client.testException('Xception', function(err, response) {
- assert(!response);
- assert.equal(err.errorCode, 1001);
- assert.equal('Xception', err.message);
- });
+ client.testInsanity(testCases.crazy, function(err, response) {
+ assert.error(err, 'testInsanity: no callback error');
+ checkRecursively(testCases.insanity, response, 'testInsanity');
+ });
- client.testException('no Exception', function(err, response) {
- assert(!err);
- assert.equal(undefined, response); //void
- });
+ client.testException('TException', function(err, response) {
+ assert.error(err, 'testException: no callback error');
+ assert.ok(!response, 'testException: no response');
+ });
- client.testOneway(0, function(err, response) {
- assert(false); //should not answer
- });
+ client.testException('Xception', function(err, response) {
+ assert.ok(!response, 'testException: no response');
+ assert.equal(err.errorCode, 1001, 'testException: correct error code');
+ assert.equal('Xception', err.message, 'testException: correct error message');
+ });
+
+ client.testException('no Exception', function(err, response) {
+ assert.error(err, 'testException: no callback error');
+ assert.ok(!response, 'testException: no response');
+ });
- checkOffByOne(function(done) {
- client.testI32(-1, function(err, response) {
- assert(!err);
- assert.equal(-1, response);
- done();
+ client.testOneway(0, function(err, response) {
+ assert.fail('testOneway should not answer');
});
- }, callback);
+ checkOffByOne(function(done) {
+ client.testI32(-1, function(err, response) {
+ assert.error(err, 'checkOffByOne: no callback error');
+ assert.equal(-1, response);
+ assert.end();
+ done();
+ });
+ }, callback);
+
+ });
};
exports.ThriftTestDriverPromise = function(client, callback) {
- function makeAsserter(assertionFn) {
- return function(c) {
- var fnName = c[0];
- var expected = c[1];
- client[fnName](expected)
- .then(function(actual) {
- assert.equal(actual, expected);
- })
- .fail(failTest);
- };
- }
+ test('Q Promise Client Tests', function(assert) {
+
+ var checkRecursively = makeRecursiveCheck(assert);
+
+ function fail(msg) {
+ return function() {
+ assert.fail(msg);
+ }
+ }
+
+ function makeAsserter(assertionFn) {
+ return function(c) {
+ var fnName = c[0];
+ var expected = c[1];
+ client[fnName](expected)
+ .then(function(actual) {
+ assertionFn(actual, expected, fnName);
+ })
+ .fail(fail('fnName'));
+ };
+ }
- testCases.simple.forEach(makeAsserter(assert.equal));
- testCases.deep.forEach(makeAsserter(assert.deepEqual));
-
- client.testStruct(testCases.out)
- .then(function(response) {
- checkRecursivelyP(testCases.out, response);
- })
- .fail(failTest);
-
- client.testNest(testCases.out2)
- .then(function(response) {
- checkRecursivelyP(testCases.out2, response);
- })
- .fail(failTest);
-
- client.testInsanity(testCases.crazy)
- .then(function(response) {
- checkRecursivelyP(testCases.insanity, response);
- })
- .fail(failTest);
-
- client.testException('TException')
- .then(failTest);
-
- client.testException('Xception')
- .then(function(response) {
- assert.equal(err.errorCode, 1001);
- assert.equal('Xception', err.message);
- })
- .fail(failTest);
-
- client.testException('no Exception')
- .then(function(response) {
- assert.equal(undefined, response); //void
- })
- .fail(failTest);
-
- client.testOneway(0, failTest); //should not answer
-
- checkOffByOne(function(done) {
- client.testI32(-1)
+ testCases.simple.forEach(makeAsserter(assert.equal));
+ testCases.simpleLoose.forEach(makeAsserter(function(a, e, m){
+ assert.ok(a == e, m);
+ }));
+ testCases.deep.forEach(makeAsserter(assert.deepEqual));
+
+ client.testStruct(testCases.out)
+ .then(function(response) {
+ checkRecursively(testCases.out, response, 'testStruct');
+ })
+ .fail(fail('testStruct'));
+
+ client.testNest(testCases.out2)
.then(function(response) {
- assert.equal(-1, response);
- done();
+ checkRecursively(testCases.out2, response, 'testNest');
})
- .fail(function() {
- assert(false);
+ .fail(fail('testNest'));
+
+ client.testInsanity(testCases.crazy)
+ .then(function(response) {
+ checkRecursively(testCases.insanity, response, 'testInsanity');
+ })
+ .fail(fail('testInsanity'));
+
+ client.testException('TException')
+ .then(function(response) {
+ assert.ok(!response, 'testException: TException');
+ })
+ .fail(fail('testException: TException'));
+
+ client.testException('Xception')
+ .then(function(response) {
+ assert.ok(!response);
+ })
+ .fail(function(err) {
+ assert.equal(err.errorCode, 1001);
+ assert.equal('Xception', err.message);
});
- }, callback);
+ client.testException('no Exception')
+ .then(function(response) {
+ assert.equal(undefined, response); //void
+ })
+ .fail(fail('testException'));
+
+ client.testOneway(0, fail('testOneway: should not answer'));
+
+ checkOffByOne(function(done) {
+ client.testI32(-1)
+ .then(function(response) {
+ assert.equal(-1, response);
+ assert.end();
+ done();
+ })
+ .fail(fail('checkOffByOne'));
+ }, callback);
+ });
};
// Helper Functions
// =========================================================
-function failTest() {
- assert(false);
-}
-
-// This is the version of checkRecursively that was in the vanilla callback
-// version of test_driver.
-function checkRecursively(map1, map2) {
- if (typeof map1 !== 'function' && typeof map2 !== 'function') {
- if (!map1 || typeof map1 !== 'object') {
- //Handle int64 types (which use node-int64 in Node.js JavaScript)
- if ((typeof map1 === "number") && (typeof map2 === "object") &&
- (map2.buffer) && (map2.buffer instanceof Buffer) && (map2.buffer.length === 8)) {
- var n = new Int64(map2.buffer);
- assert.equal(map1, n.toNumber());
- } else {
- assert.equal(map1, map2);
- }
- } else {
- for (var key in map1) {
- checkRecursively(map1[key], map2[key]);
- }
- }
- }
-}
-
-// This is the version of checkRecursively that was in the promise version of
-// test_driver.
-// deepEqual doesn't work with fields using node-int64
-function checkRecursivelyP(map1, map2) {
- if (typeof map1 !== 'function' && typeof map2 !== 'function') {
- if (!map1 || typeof map1 !== 'object') {
- assert.equal(map1, map2);
- } else {
- for (var key in map1) {
- checkRecursivelyP(map1[key], map2[key]);
+function makeRecursiveCheck(assert) {
+
+ return function (map1, map2, msg) {
+ var equal = true;
+
+ var equal = checkRecursively(map1, map2);
+
+ assert.ok(equal, msg);
+
+ // deepEqual doesn't work with fields using node-int64
+ function checkRecursively(map1, map2) {
+ if (typeof map1 !== 'function' && typeof map2 !== 'function') {
+ if (!map1 || typeof map1 !== 'object') {
+ //Handle int64 types (which use node-int64 in Node.js JavaScript)
+ if ((typeof map1 === "number") && (typeof map2 === "object") &&
+ (map2.buffer) && (map2.buffer instanceof Buffer) && (map2.buffer.length === 8)) {
+ var n = new Int64(map2.buffer);
+ return map1 === n.toNumber();
+ } else {
+ return map1 == map2;
+ }
+ } else {
+ return Object.keys(map1).every(function(key) {
+ return checkRecursively(map1[key], map2[key]);
+ });
+ }
}
}
}
diff --git a/lib/nodejs/test/test_handler.js b/lib/nodejs/test/test_handler.js
index 83b7d419b..de6f50390 100644
--- a/lib/nodejs/test/test_handler.js
+++ b/lib/nodejs/test/test_handler.js
@@ -25,7 +25,7 @@ var TException = require('thrift').Thrift.TException;
function makeSyncHandler(label) {
return function(thing) {
- console.log(label + '(\'' + thing + '\')');
+ //console.log(label + '(\'' + thing + '\')');
return thing;
}
}
@@ -72,7 +72,7 @@ var identityHandlers = [
];
function testVoid() {
- console.log('testVoid()');
+ //console.log('testVoid()');
}
function testVoidAsync(result) {
@@ -80,7 +80,7 @@ function testVoidAsync(result) {
}
function testMapMap(hello) {
- console.log('testMapMap(' + hello + ')');
+ //console.log('testMapMap(' + hello + ')');
var mapmap = [];
var pos = [];
@@ -96,9 +96,9 @@ function testMapMap(hello) {
}
function testInsanity(argument) {
- console.log('testInsanity(');
- console.log(argument);
- console.log(')');
+ //console.log('testInsanity(');
+ //console.log(argument);
+ //console.log(')');
var hello = new ttypes.Xtruct();
hello.string_thing = 'Hello2';
@@ -131,13 +131,13 @@ function testInsanity(argument) {
insane[1] = first_map;
insane[2] = second_map;
- console.log('insane result:');
- console.log(insane);
+ //console.log('insane result:');
+ //console.log(insane);
return insane;
}
function testMulti(arg0, arg1, arg2, arg3, arg4, arg5) {
- console.log('testMulti()');
+ //console.log('testMulti()');
var hello = new ttypes.Xtruct();
hello.string_thing = 'Hello2';
@@ -153,7 +153,7 @@ function testMultiAsync(arg0, arg1, arg2, arg3, arg4, arg5, result) {
}
function testException(arg) {
- console.log('testException('+arg+')');
+ //console.log('testException('+arg+')');
if (arg === 'Xception') {
var x = new ttypes.Xception();
x.errorCode = 1001;
@@ -167,7 +167,7 @@ function testException(arg) {
}
function testExceptionAsync(arg, result) {
- console.log('testException('+arg+')');
+ //console.log('testException('+arg+')');
if (arg === 'Xception') {
var x = new ttypes.Xception();
x.errorCode = 1001;
@@ -181,7 +181,7 @@ function testExceptionAsync(arg, result) {
}
function testMultiException(arg0, arg1) {
- console.log('testMultiException(' + arg0 + ', ' + arg1 + ')');
+ //console.log('testMultiException(' + arg0 + ', ' + arg1 + ')');
if (arg0 === ('Xception')) {
var x = new ttypes.Xception();
x.errorCode = 1001;
@@ -201,7 +201,7 @@ function testMultiException(arg0, arg1) {
}
function testMultiExceptionAsync(arg0, arg1, result) {
- console.log('testMultiException(' + arg0 + ', ' + arg1 + ')');
+ //console.log('testMultiException(' + arg0 + ', ' + arg1 + ')');
if (arg0 === ('Xception')) {
var x = new ttypes.Xception();
x.errorCode = 1001;
@@ -221,7 +221,7 @@ function testMultiExceptionAsync(arg0, arg1, result) {
}
function testOneway(sleepFor) {
- console.log('testOneway(' + sleepFor + ') => JavaScript (like Rust) never sleeps!');
+ //console.log('testOneway(' + sleepFor + ') => JavaScript (like Rust) never sleeps!');
}
function testOnewayAsync(sleepFor, result) {
diff --git a/package.json b/package.json
index 73524c480..0fbb80eaa 100755..100644
--- a/package.json
+++ b/package.json
@@ -32,14 +32,14 @@
"dependencies": {
"node-int64": "~0.3.0",
"q": "1.0.x",
- "nodeunit": "~0.8.0",
"ws": "~0.4.32"
},
"devDependencies": {
- "connect": "2.7.x",
"commander": "2.1.x",
+ "connect": "2.7.x",
"istanbul": "^0.3.5",
- "tape": "^3.4.0"
+ "run-browser": "^2.0.1",
+ "tape": "~3.5.0"
},
"scripts": {
"cover": "lib/nodejs/test/testAll.sh COVER",