THRIFT-2350 Add async calls to normal JavaScript
Patch: Randy Abernethy
diff --git a/lib/js/test/test-jq.js b/lib/js/test/test-jq.js
new file mode 100644
index 0000000..ed658e4
--- /dev/null
+++ b/lib/js/test/test-jq.js
@@ -0,0 +1,161 @@
+/*

+ * 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.

+ */

+ /* jshint -W100 */

+ 

+/*

+ * JavaScript test suite for ThriftTest.thrift. These tests

+ * will run only with jQuery (-gen js:jquery) Apache Thrift 

+ * interfaces. To create client code:

+ *      $ thrift -gen js:jquery ThriftTest.thrift

+ *

+ * See also:

+ * ++ test.js for generic tests  

+ * ++ test-nojq.js for "-gen js" only tests

+ */

+

+var transport = new Thrift.Transport("/service");

+var protocol  = new Thrift.Protocol(transport);

+var client    = new ThriftTest.ThriftTestClient(protocol);

+

+//////////////////////////////////

+//jQuery asynchronous tests

+jQuery.ajaxSetup({ timeout: 0 });

+$(document).ajaxError( function() { QUnit.start(); } );

+

+module("jQ Async Manual");

+

+  test("testI32", function() {

+    expect( 2 );

+    QUnit.stop();

+

+    var transport = new Thrift.Transport();

+    var protocol  = new Thrift.Protocol(transport);

+    var client    = new ThriftTest.ThriftTestClient(protocol);

+

+    var jqxhr = jQuery.ajax({

+      url: "/service",

+      data: client.send_testI32(Math.pow(-2,31)),

+      type: "POST",

+      cache: false,

+      dataType: "text",

+      success: function(res){

+        transport.setRecvBuffer( res );

+        equal(client.recv_testI32(), Math.pow(-2,31));

+      },

+      error: function() { ok(false); },

+      complete: function() {

+        ok(true);

+        QUnit.start();

+      }

+    });

+  });

+

+  test("testI64", function() {

+    expect( 2 );

+    QUnit.stop();

+

+    var transport = new Thrift.Transport();

+    var protocol  = new Thrift.Protocol(transport);

+    var client    = new ThriftTest.ThriftTestClient(protocol);

+

+    jQuery.ajax({

+      url: "/service",

+      //This is usually 2^61 but JS cannot represent anything over 2^52 accurately

+      data: client.send_testI64(Math.pow(-2,52)),

+      type: "POST",

+      cache: false,

+      dataType: "text",

+      success: function(res){

+        transport.setRecvBuffer( res );

+        //This is usually 2^61 but JS cannot represent anything over 2^52 accurately

+        equal(client.recv_testI64(), Math.pow(-2,52));

+      },

+      error: function() { ok(false); },

+      complete: function() {

+        ok(true);

+        QUnit.start();

+      }

+    });

+  });

+

+

+module("jQ Async");

+  test("I32", function() {

+    expect( 3 );

+

+    QUnit.stop();

+    client.testI32(Math.pow(2,30), function(result) {

+      equal(result, Math.pow(2,30));

+      QUnit.start();

+    });

+

+    QUnit.stop();

+    var jqxhr = client.testI32(Math.pow(-2,31), function(result) {

+      equal(result, Math.pow(-2,31));

+    });

+

+    jqxhr.success(function(result) {

+      equal(result, Math.pow(-2,31));

+      QUnit.start();

+    });

+  });

+

+  test("I64", function() {

+    expect( 4 );

+

+    QUnit.stop();

+    //This is usually 2^60 but JS cannot represent anything over 2^52 accurately

+    client.testI64(Math.pow(2,52), function(result) {

+      equal(result, Math.pow(2,52));

+      QUnit.start();

+    });

+

+    QUnit.stop();

+    //This is usually 2^60 but JS cannot represent anything over 2^52 accurately

+    client.testI64(Math.pow(-2,52), function(result) {

+      equal(result, Math.pow(-2,52));

+    })

+    .error( function(xhr, status, e) {  ok(false, e.message); } )

+    .success(function(result) {

+      //This is usually 2^60 but JS cannot represent anything over 2^52 accurately

+      equal(result, Math.pow(-2,52));

+    })

+    .complete(function() {

+      ok(true);

+      QUnit.start();

+    });

+  });

+

+  test("Xception", function() {

+    expect( 2 );

+

+    QUnit.stop();

+

+    var dfd = client.testException("Xception", function(result) {

+      ok(false);

+      QUnit.start();

+    })

+    .error(function(xhr, status, e){

+      equal(e.errorCode, 1001);

+      equal(e.message, "Xception");

+      //QUnit.start();

+      //Note start is not required here because:

+      //$(document).ajaxError( function() { QUnit.start(); } );

+    });

+  });

diff --git a/lib/js/test/test-nojq.html b/lib/js/test/test-nojq.html
new file mode 100644
index 0000000..290816e
--- /dev/null
+++ b/lib/js/test/test-nojq.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!--
+  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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <title>Thrift Javascript Bindings: Unit Test</title>
+
+  <script src="build/js/thrift.js"         type="text/javascript" charset="utf-8"></script>
+  <script src="gen-js/ThriftTest_types.js" type="text/javascript" charset="utf-8"></script>
+  <script src="gen-js/ThriftTest.js"       type="text/javascript" charset="utf-8"></script>
+
+  <!-- QUnit Test framework-->
+  <script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.14.0.js" charset="utf-8"></script>
+  <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.14.0.css" type="text/css" media="screen" />
+  
+  <!-- the Test Suite-->
+  <script type="text/javascript" src="test.js" charset="utf-8"></script>
+  <script type="text/javascript" src="test-nojq.js" charset="utf-8"></script>
+</head>
+<body>
+  <h1 id="qunit-header">Thrift Javascript Bindings: Unit Test (<a href="https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob;f=test/ThriftTest.thrift;hb=HEAD">ThriftTest.thrift</a>)</h1>
+  <h2 id="qunit-banner"></h2>
+  <div id="qunit-testrunner-toolbar"></div> 
+  <h2 id="qunit-userAgent"></h2>
+  <ol id="qunit-tests"><li><!-- get valid xhtml strict--></li></ol>
+  <p>
+      <a href="http://validator.w3.org/check/referer"><img
+          src="http://www.w3.org/Icons/valid-xhtml10"
+          alt="Valid XHTML 1.0!" height="31" width="88" /></a>
+  </p>
+</body>
+</html>
+
diff --git a/lib/js/test/test-nojq.js b/lib/js/test/test-nojq.js
new file mode 100644
index 0000000..f67ea62
--- /dev/null
+++ b/lib/js/test/test-nojq.js
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+ /* jshint -W100 */
+ 
+/*
+ * JavaScript test suite for ThriftTest.thrift. These tests
+ * will run only with normal "-gen js" Apache Thrift interfaces.
+ * To create client code:
+ *      $ thrift -gen js ThriftTest.thrift
+ *
+ * See also:
+ * ++ test.js for generic tests  
+ * ++ test-jq.js for "-gen js:jquery" only tests
+ */
+
+var transport = new Thrift.Transport("/service");
+var protocol  = new Thrift.Protocol(transport);
+var client    = new ThriftTest.ThriftTestClient(protocol);
+
+//////////////////////////////////
+//Async exception tests
+
+module("NojQ Async");
+
+  test("Xception", function() {
+    expect( 2 );
+
+    QUnit.stop();
+
+    client.testException("Xception", function(result) {
+      equal(result.errorCode, 1001);
+      equal(result.message, "Xception");
+      QUnit.start();
+    });
+  });
+
diff --git a/lib/js/test/test.html b/lib/js/test/test.html
index 93894c7..8f9e7ee 100755
--- a/lib/js/test/test.html
+++ b/lib/js/test/test.html
@@ -1,51 +1,52 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<!--
-  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.
--->
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-  <title>Thrift Javascript Bindings: Unit Test</title>
-
-  <script src="/src/thrift.js"                  type="text/javascript" charset="utf-8"></script>
-  <script src="gen-js/ThriftTest_types.js" type="text/javascript" charset="utf-8"></script>
-  <script src="gen-js/ThriftTest.js"       type="text/javascript" charset="utf-8"></script>
-
-  <!-- jQuery -->
-  <script type="text/javascript" src="build/js/lib/jquery-1.7.2.js" charset="utf-8"></script>
-  
-  <!-- QUnit Test framework-->
-  <script type="text/javascript" src="build/js/lib/qunit.js" charset="utf-8"></script>
-  <link rel="stylesheet" href="build/js/lib/qunit.css" type="text/css" media="screen" />
-  
-  <!-- the Test Suite-->
-  <script type="text/javascript" src="test.js" charset="utf-8"></script>
-</head>
-<body>
-  <h1 id="qunit-header">Thrift Javascript Bindings: Unit Test (<a href="https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob;f=test/ThriftTest.thrift;hb=HEAD">ThriftTest.thrift</a>)</h1>
-  <h2 id="qunit-banner"></h2>
-  <div id="qunit-testrunner-toolbar"></div> 
-  <h2 id="qunit-userAgent"></h2>
-  <ol id="qunit-tests"><li><!-- get valid xhtml strict--></li></ol>
-  <p>
-      <a href="http://validator.w3.org/check/referer"><img
-          src="http://www.w3.org/Icons/valid-xhtml10"
-          alt="Valid XHTML 1.0!" height="31" width="88" /></a>
-  </p>
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

+<!--

+  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.

+-->

+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

+<head>

+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

+  <title>Thrift Javascript Bindings: Unit Test</title>

+

+  <script src="build/js/thrift.js"         type="text/javascript" charset="utf-8"></script>

+  <script src="gen-js/ThriftTest_types.js" type="text/javascript" charset="utf-8"></script>

+  <script src="gen-js/ThriftTest.js"       type="text/javascript" charset="utf-8"></script>

+

+  <!-- jQuery -->

+  <script type="text/javascript" src="build/js/lib/jquery-1.7.2.js" charset="utf-8"></script>

+  

+  <!-- QUnit Test framework-->

+  <script type="text/javascript" src="build/js/lib/qunit.js" charset="utf-8"></script>

+  <link rel="stylesheet" href="build/js/lib/qunit.css" type="text/css" media="screen" />

+  

+  <!-- the Test Suite-->

+  <script type="text/javascript" src="test.js" charset="utf-8"></script>

+  <script type="text/javascript" src="test-jq.js" charset="utf-8"></script>

+</head>

+<body>

+  <h1 id="qunit-header">Thrift Javascript Bindings: Unit Test (<a href="https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob;f=test/ThriftTest.thrift;hb=HEAD">ThriftTest.thrift</a>)</h1>

+  <h2 id="qunit-banner"></h2>

+  <div id="qunit-testrunner-toolbar"></div> 

+  <h2 id="qunit-userAgent"></h2>

+  <ol id="qunit-tests"><li><!-- get valid xhtml strict--></li></ol>

+  <p>

+      <a href="http://validator.w3.org/check/referer"><img

+          src="http://www.w3.org/Icons/valid-xhtml10"

+          alt="Valid XHTML 1.0!" height="31" width="88" /></a>

+  </p>

+</body>

+</html>

diff --git a/lib/js/test/test.js b/lib/js/test/test.js
index b0904a9..7351fd9 100755
--- a/lib/js/test/test.js
+++ b/lib/js/test/test.js
@@ -1,4 +1,4 @@
-/*
+/*
  * 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
@@ -19,7 +19,32 @@
  /* jshint -W100 */
  
 /*
- * JavaScript test suite
+ * JavaScript test suite for ThriftTest.thrift. These tests
+ * will run against Normal (-gen js) and jQuery (-gen js:jquery)
+ * Apache Thrift interfaces.
+ *
+ * Synchronous blocking calls should be identical in both 
+ * Normal and jQuery interfaces. All synchronous tests belong
+ * here.
+ * 
+ * Asynchronous sucess callbacks passed as the last parameter 
+ * of an RPC call should be identical in both Normal and jQuery
+ * interfaces. Async success tests belong here.
+ * 
+ * Asynchronous exception processing is different in Normal
+ * and jQuery interfaces. Such tests belong in the test-nojq.js
+ * or test-jq.js files respectively. jQuery specific XHR object
+ * tests also belong in test-jq.js. Do not create any jQuery 
+ * dependencies in this file or in test-nojq.js
+ *
+ * To compile client code for this test use:
+ *      $ thrift -gen js ThriftTest.thrift
+ *      -- or --
+ *      $ thrift -gen js:jquery ThriftTest.thrift
+ *
+ * See also:
+ * ++ test-nojq.js for "-gen js" only tests  
+ * ++ test-jq.js for "-gen js:jquery" only tests
  */
 
 var transport = new Thrift.Transport("/service");
@@ -74,8 +99,9 @@
   });
   test("I64", function() {
     equal(client.testI64(0), 0);
-    equal(client.testI64(Math.pow(2,60)), Math.pow(2,60));
-    equal(client.testI64(-Math.pow(2,60)), -Math.pow(2,60));
+    //This is usually 2^60 but JS cannot represent anything over 2^52 accurately
+    equal(client.testI64(Math.pow(2,52)), Math.pow(2,52));
+    equal(client.testI64(-Math.pow(2,52)), -Math.pow(2,52));
   });
 
 
@@ -86,7 +112,8 @@
     structTestInput.string_thing = 'worked';
     structTestInput.byte_thing = 0x01;
     structTestInput.i32_thing = Math.pow(2,30);
-    structTestInput.i64_thing = Math.pow(2,60);
+    //This is usually 2^60 but JS cannot represent anything over 2^52 accurately
+    structTestInput.i64_thing = Math.pow(2,52);
 
     var structTestOutput = client.testStruct(structTestInput);
 
@@ -103,7 +130,8 @@
     xtrTestInput.string_thing = 'worked';
     xtrTestInput.byte_thing = 0x01;
     xtrTestInput.i32_thing = Math.pow(2,30);
-    xtrTestInput.i64_thing = Math.pow(2,60);
+    //This is usually 2^60 but JS cannot represent anything over 2^52 accurately
+    xtrTestInput.i64_thing = Math.pow(2,52);
     
     var nestTestInput = new ThriftTest.Xtruct2();
     nestTestInput.byte_thing = 0x02;
@@ -206,12 +234,16 @@
   });
 
   test("TException", function() {
+    //ThriftTest does not list TException as a legal exception so it will
+    // generate an exception on the server that does not propagate back to 
+    // the client. This test has been modified to equate to "no exception"
     expect(1);
     try{
       client.testException("TException");
     } catch(e) {
-      ok(true);
+      //ok(false);
     }
+    ok(true);
   });
 
 
@@ -265,64 +297,6 @@
 
 //////////////////////////////////
 //Run same tests asynchronously
-jQuery.ajaxSetup({ timeout: 0 });
-$(document).ajaxError( function() { QUnit.start(); } );
-
-module("Async Manual");
-
-  test("testI32", function() {
-    expect( 2 );
-    QUnit.stop();
-
-    var transport = new Thrift.Transport();
-    var protocol  = new Thrift.Protocol(transport);
-    var client    = new ThriftTest.ThriftTestClient(protocol);
-
-    var jqxhr = jQuery.ajax({
-      url: "/service",
-      data: client.send_testI32(Math.pow(-2,31)),
-      type: "POST",
-      cache: false,
-      dataType: "text",
-      success: function(res){
-        transport.setRecvBuffer( res );
-        equal(client.recv_testI32(), Math.pow(-2,31));
-      },
-      error: function() { ok(false); },
-      complete: function() {
-        ok(true);
-        QUnit.start();
-      }
-    });
-  });
-
-
-  test("testI64", function() {
-    expect( 2 );
-    QUnit.stop();
-
-    var transport = new Thrift.Transport();
-    var protocol  = new Thrift.Protocol(transport);
-    var client    = new ThriftTest.ThriftTestClient(protocol);
-
-    jQuery.ajax({
-      url: "/service",
-      data: client.send_testI64(Math.pow(-2,61)),
-      type: "POST",
-      cache: false,
-      dataType: "text",
-      success: function(res){
-        transport.setRecvBuffer( res );
-        equal(client.recv_testI64(), Math.pow(-2,61));
-      },
-      error: function() { ok(false); },
-      complete: function() {
-        ok(true);
-        QUnit.start();
-      }
-    });
-  });
-
 
 module("Async");
 
@@ -347,7 +321,7 @@
   });
 
   test("I32", function() {
-    expect( 3 );
+    expect( 2 );
 
     QUnit.stop();
     client.testI32(Math.pow(2,30), function(result) {
@@ -356,53 +330,26 @@
     });
 
     QUnit.stop();
-    var jqxhr = client.testI32(Math.pow(-2,31), function(result) {
-      equal(result, Math.pow(-2,31));
-    });
-
-    jqxhr.success(function(result) {
+    client.testI32(Math.pow(-2,31), function(result) {
       equal(result, Math.pow(-2,31));
       QUnit.start();
     });
   });
 
   test("I64", function() {
-    expect( 4 );
-
-    QUnit.stop();
-    client.testI64(Math.pow(2,60), function(result) {
-      equal(result, Math.pow(2,60));
-      QUnit.start();
-    });
-
-    QUnit.stop();
-    client.testI64(Math.pow(-2,61), function(result) {
-      equal(result, Math.pow(-2,61));
-    })
-    .error( function(xhr, status, e) {  ok(false, e.message); } )
-    .success(function(result) {
-      equal(result, Math.pow(-2,61));
-    })
-    .complete(function() {
-      ok(true);
-      QUnit.start();
-    });
-  });
-
-  test("Xception", function() {
     expect( 2 );
 
     QUnit.stop();
-
-    var dfd = client.testException("Xception", function(result) {
-      ok(false);
+    //This is usually 2^60 but JS cannot represent anything over 2^52 accurately
+    client.testI64(Math.pow(2,52), function(result) {
+      equal(result, Math.pow(2,52));
       QUnit.start();
-    })
-    .error(function(xhr, status, e){
-      equal(e.errorCode, 1001);
-      equal(e.message, "Xception");
-      //QUnit.start();
-      //Note start is not required here because:
-      //$(document).ajaxError( function() { QUnit.start(); } );
+    });
+
+    QUnit.stop();
+    //This is usually 2^60 but JS cannot represent anything over 2^52 accurately
+    client.testI64(Math.pow(-2,52), function(result) {
+      equal(result, Math.pow(-2,52));
+      QUnit.start();
     });
   });