You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by jk...@apache.org on 2018/09/28 14:37:01 UTC

[thrift] branch master updated (98acf18 -> c64389a)

This is an automated email from the ASF dual-hosted git repository.

jking pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/thrift.git.


    from 98acf18  fix Ubuntu Xenial docker build environment (lock deimos for openssl to older version)
     new b5d6ea3  THRIFT-4625: Use let/const variable decorators in ES6 Javascript
     new c64389a  THRIFT-4625: Pin dart version to 1.x in build

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 build/docker/ubuntu-artful/Dockerfile              |  10 +-
 build/docker/ubuntu-bionic/Dockerfile              |  10 +-
 build/docker/ubuntu-xenial/Dockerfile              |   9 +-
 compiler/cpp/src/thrift/generate/t_js_generator.cc | 277 ++++----
 lib/js/Gruntfile.js                                | 186 ++++--
 lib/js/README.md                                   |  17 +-
 lib/js/package-lock.json                           | 736 +++++----------------
 lib/js/package.json                                |   2 +-
 lib/js/test/build.xml                              |   5 +-
 lib/js/test/deep-constructor.test.js               |  34 +-
 lib/js/test/server_http.js                         |  26 +-
 lib/js/test/server_https.js                        |  22 +-
 lib/js/test/test-async.js                          | 296 +++++----
 lib/js/test/test-double-rendering.js               |  28 +-
 lib/js/test/test-es6.html                          |  17 +-
 lib/js/test/test-es6.js                            | 276 ++++----
 lib/js/test/test-jq.js                             | 113 ++--
 lib/js/test/test-nojq.html                         |   4 +-
 lib/js/test/test-nojq.js                           |  15 +-
 lib/js/test/test.html                              |   9 +-
 lib/js/test/test.js                                | 297 +++++----
 lib/js/test/test_handler.js                        |  40 +-
 lib/js/test/testws.html                            |  10 +-
 package-lock.json                                  | 586 ----------------
 package.json                                       |   1 -
 25 files changed, 1097 insertions(+), 1929 deletions(-)


[thrift] 01/02: THRIFT-4625: Use let/const variable decorators in ES6 Javascript

Posted by jk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jking pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/thrift.git

commit b5d6ea390fc5732ed1c1772709ab3731555dc3fc
Author: Brian Forbis <bf...@athenahealth.com>
AuthorDate: Sat Aug 25 23:39:29 2018 -0400

    THRIFT-4625: Use let/const variable decorators in ES6 Javascript
---
 build/docker/ubuntu-artful/Dockerfile              |   5 +
 build/docker/ubuntu-bionic/Dockerfile              |   5 +
 build/docker/ubuntu-xenial/Dockerfile              |   9 +-
 compiler/cpp/src/thrift/generate/t_js_generator.cc | 277 ++++----
 lib/js/Gruntfile.js                                | 186 ++++--
 lib/js/README.md                                   |  17 +-
 lib/js/package-lock.json                           | 736 +++++----------------
 lib/js/package.json                                |   2 +-
 lib/js/test/build.xml                              |   5 +-
 lib/js/test/deep-constructor.test.js               |  34 +-
 lib/js/test/server_http.js                         |  26 +-
 lib/js/test/server_https.js                        |  22 +-
 lib/js/test/test-async.js                          | 296 +++++----
 lib/js/test/test-double-rendering.js               |  28 +-
 lib/js/test/test-es6.html                          |  17 +-
 lib/js/test/test-es6.js                            | 276 ++++----
 lib/js/test/test-jq.js                             | 113 ++--
 lib/js/test/test-nojq.html                         |   4 +-
 lib/js/test/test-nojq.js                           |  15 +-
 lib/js/test/test.html                              |   9 +-
 lib/js/test/test.js                                | 297 +++++----
 lib/js/test/test_handler.js                        |  40 +-
 lib/js/test/testws.html                            |  10 +-
 package-lock.json                                  | 586 ----------------
 package.json                                       |   1 -
 25 files changed, 1091 insertions(+), 1925 deletions(-)

diff --git a/build/docker/ubuntu-artful/Dockerfile b/build/docker/ubuntu-artful/Dockerfile
index 153ce61..4ea95d5 100644
--- a/build/docker/ubuntu-artful/Dockerfile
+++ b/build/docker/ubuntu-artful/Dockerfile
@@ -183,6 +183,11 @@ RUN apt-get install -y --no-install-recommends \
 `# Node.js dependencies` \
       nodejs
 
+# Test dependencies for running puppeteer
+RUN apt-get install -y --no-install-recommends \
+`# JS dependencies` \
+      libxss1
+
 RUN apt-get install -y --no-install-recommends \
 `# OCaml dependencies` \
       ocaml \
diff --git a/build/docker/ubuntu-bionic/Dockerfile b/build/docker/ubuntu-bionic/Dockerfile
index 1fe4c3d..da574e1 100644
--- a/build/docker/ubuntu-bionic/Dockerfile
+++ b/build/docker/ubuntu-bionic/Dockerfile
@@ -181,6 +181,11 @@ RUN apt-get install -y --no-install-recommends \
 `# Node.js dependencies` \
       nodejs
 
+# Test dependencies for running puppeteer
+RUN apt-get install -y --no-install-recommends \
+`# JS dependencies` \
+      libxss1
+
 RUN apt-get install -y --no-install-recommends \
 `# OCaml dependencies` \
       ocaml \
diff --git a/build/docker/ubuntu-xenial/Dockerfile b/build/docker/ubuntu-xenial/Dockerfile
index c745a59..3372b4d 100644
--- a/build/docker/ubuntu-xenial/Dockerfile
+++ b/build/docker/ubuntu-xenial/Dockerfile
@@ -60,7 +60,7 @@ RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /et
 # node.js
 RUN curl -sL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \
     echo "deb https://deb.nodesource.com/node_6.x xenial main" | tee /etc/apt/sources.list.d/nodesource.list
-    
+
 ### install general dependencies
 RUN apt-get update && apt-get install -y --no-install-recommends \
 `# General dependencies` \
@@ -190,6 +190,13 @@ RUN apt-get install -y --no-install-recommends \
 `# Node.js dependencies` \
       nodejs
 
+# Test dependencies for running puppeteer
+RUN apt-get install -y --no-install-recommends \
+`# JS dependencies` \
+      libxss1 \
+      libatk-bridge2.0-0 \
+      libgtk-3-0
+
 # THRIFT-4517: causes stack overflows; version too old; skip ocaml in xenial
 # RUN apt-get install -y --no-install-recommends \
 # `# OCaml dependencies` \
diff --git a/compiler/cpp/src/thrift/generate/t_js_generator.cc b/compiler/cpp/src/thrift/generate/t_js_generator.cc
index 4d1cea6..1ae8167 100644
--- a/compiler/cpp/src/thrift/generate/t_js_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_js_generator.cc
@@ -97,6 +97,15 @@ public:
       throw "Invalid switch: [-gen js:with_ns] is only valid when using node.js";
     }
 
+    // Depending on the processing flags, we will update these to be ES6 compatible
+    js_const_type_ = "var ";
+    js_let_type_ = "var ";
+    js_var_type_ = "var ";
+    if (gen_es6_) {
+      js_const_type_ = "const ";
+      js_let_type_ = "let ";
+    }
+
     if (gen_node_) {
       out_dir_base_ = "gen-nodejs";
       no_ns_ = !with_ns_;
@@ -352,6 +361,21 @@ private:
   bool no_ns_;
 
   /**
+   * The variable decorator for "const" variables. Will default to "var" if in an incompatible language.
+   */
+  string js_const_type_;
+
+   /**
+   * The variable decorator for "let" variables. Will default to "var" if in an incompatible language.
+   */
+  string js_let_type_;
+
+   /**
+   * The default variable decorator. Supports all javascript languages, but is not scoped to functions or closures.
+   */
+  string js_var_type_;
+
+  /**
    * File streams
    */
   ofstream_with_content_based_conditional_update f_types_;
@@ -395,7 +419,7 @@ void t_js_generator::init_generator() {
   }
 
   if (gen_node_) {
-    f_types_ << "var ttypes = module.exports = {};" << endl;
+    f_types_ << js_const_type_ << "ttypes = module.exports = {};" << endl;
   }
 
   string pns;
@@ -422,11 +446,10 @@ void t_js_generator::init_generator() {
  */
 string t_js_generator::js_includes() {
   if (gen_node_) {
-    string result = string(
-        "var thrift = require('thrift');\n"
-        "var Thrift = thrift.Thrift;\n");
+    string result = js_const_type_ + "thrift = require('thrift');\n"
+        + js_const_type_ + "Thrift = thrift.Thrift;\n";
     if (!gen_es6_) {
-      result += "var Q = thrift.Q;\n";
+      result += js_const_type_ + "Q = thrift.Q;\n";
     }
     return result;
   }
@@ -443,7 +466,7 @@ string t_js_generator::render_includes() {
   if (gen_node_) {
     const vector<t_program*>& includes = program_->get_includes();
     for (size_t i = 0; i < includes.size(); ++i) {
-      result += "var " + make_valid_nodeJs_identifier(includes[i]->get_name()) + "_ttypes = require('./" + includes[i]->get_name()
+      result += js_const_type_ + make_valid_nodeJs_identifier(includes[i]->get_name()) + "_ttypes = require('./" + includes[i]->get_name()
                 + "_types');\n";
     }
     if (includes.size() > 0) {
@@ -532,7 +555,7 @@ void t_js_generator::generate_const(t_const* tconst) {
   f_types_ << render_const_value(type, value) << ";" << endl;
 
   if (gen_ts_) {
-    f_types_ts_ << ts_print_doc(tconst) << ts_indent() << ts_declare() << "var " << name << ": "
+    f_types_ts_ << ts_print_doc(tconst) << ts_indent() << ts_declare() << js_const_type_ << name << ": "
                 << ts_get_type(type) << ";" << endl;
   }
 }
@@ -694,7 +717,7 @@ void t_js_generator::generate_js_struct_definition(ostream& out,
   vector<t_field*>::const_iterator m_iter;
 
   if (gen_node_) {
-    string prefix = has_js_namespace(tstruct->get_program()) ? js_namespace(tstruct->get_program()) : "var ";
+    string prefix = has_js_namespace(tstruct->get_program()) ? js_namespace(tstruct->get_program()) : js_const_type_;
     if (is_exported) {
       out << prefix << tstruct->get_name() << " = "
           << "module.exports." << tstruct->get_name() << " = function(args) {" << endl;
@@ -860,14 +883,15 @@ void t_js_generator::generate_js_struct_reader(ostream& out, t_struct* tstruct)
   indent(out) << "input.readStructBegin();" << endl;
 
   // Loop over reading in fields
-  indent(out) << "while (true)" << endl;
+  indent(out) << "while (true) {" << endl;
 
-  scope_up(out);
+  indent_up();
 
-  indent(out) << "var ret = input.readFieldBegin();" << endl;
-  indent(out) << "var fname = ret.fname;" << endl;
-  indent(out) << "var ftype = ret.ftype;" << endl;
-  indent(out) << "var fid = ret.fid;" << endl;
+  indent(out) << js_const_type_ << "ret = input.readFieldBegin();" << endl;
+  indent(out) << js_const_type_ << "ftype = ret.ftype;" << endl;
+  if (!fields.empty()) {
+    indent(out) << js_const_type_ << "fid = ret.fid;" << endl;
+  }
 
   // Check for field STOP marker and break
   indent(out) << "if (ftype == Thrift.Type.STOP) {" << endl;
@@ -877,9 +901,9 @@ void t_js_generator::generate_js_struct_reader(ostream& out, t_struct* tstruct)
   indent(out) << "}" << endl;
   if (!fields.empty()) {
     // Switch statement on the field we are reading
-    indent(out) << "switch (fid)" << endl;
+    indent(out) << "switch (fid) {" << endl;
 
-    scope_up(out);
+    indent_up();
 
     // Generate deserialization code for known cases
     for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@@ -1001,15 +1025,15 @@ void t_js_generator::generate_service(t_service* tservice) {
 
   if (gen_node_) {
     if (tservice->get_extends() != NULL) {
-      f_service_ << "var " << tservice->get_extends()->get_name() << " = require('./"
-                 << tservice->get_extends()->get_name() << "');" << endl << "var "
+      f_service_ << js_const_type_ <<  tservice->get_extends()->get_name() << " = require('./"
+                 << tservice->get_extends()->get_name() << "');" << endl << js_const_type_
                  << tservice->get_extends()->get_name()
                  << "Client = " << tservice->get_extends()->get_name() << ".Client;" << endl
-                 << "var " << tservice->get_extends()->get_name()
+                 << js_const_type_ << tservice->get_extends()->get_name()
                  << "Processor = " << tservice->get_extends()->get_name() << ".Processor;" << endl;
     }
 
-    f_service_ << "var ttypes = require('./" + program_->get_name() + "_types');" << endl;
+    f_service_ << js_const_type_ << "ttypes = require('./" + program_->get_name() + "_types');" << endl;
   }
 
   generate_service_helpers(tservice);
@@ -1039,19 +1063,17 @@ void t_js_generator::generate_service_processor(t_service* tservice) {
   vector<t_function*>::iterator f_iter;
 
   if (gen_node_) {
-    string prefix = has_js_namespace(tservice->get_program()) ? js_namespace(tservice->get_program()) : "var ";
-    f_service_ << prefix << service_name_ << "Processor = " << "exports.Processor = function(handler) ";
+    string prefix = has_js_namespace(tservice->get_program()) ? js_namespace(tservice->get_program()) : js_const_type_;
+    f_service_ << prefix << service_name_ << "Processor = " << "exports.Processor = function(handler) {" << endl;
   } else {
     f_service_ << js_namespace(tservice->get_program()) << service_name_ << "Processor = "
-             << "exports.Processor = function(handler) ";
+             << "exports.Processor = function(handler) {" << endl;
   }
 
-  scope_up(f_service_);
-
-  f_service_ << indent() << "this._handler = handler;" << endl;
-
-  scope_down(f_service_);
-  f_service_ << ";" << endl;
+  indent_up();
+  indent(f_service_) << "this._handler = handler;" << endl;
+  indent_down();
+  f_service_ << "};" << endl;
 
   if (tservice->get_extends() != NULL) {
     indent(f_service_) << "Thrift.inherits(" << js_namespace(tservice->get_program())
@@ -1061,16 +1083,16 @@ void t_js_generator::generate_service_processor(t_service* tservice) {
 
   // Generate the server implementation
   indent(f_service_) << js_namespace(tservice->get_program()) << service_name_
-                     << "Processor.prototype.process = function(input, output) ";
+                     << "Processor.prototype.process = function(input, output) {" << endl;
 
-  scope_up(f_service_);
+  indent_up();
 
-  f_service_ << indent() << "var r = input.readMessageBegin();" << endl << indent()
+  indent(f_service_) << js_const_type_ << "r = input.readMessageBegin();" << endl << indent()
              << "if (this['process_' + r.fname]) {" << endl << indent()
              << "  return this['process_' + r.fname].call(this, r.rseqid, input, output);" << endl
              << indent() << "} else {" << endl << indent() << "  input.skip(Thrift.Type.STRUCT);"
              << endl << indent() << "  input.readMessageEnd();" << endl << indent()
-             << "  var x = new "
+             << "  " << js_const_type_ << "x = new "
                 "Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN_METHOD, "
                 "'Unknown function ' + r.fname);" << endl << indent()
              << "  output.writeMessageBegin(r.fname, Thrift.MessageType.EXCEPTION, r.rseqid);"
@@ -1078,8 +1100,8 @@ void t_js_generator::generate_service_processor(t_service* tservice) {
              << "  output.writeMessageEnd();" << endl << indent() << "  output.flush();" << endl
              << indent() << "}" << endl;
 
-  scope_down(f_service_);
-  f_service_ << ";" << endl;
+  indent_down();
+  f_service_ << "};" << endl;
 
   // Generate the process subfunctions
   for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
@@ -1095,15 +1117,15 @@ void t_js_generator::generate_service_processor(t_service* tservice) {
 void t_js_generator::generate_process_function(t_service* tservice, t_function* tfunction) {
   indent(f_service_) << js_namespace(tservice->get_program()) << service_name_
                      << "Processor.prototype.process_" + tfunction->get_name()
-                        + " = function(seqid, input, output) ";
+                        + " = function(seqid, input, output) {" << endl;
 
-  scope_up(f_service_);
+  indent_up();
 
   string argsname = js_namespace(program_) + service_name_ + "_" + tfunction->get_name() + "_args";
   string resultname = js_namespace(program_) + service_name_ + "_" + tfunction->get_name()
                       + "_result";
 
-  f_service_ << indent() << "var args = new " << argsname << "();" << endl << indent()
+  indent(f_service_) << js_const_type_ << "args = new " << argsname << "();" << endl << indent()
              << "args.read(input);" << endl << indent() << "input.readMessageEnd();" << endl;
 
   // Generate the function call
@@ -1126,33 +1148,47 @@ void t_js_generator::generate_process_function(t_service* tservice, t_function*
     }
 
     f_service_ << ");" << endl;
-    scope_down(f_service_);
-    f_service_ << ";" << endl;
+    indent_down();
+    f_service_ << "};" << endl;
     return;
   }
 
-  f_service_ << indent() << "if (this._handler." << tfunction->get_name()
+  indent(f_service_) << "if (this._handler." << tfunction->get_name()
              << ".length === " << fields.size() << ") {" << endl;
   indent_up();
-  indent(f_service_) << "Q.fcall(this._handler." << tfunction->get_name() << ".bind(this._handler)";
 
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    f_service_ << ", args." << (*f_iter)->get_name();
+  if (gen_es6_) {
+    indent(f_service_) << "Promise.resolve(this._handler." << tfunction->get_name() << ".bind(this._handler)(" << endl;
+  } else {
+    string maybeComma = (fields.size() > 0 ? "," : "");
+    indent(f_service_) << "Q.fcall(this._handler." << tfunction->get_name() << ".bind(this._handler)"
+                       << maybeComma << endl;
   }
 
-  f_service_ << ")" << endl;
   indent_up();
-  indent(f_service_) << ".then(function(result) {" << endl;
+  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+    string maybeComma = (f_iter != fields.end() - 1 ? "," : "");
+    indent(f_service_) << "args." << (*f_iter)->get_name() << maybeComma << endl;
+  }
+  indent_down();
+
+  if (gen_es6_) {
+    indent(f_service_) << ")).then(function(result) {" << endl;
+  } else {
+    indent(f_service_) << ").then(function(result) {" << endl;
+  }
+
   indent_up();
-  f_service_ << indent() << "var result_obj = new " << resultname << "({success: result});" << endl
+  f_service_ << indent() << js_const_type_ << "result_obj = new " << resultname << "({success: result});" << endl
              << indent() << "output.writeMessageBegin(\"" << tfunction->get_name()
              << "\", Thrift.MessageType.REPLY, seqid);" << endl << indent()
              << "result_obj.write(output);" << endl << indent() << "output.writeMessageEnd();" << endl
              << indent() << "output.flush();" << endl;
   indent_down();
-  indent(f_service_) << "}, function (err) {" << endl;
+
+  indent(f_service_) << "}).catch(function (err) {" << endl;
   indent_up();
-  indent(f_service_) << "var result;" << endl;
+  indent(f_service_) << js_let_type_ << "result;" << endl;
 
   bool has_exception = false;
   t_struct* exceptions = tfunction->get_xceptions();
@@ -1200,7 +1236,6 @@ void t_js_generator::generate_process_function(t_service* tservice, t_function*
   indent_down();
   indent(f_service_) << "});" << endl;
   indent_down();
-  indent_down();
   indent(f_service_) << "} else {" << endl;
   indent_up();
   indent(f_service_) << "this._handler." << tfunction->get_name() << "(";
@@ -1211,7 +1246,7 @@ void t_js_generator::generate_process_function(t_service* tservice, t_function*
 
   f_service_ << "function (err, result) {" << endl;
   indent_up();
-  indent(f_service_) << "var result_obj;" << endl;
+  indent(f_service_) << js_let_type_ << "result_obj;" << endl;
 
   indent(f_service_) << "if ((err === null || typeof err === 'undefined')";
   if (has_exception) {
@@ -1320,7 +1355,7 @@ void t_js_generator::generate_service_rest(t_service* tservice) {
  */
 void t_js_generator::generate_service_client(t_service* tservice) {
   if (gen_node_) {
-    string prefix = has_js_namespace(tservice->get_program()) ? js_namespace(tservice->get_program()) : "var ";
+    string prefix = has_js_namespace(tservice->get_program()) ? js_namespace(tservice->get_program()) : js_const_type_;
     f_service_ << prefix << service_name_ << "Client = "
                << "exports.Client = function(output, pClass) {" << endl;
   } else {
@@ -1406,7 +1441,7 @@ void t_js_generator::generate_service_client(t_service* tservice) {
 
     if (gen_es6_ && gen_node_) {
       f_service_ << indent() << "this._seqid = this.new_seqid();" << endl;
-      f_service_ << indent() << "var self = this;" << endl << indent()
+      f_service_ << indent() << js_const_type_ << "self = this;" << endl << indent()
                  << "return new Promise(function(resolve, reject) {" << endl;
       indent_up();
       f_service_ << indent() << "self._reqs[self.seqid()] = function(error, result) {" << endl;
@@ -1429,7 +1464,7 @@ void t_js_generator::generate_service_client(t_service* tservice) {
       f_service_ << indent() << "this._seqid = this.new_seqid();" << endl << indent()
                  << "if (callback === undefined) {" << endl;
       indent_up();
-      f_service_ << indent() << "var _defer = Q.defer();" << endl << indent()
+      f_service_ << indent() << js_const_type_ << "_defer = Q.defer();" << endl << indent()
                  << "this._reqs[this.seqid()] = function(error, result) {" << endl;
       indent_up();
       indent(f_service_) << "if (error) {" << endl;
@@ -1453,7 +1488,7 @@ void t_js_generator::generate_service_client(t_service* tservice) {
       indent_down();
       indent(f_service_) << "}" << endl;
     } else if (gen_es6_) {
-      f_service_ << indent() << "var self = this;" << endl << indent()
+      f_service_ << indent() << js_const_type_ << "self = this;" << endl << indent()
                  << "return new Promise(function(resolve, reject) {" << endl;
       indent_up();
       f_service_ << indent() << "self.send_" << funname << "(" << arglist
@@ -1483,7 +1518,7 @@ void t_js_generator::generate_service_client(t_service* tservice) {
       indent_down();
       f_service_ << indent() << "} else {" << endl;
       indent_up();
-      f_service_ << indent() << "var postData = this.send_" << funname << "(" << arglist
+      f_service_ << indent() << js_const_type_ << "postData = this.send_" << funname << "(" << arglist
                  << (arglist.empty() ? "" : ", ") << "true);" << endl;
       f_service_ << indent() << "return this.output.getTransport()" << endl;
       indent_up();
@@ -1518,7 +1553,7 @@ void t_js_generator::generate_service_client(t_service* tservice) {
 
     std::string outputVar;
     if (gen_node_) {
-      f_service_ << indent() << "var output = new this.pClass(this.output);" << endl;
+      f_service_ << indent() << js_const_type_ << "output = new this.pClass(this.output);" << endl;
       outputVar = "output";
     } else {
       outputVar = "this.output";
@@ -1531,7 +1566,7 @@ void t_js_generator::generate_service_client(t_service* tservice) {
                                                      : "Thrift.MessageType.CALL";
     // Build args
     if (fields.size() > 0){
-      f_service_ << indent() << "var params = {" << endl;
+      f_service_ << indent() << js_const_type_ << "params = {" << endl;
       for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
         f_service_ << indent() << indent() << (*fld_iter)->get_name() << ": " << (*fld_iter)->get_name();
         if (fld_iter != fields.end()-1) {
@@ -1541,9 +1576,9 @@ void t_js_generator::generate_service_client(t_service* tservice) {
         }
       }
       f_service_ << indent() << "};" << endl;
-      f_service_ << indent() << "var args = new " << argsname << "(params);" << endl;
+      f_service_ << indent() << js_const_type_ << "args = new " << argsname << "(params);" << endl;
     } else {
-      f_service_ << indent() << "var args = new " << argsname << "();" << endl;
+      f_service_ << indent() << js_const_type_ << "args = new " << argsname << "();" << endl;
     }
 
 
@@ -1567,7 +1602,7 @@ void t_js_generator::generate_service_client(t_service* tservice) {
     if (gen_node_) {
       if((*f_iter)->is_oneway()) {
         f_service_ << indent() << "this.output.flush();" << endl;
-        f_service_ << indent() << "var callback = this._reqs[this.seqid()] || function() {};" << endl;
+        f_service_ << indent() << js_const_type_ << "callback = this._reqs[this.seqid()] || function() {};" << endl;
         f_service_ << indent() << "delete this._reqs[this.seqid()];" << endl;
         f_service_ << indent() << "callback(null);" << endl;
       } else {
@@ -1577,14 +1612,14 @@ void t_js_generator::generate_service_client(t_service* tservice) {
       if (gen_jquery_) {
         f_service_ << indent() << "return this.output.getTransport().flush(callback);" << endl;
       } else if (gen_es6_) {
-        f_service_ << indent() << "var self = this;" << endl;
+        f_service_ << indent() << js_const_type_ << "self = this;" << endl;
         if((*f_iter)->is_oneway()) {
           f_service_ << indent() << "this.output.getTransport().flush(true, null);" << endl;
           f_service_ << indent() << "callback();" << endl;
         } else {
           f_service_ << indent() << "this.output.getTransport().flush(true, function() {" << endl;
           indent_up();
-          f_service_ << indent() << "var error = null, result = null;" << endl;
+          f_service_ << indent() << js_let_type_ << "error = null, result = null;" << endl;
           f_service_ << indent() << "try {" << endl;
           f_service_ << indent() << "  result = self.recv_" << funname << "();" << endl;
           f_service_ << indent() << "} catch (e) {" << endl;
@@ -1596,21 +1631,25 @@ void t_js_generator::generate_service_client(t_service* tservice) {
         }
       } else {
         f_service_ << indent() << "if (callback) {" << endl;
+        indent_up();
         if((*f_iter)->is_oneway()) {
-          f_service_ << indent() << "  this.output.getTransport().flush(true, null);" << endl;
-          f_service_ << indent() << "  callback();" << endl;
+          f_service_ << indent() << "this.output.getTransport().flush(true, null);" << endl;
+          f_service_ << indent() << "callback();" << endl;
         } else {
-          f_service_ << indent() << "  var self = this;" << endl;
-          f_service_ << indent() << "  this.output.getTransport().flush(true, function() {" << endl;
-          f_service_ << indent() << "    var result = null;" << endl;
-          f_service_ << indent() << "    try {" << endl;
-          f_service_ << indent() << "      result = self.recv_" << funname << "();" << endl;
-          f_service_ << indent() << "    } catch (e) {" << endl;
-          f_service_ << indent() << "      result = e;" << endl;
-          f_service_ << indent() << "    }" << endl;
-          f_service_ << indent() << "    callback(result);" << endl;
-          f_service_ << indent() << "  });" << endl;
+          f_service_ << indent() << js_const_type_ << "self = this;" << endl;
+          f_service_ << indent() << "this.output.getTransport().flush(true, function() {" << endl;
+          indent_up();
+          f_service_ << indent() << js_let_type_ << "result = null;" << endl;
+          f_service_ << indent() << "try {" << endl;
+          f_service_ << indent() << "  result = self.recv_" << funname << "();" << endl;
+          f_service_ << indent() << "} catch (e) {" << endl;
+          f_service_ << indent() << "  result = e;" << endl;
+          f_service_ << indent() << "}" << endl;
+          f_service_ << indent() << "callback(result);" << endl;
+          indent_down();
+          f_service_ << indent() << "});" << endl;
         }
+        indent_down();
         f_service_ << indent() << "} else {" << endl;
         f_service_ << indent() << "  return this.output.getTransport().flush();" << endl;
         f_service_ << indent() << "}" << endl;
@@ -1671,21 +1710,23 @@ void t_js_generator::generate_service_client(t_service* tservice) {
       }
 
       if (gen_node_) {
-        f_service_ << indent() << "var callback = this._reqs[rseqid] || function() {};" << endl
+        f_service_ << indent() << js_const_type_ << "callback = this._reqs[rseqid] || function() {};" << endl
                    << indent() << "delete this._reqs[rseqid];" << endl;
       } else {
-        f_service_ << indent() << "var ret = this.input.readMessageBegin();" << endl << indent()
-                   << "var fname = ret.fname;" << endl << indent() << "var mtype = ret.mtype;"
-                   << endl << indent() << "var rseqid = ret.rseqid;" << endl;
+        f_service_ << indent() << js_const_type_ << "ret = this.input.readMessageBegin();" << endl
+                   << indent() << js_const_type_ << "mtype = ret.mtype;" << endl;
       }
 
-      f_service_ << indent() << "if (mtype == Thrift.MessageType.EXCEPTION) {" << endl << indent()
-                 << "  var x = new Thrift.TApplicationException();" << endl << indent()
-                 << "  x.read(" << inputVar << ");" << endl << indent() << "  " << inputVar
-                 << ".readMessageEnd();" << endl << indent() << "  " << render_recv_throw("x")
-                 << endl << indent() << "}" << endl;
+      f_service_ << indent() << "if (mtype == Thrift.MessageType.EXCEPTION) {" << endl;
 
-      f_service_ << indent() << "var result = new " << resultname << "();" << endl << indent()
+      indent_up();
+      f_service_ << indent() << js_const_type_ << "x = new Thrift.TApplicationException();" << endl
+                 << indent() << "x.read(" << inputVar << ");" << endl
+                 << indent() << inputVar << ".readMessageEnd();" << endl
+                 << indent() << render_recv_throw("x") << endl;
+      scope_down(f_service_);
+
+      f_service_ << indent() << js_const_type_ << "result = new " << resultname << "();" << endl << indent()
                  << "result.read(" << inputVar << ");" << endl;
 
       f_service_ << indent() << inputVar << ".readMessageEnd();" << endl << endl;
@@ -1823,47 +1864,35 @@ void t_js_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct
 
 void t_js_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   string size = tmp("_size");
-  string ktype = tmp("_ktype");
-  string vtype = tmp("_vtype");
-  string etype = tmp("_etype");
   string rtmp3 = tmp("_rtmp3");
 
   t_field fsize(g_type_i32, size);
-  t_field fktype(g_type_i8, ktype);
-  t_field fvtype(g_type_i8, vtype);
-  t_field fetype(g_type_i8, etype);
-
-  out << indent() << "var " << size << " = 0;" << endl;
-  out << indent() << "var " << rtmp3 << ";" << endl;
 
   // Declare variables, read header
   if (ttype->is_map()) {
-    out << indent() << prefix << " = {};" << endl << indent() << "var " << ktype << " = 0;" << endl
-        << indent() << "var " << vtype << " = 0;" << endl;
+    out << indent() << prefix << " = {};" << endl;
 
-    out << indent() << rtmp3 << " = input.readMapBegin();" << endl;
-    out << indent() << ktype << " = " << rtmp3 << ".ktype;" << endl;
-    out << indent() << vtype << " = " << rtmp3 << ".vtype;" << endl;
-    out << indent() << size << " = " << rtmp3 << ".size;" << endl;
+    out << indent() << js_const_type_ << rtmp3 << " = input.readMapBegin();" << endl;
+    out << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << endl;
 
   } else if (ttype->is_set()) {
 
-    out << indent() << prefix << " = [];" << endl << indent() << "var " << etype << " = 0;" << endl
-        << indent() << rtmp3 << " = input.readSetBegin();" << endl << indent() << etype << " = "
-        << rtmp3 << ".etype;" << endl << indent() << size << " = " << rtmp3 << ".size;" << endl;
+    out << indent() << prefix << " = [];" << endl
+        << indent() << js_const_type_ << rtmp3 << " = input.readSetBegin();" << endl
+        << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << endl;
 
   } else if (ttype->is_list()) {
 
-    out << indent() << prefix << " = [];" << endl << indent() << "var " << etype << " = 0;" << endl
-        << indent() << rtmp3 << " = input.readListBegin();" << endl << indent() << etype << " = "
-        << rtmp3 << ".etype;" << endl << indent() << size << " = " << rtmp3 << ".size;" << endl;
+    out << indent() << prefix << " = [];" << endl
+        << indent() << js_const_type_ << rtmp3 << " = input.readListBegin();" << endl
+        << indent() << js_const_type_ << size << " = " << rtmp3 << ".size || 0;" << endl;
   }
 
   // For loop iterates over elements
   string i = tmp("_i");
-  indent(out) << "for (var " << i << " = 0; " << i << " < " << size << "; ++" << i << ")" << endl;
+  indent(out) << "for (" << js_let_type_ << i << " = 0; " << i << " < " << size << "; ++" << i << ") {" << endl;
 
-  scope_up(out);
+  indent_up();
 
   if (ttype->is_map()) {
     if (!gen_node_) {
@@ -1914,7 +1943,7 @@ void t_js_generator::generate_deserialize_set_element(ostream& out, t_set* tset,
   string elem = tmp("elem");
   t_field felem(tset->get_elem_type(), elem);
 
-  indent(out) << "var " << elem << " = null;" << endl;
+  indent(out) << js_let_type_ << elem << " = null;" << endl;
 
   generate_deserialize_field(out, &felem);
 
@@ -1927,7 +1956,7 @@ void t_js_generator::generate_deserialize_list_element(ostream& out,
   string elem = tmp("elem");
   t_field felem(tlist->get_elem_type(), elem);
 
-  indent(out) << "var " << elem << " = null;" << endl;
+  indent(out) << js_let_type_ << elem << " = null;" << endl;
 
   generate_deserialize_field(out, &felem);
 
@@ -2037,21 +2066,21 @@ void t_js_generator::generate_serialize_container(ostream& out, t_type* ttype, s
   if (ttype->is_map()) {
     string kiter = tmp("kiter");
     string viter = tmp("viter");
-    indent(out) << "for (var " << kiter << " in " << prefix << ")" << endl;
-    scope_up(out);
-    indent(out) << "if (" << prefix << ".hasOwnProperty(" << kiter << "))" << endl;
-    scope_up(out);
-    indent(out) << "var " << viter << " = " << prefix << "[" << kiter << "];" << endl;
+    indent(out) << "for (" << js_let_type_ << kiter << " in " << prefix << ") {" << endl;
+    indent_up();
+    indent(out) << "if (" << prefix << ".hasOwnProperty(" << kiter << ")) {" << endl;
+    indent_up();
+    indent(out) << js_let_type_ << viter << " = " << prefix << "[" << kiter << "];" << endl;
     generate_serialize_map_element(out, (t_map*)ttype, kiter, viter);
     scope_down(out);
     scope_down(out);
 
   } else if (ttype->is_set()) {
     string iter = tmp("iter");
-    indent(out) << "for (var " << iter << " in " << prefix << ")" << endl;
-    scope_up(out);
-    indent(out) << "if (" << prefix << ".hasOwnProperty(" << iter << "))" << endl;
-    scope_up(out);
+    indent(out) << "for (" << js_let_type_ << iter << " in " << prefix << ") {" << endl;
+    indent_up();
+    indent(out) << "if (" << prefix << ".hasOwnProperty(" << iter << ")) {" << endl;
+    indent_up();
     indent(out) << iter << " = " << prefix << "[" << iter << "];" << endl;
     generate_serialize_set_element(out, (t_set*)ttype, iter);
     scope_down(out);
@@ -2059,10 +2088,10 @@ void t_js_generator::generate_serialize_container(ostream& out, t_type* ttype, s
 
   } else if (ttype->is_list()) {
     string iter = tmp("iter");
-    indent(out) << "for (var " << iter << " in " << prefix << ")" << endl;
-    scope_up(out);
-    indent(out) << "if (" << prefix << ".hasOwnProperty(" << iter << "))" << endl;
-    scope_up(out);
+    indent(out) << "for (" << js_let_type_ << iter << " in " << prefix << ") {" << endl;
+    indent_up();
+    indent(out) << "if (" << prefix << ".hasOwnProperty(" << iter << ")) {" << endl;
+    indent_up();
     indent(out) << iter << " = " << prefix << "[" << iter << "];" << endl;
     generate_serialize_list_element(out, (t_list*)ttype, iter);
     scope_down(out);
@@ -2118,7 +2147,7 @@ string t_js_generator::declare_field(t_field* tfield, bool init, bool obj) {
   string result = "this." + tfield->get_name();
 
   if (!obj) {
-    result = "var " + tfield->get_name();
+    result = js_let_type_ + tfield->get_name();
   }
 
   if (init) {
diff --git a/lib/js/Gruntfile.js b/lib/js/Gruntfile.js
index 1dcead6..fd290d2 100644
--- a/lib/js/Gruntfile.js
+++ b/lib/js/Gruntfile.js
@@ -3,6 +3,7 @@
 //Prerequisites:
 // Node Setup -   nodejs.org
 // Grunt Setup -  npm install  //reads the ./package.json and installs project dependencies
+// Run grunt -    npx grunt  // uses project-local installed version of grunt (from package.json)
 
 module.exports = function(grunt) {
   'use strict';
@@ -38,7 +39,7 @@ module.exports = function(grunt) {
     },
     shell: {
       InstallThriftJS: {
-        command: 'mkdir test/build; mkdir test/build/js; mkdir test/build/js/lib; cp src/thrift.js test/build/js/thrift.js'
+        command: 'mkdir -p test/build/js/lib; cp src/thrift.js test/build/js/thrift.js'
       },
       InstallThriftNodeJSDep: {
         command: 'cd ../..; npm install'
@@ -47,7 +48,19 @@ module.exports = function(grunt) {
         command: 'cd test; ant download_jslibs'
       },
       ThriftGen: {
-        command: '../../compiler/cpp/thrift -gen js -gen js:node -o test ../../test/ThriftTest.thrift'
+        command: [
+          'mkdir -p test/gen-js',
+          '../../compiler/cpp/thrift -gen js --out test/gen-js ../../test/ThriftTest.thrift',
+          '../../compiler/cpp/thrift -gen js --out test/gen-js ../../test/JsDeepConstructorTest.thrift',
+          'mkdir -p test/gen-js-jquery',
+          '../../compiler/cpp/thrift -gen js:jquery --out test/gen-js-jquery ../../test/ThriftTest.thrift',
+          'mkdir -p test/gen-nodejs',
+          '../../compiler/cpp/thrift -gen js:node --out test/gen-nodejs ../../test/ThriftTest.thrift',
+          'mkdir -p test/gen-js-es6',
+          '../../compiler/cpp/thrift -gen js:es6 --out test/gen-js-es6 ../../test/ThriftTest.thrift',
+          'mkdir -p test/gen-nodejs-es6',
+          '../../compiler/cpp/thrift -gen js:node,es6 --out ./test/gen-nodejs-es6 ../../test/ThriftTest.thrift',
+        ].join(' && ')
       },
       ThriftGenJQ: {
         command: '../../compiler/cpp/thrift -gen js:jquery -gen js:node -o test ../../test/ThriftTest.thrift'
@@ -58,9 +71,6 @@ module.exports = function(grunt) {
       ThriftGenDoubleConstants: {
         command: '../../compiler/cpp/thrift -gen js -o test ../../test/DoubleConstantsTest.thrift'
       },
-      ThriftGenES6: {
-        command: '../../compiler/cpp/thrift -gen js -gen js:es6 -o test ../../test/ThriftTest.thrift'
-      },
       ThriftTestServer: {
         options: {
           async: true,
@@ -71,6 +81,16 @@ module.exports = function(grunt) {
         },
         command: "node server_http.js",
       },
+      ThriftTestServerES6: {
+        options: {
+          async: true,
+          execOptions: {
+            cwd: "./test",
+            env: {NODE_PATH: "../../nodejs/lib:../../../node_modules"}
+          }
+        },
+        command: "node server_http.js --es6",
+      },
       ThriftTestServer_TLS: {
         options: {
           async: true,
@@ -81,88 +101,151 @@ module.exports = function(grunt) {
         },
         command: "node server_https.js",
       },
+      ThriftTestServerES6_TLS: {
+        options: {
+          async: true,
+          execOptions: {
+            cwd: "./test",
+            env: {NODE_PATH: "../../nodejs/lib:../../../node_modules"}
+          }
+        },
+        command: "node server_https.js --es6",
+      },
     },
     qunit: {
       ThriftJS: {
         options: {
           urls: [
-            'http://localhost:8088/test-nojq.html'
-          ]
+            'http://localhost:8089/test-nojq.html'
+          ],
+          puppeteer: {
+            headless: true,
+            args: ['--no-sandbox'],
+          },
         }
       },
       ThriftJSJQ: {
         options: {
           urls: [
-            'http://localhost:8088/test.html'
-          ]
+            'http://localhost:8089/test.html'
+          ],
+          puppeteer: {
+            headless: true,
+            args: ['--no-sandbox'],
+          },
         }
       },
       ThriftJS_DoubleRendering: {
         options: {
-          '--ignore-ssl-errors': true,
           urls: [
-            'http://localhost:8088/test-double-rendering.html'
-          ]
+            'http://localhost:8089/test-double-rendering.html'
+          ],
+          puppeteer: {
+            headless: true,
+            args: ['--no-sandbox'],
+            ignoreHTTPSErrors: true,
+          },
         }
       },
       ThriftWS: {
         options: {
           urls: [
-            'http://localhost:8088/testws.html'
-          ]
+            'http://localhost:8089/testws.html'
+          ],
+          puppeteer: {
+            headless: true,
+            args: ['--no-sandbox'],
+          },
         }
       },
       ThriftJS_TLS: {
         options: {
-          '--ignore-ssl-errors': true,
           urls: [
-            'https://localhost:8089/test-nojq.html'
-          ]
+            'https://localhost:8091/test-nojq.html'
+          ],
+          puppeteer: {
+            headless: true,
+            args: ['--no-sandbox'],
+            ignoreHTTPSErrors: true,
+          },
         }
       },
       ThriftJSJQ_TLS: {
         options: {
-          '--ignore-ssl-errors': true,
           urls: [
-            'https://localhost:8089/test.html'
-          ]
+            'https://localhost:8091/test.html'
+          ],
+          puppeteer: {
+            headless: true,
+            args: ['--no-sandbox'],
+            ignoreHTTPSErrors: true,
+          },
         }
       },
       ThriftWS_TLS: {
         options: {
-          '--ignore-ssl-errors': true,
           urls: [
-            'https://localhost:8089/testws.html'
-          ]
+            'https://localhost:8091/testws.html'
+          ],
+          puppeteer: {
+            headless: true,
+            args: ['--no-sandbox'],
+            ignoreHTTPSErrors: true,
+          },
         }
       },
       ThriftDeepConstructor: {
         options: {
           urls: [
-            'http://localhost:8088/test-deep-constructor.html'
-          ]
+            'http://localhost:8089/test-deep-constructor.html'
+          ],
+          puppeteer: {
+            headless: true,
+            args: ['--no-sandbox'],
+          },
         }
       },
       ThriftWSES6: {
         options: {
           urls: [
             'http://localhost:8088/test-es6.html'
-          ]
+          ],
+          puppeteer: {
+            headless: true,
+            args: ['--no-sandbox'],
+          },
         }
       }
     },
     jshint: {
-      files: ['Gruntfile.js', 'src/**/*.js', 'test/*.js'],
-      options: {
-        // options here to override JSHint defaults
-        globals: {
-          jQuery: true,
-          console: true,
-          module: true,
-          document: true
+      // The main thrift library file. not es6 yet :(
+      lib: {
+        src: ['src/**/*.js'],
+        options: {
+          // options here to override JSHint defaults
+          globals: {
+            jQuery: true,
+            console: true,
+            module: true,
+            document: true,
+          },
         }
-      }
-    },
+      },
+      // The test files use es6
+      test: {
+        src: ['Gruntfile.js', 'test/*.js'],
+        options: {
+          // options here to override JSHint defaults
+          globals: {
+            jQuery: true,
+            console: true,
+            module: true,
+            document: true,
+          },
+          esversion: 6,
+        }
+      },
+    }
   });
 
   grunt.loadNpmTasks('grunt-contrib-uglify');
@@ -179,16 +262,25 @@ module.exports = function(grunt) {
     }, 1000);
   });
 
-  grunt.registerTask('test', ['jshint', 'shell:InstallThriftJS', 'shell:InstallThriftNodeJSDep', 'shell:ThriftGen',
-                              'shell:InstallTestLibs',
-                              'shell:ThriftTestServer', 'shell:ThriftTestServer_TLS',
-                              'wait',
-                              'shell:ThriftGenDeepConstructor', 'qunit:ThriftDeepConstructor',
-                              'qunit:ThriftJS', 'qunit:ThriftJS_TLS',
-                              'qunit:ThriftWS',
-                              'shell:ThriftGenJQ', 'qunit:ThriftJSJQ', 'qunit:ThriftJSJQ_TLS',
-                              'shell:ThriftGenES6', 'qunit:ThriftWSES6',
-                              'shell:ThriftTestServer:kill', 'shell:ThriftTestServer_TLS:kill',
-                             ]);
+  grunt.registerTask('installAndGenerate', [
+    'shell:InstallThriftJS', 'shell:InstallThriftNodeJSDep', 'shell:ThriftGen',
+    'shell:ThriftGenDeepConstructor',
+    'shell:InstallTestLibs',
+  ]);
+
+  grunt.registerTask('test', [
+    'jshint',
+    'installAndGenerate',
+    'shell:ThriftTestServer', 'shell:ThriftTestServer_TLS',
+    'shell:ThriftTestServerES6', 'shell:ThriftTestServerES6_TLS',
+    'wait',
+    'qunit:ThriftDeepConstructor',
+    'qunit:ThriftJS', 'qunit:ThriftJS_TLS',
+    'qunit:ThriftWS',
+    'qunit:ThriftJSJQ', 'qunit:ThriftJSJQ_TLS',
+    'qunit:ThriftWSES6',
+    'shell:ThriftTestServer:kill', 'shell:ThriftTestServer_TLS:kill',
+    'shell:ThriftTestServerES6:kill', 'shell:ThriftTestServerES6_TLS:kill',
+  ]);
   grunt.registerTask('default', ['test', 'concat', 'uglify', 'jsdoc']);
 };
diff --git a/lib/js/README.md b/lib/js/README.md
index dfa6e82..9d51e2a 100644
--- a/lib/js/README.md
+++ b/lib/js/README.md
@@ -38,19 +38,12 @@ This reads the package.json and pulls in the appropriate
 sources from the internet. To build the JavaScript branch
 of Apache Thrift execute the command:
 
-    grunt
+    npx grunt
     
-This runs the grunt build tool, linting all of the source
-files, setting up and running the tests, concatenating and
-minifying the main libraries and generating the html 
-documentation.
-
-If grunt is not installed you can install it with npm
-like this:
-
-   sudo npm install -g grunt-cli
-   npm install grunt --save-dev
-
+This runs the grunt build tool (from within `./node_modules/.bin/`),
+linting all of the source files, setting up and running the
+tests, concatenating and minifying the main libraries and
+generating the html documentation.
 
 Tree
 ----
diff --git a/lib/js/package-lock.json b/lib/js/package-lock.json
index 02347cf..f0943b0 100644
--- a/lib/js/package-lock.json
+++ b/lib/js/package-lock.json
@@ -9,16 +9,13 @@
       "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
       "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg="
     },
-    "ajv": {
-      "version": "5.5.2",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
-      "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+    "agent-base": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
+      "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
       "dev": true,
       "requires": {
-        "co": "4.6.0",
-        "fast-deep-equal": "1.1.0",
-        "fast-json-stable-stringify": "2.0.0",
-        "json-schema-traverse": "0.3.1"
+        "es6-promisify": "5.0.0"
       }
     },
     "align-text": {
@@ -67,40 +64,16 @@
       "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
       "dev": true
     },
-    "asn1": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
-      "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
-      "dev": true
-    },
-    "assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-      "dev": true
-    },
     "async": {
       "version": "1.5.2",
       "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
       "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
       "dev": true
     },
-    "asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
-      "dev": true
-    },
-    "aws-sign2": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
-      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
-      "dev": true
-    },
-    "aws4": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
-      "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
+    "async-limiter": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
+      "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
       "dev": true
     },
     "babylon": {
@@ -114,30 +87,11 @@
       "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
       "dev": true
     },
-    "bcrypt-pbkdf": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
-      "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
-      "dev": true,
-      "optional": true,
-      "requires": {
-        "tweetnacl": "0.14.5"
-      }
-    },
     "bluebird": {
       "version": "3.5.1",
       "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
       "integrity": "sha1-2VUfnemPH82h5oPRfukaBgLuLrk="
     },
-    "boom": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
-      "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
-      "dev": true,
-      "requires": {
-        "hoek": "4.2.1"
-      }
-    },
     "brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -157,6 +111,12 @@
         "pako": "0.2.9"
       }
     },
+    "buffer-from": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
+    },
     "buffer-shims": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
@@ -185,12 +145,6 @@
         "map-obj": "1.0.1"
       }
     },
-    "caseless": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
-      "dev": true
-    },
     "catharsis": {
       "version": "0.8.9",
       "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.9.tgz",
@@ -268,12 +222,6 @@
         "wordwrap": "0.0.2"
       }
     },
-    "co": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
-      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
-      "dev": true
-    },
     "coffeescript": {
       "version": "1.10.0",
       "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz",
@@ -286,15 +234,6 @@
       "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
       "dev": true
     },
-    "combined-stream": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
-      "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
-      "dev": true,
-      "requires": {
-        "delayed-stream": "1.0.0"
-      }
-    },
     "concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -390,26 +329,6 @@
         }
       }
     },
-    "cryptiles": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
-      "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
-      "dev": true,
-      "requires": {
-        "boom": "5.2.0"
-      },
-      "dependencies": {
-        "boom": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
-          "integrity": "sha1-XdnabuOl8wIHdDYpDLcX0/SlTgI=",
-          "dev": true,
-          "requires": {
-            "hoek": "4.2.1"
-          }
-        }
-      }
-    },
     "currently-unhandled": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
@@ -419,15 +338,6 @@
         "array-find-index": "1.0.2"
       }
     },
-    "dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "1.0.0"
-      }
-    },
     "date-now": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
@@ -445,9 +355,9 @@
       }
     },
     "debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
       "dev": true,
       "requires": {
         "ms": "2.0.0"
@@ -459,12 +369,6 @@
       "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
       "dev": true
     },
-    "delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
-      "dev": true
-    },
     "dom-serializer": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
@@ -514,16 +418,6 @@
         "domelementtype": "1.3.0"
       }
     },
-    "ecc-jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
-      "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
-      "dev": true,
-      "optional": true,
-      "requires": {
-        "jsbn": "0.1.1"
-      }
-    },
     "entities": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
@@ -545,6 +439,15 @@
       "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
       "dev": true
     },
+    "es6-promisify": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+      "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
+      "dev": true,
+      "requires": {
+        "es6-promise": "4.2.4"
+      }
+    },
     "escape-string-regexp": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@@ -568,53 +471,71 @@
       "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
       "dev": true
     },
-    "extend": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
-      "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
-      "dev": true
-    },
     "extract-zip": {
-      "version": "1.6.6",
-      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz",
-      "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=",
+      "version": "1.6.7",
+      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
+      "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
       "dev": true,
       "requires": {
-        "concat-stream": "1.6.0",
+        "concat-stream": "1.6.2",
         "debug": "2.6.9",
-        "mkdirp": "0.5.0",
+        "mkdirp": "0.5.1",
         "yauzl": "2.4.1"
       },
       "dependencies": {
-        "mkdirp": {
-          "version": "0.5.0",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
-          "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=",
+        "concat-stream": {
+          "version": "1.6.2",
+          "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+          "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+          "dev": true,
+          "requires": {
+            "buffer-from": "1.1.1",
+            "inherits": "2.0.3",
+            "readable-stream": "2.3.6",
+            "typedarray": "0.0.6"
+          }
+        },
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
           "dev": true,
           "requires": {
-            "minimist": "0.0.8"
+            "ms": "2.0.0"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "2.0.0",
+            "safe-buffer": "5.1.1",
+            "string_decoder": "1.1.1",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.1.1"
           }
         }
       }
     },
-    "extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
-      "dev": true
-    },
-    "fast-deep-equal": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
-      "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
-      "dev": true
-    },
-    "fast-json-stable-stringify": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
-      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
-      "dev": true
-    },
     "fd-slicer": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
@@ -668,45 +589,6 @@
         }
       }
     },
-    "forever-agent": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
-      "dev": true
-    },
-    "form-data": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
-      "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
-      "dev": true,
-      "requires": {
-        "asynckit": "0.4.0",
-        "combined-stream": "1.0.6",
-        "mime-types": "2.1.18"
-      }
-    },
-    "fs-extra": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
-      "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "4.1.11",
-        "jsonfile": "2.4.0",
-        "klaw": "1.3.1"
-      },
-      "dependencies": {
-        "klaw": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
-          "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
-          "dev": true,
-          "requires": {
-            "graceful-fs": "4.1.11"
-          }
-        }
-      }
-    },
     "fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -725,15 +607,6 @@
       "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=",
       "dev": true
     },
-    "getpass": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "1.0.0"
-      }
-    },
     "glob": {
       "version": "7.0.6",
       "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
@@ -864,12 +737,22 @@
       }
     },
     "grunt-contrib-qunit": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-1.3.0.tgz",
-      "integrity": "sha1-naxijP1OyBWZhjPbc7Ur2z3byZ4=",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-3.0.1.tgz",
+      "integrity": "sha512-s994+ipKwc+oUUIWaGIw1soyID4pExSGMd/cHQN5h0p8KbIjR1Le3ZC3giSDDKXtZFE0i+Obf0uIjNvjftX2Cw==",
       "dev": true,
       "requires": {
-        "grunt-lib-phantomjs": "1.1.0"
+        "eventemitter2": "5.0.1",
+        "p-each-series": "1.0.0",
+        "puppeteer": "1.7.0"
+      },
+      "dependencies": {
+        "eventemitter2": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz",
+          "integrity": "sha1-YZegldX7a1folC9v1+qtY6CclFI=",
+          "dev": true
+        }
       }
     },
     "grunt-contrib-uglify": {
@@ -970,53 +853,6 @@
         }
       }
     },
-    "grunt-lib-phantomjs": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/grunt-lib-phantomjs/-/grunt-lib-phantomjs-1.1.0.tgz",
-      "integrity": "sha1-np7c3Z/S3UDgwYHJQ3HVcqpe6tI=",
-      "dev": true,
-      "requires": {
-        "eventemitter2": "0.4.14",
-        "phantomjs-prebuilt": "2.1.16",
-        "rimraf": "2.6.2",
-        "semver": "5.5.0",
-        "temporary": "0.0.8"
-      },
-      "dependencies": {
-        "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=",
-          "dev": true,
-          "requires": {
-            "fs.realpath": "1.0.0",
-            "inflight": "1.0.6",
-            "inherits": "2.0.3",
-            "minimatch": "3.0.4",
-            "once": "1.4.0",
-            "path-is-absolute": "1.0.1"
-          }
-        },
-        "minimatch": {
-          "version": "3.0.4",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-          "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "1.1.11"
-          }
-        },
-        "rimraf": {
-          "version": "2.6.2",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
-          "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=",
-          "dev": true,
-          "requires": {
-            "glob": "7.1.2"
-          }
-        }
-      }
-    },
     "grunt-shell-spawn": {
       "version": "0.3.10",
       "resolved": "https://registry.npmjs.org/grunt-shell-spawn/-/grunt-shell-spawn-0.3.10.tgz",
@@ -1037,22 +873,6 @@
         "concat-stream": "1.6.0"
       }
     },
-    "har-schema": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
-      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
-      "dev": true
-    },
-    "har-validator": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
-      "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
-      "dev": true,
-      "requires": {
-        "ajv": "5.5.2",
-        "har-schema": "2.0.0"
-      }
-    },
     "has-ansi": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
@@ -1062,34 +882,6 @@
         "ansi-regex": "2.1.1"
       }
     },
-    "hasha": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz",
-      "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=",
-      "dev": true,
-      "requires": {
-        "is-stream": "1.1.0",
-        "pinkie-promise": "2.0.1"
-      }
-    },
-    "hawk": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
-      "integrity": "sha1-r02RTrBl+bXOTZ0RwcshJu7MMDg=",
-      "dev": true,
-      "requires": {
-        "boom": "4.3.1",
-        "cryptiles": "3.1.2",
-        "hoek": "4.2.1",
-        "sntp": "2.1.0"
-      }
-    },
-    "hoek": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
-      "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==",
-      "dev": true
-    },
     "hooker": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
@@ -1115,15 +907,14 @@
         "readable-stream": "1.1.14"
       }
     },
-    "http-signature": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+    "https-proxy-agent": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
+      "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
       "dev": true,
       "requires": {
-        "assert-plus": "1.0.0",
-        "jsprim": "1.4.1",
-        "sshpk": "1.13.1"
+        "agent-base": "4.2.1",
+        "debug": "3.1.0"
       }
     },
     "iconv-lite": {
@@ -1187,18 +978,6 @@
         "number-is-nan": "1.0.1"
       }
     },
-    "is-stream": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
-      "dev": true
-    },
-    "is-typedarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
-      "dev": true
-    },
     "is-utf8": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
@@ -1217,12 +996,6 @@
       "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
       "dev": true
     },
-    "isstream": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
-      "dev": true
-    },
     "js-yaml": {
       "version": "3.5.5",
       "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz",
@@ -1241,13 +1014,6 @@
         "xmlcreate": "1.0.2"
       }
     },
-    "jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-      "dev": true,
-      "optional": true
-    },
     "jsdoc": {
       "version": "3.5.5",
       "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.5.5.tgz",
@@ -1370,51 +1136,6 @@
         }
       }
     },
-    "json-schema": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
-      "dev": true
-    },
-    "json-schema-traverse": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
-      "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
-      "dev": true
-    },
-    "json-stringify-safe": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
-      "dev": true
-    },
-    "jsonfile": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
-      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "4.1.11"
-      }
-    },
-    "jsprim": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "1.0.0",
-        "extsprintf": "1.3.0",
-        "json-schema": "0.2.3",
-        "verror": "1.10.0"
-      }
-    },
-    "kew": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
-      "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
-      "dev": true
-    },
     "kind-of": {
       "version": "3.2.2",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
@@ -1522,21 +1243,12 @@
         }
       }
     },
-    "mime-db": {
-      "version": "1.33.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
-      "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
+    "mime": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
+      "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
       "dev": true
     },
-    "mime-types": {
-      "version": "2.1.18",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
-      "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
-      "dev": true,
-      "requires": {
-        "mime-db": "1.33.0"
-      }
-    },
     "minimatch": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -1592,12 +1304,6 @@
       "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
       "dev": true
     },
-    "oauth-sign": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
-      "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
-      "dev": true
-    },
     "object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -1632,10 +1338,19 @@
         "os-tmpdir": "1.0.2"
       }
     },
-    "package": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/package/-/package-1.0.1.tgz",
-      "integrity": "sha1-0lofmeJQbcsn1nBLg9yooxLk7cw=",
+    "p-each-series": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz",
+      "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=",
+      "dev": true,
+      "requires": {
+        "p-reduce": "1.0.0"
+      }
+    },
+    "p-reduce": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz",
+      "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=",
       "dev": true
     },
     "pako": {
@@ -1685,40 +1400,6 @@
       "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
       "dev": true
     },
-    "performance-now": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
-      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
-      "dev": true
-    },
-    "phantomjs-prebuilt": {
-      "version": "2.1.16",
-      "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz",
-      "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=",
-      "dev": true,
-      "requires": {
-        "es6-promise": "4.2.4",
-        "extract-zip": "1.6.6",
-        "fs-extra": "1.0.0",
-        "hasha": "2.2.0",
-        "kew": "0.7.0",
-        "progress": "1.1.8",
-        "request": "2.83.0",
-        "request-progress": "2.0.1",
-        "which": "1.3.0"
-      },
-      "dependencies": {
-        "which": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
-          "integrity": "sha1-/wS9/AEO5UfXgL7DjhrBwnd9JTo=",
-          "dev": true,
-          "requires": {
-            "isexe": "2.0.0"
-          }
-        }
-      }
-    },
     "pify": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
@@ -1757,9 +1438,15 @@
       "dev": true
     },
     "progress": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
-      "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
+      "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
+      "dev": true
+    },
+    "proxy-from-env": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
+      "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=",
       "dev": true
     },
     "pseudomap": {
@@ -1768,17 +1455,32 @@
       "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
       "dev": true
     },
-    "punycode": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
-      "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
-      "dev": true
-    },
-    "qs": {
-      "version": "6.5.1",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
-      "integrity": "sha1-NJzfbu+J7EXBLX1es/wMhwNDptg=",
-      "dev": true
+    "puppeteer": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.7.0.tgz",
+      "integrity": "sha512-f+1DxKHPqce6CXUBz2eVO2WcATeVeQSOPG9GYaGObEZDCiCEUwG+gogjMsrvn7he2wHTqNVb5p6RUrwmr8XFBA==",
+      "dev": true,
+      "requires": {
+        "debug": "3.1.0",
+        "extract-zip": "1.6.7",
+        "https-proxy-agent": "2.2.1",
+        "mime": "2.3.1",
+        "progress": "2.0.0",
+        "proxy-from-env": "1.0.0",
+        "rimraf": "2.6.2",
+        "ws": "5.2.2"
+      },
+      "dependencies": {
+        "rimraf": {
+          "version": "2.6.2",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+          "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+          "dev": true,
+          "requires": {
+            "glob": "7.0.6"
+          }
+        }
+      }
     },
     "read-pkg": {
       "version": "1.1.0",
@@ -1838,45 +1540,6 @@
         "is-finite": "1.0.2"
       }
     },
-    "request": {
-      "version": "2.83.0",
-      "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
-      "integrity": "sha1-ygtl2gLtYpNYh4COb1EDgQNOM1Y=",
-      "dev": true,
-      "requires": {
-        "aws-sign2": "0.7.0",
-        "aws4": "1.6.0",
-        "caseless": "0.12.0",
-        "combined-stream": "1.0.6",
-        "extend": "3.0.1",
-        "forever-agent": "0.6.1",
-        "form-data": "2.3.2",
-        "har-validator": "5.0.3",
-        "hawk": "6.0.2",
-        "http-signature": "1.2.0",
-        "is-typedarray": "1.0.0",
-        "isstream": "0.1.2",
-        "json-stringify-safe": "5.0.1",
-        "mime-types": "2.1.18",
-        "oauth-sign": "0.8.2",
-        "performance-now": "2.1.0",
-        "qs": "6.5.1",
-        "safe-buffer": "5.1.1",
-        "stringstream": "0.0.5",
-        "tough-cookie": "2.3.4",
-        "tunnel-agent": "0.6.0",
-        "uuid": "3.2.1"
-      }
-    },
-    "request-progress": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz",
-      "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=",
-      "dev": true,
-      "requires": {
-        "throttleit": "1.0.0"
-      }
-    },
     "requizzle": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.1.tgz",
@@ -1937,15 +1600,6 @@
       "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
       "dev": true
     },
-    "sntp": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
-      "integrity": "sha1-LGzsFP7cIiJznK+bXD2F0cxaLMg=",
-      "dev": true,
-      "requires": {
-        "hoek": "4.2.1"
-      }
-    },
     "source-map": {
       "version": "0.5.7",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -1990,34 +1644,12 @@
       "integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw=",
       "dev": true
     },
-    "sshpk": {
-      "version": "1.13.1",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
-      "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
-      "dev": true,
-      "requires": {
-        "asn1": "0.2.3",
-        "assert-plus": "1.0.0",
-        "bcrypt-pbkdf": "1.0.1",
-        "dashdash": "1.14.1",
-        "ecc-jsbn": "0.1.1",
-        "getpass": "0.1.7",
-        "jsbn": "0.1.1",
-        "tweetnacl": "0.14.5"
-      }
-    },
     "string_decoder": {
       "version": "0.10.31",
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
       "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
       "dev": true
     },
-    "stringstream": {
-      "version": "0.0.5",
-      "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
-      "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
-      "dev": true
-    },
     "strip-ansi": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
@@ -2067,52 +1699,12 @@
       "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
       "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg="
     },
-    "temporary": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/temporary/-/temporary-0.0.8.tgz",
-      "integrity": "sha1-oYqYHSi6jKNgJ/s8MFOMPst0CsA=",
-      "dev": true,
-      "requires": {
-        "package": "1.0.1"
-      }
-    },
-    "throttleit": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
-      "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
-      "dev": true
-    },
-    "tough-cookie": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
-      "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
-      "dev": true,
-      "requires": {
-        "punycode": "1.4.1"
-      }
-    },
     "trim-newlines": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
       "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
       "dev": true
     },
-    "tunnel-agent": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "5.1.1"
-      }
-    },
-    "tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
-      "dev": true,
-      "optional": true
-    },
     "typedarray": {
       "version": "0.0.6",
       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
@@ -2187,12 +1779,6 @@
       "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
       "dev": true
     },
-    "uuid": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
-      "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==",
-      "dev": true
-    },
     "validate-npm-package-license": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz",
@@ -2203,17 +1789,6 @@
         "spdx-expression-parse": "3.0.0"
       }
     },
-    "verror": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "1.0.0",
-        "core-util-is": "1.0.2",
-        "extsprintf": "1.3.0"
-      }
-    },
     "which": {
       "version": "1.2.14",
       "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz",
@@ -2241,6 +1816,15 @@
       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
       "dev": true
     },
+    "ws": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
+      "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
+      "dev": true,
+      "requires": {
+        "async-limiter": "1.0.0"
+      }
+    },
     "xmlcreate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-1.0.2.tgz",
diff --git a/lib/js/package.json b/lib/js/package.json
index f3ed3e1..a59cdc4 100644
--- a/lib/js/package.json
+++ b/lib/js/package.json
@@ -6,7 +6,7 @@
     "grunt-cli": "^1.2.0",
     "grunt-contrib-concat": "^1.0.1",
     "grunt-contrib-jshint": "^1.0.0",
-    "grunt-contrib-qunit": "^1.2.0",
+    "grunt-contrib-qunit": "^3.0.1",
     "grunt-contrib-uglify": "^1.0.1",
     "grunt-jsdoc": "^2.2.1",
     "grunt-shell-spawn": "^0.3.10",
diff --git a/lib/js/test/build.xml b/lib/js/test/build.xml
index 0ba3828..04c1360 100755
--- a/lib/js/test/build.xml
+++ b/lib/js/test/build.xml
@@ -100,9 +100,8 @@
 
   <target name="download_jslibs">
     <get src="http://code.jquery.com/jquery-1.11.3.min.js" dest="${build}/js/lib/jquery.js" usetimestamp="true"/>
-    <get src="http://code.jquery.com/qunit/qunit-1.18.0.js" dest="${build}/js/lib/qunit.js" usetimestamp="true"/>
-    <get src="http://code.jquery.com/qunit/qunit-1.18.0.css" dest="${build}/js/lib/qunit.css" usetimestamp="true"/>
-    <get src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js" dest="${build}/js/lib/es6-promise.js" usetimestamp="true"/>
+    <get src="http://code.jquery.com/qunit/qunit-2.6.2.js" dest="${build}/js/lib/qunit.js" usetimestamp="true"/>
+    <get src="http://code.jquery.com/qunit/qunit-2.6.2.css" dest="${build}/js/lib/qunit.css" usetimestamp="true"/>
   </target>
 
   <target name="jslibs" depends="init, proxy, download_jslibs">
diff --git a/lib/js/test/deep-constructor.test.js b/lib/js/test/deep-constructor.test.js
index f349e46..82d3a1e 100644
--- a/lib/js/test/deep-constructor.test.js
+++ b/lib/js/test/deep-constructor.test.js
@@ -1,6 +1,6 @@
 function serialize(data) {
-  var transport = new Thrift.Transport('/service');
-  var protocol = new Thrift.Protocol(transport);
+  const transport = new Thrift.Transport('/service');
+  const protocol = new Thrift.Protocol(transport);
   protocol.writeMessageBegin('', 0, 0);
   data.write(protocol);
   protocol.writeMessageEnd();
@@ -8,11 +8,11 @@ function serialize(data) {
 }
 
 function deserialize(serialized, type) {
-  var transport = new Thrift.Transport('/service');
+  const transport = new Thrift.Transport('/service');
   transport.setRecvBuffer(serialized);
-  var protocol = new Thrift.Protocol(transport);
+  const protocol = new Thrift.Protocol(transport);
   protocol.readMessageBegin();
-  var data = new type();
+  const data = new type();
   data.read(protocol);
   protocol.readMessageEnd();
   return data;
@@ -145,36 +145,36 @@ function assertValues(obj, assert) {
     assert.equal(obj.list_of_list_field[2][1], 'six');
 }
 
-var cases = {
+const cases = {
 
   'Serialize/deserialize simple struct should return equal object': function(assert) {
-    var tObj = new Simple({value: 'a'});
-    var received = deserialize(serialize(tObj), Simple);
+    const tObj = new Simple({value: 'a'});
+    const received = deserialize(serialize(tObj), Simple);
     assert.ok(tObj !== received);
     assert.deepEqual(received, tObj);
   },
 
 
   'Serialize/deserialize should return equal object': function(assert) {
-    var tObj = createThriftObj();
-    var received = deserialize(serialize(tObj), Complex);
+    const tObj = createThriftObj();
+    const received = deserialize(serialize(tObj), Complex);
     assert.ok(tObj !== received);
     assert.deepEqual(received, tObj);
   },
 
   'Nested structs and containers initialized from plain js objects should serialize same as if initialized from thrift objects': function(assert) {
-    var tObj1 = createThriftObj();
-    var tObj2 = new Complex(createJsObj());
+    const tObj1 = createThriftObj();
+    const tObj2 = new Complex(createJsObj());
     assertValues(tObj2, assert);
     assert.equal(serialize(tObj2), serialize(tObj1));
   },
 
   'Modifications to args object should not affect constructed Thrift object': function(assert) {
 
-    var args = createJsObj();
+    const args = createJsObj();
     assertValues(args, assert);
 
-    var tObj = new Complex(args);
+    const tObj = new Complex(args);
     assertValues(tObj, assert);
 
     args.struct_field.value = 'ZZZ';
@@ -193,7 +193,7 @@ var cases = {
   },
 
   'nulls are ok': function(assert) {
-    var tObj = new Complex({
+    const tObj = new Complex({
       struct_field: null,
       struct_list_field: null,
       struct_set_field: null,
@@ -201,7 +201,7 @@ var cases = {
       struct_nested_containers_field: null,
       struct_nested_containers_field2: null
     });
-    var received = deserialize(serialize(tObj), Complex);
+    const received = deserialize(serialize(tObj), Complex);
     assert.ok(tObj !== received);
     assert.deepEqual(tObj, received);
   }
@@ -209,5 +209,5 @@ var cases = {
 };
 
 Object.keys(cases).forEach(function(caseName) {
-  test(caseName, cases[caseName]);
+  QUnit.test(caseName, cases[caseName]);
 });
diff --git a/lib/js/test/server_http.js b/lib/js/test/server_http.js
index 1115474..d04f578 100644
--- a/lib/js/test/server_http.js
+++ b/lib/js/test/server_http.js
@@ -17,33 +17,39 @@
  * under the License.
  */
 
-//This HTTP server is designed to serve the test.html browser
+//  This HTTP server is designed to serve the test.html browser
 //  based JavaScript test page (which must be in the current directory).
 //  This server also supplies the Thrift based test service, which depends
 //  on the standard ThriftTest.thrift IDL service (which must be compiled
 //  for Node and browser based JavaScript in ./gen-nodejs and ./gen-js
 //  respectively).
+//
+//  Using the command flag --es6, this server can be run using nodejs code built
+//  for the es6 environment or for pre-es6 environment.
+//
 
-var thrift = require('../../nodejs/lib/thrift');
-var ThriftTestSvc = require('./gen-nodejs/ThriftTest.js');
-var ThriftTestHandler = require('./test_handler').ThriftTestHandler;
+const thrift = require('../../nodejs/lib/thrift');
+const es6Mode = process.argv.includes('--es6');
+const genFolder = es6Mode ? 'gen-nodejs-es6' : 'gen-nodejs';
+const ThriftTestSvc = require(`./${genFolder}/ThriftTest.js`);
+const ThriftTestHandler = require('./test_handler').ThriftTestHandler;
 
-var ThriftTestSvcOpt = {
+const ThriftTestSvcOpt = {
 	transport: thrift.TBufferedTransport,
 	protocol: thrift.TJSONProtocol,
 	processor: ThriftTestSvc,
 	handler: ThriftTestHandler
 };
 
-var ThriftWebServerOptions = {
+const ThriftWebServerOptions = {
 	files: '.',
 	services: {
 		'/service': ThriftTestSvcOpt
 	}
 };
 
-var server = thrift.createWebServer(ThriftWebServerOptions);
-var port = 8088;
+const server = thrift.createWebServer(ThriftWebServerOptions);
+const port = es6Mode ? 8088 : 8089;
 server.listen(port);
-console.log('Serving files from: ' + __dirname);
-console.log('Http/Thrift Server running on port: ' + port);
+console.log(`Serving files from: ${__dirname}`);
+console.log(`Http/Thrift Server (ES6 mode ${es6Mode}) running on port: ${port}`);
diff --git a/lib/js/test/server_https.js b/lib/js/test/server_https.js
index 7e78d9e..504f3b5 100644
--- a/lib/js/test/server_https.js
+++ b/lib/js/test/server_https.js
@@ -26,20 +26,22 @@
 //  support libraries for test.html (jquery.js, qunit.js and qunit.css
 //  in ./build/js/lib).
 
-var fs = require('fs');
-var thrift = require('../../nodejs/lib/thrift');
-var ThriftTestSvc = require('./gen-nodejs/ThriftTest.js');
-var ThriftTestHandler = require('./test_handler').ThriftTestHandler;
+const fs = require('fs');
+const thrift = require('../../nodejs/lib/thrift');
+const es6Mode = process.argv.includes('--es6');
+const genFolder = es6Mode ? 'gen-nodejs-es6' : 'gen-nodejs';
+const ThriftTestSvc = require(`./${genFolder}/ThriftTest.js`);
+const ThriftTestHandler = require('./test_handler').ThriftTestHandler;
 
 //Setup the I/O stack options for the ThriftTest service
-var ThriftTestSvcOpt = {
+const ThriftTestSvcOpt = {
   transport: thrift.TBufferedTransport,
   protocol: thrift.TJSONProtocol,
   processor: ThriftTestSvc,
   handler: ThriftTestHandler
 };
 
-var ThriftWebServerOptions = {
+const ThriftWebServerOptions = {
   files: '.',
   tls: {
      key: fs.readFileSync('../../../test/keys/server.key'),
@@ -50,8 +52,8 @@ var ThriftWebServerOptions = {
   }
 };
 
-var server = thrift.createWebServer(ThriftWebServerOptions);
-var port = 8089;
+const server = thrift.createWebServer(ThriftWebServerOptions);
+const port = es6Mode ? 8090 : 8091;
 server.listen(port);
-console.log('Serving files from: ' + __dirname);
-console.log('Http/Thrift Server running on port: ' + port);
+console.log(`Serving files from: ${__dirname}`);
+console.log(`Http/Thrift Server (ES6 mode ${es6Mode}) running on port: ${port}`);
diff --git a/lib/js/test/test-async.js b/lib/js/test/test-async.js
index b4e9854..8c6b13e 100644
--- a/lib/js/test/test-async.js
+++ b/lib/js/test/test-async.js
@@ -30,128 +30,130 @@
 
 
 // all Languages in UTF-8
-var stringTest = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, Français, Arpetan, Furlan, Frysk, Gaeilg [...]
+const stringTest = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, Français, Arpetan, Furlan, Frysk, Gaei [...]
 
-function checkRecursively(map1, map2) {
+function checkRecursively(assert, map1, map2) {
   if (typeof map1 !== 'function' && typeof map2 !== 'function') {
     if (!map1 || typeof map1 !== 'object') {
-        equal(map1, map2);
+        assert.equal(map1, map2);
     } else {
-      for (var key in map1) {
-        checkRecursively(map1[key], map2[key]);
+      for (let key in map1) {
+        checkRecursively(assert, map1[key], map2[key]);
       }
     }
   }
 }
 
-module('Base Types');
+QUnit.module('Base Types');
 
-  asyncTest('Void', function() {
-    expect(1);
+  QUnit.test('Void', function(assert) {
+    assert.expect(1);
+    const done = assert.async();
     client.testVoid(function(result) {
-      equal(result, undefined);
-      QUnit.start();
+      assert.equal(result, undefined);
+      done();
     });
   });
 
 
-  asyncTest('String', function() {
-    expect(3);
-    QUnit.stop(2);
+  QUnit.test('String', function(assert) {
+    assert.expect(3);
+    const done = assert.async(3);
     client.testString('', function(result) {
-       equal(result, '');
-       QUnit.start();
+       assert.equal(result, '');
+       done();
     });
     client.testString(stringTest, function(result) {
-       equal(result, stringTest);
-       QUnit.start();
+       assert.equal(result, stringTest);
+       done();
     });
 
-    var specialCharacters = 'quote: \" backslash:' +
+    const specialCharacters = 'quote: \" backslash:' +
           ' forwardslash-escaped: \/ ' +
           ' backspace: \b formfeed: \f newline: \n return: \r tab: ' +
           ' now-all-of-them-together: "\\\/\b\n\r\t' +
           ' now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><';
     client.testString(specialCharacters, function(result) {
-       equal(result, specialCharacters);
-       QUnit.start();
+       assert.equal(result, specialCharacters);
+       done();
     });
   });
-  asyncTest('Double', function() {
-    expect(4);
-    QUnit.stop(3);
+  QUnit.test('Double', function(assert) {
+    assert.expect(4);
+    const done = assert.async(4);
     client.testDouble(0, function(result) {
-       equal(result, 0);
-       QUnit.start();
+       assert.equal(result, 0);
+       done();
     });
     client.testDouble(-1, function(result) {
-       equal(result, -1);
-       QUnit.start();
+       assert.equal(result, -1);
+       done();
     });
     client.testDouble(3.14, function(result) {
-       equal(result, 3.14);
-       QUnit.start();
+       assert.equal(result, 3.14);
+       done();
     });
     client.testDouble(Math.pow(2, 60), function(result) {
-       equal(result, Math.pow(2, 60));
-       QUnit.start();
+       assert.equal(result, Math.pow(2, 60));
+       done();
     });
   });
   // TODO: add testBinary()
-  asyncTest('Byte', function() {
-    expect(2);
-    QUnit.stop();
+  QUnit.test('Byte', function(assert) {
+    assert.expect(2);
+    const done = assert.async(2);
     client.testByte(0, function(result) {
-       equal(result, 0);
-       QUnit.start();
+       assert.equal(result, 0);
+       done();
     });
     client.testByte(0x01, function(result) {
-       equal(result, 0x01);
-       QUnit.start();
+       assert.equal(result, 0x01);
+       done();
     });
   });
-  asyncTest('I32', function() {
-    expect(3);
-    QUnit.stop(2);
+  QUnit.test('I32', function(assert) {
+    assert.expect(3);
+    const done = assert.async(3);
     client.testI32(0, function(result) {
-       equal(result, 0);
-       QUnit.start();
+       assert.equal(result, 0);
+       done();
     });
     client.testI32(Math.pow(2, 30), function(result) {
-       equal(result, Math.pow(2, 30));
-       QUnit.start();
+       assert.equal(result, Math.pow(2, 30));
+       done();
     });
     client.testI32(-Math.pow(2, 30), function(result) {
-       equal(result, -Math.pow(2, 30));
-       QUnit.start();
+       assert.equal(result, -Math.pow(2, 30));
+       done();
     });
   });
-  asyncTest('I64', function() {
-    expect(3);
-    QUnit.stop(2);
+  QUnit.test('I64', function(assert) {
+    assert.expect(3);
+    const done = assert.async(3);
     client.testI64(0, function(result) {
-       equal(result, 0);
-       QUnit.start();
+       assert.equal(result, 0);
+       done();
     });
     //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();
+       assert.equal(result, Math.pow(2, 52));
+       done();
     });
     client.testI64(-Math.pow(2, 52), function(result) {
-       equal(result, -Math.pow(2, 52));
-       QUnit.start();
+       assert.equal(result, -Math.pow(2, 52));
+       done();
     });
   });
 
 
 
 
-module('Structured Types');
+QUnit.module('Structured Types');
 
-  asyncTest('Struct', function() {
-    expect(5);
-    var structTestInput = new ThriftTest.Xtruct();
+  QUnit.test('Struct', function(assert) {
+    assert.expect(5);
+    const done = assert.async();
+    const structTestInput = new ThriftTest.Xtruct();
     structTestInput.string_thing = 'worked';
     structTestInput.byte_thing = 0x01;
     structTestInput.i32_thing = Math.pow(2, 30);
@@ -159,148 +161,159 @@ module('Structured Types');
     structTestInput.i64_thing = Math.pow(2, 52);
 
     client.testStruct(structTestInput, function(result) {
-      equal(result.string_thing, structTestInput.string_thing);
-      equal(result.byte_thing, structTestInput.byte_thing);
-      equal(result.i32_thing, structTestInput.i32_thing);
-      equal(result.i64_thing, structTestInput.i64_thing);
-      equal(JSON.stringify(result), JSON.stringify(structTestInput));
-      QUnit.start();
+      assert.equal(result.string_thing, structTestInput.string_thing);
+      assert.equal(result.byte_thing, structTestInput.byte_thing);
+      assert.equal(result.i32_thing, structTestInput.i32_thing);
+      assert.equal(result.i64_thing, structTestInput.i64_thing);
+      assert.equal(JSON.stringify(result), JSON.stringify(structTestInput));
+      done();
     });
   });
 
-  asyncTest('Nest', function() {
-    expect(7);
-    var xtrTestInput = new ThriftTest.Xtruct();
+  QUnit.test('Nest', function(assert) {
+    assert.expect(7);
+    const done = assert.async();
+    const xtrTestInput = new ThriftTest.Xtruct();
     xtrTestInput.string_thing = 'worked';
     xtrTestInput.byte_thing = 0x01;
     xtrTestInput.i32_thing = Math.pow(2, 30);
     //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();
+    const nestTestInput = new ThriftTest.Xtruct2();
     nestTestInput.byte_thing = 0x02;
     nestTestInput.struct_thing = xtrTestInput;
     nestTestInput.i32_thing = Math.pow(2, 15);
 
     client.testNest(nestTestInput, function(result) {
-      equal(result.byte_thing, nestTestInput.byte_thing);
-      equal(result.struct_thing.string_thing, nestTestInput.struct_thing.string_thing);
-      equal(result.struct_thing.byte_thing, nestTestInput.struct_thing.byte_thing);
-      equal(result.struct_thing.i32_thing, nestTestInput.struct_thing.i32_thing);
-      equal(result.struct_thing.i64_thing, nestTestInput.struct_thing.i64_thing);
-      equal(result.i32_thing, nestTestInput.i32_thing);
-      equal(JSON.stringify(result), JSON.stringify(nestTestInput));
-      QUnit.start();
+      assert.equal(result.byte_thing, nestTestInput.byte_thing);
+      assert.equal(result.struct_thing.string_thing, nestTestInput.struct_thing.string_thing);
+      assert.equal(result.struct_thing.byte_thing, nestTestInput.struct_thing.byte_thing);
+      assert.equal(result.struct_thing.i32_thing, nestTestInput.struct_thing.i32_thing);
+      assert.equal(result.struct_thing.i64_thing, nestTestInput.struct_thing.i64_thing);
+      assert.equal(result.i32_thing, nestTestInput.i32_thing);
+      assert.equal(JSON.stringify(result), JSON.stringify(nestTestInput));
+      done();
     });
   });
 
-  asyncTest('Map', function() {
-    expect(3);
-    var mapTestInput = {7: 77, 8: 88, 9: 99};
+  QUnit.test('Map', function(assert) {
+    assert.expect(3);
+    const done = assert.async();
+    const mapTestInput = {7: 77, 8: 88, 9: 99};
 
     client.testMap(mapTestInput, function(result) {
-      for (var key in result) {
-        equal(result[key], mapTestInput[key]);
+      for (let key in result) {
+        assert.equal(result[key], mapTestInput[key]);
       }
-      QUnit.start();
+      done();
     });
   });
 
-  asyncTest('StringMap', function() {
-    expect(6);
-    var mapTestInput = {
+  QUnit.test('StringMap', function(assert) {
+    assert.expect(6);
+    const done = assert.async();
+    const mapTestInput = {
       'a': '123', 'a b': 'with spaces ', 'same': 'same', '0': 'numeric key',
       'longValue': stringTest, stringTest: 'long key'
     };
 
     client.testStringMap(mapTestInput, function(result) {
-      for (var key in result) {
-        equal(result[key], mapTestInput[key]);
+      for (let key in result) {
+        assert.equal(result[key], mapTestInput[key]);
       }
-      QUnit.start();
+      done();
     });
   });
 
-  asyncTest('Set', function() {
-    expect(1);
-    var setTestInput = [1, 2, 3];
+  QUnit.test('Set', function(assert) {
+    assert.expect(1);
+    const done = assert.async();
+    const setTestInput = [1, 2, 3];
     client.testSet(setTestInput, function(result) {
-      ok(result, setTestInput);
-      QUnit.start();
+      assert.ok(result, setTestInput);
+      done();
     });
   });
 
-  asyncTest('List', function() {
-    expect(1);
-    var listTestInput = [1, 2, 3];
+  QUnit.test('List', function(assert) {
+    assert.expect(1);
+    const done = assert.async();
+    const listTestInput = [1, 2, 3];
     client.testList(listTestInput, function(result) {
-      ok(result, listTestInput);
-      QUnit.start();
+      assert.ok(result, listTestInput);
+      done();
     });
   });
 
-  asyncTest('Enum', function() {
-    expect(1);
+  QUnit.test('Enum', function(assert) {
+    assert.expect(1);
+    const done = assert.async();
     client.testEnum(ThriftTest.Numberz.ONE, function(result) {
-      equal(result, ThriftTest.Numberz.ONE);
-      QUnit.start();
+      assert.equal(result, ThriftTest.Numberz.ONE);
+      done();
     });
   });
 
-  asyncTest('TypeDef', function() {
-    expect(1);
+  QUnit.test('TypeDef', function(assert) {
+    assert.expect(1);
+    const done = assert.async();
     client.testTypedef(69, function(result) {
-      equal(result, 69);
-      QUnit.start();
+      assert.equal(result, 69);
+      done();
     });
   });
 
 
-module('deeper!');
+QUnit.module('deeper!');
 
-  asyncTest('MapMap', function() {
-    expect(16);
-    var mapMapTestExpectedResult = {
+  QUnit.test('MapMap', function(assert) {
+    assert.expect(16);
+    const done = assert.async();
+    const mapMapTestExpectedResult = {
       '4': {'1': 1, '2': 2, '3': 3, '4': 4},
       '-4': {'-4': -4, '-3': -3, '-2': -2, '-1': -1}
     };
 
     client.testMapMap(1, function(result) {
-      for (var key in result) {
-        for (var key2 in result[key]) {
-          equal(result[key][key2], mapMapTestExpectedResult[key][key2]);
+      for (let key in result) {
+        for (let key2 in result[key]) {
+          assert.equal(result[key][key2], mapMapTestExpectedResult[key][key2]);
         }
       }
-      checkRecursively(result, mapMapTestExpectedResult);
-      QUnit.start();
+      checkRecursively(assert, result, mapMapTestExpectedResult);
+      done();
     });
   });
 
 
-module('Exception');
+QUnit.module('Exception');
 
-  asyncTest('Xception', function() {
-    expect(2);
+  QUnit.test('Xception', function(assert) {
+    assert.expect(2);
+    const done = assert.async();
     client.testException('Xception', function(e) {
-      equal(e.errorCode, 1001);
-      equal(e.message, 'Xception');
-      QUnit.start();
+      assert.equal(e.errorCode, 1001);
+      assert.equal(e.message, 'Xception');
+      done();
     });
   });
 
-  asyncTest('no Exception', 0, function() {
-    expect(1);
+  QUnit.test('no Exception', function(assert) {
+    assert.expect(1);
+    const done = assert.async();
     client.testException('no Exception', function(e) {
-      ok(!e);
-      QUnit.start();
+      assert.ok(!e);
+      done();
     });
   });
 
-module('Insanity');
+QUnit.module('Insanity');
 
-  asyncTest('testInsanity', function() {
-    expect(24);
-    var insanity = {
+  QUnit.test('testInsanity', function(assert) {
+    assert.expect(24);
+    const done = assert.async();
+    const insanity = {
       '1': {
         '2': {
           'userMap': { '5': 5, '8': 8 },
@@ -338,19 +351,20 @@ module('Insanity');
       '2': { '6': { 'userMap': null, 'xtructs': null } }
     };
     client.testInsanity(new ThriftTest.Insanity(), function(res) {
-      ok(res, JSON.stringify(res));
-      ok(insanity, JSON.stringify(insanity));
-      checkRecursively(res, insanity);
-      QUnit.start();
+      assert.ok(res, JSON.stringify(res));
+      assert.ok(insanity, JSON.stringify(insanity));
+      checkRecursively(assert, res, insanity);
+      done();
     });
   });
 
-module('Oneway');
+QUnit.module('Oneway');
 
-  asyncTest('testOneway', function() {
-    expect(1);
+  QUnit.test('testOneway', function(assert) {
+    assert.expect(1);
+    const done = assert.async();
     client.testOneway(1, function(result) {
-      equal(result, undefined);
-      QUnit.start();
+      assert.equal(result, undefined);
+      done();
     });
-  });
\ No newline at end of file
+  });
diff --git a/lib/js/test/test-double-rendering.js b/lib/js/test/test-double-rendering.js
index 5d9cd2a..b4b79b8 100644
--- a/lib/js/test/test-double-rendering.js
+++ b/lib/js/test/test-double-rendering.js
@@ -46,7 +46,7 @@
  */
 
 // double assertion threshold
-var EPSILON = 0.0000001;
+const EPSILON = 0.0000001;
 
 // Work around for old API used by QUnitAdapter of jsTestDriver
 if (typeof QUnit.log == 'function') {
@@ -67,17 +67,17 @@ QUnit.module('Double rendering');
 
   QUnit.test('Double (rendering)', function(assert) {
     console.log('Double rendering test -- starts');
-    var EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT = 1;
-    var EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT = -100;
-    var EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT = 9223372036854775807;
-    var EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT = -9223372036854775807;
-    var EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS = 3.14159265359;
-    var EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE = 1000000.1;
-    var EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE = -1000000.1;
-    var EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE = 1.7e+308;
-    var EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE = 9223372036854775816.43;
-    var EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE = -1.7e+308;
-    var EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE = -9223372036854775816.43;
+    const EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT = 1;
+    const EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT = -100;
+    const EXPECTED_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT = 9223372036854775807;
+    const EXPECTED_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT = -9223372036854775807;
+    const EXPECTED_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS = 3.14159265359;
+    const EXPECTED_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE = 1000000.1;
+    const EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE = -1000000.1;
+    const EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE = 1.7e+308;
+    const EXPECTED_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE = 9223372036854775816.43;
+    const EXPECTED_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE = -1.7e+308;
+    const EXPECTED_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE = -9223372036854775816.43;
     assert.ok(
         Math.abs(EXPECTED_DOUBLE_ASSIGNED_TO_INT_CONSTANT - DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST) <= EPSILON);
     assert.ok(
@@ -131,11 +131,11 @@ QUnit.module('Double rendering');
     assert.equal(typeof DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST, 'number');
     assert.equal(typeof DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST, 'number');
     assert.equal(typeof DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST, 'number');
-    var EXPECTED_DOUBLE_LIST =
+    const EXPECTED_DOUBLE_LIST =
         [1,-100,100,9223372036854775807,-9223372036854775807,3.14159265359,1000000.1,-1000000.1,1.7e+308,-1.7e+308,
             9223372036854775816.43,-9223372036854775816.43];
     assert.equal(DOUBLE_LIST_TEST.length, EXPECTED_DOUBLE_LIST.length);
-    for (var i = 0; i < EXPECTED_DOUBLE_LIST.length; ++i) {
+    for (let i = 0; i < EXPECTED_DOUBLE_LIST.length; ++i) {
            assert.ok(Math.abs(EXPECTED_DOUBLE_LIST[i] - DOUBLE_LIST_TEST[i]) <= EPSILON);
     }
     console.log('Double rendering test -- ends');
diff --git a/lib/js/test/test-es6.html b/lib/js/test/test-es6.html
index 92d0738..5f55da7 100644
--- a/lib/js/test/test-es6.html
+++ b/lib/js/test/test-es6.html
@@ -23,11 +23,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>
-
-  <!-- ES6 Promise Polyfill -->
-  <script type="text/javascript" src="build/js/lib/es6-promise.js" charset="utf-8"></script>
+  <script src="gen-js-es6/ThriftTest_types.js" type="text/javascript" charset="utf-8"></script>
+  <script src="gen-js-es6/ThriftTest.js"       type="text/javascript" charset="utf-8"></script>
 
   <!-- jQuery -->
   <script type="text/javascript" src="build/js/lib/jquery.js" charset="utf-8"></script>
@@ -38,12 +35,12 @@
 
   <!-- the Test Suite-->
   <script>
-    var loc = window.location;
-    var ws_uri = ((loc.protocol === "https:") ? "wss://" : "ws://") +
+    const loc = window.location;
+    const ws_uri = ((loc.protocol === "https:") ? "wss://" : "ws://") +
                    loc.hostname + ":" + loc.port + loc.pathname;
-    var transport = new Thrift.TWebSocketTransport(ws_uri);
-    var protocol  = new Thrift.Protocol(transport);
-    var client    = new ThriftTest.ThriftTestClient(protocol);
+    const transport = new Thrift.TWebSocketTransport(ws_uri);
+    const protocol  = new Thrift.Protocol(transport);
+    const client    = new ThriftTest.ThriftTestClient(protocol);
     transport.open();
   </script>
   <script type="text/javascript" src="test-es6.js" charset="utf-8"></script>
diff --git a/lib/js/test/test-es6.js b/lib/js/test/test-es6.js
index a3a31dc..845171b 100644
--- a/lib/js/test/test-es6.js
+++ b/lib/js/test/test-es6.js
@@ -24,46 +24,48 @@
  * (which is exclusively async).
  *
  * To compile client code for this test use:
- *      $ thrift -gen js ThriftTest.thrift
+ *      $ thrift -gen js:es6 ThriftTest.thrift
  */
 
 
 
 // all Languages in UTF-8
-var stringTest = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, Français, Arpetan, Furlan, Frysk, Gaeilg [...]
 
-function checkRecursively(map1, map2) {
+const stringTest = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, Français, Arpetan, Furlan, Frysk, Gaei [...]
+
+function checkRecursively(assert, map1, map2) {
   if (typeof map1 !== 'function' && typeof map2 !== 'function') {
     if (!map1 || typeof map1 !== 'object') {
-        equal(map1, map2);
+        assert.equal(map1, map2);
     } else {
       for (var key in map1) {
-        checkRecursively(map1[key], map2[key]);
+        checkRecursively(assert, map1[key], map2[key]);
       }
     }
   }
 }
 
-module('Base Types');
+QUnit.module('Base Types');
 
-  asyncTest('Void', function() {
-    expect(1);
+  QUnit.test('Void', function( assert ) {
+    assert.expect(1);
+    const done = assert.async();
     client.testVoid().then(function(result) {
-      equal(result, undefined);
-      QUnit.start();
+      assert.equal(result, undefined);
+      done();
     });
   });
 
-  asyncTest('String', function() {
-    expect(3);
-    QUnit.stop(2);
+  QUnit.test('String', function( assert ) {
+    assert.expect(3);
+    const done = assert.async(3);
     client.testString('').then(function(result) {
-       equal(result, '');
-       QUnit.start();
+       assert.equal(result, '');
+       done();
     });
     client.testString(stringTest).then(function(result) {
-       equal(result, stringTest);
-       QUnit.start();
+       assert.equal(result, stringTest);
+       done();
     });
     var specialCharacters = 'quote: \" backslash:' +
           ' forwardslash-escaped: \/ ' +
@@ -71,83 +73,84 @@ module('Base Types');
           ' now-all-of-them-together: "\\\/\b\n\r\t' +
           ' now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><';
     client.testString(specialCharacters).then(function(result) {
-       equal(result, specialCharacters);
-       QUnit.start();
+       assert.equal(result, specialCharacters);
+       done();
     });
   });
 
-  asyncTest('Double', function() {
-    expect(4);
-    QUnit.stop(3);
+  QUnit.test('Double', function( assert ) {
+    assert.expect(4);
+    const done = assert.async(4);
     client.testDouble(0).then(function(result) {
-       equal(result, 0);
-       QUnit.start();
+       assert.equal(result, 0);
+       done();
     });
     client.testDouble(-1).then(function(result) {
-       equal(result, -1);
-       QUnit.start();
+       assert.equal(result, -1);
+       done();
     });
     client.testDouble(3.14).then(function(result) {
-       equal(result, 3.14);
-       QUnit.start();
+       assert.equal(result, 3.14);
+       done();
     });
     client.testDouble(Math.pow(2, 60)).then(function(result) {
-       equal(result, Math.pow(2, 60));
-       QUnit.start();
+       assert.equal(result, Math.pow(2, 60));
+       done();
     });
   });
   // TODO: add testBinary()
-  asyncTest('Byte', function() {
-    expect(2);
-    QUnit.stop();
+  QUnit.test('Byte', function( assert ) {
+    assert.expect(2);
+    const done = assert.async(2);
     client.testByte(0).then(function(result) {
-       equal(result, 0);
-       QUnit.start();
+       assert.equal(result, 0);
+       done();
     });
     client.testByte(0x01).then(function(result) {
-       equal(result, 0x01);
-       QUnit.start();
+       assert.equal(result, 0x01);
+       done();
     });
   });
-  asyncTest('I32', function() {
-    expect(3);
-    QUnit.stop(2);
+  QUnit.test('I32', function( assert ) {
+    assert.expect(3);
+    const done = assert.async(3);
     client.testI32(0).then(function(result) {
-       equal(result, 0);
-       QUnit.start();
+       assert.equal(result, 0);
+       done();
     });
     client.testI32(Math.pow(2, 30)).then(function(result) {
-       equal(result, Math.pow(2, 30));
-       QUnit.start();
+       assert.equal(result, Math.pow(2, 30));
+       done();
     });
     client.testI32(-Math.pow(2, 30)).then(function(result) {
-       equal(result, -Math.pow(2, 30));
-       QUnit.start();
+       assert.equal(result, -Math.pow(2, 30));
+       done();
     });
   });
-  asyncTest('I64', function() {
-    expect(3);
-    QUnit.stop(2);
+  QUnit.test('I64', function( assert ) {
+    assert.expect(3);
+    const done = assert.async(3);
     client.testI64(0).then(function(result) {
-       equal(result, 0);
-       QUnit.start();
+       assert.equal(result, 0);
+       done();
     });
     //This is usually 2^60 but JS cannot represent anything over 2^52 accurately
     client.testI64(Math.pow(2, 52)).then(function(result) {
-       equal(result, Math.pow(2, 52));
-       QUnit.start();
+       assert.equal(result, Math.pow(2, 52));
+       done();
     });
     client.testI64(-Math.pow(2, 52)).then(function(result) {
-       equal(result, -Math.pow(2, 52));
-       QUnit.start();
+       assert.equal(result, -Math.pow(2, 52));
+       done();
     });
   });
 
 
-module('Structured Types');
+QUnit.module('Structured Types');
 
-  asyncTest('Struct', function() {
-    expect(5);
+  QUnit.test('Struct', function( assert ) {
+    assert.expect(5);
+    const done = assert.async();
     var structTestInput = new ThriftTest.Xtruct();
     structTestInput.string_thing = 'worked';
     structTestInput.byte_thing = 0x01;
@@ -156,17 +159,18 @@ module('Structured Types');
     structTestInput.i64_thing = Math.pow(2, 52);
 
     client.testStruct(structTestInput).then(function(result) {
-      equal(result.string_thing, structTestInput.string_thing);
-      equal(result.byte_thing, structTestInput.byte_thing);
-      equal(result.i32_thing, structTestInput.i32_thing);
-      equal(result.i64_thing, structTestInput.i64_thing);
-      equal(JSON.stringify(result), JSON.stringify(structTestInput));
-      QUnit.start();
+      assert.equal(result.string_thing, structTestInput.string_thing);
+      assert.equal(result.byte_thing, structTestInput.byte_thing);
+      assert.equal(result.i32_thing, structTestInput.i32_thing);
+      assert.equal(result.i64_thing, structTestInput.i64_thing);
+      assert.equal(JSON.stringify(result), JSON.stringify(structTestInput));
+      done();
     });
   });
 
-  asyncTest('Nest', function() {
-    expect(7);
+  QUnit.test('Nest', function( assert ) {
+    assert.expect(7);
+    const done = assert.async();
     var xtrTestInput = new ThriftTest.Xtruct();
     xtrTestInput.string_thing = 'worked';
     xtrTestInput.byte_thing = 0x01;
@@ -180,31 +184,33 @@ module('Structured Types');
     nestTestInput.i32_thing = Math.pow(2, 15);
 
     client.testNest(nestTestInput).then(function(result) {
-      equal(result.byte_thing, nestTestInput.byte_thing);
-      equal(result.struct_thing.string_thing, nestTestInput.struct_thing.string_thing);
-      equal(result.struct_thing.byte_thing, nestTestInput.struct_thing.byte_thing);
-      equal(result.struct_thing.i32_thing, nestTestInput.struct_thing.i32_thing);
-      equal(result.struct_thing.i64_thing, nestTestInput.struct_thing.i64_thing);
-      equal(result.i32_thing, nestTestInput.i32_thing);
-      equal(JSON.stringify(result), JSON.stringify(nestTestInput));
-      QUnit.start();
+      assert.equal(result.byte_thing, nestTestInput.byte_thing);
+      assert.equal(result.struct_thing.string_thing, nestTestInput.struct_thing.string_thing);
+      assert.equal(result.struct_thing.byte_thing, nestTestInput.struct_thing.byte_thing);
+      assert.equal(result.struct_thing.i32_thing, nestTestInput.struct_thing.i32_thing);
+      assert.equal(result.struct_thing.i64_thing, nestTestInput.struct_thing.i64_thing);
+      assert.equal(result.i32_thing, nestTestInput.i32_thing);
+      assert.equal(JSON.stringify(result), JSON.stringify(nestTestInput));
+      done();
     });
   });
 
-  asyncTest('Map', function() {
-    expect(3);
+  QUnit.test('Map', function( assert ) {
+    assert.expect(3);
+    const done = assert.async();
     var mapTestInput = {7: 77, 8: 88, 9: 99};
 
     client.testMap(mapTestInput).then(function(result) {
       for (var key in result) {
-        equal(result[key], mapTestInput[key]);
+        assert.equal(result[key], mapTestInput[key]);
       }
-      QUnit.start();
+      done();
     });
   });
 
-  asyncTest('StringMap', function() {
-    expect(6);
+  QUnit.test('StringMap', function( assert ) {
+    assert.expect(6);
+    const done = assert.async();
     var mapTestInput = {
       'a': '123', 'a b': 'with spaces ', 'same': 'same', '0': 'numeric key',
       'longValue': stringTest, stringTest: 'long key'
@@ -212,51 +218,56 @@ module('Structured Types');
 
     client.testStringMap(mapTestInput).then(function(result) {
       for (var key in result) {
-        equal(result[key], mapTestInput[key]);
+        assert.equal(result[key], mapTestInput[key]);
       }
-      QUnit.start();
+      done();
     });
   });
 
-  asyncTest('Set', function() {
-    expect(1);
+  QUnit.test('Set', function( assert ) {
+    assert.expect(1);
+    const done = assert.async();
     var setTestInput = [1, 2, 3];
     client.testSet(setTestInput).then(function(result) {
-      ok(result, setTestInput);
-      QUnit.start();
+      assert.ok(result, setTestInput);
+      done();
     });
   });
 
-  asyncTest('List', function() {
-    expect(1);
+  QUnit.test('List', function( assert ) {
+    assert.expect(1);
+    const done = assert.async();
     var listTestInput = [1, 2, 3];
     client.testList(listTestInput).then(function(result) {
-      ok(result, listTestInput);
-      QUnit.start();
+      assert.ok(result, listTestInput);
+      done();
     });
   });
 
-  asyncTest('Enum', function() {
-    expect(1);
+  QUnit.test('Enum', function( assert ) {
+    assert.expect(1);
+    const done = assert.async();
     client.testEnum(ThriftTest.Numberz.ONE).then(function(result) {
-      equal(result, ThriftTest.Numberz.ONE);
-      QUnit.start();
+      assert.equal(result, ThriftTest.Numberz.ONE);
+      done();
     });
   });
 
-  asyncTest('TypeDef', function() {
-    expect(1);
+  QUnit.test('TypeDef', function( assert ) {
+    assert.expect(1);
+    const done = assert.async();
     client.testTypedef(69).then(function(result) {
-      equal(result, 69);
-      QUnit.start();
+      assert.equal(result, 69);
+      done();
     });
   });
 
 
-module('deeper!');
+QUnit.module('deeper!');
 
-  asyncTest('MapMap', function() {
-    expect(16);
+  QUnit.test('MapMap', function( assert ) {
+    assert.expect(16);
+    const done = assert.async();
     var mapMapTestExpectedResult = {
       '4': {'1': 1, '2': 2, '3': 3, '4': 4},
       '-4': {'-4': -4, '-3': -3, '-2': -2, '-1': -1}
@@ -265,40 +276,48 @@ module('deeper!');
     client.testMapMap(1).then(function(result) {
       for (var key in result) {
         for (var key2 in result[key]) {
-          equal(result[key][key2], mapMapTestExpectedResult[key][key2]);
+          assert.equal(result[key][key2], mapMapTestExpectedResult[key][key2]);
         }
       }
-      checkRecursively(result, mapMapTestExpectedResult);
-      QUnit.start();
+      checkRecursively(assert, result, mapMapTestExpectedResult);
+      done();
     });
   });
 
 
-module('Exception');
+QUnit.module('Exception');
 
-  asyncTest('Xception', function() {
-    expect(2);
+  QUnit.test('Xception', function( assert ) {
+    assert.expect(2);
+    const done = assert.async();
     client.testException('Xception').then(function(res) {
-      ok(false);
+      assert.ok(false);
     }).catch(function(e) {
-      equal(e.errorCode, 1001);
-      equal(e.message, 'Xception');
-      QUnit.start();
+
+      console.log(`Exception exception e`);
+      console.log(e);
+      console.log(JSON.stringify(e, null, 2));
+
+      assert.equal(e.errorCode, 1001);
+      assert.equal(e.message, 'Xception');
+      done();
     });
   });
 
-  asyncTest('no Exception', 0, function() {
-    expect(1);
+  QUnit.test('no Exception', function( assert ) {
+    assert.expect(1);
+    const done = assert.async();
     client.testException('no Exception').then(function(e) {
-      ok(!e);
-      QUnit.start();
+      assert.ok(!e);
+      done();
     });
   });
 
-module('Insanity');
+QUnit.module('Insanity');
 
-  asyncTest('testInsanity', function() {
-    expect(24);
+  QUnit.test('testInsanity', function( assert ) {
+    assert.expect(24);
+    const done = assert.async();
     var insanity = {
       '1': {
         '2': {
@@ -337,18 +356,19 @@ module('Insanity');
       '2': { '6': { 'userMap': null, 'xtructs': null } }
     };
     client.testInsanity(new ThriftTest.Insanity()).then(function(res) {
-      ok(res, JSON.stringify(res));
-      ok(insanity, JSON.stringify(insanity));
-      checkRecursively(res, insanity);
-      QUnit.start();
+      assert.ok(res, JSON.stringify(res));
+      assert.ok(insanity, JSON.stringify(insanity));
+      checkRecursively(assert, res, insanity);
+      done();
     });
   });
 
-module('Oneway');
-  asyncTest('testOneway', function() {
-    expect(1);
+QUnit.module('Oneway');
+  QUnit.test('testOneway', function( assert ) {
+    assert.expect(1);
+    const done = assert.async();
     client.testOneway(1).then(function(result) {
-      equal(result, undefined);
-      QUnit.start();
+      assert.equal(result, undefined);
+      done();
     });
-  });
\ No newline at end of file
+  });
diff --git a/lib/js/test/test-jq.js b/lib/js/test/test-jq.js
index d8649a0..f62bb95 100644
--- a/lib/js/test/test-jq.js
+++ b/lib/js/test/test-jq.js
@@ -33,19 +33,18 @@
 //////////////////////////////////
 //jQuery asynchronous tests
 jQuery.ajaxSetup({ timeout: 0 });
-$(document).ajaxError(function() { QUnit.start(); });
 
-module('jQ Async Manual');
+QUnit.module('jQ Async Manual');
 
-  test('testI32', function() {
-    expect(2);
-    QUnit.stop();
+  QUnit.test('testI32', function(assert) {
+    assert.expect(2);
+    const done = assert.async(2);
 
-    var transport = new Thrift.Transport();
-    var protocol = new Thrift.Protocol(transport);
-    var client = new ThriftTest.ThriftTestClient(protocol);
+    const transport = new Thrift.Transport();
+    const protocol = new Thrift.Protocol(transport);
+    const client = new ThriftTest.ThriftTestClient(protocol);
 
-    var jqxhr = jQuery.ajax({
+    const jqxhr = jQuery.ajax({
       url: '/service',
       data: client.send_testI32(Math.pow(-2, 31)),
       type: 'POST',
@@ -53,23 +52,24 @@ module('jQ Async Manual');
       dataType: 'text',
       success: function(res) {
         transport.setRecvBuffer(res);
-        equal(client.recv_testI32(), Math.pow(-2, 31));
+        assert.equal(client.recv_testI32(), Math.pow(-2, 31));
+        done();
       },
-      error: function() { ok(false); },
+      error: function() { assert.ok(false); },
       complete: function() {
-        ok(true);
-        QUnit.start();
+        assert.ok(true);
+        done();
       }
     });
   });
 
-  test('testI64', function() {
-    expect(2);
-    QUnit.stop();
+  QUnit.test('testI64', function(assert) {
+    assert.expect(2);
+    const done = assert.async(2);
 
-    var transport = new Thrift.Transport();
-    var protocol = new Thrift.Protocol(transport);
-    var client = new ThriftTest.ThriftTestClient(protocol);
+    const transport = new Thrift.Transport();
+    const protocol = new Thrift.Protocol(transport);
+    const client = new ThriftTest.ThriftTestClient(protocol);
 
     jQuery.ajax({
       url: '/service',
@@ -81,78 +81,79 @@ module('jQ Async Manual');
       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));
+        assert.equal(client.recv_testI64(), Math.pow(-2, 52));
+        done();
       },
-      error: function() { ok(false); },
+      error: function() { assert.ok(false); },
       complete: function() {
-        ok(true);
-        QUnit.start();
+        assert.ok(true);
+        done();
       }
     });
   });
 
 
-module('jQ Async');
-  test('I32', function() {
-    expect(3);
+QUnit.module('jQ Async');
+  QUnit.test('I32', function(assert) {
+    assert.expect(3);
 
-    QUnit.stop();
+    const done = assert.async(3);
     client.testI32(Math.pow(2, 30), function(result) {
-      equal(result, Math.pow(2, 30));
-      QUnit.start();
+      assert.equal(result, Math.pow(2, 30));
+      done();
     });
 
-    QUnit.stop();
-    var jqxhr = client.testI32(Math.pow(-2, 31), function(result) {
-      equal(result, Math.pow(-2, 31));
+    const jqxhr = client.testI32(Math.pow(-2, 31), function(result) {
+      assert.equal(result, Math.pow(-2, 31));
+      done();
     });
 
     jqxhr.success(function(result) {
-      equal(result, Math.pow(-2, 31));
-      QUnit.start();
+      assert.equal(result, Math.pow(-2, 31));
+      done();
     });
   });
 
-  test('I64', function() {
-    expect(4);
+  QUnit.test('I64', function(assert) {
+    assert.expect(4);
 
-    QUnit.stop();
+    const done = assert.async(4);
     //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();
+      assert.equal(result, Math.pow(2, 52));
+      done();
     });
 
-    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));
+      assert.equal(result, Math.pow(-2, 52));
+      done();
     })
-    .error(function(xhr, status, e) { ok(false, e.message); })
+    .error(function(xhr, status, e) { assert.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));
+      assert.equal(result, Math.pow(-2, 52));
+      done();
     })
     .complete(function() {
-      ok(true);
-      QUnit.start();
+      assert.ok(true);
+      done();
     });
   });
 
-  test('Xception', function() {
-    expect(2);
+  QUnit.test('Xception', function(assert) {
+    assert.expect(2);
 
-    QUnit.stop();
+    const done = assert.async(2);
 
-    var dfd = client.testException('Xception', function(result) {
-      ok(false);
-      QUnit.start();
+    const dfd = client.testException('Xception', function(result) {
+      assert.ok(false);
+      done();
     })
     .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(); } );
+      assert.equal(e.errorCode, 1001);
+      assert.equal(e.message, 'Xception');
+      done();
+      $(document).ajaxError( function() { done(); } );
     });
   });
diff --git a/lib/js/test/test-nojq.html b/lib/js/test/test-nojq.html
index 541bffe..9eec7fc 100644
--- a/lib/js/test/test-nojq.html
+++ b/lib/js/test/test-nojq.html
@@ -29,7 +29,7 @@
   <!-- 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-nojq.js" charset="utf-8"></script>
@@ -37,7 +37,7 @@
 <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> 
+  <div id="qunit-testrunner-toolbar"></div>
   <h2 id="qunit-userAgent"></h2>
   <ol id="qunit-tests"><li><!-- get valid xhtml strict--></li></ol>
   <!-- Uncomment this to check the validity. This significantly slows down the test.
diff --git a/lib/js/test/test-nojq.js b/lib/js/test/test-nojq.js
index c4f3cf7..2b801d2 100644
--- a/lib/js/test/test-nojq.js
+++ b/lib/js/test/test-nojq.js
@@ -33,17 +33,16 @@
 //////////////////////////////////
 //Async exception tests
 
-module('NojQ Async');
+QUnit.module('NojQ Async');
 
-  test('Xception', function() {
-    expect(2);
-
-    QUnit.stop();
+QUnit.test('Xception', function(assert) {
+    assert.expect(2);
+    const done = assert.async();
 
     client.testException('Xception', function(result) {
-      equal(result.errorCode, 1001);
-      equal(result.message, 'Xception');
-      QUnit.start();
+      assert.equal(result.errorCode, 1001);
+      assert.equal(result.message, 'Xception');
+      done();
     });
   });
 
diff --git a/lib/js/test/test.html b/lib/js/test/test.html
index edec3a3..af035b6 100755
--- a/lib/js/test/test.html
+++ b/lib/js/test/test.html
@@ -23,8 +23,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>
+  <script src="gen-js-jquery/ThriftTest_types.js" type="text/javascript" charset="utf-8"></script>
+  <script src="gen-js-jquery/ThriftTest.js"       type="text/javascript" charset="utf-8"></script>
 
   <!-- jQuery -->
   <script type="text/javascript" src="build/js/lib/jquery.js" charset="utf-8"></script>
@@ -34,11 +34,6 @@
   <link rel="stylesheet" href="build/js/lib/qunit.css" type="text/css" media="screen" />
 
   <!-- the Test Suite-->
-  <script>
-    var transport = new Thrift.Transport("/service");
-    var protocol  = new Thrift.Protocol(transport);
-    var client    = new ThriftTest.ThriftTestClient(protocol);
-  </script>
   <script type="text/javascript" src="test.js" charset="utf-8"></script>
   <script type="text/javascript" src="test-jq.js" charset="utf-8"></script>
 </head>
diff --git a/lib/js/test/test.js b/lib/js/test/test.js
index e3b8d51..a86a509 100755
--- a/lib/js/test/test.js
+++ b/lib/js/test/test.js
@@ -47,9 +47,9 @@
  * ++ 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);
+const transport = new Thrift.Transport('/service');
+const protocol = new Thrift.Protocol(transport);
+const client = new ThriftTest.ThriftTestClient(protocol);
 
 // Work around for old API used by QUnitAdapter of jsTestDriver
 if (typeof QUnit.log == 'function') {
@@ -67,170 +67,170 @@ if (typeof QUnit.log == 'function') {
 }
 
 // all Languages in UTF-8
-var stringTest = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, Français, Arpetan, Furlan, Frysk, Gaeilg [...]
+const stringTest = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, Français, Arpetan, Furlan, Frysk, Gaei [...]
 
-function checkRecursively(map1, map2) {
+function checkRecursively(assert, map1, map2) {
   if (typeof map1 !== 'function' && typeof map2 !== 'function') {
     if (!map1 || typeof map1 !== 'object') {
-        equal(map1, map2);
+        assert.equal(map1, map2);
     } else {
-      for (var key in map1) {
-        checkRecursively(map1[key], map2[key]);
+      for (let key in map1) {
+        checkRecursively(assert, map1[key], map2[key]);
       }
     }
   }
 }
 
-module('Base Types');
+QUnit.module('Base Types');
 
-  test('Void', function() {
-    equal(client.testVoid(), undefined);
+  QUnit.test('Void', function(assert) {
+    assert.equal(client.testVoid(), undefined);
   });
-  test('Binary (String)', function() {
-    var binary = '';
-    for (var v = 255; v >= 0; --v) {
+  QUnit.test('Binary (String)', function(assert) {
+    let binary = '';
+    for (let v = 255; v >= 0; --v) {
       binary += String.fromCharCode(v);
     }
-    equal(client.testBinary(binary), binary);
+    assert.equal(client.testBinary(binary), binary);
   });
-  test('Binary (Uint8Array)', function() {
-    var binary = '';
-    for (var v = 255; v >= 0; --v) {
+  QUnit.test('Binary (Uint8Array)', function(assert) {
+    let binary = '';
+    for (let v = 255; v >= 0; --v) {
       binary += String.fromCharCode(v);
     }
-    var arr = new Uint8Array(binary.length);
-    for (var i = 0; i < binary.length; ++i) {
+    const arr = new Uint8Array(binary.length);
+    for (let i = 0; i < binary.length; ++i) {
       arr[i] = binary[i].charCodeAt();
     }
-    equal(client.testBinary(arr), binary);
+    assert.equal(client.testBinary(arr), binary);
   });
-  test('String', function() {
-    equal(client.testString(''), '');
-    equal(client.testString(stringTest), stringTest);
+  QUnit.test('String', function(assert) {
+    assert.equal(client.testString(''), '');
+    assert.equal(client.testString(stringTest), stringTest);
 
-    var specialCharacters = 'quote: \" backslash:' +
+    const specialCharacters = 'quote: \" backslash:' +
           ' forwardslash-escaped: \/ ' +
           ' backspace: \b formfeed: \f newline: \n return: \r tab: ' +
           ' now-all-of-them-together: "\\\/\b\n\r\t' +
           ' now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><';
-    equal(client.testString(specialCharacters), specialCharacters);
+    assert.equal(client.testString(specialCharacters), specialCharacters);
   });
-  test('Double', function() {
-    equal(client.testDouble(0), 0);
-    equal(client.testDouble(-1), -1);
-    equal(client.testDouble(3.14), 3.14);
-    equal(client.testDouble(Math.pow(2, 60)), Math.pow(2, 60));
+  QUnit.test('Double', function(assert) {
+    assert.equal(client.testDouble(0), 0);
+    assert.equal(client.testDouble(-1), -1);
+    assert.equal(client.testDouble(3.14), 3.14);
+    assert.equal(client.testDouble(Math.pow(2, 60)), Math.pow(2, 60));
   });
-  test('Byte', function() {
-    equal(client.testByte(0), 0);
-    equal(client.testByte(0x01), 0x01);
+  QUnit.test('Byte', function(assert) {
+    assert.equal(client.testByte(0), 0);
+    assert.equal(client.testByte(0x01), 0x01);
   });
-  test('I32', function() {
-    equal(client.testI32(0), 0);
-    equal(client.testI32(Math.pow(2, 30)), Math.pow(2, 30));
-    equal(client.testI32(-Math.pow(2, 30)), -Math.pow(2, 30));
+  QUnit.test('I32', function(assert) {
+    assert.equal(client.testI32(0), 0);
+    assert.equal(client.testI32(Math.pow(2, 30)), Math.pow(2, 30));
+    assert.equal(client.testI32(-Math.pow(2, 30)), -Math.pow(2, 30));
   });
-  test('I64', function() {
-    equal(client.testI64(0), 0);
+  QUnit.test('I64', function(assert) {
+    assert.equal(client.testI64(0), 0);
     //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));
+    assert.equal(client.testI64(Math.pow(2, 52)), Math.pow(2, 52));
+    assert.equal(client.testI64(-Math.pow(2, 52)), -Math.pow(2, 52));
   });
 
 
-module('Structured Types');
+QUnit.module('Structured Types');
 
-  test('Struct', function() {
-    var structTestInput = new ThriftTest.Xtruct();
+  QUnit.test('Struct', function(assert) {
+    const structTestInput = new ThriftTest.Xtruct();
     structTestInput.string_thing = 'worked';
     structTestInput.byte_thing = 0x01;
     structTestInput.i32_thing = Math.pow(2, 30);
     //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);
+    const structTestOutput = client.testStruct(structTestInput);
 
-    equal(structTestOutput.string_thing, structTestInput.string_thing);
-    equal(structTestOutput.byte_thing, structTestInput.byte_thing);
-    equal(structTestOutput.i32_thing, structTestInput.i32_thing);
-    equal(structTestOutput.i64_thing, structTestInput.i64_thing);
+    assert.equal(structTestOutput.string_thing, structTestInput.string_thing);
+    assert.equal(structTestOutput.byte_thing, structTestInput.byte_thing);
+    assert.equal(structTestOutput.i32_thing, structTestInput.i32_thing);
+    assert.equal(structTestOutput.i64_thing, structTestInput.i64_thing);
 
-    equal(JSON.stringify(structTestOutput), JSON.stringify(structTestInput));
+    assert.equal(JSON.stringify(structTestOutput), JSON.stringify(structTestInput));
   });
 
-  test('Nest', function() {
-    var xtrTestInput = new ThriftTest.Xtruct();
+  QUnit.test('Nest', function(assert) {
+    const xtrTestInput = new ThriftTest.Xtruct();
     xtrTestInput.string_thing = 'worked';
     xtrTestInput.byte_thing = 0x01;
     xtrTestInput.i32_thing = Math.pow(2, 30);
     //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();
+    const nestTestInput = new ThriftTest.Xtruct2();
     nestTestInput.byte_thing = 0x02;
     nestTestInput.struct_thing = xtrTestInput;
     nestTestInput.i32_thing = Math.pow(2, 15);
 
-    var nestTestOutput = client.testNest(nestTestInput);
+    const nestTestOutput = client.testNest(nestTestInput);
 
-    equal(nestTestOutput.byte_thing, nestTestInput.byte_thing);
-    equal(nestTestOutput.struct_thing.string_thing, nestTestInput.struct_thing.string_thing);
-    equal(nestTestOutput.struct_thing.byte_thing, nestTestInput.struct_thing.byte_thing);
-    equal(nestTestOutput.struct_thing.i32_thing, nestTestInput.struct_thing.i32_thing);
-    equal(nestTestOutput.struct_thing.i64_thing, nestTestInput.struct_thing.i64_thing);
-    equal(nestTestOutput.i32_thing, nestTestInput.i32_thing);
+    assert.equal(nestTestOutput.byte_thing, nestTestInput.byte_thing);
+    assert.equal(nestTestOutput.struct_thing.string_thing, nestTestInput.struct_thing.string_thing);
+    assert.equal(nestTestOutput.struct_thing.byte_thing, nestTestInput.struct_thing.byte_thing);
+    assert.equal(nestTestOutput.struct_thing.i32_thing, nestTestInput.struct_thing.i32_thing);
+    assert.equal(nestTestOutput.struct_thing.i64_thing, nestTestInput.struct_thing.i64_thing);
+    assert.equal(nestTestOutput.i32_thing, nestTestInput.i32_thing);
 
-    equal(JSON.stringify(nestTestOutput), JSON.stringify(nestTestInput));
+    assert.equal(JSON.stringify(nestTestOutput), JSON.stringify(nestTestInput));
   });
 
-  test('Map', function() {
-    var mapTestInput = {7: 77, 8: 88, 9: 99};
+  QUnit.test('Map', function(assert) {
+    const mapTestInput = {7: 77, 8: 88, 9: 99};
 
-    var mapTestOutput = client.testMap(mapTestInput);
+    const mapTestOutput = client.testMap(mapTestInput);
 
-    for (var key in mapTestOutput) {
-      equal(mapTestOutput[key], mapTestInput[key]);
+    for (let key in mapTestOutput) {
+      assert.equal(mapTestOutput[key], mapTestInput[key]);
     }
   });
 
-  test('StringMap', function() {
-    var mapTestInput = {
+  QUnit.test('StringMap', function(assert) {
+    const mapTestInput = {
       'a': '123', 'a b': 'with spaces ', 'same': 'same', '0': 'numeric key',
       'longValue': stringTest, stringTest: 'long key'
     };
 
-    var mapTestOutput = client.testStringMap(mapTestInput);
+    const mapTestOutput = client.testStringMap(mapTestInput);
 
-    for (var key in mapTestOutput) {
-      equal(mapTestOutput[key], mapTestInput[key]);
+    for (let key in mapTestOutput) {
+      assert.equal(mapTestOutput[key], mapTestInput[key]);
     }
   });
 
-  test('Set', function() {
-    var setTestInput = [1, 2, 3];
-    ok(client.testSet(setTestInput), setTestInput);
+  QUnit.test('Set', function(assert) {
+    const setTestInput = [1, 2, 3];
+    assert.ok(client.testSet(setTestInput), setTestInput);
   });
 
-  test('List', function() {
-    var listTestInput = [1, 2, 3];
-    ok(client.testList(listTestInput), listTestInput);
+  QUnit.test('List', function(assert) {
+    const listTestInput = [1, 2, 3];
+    assert.ok(client.testList(listTestInput), listTestInput);
   });
 
-  test('Enum', function() {
-    equal(client.testEnum(ThriftTest.Numberz.ONE), ThriftTest.Numberz.ONE);
+  QUnit.test('Enum', function(assert) {
+    assert.equal(client.testEnum(ThriftTest.Numberz.ONE), ThriftTest.Numberz.ONE);
   });
 
-  test('TypeDef', function() {
-    equal(client.testTypedef(69), 69);
+  QUnit.test('TypeDef', function(assert) {
+    assert.equal(client.testTypedef(69), 69);
   });
 
-  test('Skip', function() {
-    var structTestInput = new ThriftTest.Xtruct();
-    var modifiedClient = new ThriftTest.ThriftTestClient(protocol);
+  QUnit.test('Skip', function(assert) {
+    const structTestInput = new ThriftTest.Xtruct();
+    const modifiedClient = new ThriftTest.ThriftTestClient(protocol);
 
     modifiedClient.recv_testStruct = function() {
-      var input = modifiedClient.input;
-      var xtruct3 = new ThriftTest.Xtruct3();
+      const input = modifiedClient.input;
+      const xtruct3 = new ThriftTest.Xtruct3();
 
       input.readMessageBegin();
       input.readStructBegin();
@@ -254,74 +254,79 @@ module('Structured Types');
     structTestInput.i32_thing = Math.pow(2, 30);
     structTestInput.i64_thing = Math.pow(2, 52);
 
-    var structTestOutput = modifiedClient.testStruct(structTestInput);
+    const structTestOutput = modifiedClient.testStruct(structTestInput);
 
-    equal(structTestOutput instanceof ThriftTest.Xtruct3, true);
-    equal(structTestOutput.string_thing, structTestInput.string_thing);
-    equal(structTestOutput.changed, null);
-    equal(structTestOutput.i32_thing, structTestInput.i32_thing);
-    equal(structTestOutput.i64_thing, structTestInput.i64_thing);
+    assert.equal(structTestOutput instanceof ThriftTest.Xtruct3, true);
+    assert.equal(structTestOutput.string_thing, structTestInput.string_thing);
+    assert.equal(structTestOutput.changed, null);
+    assert.equal(structTestOutput.i32_thing, structTestInput.i32_thing);
+    assert.equal(structTestOutput.i64_thing, structTestInput.i64_thing);
   });
 
 
-module('deeper!');
+QUnit.module('deeper!');
 
-  test('MapMap', function() {
-    var mapMapTestExpectedResult = {
+  QUnit.test('MapMap', function(assert) {
+    const mapMapTestExpectedResult = {
       '4': {'1': 1, '2': 2, '3': 3, '4': 4},
       '-4': {'-4': -4, '-3': -3, '-2': -2, '-1': -1}
     };
 
-    var mapMapTestOutput = client.testMapMap(1);
+    const mapMapTestOutput = client.testMapMap(1);
 
 
-    for (var key in mapMapTestOutput) {
-      for (var key2 in mapMapTestOutput[key]) {
-        equal(mapMapTestOutput[key][key2], mapMapTestExpectedResult[key][key2]);
+    for (let key in mapMapTestOutput) {
+      for (let key2 in mapMapTestOutput[key]) {
+        assert.equal(mapMapTestOutput[key][key2], mapMapTestExpectedResult[key][key2]);
       }
     }
 
-    checkRecursively(mapMapTestOutput, mapMapTestExpectedResult);
+    checkRecursively(assert, mapMapTestOutput, mapMapTestExpectedResult);
   });
 
 
-module('Exception');
+QUnit.module('Exception');
 
-  test('Xception', function() {
-    expect(2);
+  QUnit.test('Xception', function(assert) {
+    assert.expect(2);
+    const done = assert.async();
     try {
       client.testException('Xception');
+      assert.ok(false);
     }catch (e) {
-      equal(e.errorCode, 1001);
-      equal(e.message, 'Xception');
+      assert.equal(e.errorCode, 1001);
+      assert.equal(e.message, 'Xception');
+      done();
     }
   });
 
-  test('no Exception', 0, function() {
+  QUnit.test('no Exception', function(assert) {
+    assert.expect(1);
     try {
       client.testException('no Exception');
+      assert.ok(true);
     }catch (e) {
-      ok(false);
+      assert.ok(false);
     }
   });
 
-  test('TException', function() {
+  QUnit.test('TException', function(assert) {
     //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);
+    assert.expect(1);
     try {
       client.testException('TException');
     } catch (e) {
-      //ok(false);
+      //assert.ok(false);
     }
-    ok(true);
+    assert.ok(true);
   });
 
 
-module('Insanity');
+QUnit.module('Insanity');
 
-  var crazy = {
+  const crazy = {
     'userMap': { '5': 5, '8': 8 },
     'xtructs': [{
       'string_thing': 'Goodbye4',
@@ -336,77 +341,75 @@ module('Insanity');
       'i64_thing': 2
     }]
   };
-  test('testInsanity', function() {
-    var insanity = {
+  QUnit.test('testInsanity', function(assert) {
+    const insanity = {
       '1': {
         '2': crazy,
         '3': crazy
       },
       '2': { '6': { 'userMap': null, 'xtructs': null } }
     };
-    var res = client.testInsanity(new ThriftTest.Insanity(crazy));
-    ok(res, JSON.stringify(res));
-    ok(insanity, JSON.stringify(insanity));
+    const res = client.testInsanity(new ThriftTest.Insanity(crazy));
+    assert.ok(res, JSON.stringify(res));
+    assert.ok(insanity, JSON.stringify(insanity));
 
-    checkRecursively(res, insanity);
+    checkRecursively(assert, res, insanity);
   });
 
 
 //////////////////////////////////
 //Run same tests asynchronously
 
-module('Async');
+QUnit.module('Async');
 
-  test('Double', function() {
-    expect(1);
+  QUnit.test('Double', function(assert) {
+    assert.expect(1);
 
-    QUnit.stop();
+    const done = assert.async();
     client.testDouble(3.14159265, function(result) {
-      equal(result, 3.14159265);
-      QUnit.start();
+      assert.equal(result, 3.14159265);
+      done();
     });
   });
 
-  test('Byte', function() {
-    expect(1);
+  QUnit.test('Byte', function(assert) {
+    assert.expect(1);
 
-    QUnit.stop();
+    const done = assert.async();
     client.testByte(0x01, function(result) {
-      equal(result, 0x01);
-      QUnit.start();
+      assert.equal(result, 0x01);
+      done();
     });
   });
 
-  test('I32', function() {
-    expect(2);
+  QUnit.test('I32', function(assert) {
+    assert.expect(2);
 
-    QUnit.stop();
+    const done = assert.async(2);
     client.testI32(Math.pow(2, 30), function(result) {
-      equal(result, Math.pow(2, 30));
-      QUnit.start();
+      assert.equal(result, Math.pow(2, 30));
+      done();
     });
 
-    QUnit.stop();
     client.testI32(Math.pow(-2, 31), function(result) {
-      equal(result, Math.pow(-2, 31));
-      QUnit.start();
+      assert.equal(result, Math.pow(-2, 31));
+      done();
     });
   });
 
-  test('I64', function() {
-    expect(2);
+  QUnit.test('I64', function(assert) {
+    assert.expect(2);
 
-    QUnit.stop();
+    const done = assert.async(2);
     //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();
+      assert.equal(result, Math.pow(2, 52));
+      done();
     });
 
-    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();
+      assert.equal(result, Math.pow(-2, 52));
+      done();
     });
   });
diff --git a/lib/js/test/test_handler.js b/lib/js/test/test_handler.js
index 496b5e0..af5f7bd 100644
--- a/lib/js/test/test_handler.js
+++ b/lib/js/test/test_handler.js
@@ -20,10 +20,12 @@
 //This is the server side Node test handler for the standard
 //  Apache Thrift test service.
 
-var ttypes = require('./gen-nodejs/ThriftTest_types');
-var TException = require('../../nodejs/lib/thrift').TException;
+const es6Mode = process.argv.includes('--es6');
+const genFolder = es6Mode ? 'gen-nodejs-es6' : 'gen-nodejs';
+const ttypes = require(`./${genFolder}/ThriftTest_types`);
+const TException = require('../../nodejs/lib/thrift').TException;
 
-var ThriftTestHandler = exports.ThriftTestHandler = {
+exports.ThriftTestHandler = {
   testVoid: function(result) {
     console.log('testVoid()');
     result(null);
@@ -99,10 +101,10 @@ var ThriftTestHandler = exports.ThriftTestHandler = {
   testMapMap: function(hello, result) {
     console.log('testMapMap(' + hello + ')');
 
-    var mapmap = [];
-    var pos = [];
-    var neg = [];
-    for (var i = 1; i < 5; i++) {
+    const mapmap = [];
+    const pos = [];
+    const neg = [];
+    for (let i = 1; i < 5; i++) {
       pos[i] = i;
       neg[-i] = -i;
     }
@@ -116,34 +118,34 @@ var ThriftTestHandler = exports.ThriftTestHandler = {
     console.log(argument);
     console.log(')');
 
-    var hello = new ttypes.Xtruct();
+    const hello = new ttypes.Xtruct();
     hello.string_thing = 'Hello2';
     hello.byte_thing = 2;
     hello.i32_thing = 2;
     hello.i64_thing = 2;
 
-    var goodbye = new ttypes.Xtruct();
+    const goodbye = new ttypes.Xtruct();
     goodbye.string_thing = 'Goodbye4';
     goodbye.byte_thing = 4;
     goodbye.i32_thing = 4;
     goodbye.i64_thing = 4;
 
-    var crazy = new ttypes.Insanity();
+    const crazy = new ttypes.Insanity();
     crazy.userMap = [];
     crazy.userMap[ttypes.Numberz.EIGHT] = 8;
     crazy.userMap[ttypes.Numberz.FIVE] = 5;
     crazy.xtructs = [goodbye, hello];
 
-    var first_map = [];
-    var second_map = [];
+    const first_map = [];
+    const second_map = [];
 
     first_map[ttypes.Numberz.TWO] = crazy;
     first_map[ttypes.Numberz.THREE] = crazy;
 
-    var looney = new ttypes.Insanity();
+    const looney = new ttypes.Insanity();
     second_map[ttypes.Numberz.SIX] = looney;
 
-    var insane = [];
+    const insane = [];
     insane[1] = first_map;
     insane[2] = second_map;
 
@@ -154,7 +156,7 @@ var ThriftTestHandler = exports.ThriftTestHandler = {
   testMulti: function(arg0, arg1, arg2, arg3, arg4, arg5, result) {
     console.log('testMulti()');
 
-    var hello = new ttypes.Xtruct();
+    const hello = new ttypes.Xtruct();
     hello.string_thing = 'Hello2';
     hello.byte_thing = arg0;
     hello.i32_thing = arg1;
@@ -164,7 +166,7 @@ var ThriftTestHandler = exports.ThriftTestHandler = {
   testException: function(arg, result) {
     console.log('testException(' + arg + ')');
     if (arg === 'Xception') {
-      var x = new ttypes.Xception();
+      const x = new ttypes.Xception();
       x.errorCode = 1001;
       x.message = arg;
       result(x);
@@ -177,19 +179,19 @@ var ThriftTestHandler = exports.ThriftTestHandler = {
   testMultiException: function(arg0, arg1, result) {
     console.log('testMultiException(' + arg0 + ', ' + arg1 + ')');
     if (arg0 === ('Xception')) {
-      var x = new ttypes.Xception();
+      const x = new ttypes.Xception();
       x.errorCode = 1001;
       x.message = 'This is an Xception';
       result(x);
     } else if (arg0 === ('Xception2')) {
-      var x2 = new ttypes.Xception2();
+      const x2 = new ttypes.Xception2();
       x2.errorCode = 2002;
       x2.struct_thing = new ttypes.Xtruct();
       x2.struct_thing.string_thing = 'This is an Xception2';
       result(x2);
     }
 
-    var res = new ttypes.Xtruct();
+    const res = new ttypes.Xtruct();
     res.string_thing = arg1;
     result(null, res);
   },
diff --git a/lib/js/test/testws.html b/lib/js/test/testws.html
index f99a146..1edf0e0 100644
--- a/lib/js/test/testws.html
+++ b/lib/js/test/testws.html
@@ -35,12 +35,12 @@
 
   <!-- the Test Suite-->
   <script>
-    var loc = window.location;
-    var ws_uri = ((loc.protocol === "https:") ? "wss://" : "ws://") +
+    const loc = window.location;
+    const ws_uri = ((loc.protocol === "https:") ? "wss://" : "ws://") +
                    loc.hostname + ":" + loc.port + loc.pathname;
-    var transport = new Thrift.TWebSocketTransport(ws_uri);
-    var protocol  = new Thrift.Protocol(transport);
-    var client    = new ThriftTest.ThriftTestClient(protocol);
+    const transport = new Thrift.TWebSocketTransport(ws_uri);
+    const protocol  = new Thrift.Protocol(transport);
+    const client    = new ThriftTest.ThriftTestClient(protocol);
     transport.open();
   </script>
   <script type="text/javascript" src="test-async.js" charset="utf-8"></script>
diff --git a/package-lock.json b/package-lock.json
index 4b16899..7add853 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,18 +10,6 @@
       "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
       "dev": true
     },
-    "ajv": {
-      "version": "5.5.2",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
-      "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
-      "dev": true,
-      "requires": {
-        "co": "4.6.0",
-        "fast-deep-equal": "1.1.0",
-        "fast-json-stable-stringify": "2.0.0",
-        "json-schema-traverse": "0.3.1"
-      }
-    },
     "align-text": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
@@ -70,18 +58,6 @@
         "sprintf-js": "1.0.3"
       }
     },
-    "asn1": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
-      "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
-      "dev": true
-    },
-    "assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-      "dev": true
-    },
     "async": {
       "version": "1.5.2",
       "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
@@ -93,24 +69,6 @@
       "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
       "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
     },
-    "asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
-      "dev": true
-    },
-    "aws-sign2": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
-      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
-      "dev": true
-    },
-    "aws4": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
-      "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
-      "dev": true
-    },
     "babylon": {
       "version": "7.0.0-beta.19",
       "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.19.tgz",
@@ -123,16 +81,6 @@
       "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
       "dev": true
     },
-    "bcrypt-pbkdf": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
-      "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
-      "dev": true,
-      "optional": true,
-      "requires": {
-        "tweetnacl": "0.14.5"
-      }
-    },
     "bindings": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz",
@@ -182,15 +130,6 @@
       "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
       "dev": true
     },
-    "boom": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
-      "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
-      "dev": true,
-      "requires": {
-        "hoek": "4.2.1"
-      }
-    },
     "brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -214,12 +153,6 @@
       "dev": true,
       "optional": true
     },
-    "caseless": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
-      "dev": true
-    },
     "catharsis": {
       "version": "0.8.9",
       "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.9.tgz",
@@ -267,27 +200,12 @@
         }
       }
     },
-    "co": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
-      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
-      "dev": true
-    },
     "code-point-at": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
       "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
       "dev": true
     },
-    "combined-stream": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
-      "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
-      "dev": true,
-      "requires": {
-        "delayed-stream": "1.0.0"
-      }
-    },
     "commander": {
       "version": "2.14.1",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",
@@ -300,17 +218,6 @@
       "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
       "dev": true
     },
-    "concat-stream": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
-      "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
-      "dev": true,
-      "requires": {
-        "inherits": "2.0.3",
-        "readable-stream": "2.3.5",
-        "typedarray": "0.0.6"
-      }
-    },
     "connect": {
       "version": "3.6.6",
       "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
@@ -335,35 +242,6 @@
       "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
       "dev": true
     },
-    "cryptiles": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
-      "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
-      "dev": true,
-      "requires": {
-        "boom": "5.2.0"
-      },
-      "dependencies": {
-        "boom": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
-          "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
-          "dev": true,
-          "requires": {
-            "hoek": "4.2.1"
-          }
-        }
-      }
-    },
-    "dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "1.0.0"
-      }
-    },
     "debug": {
       "version": "2.6.9",
       "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -410,28 +288,12 @@
         }
       }
     },
-    "delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
-      "dev": true
-    },
     "delegates": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
       "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
       "dev": true
     },
-    "ecc-jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
-      "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
-      "dev": true,
-      "optional": true,
-      "requires": {
-        "jsbn": "0.1.1"
-      }
-    },
     "ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -477,12 +339,6 @@
         "is-symbol": "1.0.1"
       }
     },
-    "es6-promise": {
-      "version": "4.2.4",
-      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
-      "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
-      "dev": true
-    },
     "escape-html": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -532,74 +388,12 @@
       "integrity": "sha512-kkjwkMqj0h4w/sb32ERCDxCQkREMCAgS39DscDnSwDsbxnwwM1BTZySdC3Bn1lhY7vL08n9GoO/fVTynjDgRyQ==",
       "dev": true
     },
-    "extend": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
-      "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
-      "dev": true
-    },
-    "extract-zip": {
-      "version": "1.6.6",
-      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz",
-      "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=",
-      "dev": true,
-      "requires": {
-        "concat-stream": "1.6.0",
-        "debug": "2.6.9",
-        "mkdirp": "0.5.0",
-        "yauzl": "2.4.1"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "0.0.8",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-          "dev": true
-        },
-        "mkdirp": {
-          "version": "0.5.0",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
-          "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=",
-          "dev": true,
-          "requires": {
-            "minimist": "0.0.8"
-          }
-        }
-      }
-    },
-    "extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
-      "dev": true
-    },
-    "fast-deep-equal": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
-      "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
-      "dev": true
-    },
-    "fast-json-stable-stringify": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
-      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
-      "dev": true
-    },
     "fast-levenshtein": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
       "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
       "dev": true
     },
-    "fd-slicer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
-      "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
-      "dev": true,
-      "requires": {
-        "pend": "1.2.0"
-      }
-    },
     "finalhandler": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
@@ -630,45 +424,6 @@
       "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
       "dev": true
     },
-    "forever-agent": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
-      "dev": true
-    },
-    "form-data": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
-      "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
-      "dev": true,
-      "requires": {
-        "asynckit": "0.4.0",
-        "combined-stream": "1.0.6",
-        "mime-types": "2.1.18"
-      }
-    },
-    "fs-extra": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
-      "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "4.1.11",
-        "jsonfile": "2.4.0",
-        "klaw": "1.3.1"
-      },
-      "dependencies": {
-        "klaw": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
-          "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
-          "dev": true,
-          "requires": {
-            "graceful-fs": "4.1.11"
-          }
-        }
-      }
-    },
     "fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -697,15 +452,6 @@
         "wide-align": "1.1.2"
       }
     },
-    "getpass": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "1.0.0"
-      }
-    },
     "github-from-package": {
       "version": "0.0.0",
       "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
@@ -754,22 +500,6 @@
         }
       }
     },
-    "har-schema": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
-      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
-      "dev": true
-    },
-    "har-validator": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
-      "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
-      "dev": true,
-      "requires": {
-        "ajv": "5.5.2",
-        "har-schema": "2.0.0"
-      }
-    },
     "has": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
@@ -791,45 +521,6 @@
       "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
       "dev": true
     },
-    "hasha": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz",
-      "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=",
-      "dev": true,
-      "requires": {
-        "is-stream": "1.1.0",
-        "pinkie-promise": "2.0.1"
-      }
-    },
-    "hawk": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
-      "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
-      "dev": true,
-      "requires": {
-        "boom": "4.3.1",
-        "cryptiles": "3.1.2",
-        "hoek": "4.2.1",
-        "sntp": "2.1.0"
-      }
-    },
-    "hoek": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
-      "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==",
-      "dev": true
-    },
-    "http-signature": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "1.0.0",
-        "jsprim": "1.4.1",
-        "sshpk": "1.13.1"
-      }
-    },
     "inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -894,24 +585,12 @@
         "has": "1.0.1"
       }
     },
-    "is-stream": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
-      "dev": true
-    },
     "is-symbol": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
       "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
       "dev": true
     },
-    "is-typedarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
-      "dev": true
-    },
     "isarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -924,12 +603,6 @@
       "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
       "dev": true
     },
-    "isstream": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
-      "dev": true
-    },
     "istanbul": {
       "version": "0.4.5",
       "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz",
@@ -979,13 +652,6 @@
         "xmlcreate": "1.0.2"
       }
     },
-    "jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-      "dev": true,
-      "optional": true
-    },
     "jsdoc": {
       "version": "3.5.5",
       "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.5.5.tgz",
@@ -1006,51 +672,6 @@
         "underscore": "1.8.3"
       }
     },
-    "json-schema": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
-      "dev": true
-    },
-    "json-schema-traverse": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
-      "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
-      "dev": true
-    },
-    "json-stringify-safe": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
-      "dev": true
-    },
-    "jsonfile": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
-      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "4.1.11"
-      }
-    },
-    "jsprim": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "1.0.0",
-        "extsprintf": "1.3.0",
-        "json-schema": "0.2.3",
-        "verror": "1.10.0"
-      }
-    },
-    "kew": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
-      "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
-      "dev": true
-    },
     "kind-of": {
       "version": "3.2.2",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
@@ -1098,21 +719,6 @@
       "integrity": "sha512-+AKbNsjZl6jFfLPwHhWmGTqE009wTKn3RTmn9K8oUKHrX/abPJjtcRtXpYB/FFrwPJRUA86LX/de3T0knkPCmQ==",
       "dev": true
     },
-    "mime-db": {
-      "version": "1.33.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
-      "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
-      "dev": true
-    },
-    "mime-types": {
-      "version": "2.1.18",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
-      "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
-      "dev": true,
-      "requires": {
-        "mime-db": "1.33.0"
-      }
-    },
     "minimatch": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -1204,12 +810,6 @@
       "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
       "dev": true
     },
-    "oauth-sign": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
-      "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
-      "dev": true
-    },
     "object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -1296,50 +896,6 @@
       "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
       "dev": true
     },
-    "pend": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
-      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
-      "dev": true
-    },
-    "performance-now": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
-      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
-      "dev": true
-    },
-    "phantomjs-prebuilt": {
-      "version": "2.1.16",
-      "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz",
-      "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=",
-      "dev": true,
-      "requires": {
-        "es6-promise": "4.2.4",
-        "extract-zip": "1.6.6",
-        "fs-extra": "1.0.0",
-        "hasha": "2.2.0",
-        "kew": "0.7.0",
-        "progress": "1.1.8",
-        "request": "2.83.0",
-        "request-progress": "2.0.1",
-        "which": "1.3.0"
-      }
-    },
-    "pinkie": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
-      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
-      "dev": true
-    },
-    "pinkie-promise": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
-      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
-      "dev": true,
-      "requires": {
-        "pinkie": "2.0.4"
-      }
-    },
     "prebuild-install": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.3.0.tgz",
@@ -1394,12 +950,6 @@
       "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
       "dev": true
     },
-    "progress": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
-      "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
-      "dev": true
-    },
     "pump": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
@@ -1410,23 +960,11 @@
         "once": "1.4.0"
       }
     },
-    "punycode": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
-      "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
-      "dev": true
-    },
     "q": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
       "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
     },
-    "qs": {
-      "version": "6.5.1",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
-      "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
-      "dev": true
-    },
     "rc": {
       "version": "1.2.5",
       "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.5.tgz",
@@ -1468,45 +1006,6 @@
       "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
       "dev": true
     },
-    "request": {
-      "version": "2.83.0",
-      "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
-      "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
-      "dev": true,
-      "requires": {
-        "aws-sign2": "0.7.0",
-        "aws4": "1.6.0",
-        "caseless": "0.12.0",
-        "combined-stream": "1.0.6",
-        "extend": "3.0.1",
-        "forever-agent": "0.6.1",
-        "form-data": "2.3.2",
-        "har-validator": "5.0.3",
-        "hawk": "6.0.2",
-        "http-signature": "1.2.0",
-        "is-typedarray": "1.0.0",
-        "isstream": "0.1.2",
-        "json-stringify-safe": "5.0.1",
-        "mime-types": "2.1.18",
-        "oauth-sign": "0.8.2",
-        "performance-now": "2.1.0",
-        "qs": "6.5.1",
-        "safe-buffer": "5.1.1",
-        "stringstream": "0.0.5",
-        "tough-cookie": "2.3.4",
-        "tunnel-agent": "0.6.0",
-        "uuid": "3.2.1"
-      }
-    },
-    "request-progress": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz",
-      "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=",
-      "dev": true,
-      "requires": {
-        "throttleit": "1.0.0"
-      }
-    },
     "requizzle": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.1.tgz",
@@ -1592,15 +1091,6 @@
         }
       }
     },
-    "sntp": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
-      "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
-      "dev": true,
-      "requires": {
-        "hoek": "4.2.1"
-      }
-    },
     "source-map": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
@@ -1617,22 +1107,6 @@
       "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
       "dev": true
     },
-    "sshpk": {
-      "version": "1.13.1",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
-      "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
-      "dev": true,
-      "requires": {
-        "asn1": "0.2.3",
-        "assert-plus": "1.0.0",
-        "bcrypt-pbkdf": "1.0.1",
-        "dashdash": "1.14.1",
-        "ecc-jsbn": "0.1.1",
-        "getpass": "0.1.7",
-        "jsbn": "0.1.1",
-        "tweetnacl": "0.14.5"
-      }
-    },
     "statuses": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
@@ -1670,12 +1144,6 @@
         "safe-buffer": "5.1.1"
       }
     },
-    "stringstream": {
-      "version": "0.0.5",
-      "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
-      "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
-      "dev": true
-    },
     "strip-ansi": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
@@ -1802,27 +1270,12 @@
         }
       }
     },
-    "throttleit": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
-      "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
-      "dev": true
-    },
     "through": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
       "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
       "dev": true
     },
-    "tough-cookie": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
-      "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
-      "dev": true,
-      "requires": {
-        "punycode": "1.4.1"
-      }
-    },
     "tunnel-agent": {
       "version": "0.6.0",
       "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -1832,13 +1285,6 @@
         "safe-buffer": "5.1.1"
       }
     },
-    "tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
-      "dev": true,
-      "optional": true
-    },
     "type-check": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
@@ -1848,12 +1294,6 @@
         "prelude-ls": "1.1.2"
       }
     },
-    "typedarray": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
-      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
-      "dev": true
-    },
     "uglify-js": {
       "version": "2.8.29",
       "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
@@ -1940,23 +1380,6 @@
       "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
       "dev": true
     },
-    "uuid": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
-      "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==",
-      "dev": true
-    },
-    "verror": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "1.0.0",
-        "core-util-is": "1.0.2",
-        "extsprintf": "1.3.0"
-      }
-    },
     "which": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
@@ -2020,15 +1443,6 @@
         "decamelize": "1.2.0",
         "window-size": "0.1.0"
       }
-    },
-    "yauzl": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
-      "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
-      "dev": true,
-      "requires": {
-        "fd-slicer": "1.0.1"
-      }
     }
   }
 }
diff --git a/package.json b/package.json
index 47bce67..94ff766 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,6 @@
     "connect": "^3.6.6",
     "istanbul": "^0.4.5",
     "jsdoc": "^3.5.5",
-    "phantomjs-prebuilt": "^2.1.16",
     "prettier": "1.11.1",
     "tape": "^4.9.0",
     "utf-8-validate": "^4.0.0"


[thrift] 02/02: THRIFT-4625: Pin dart version to 1.x in build

Posted by jk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jking pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/thrift.git

commit c64389a194fe1516fef5830151dfb8b35f6c6bb2
Author: Brian Forbis <bf...@athenahealth.com>
AuthorDate: Sat Sep 22 07:36:24 2018 -0400

    THRIFT-4625: Pin dart version to 1.x in build
---
 build/docker/ubuntu-artful/Dockerfile | 5 +++--
 build/docker/ubuntu-bionic/Dockerfile | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/build/docker/ubuntu-artful/Dockerfile b/build/docker/ubuntu-artful/Dockerfile
index 4ea95d5..abe84d1 100644
--- a/build/docker/ubuntu-artful/Dockerfile
+++ b/build/docker/ubuntu-artful/Dockerfile
@@ -15,7 +15,7 @@
 # Using all stock Ubuntu Artful packaging except for:
 # - cpp: stock boost 1.62 in artful has a nasty bug so we use stock boost 1.63
 # - d: dmd does not come with Ubuntu
-# - dart: does not come with Ubuntu
+# - dart: does not come with Ubuntu. Pinned to last 1.x release
 # - dotnet: does not come with Ubuntu
 # - haxe: version 3.4.2 that comes with Ubuntu cores in our CI build
 # - go: artful comes with 1.9, we want the latest (supported)
@@ -47,6 +47,7 @@ RUN apt-get update && \
 RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
     curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > \
       /etc/apt/sources.list.d/dart_stable.list
+ENV DART_VERSION 1.24.3-1
 
 # dotnet (netcore)
 RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \
@@ -122,7 +123,7 @@ RUN \
 
 RUN apt-get install -y --no-install-recommends \
       `# Dart dependencies` \
-      dart/stable
+      dart=$DART_VERSION
 ENV PATH /usr/lib/dart/bin:$PATH
 
 RUN apt-get install -y --no-install-recommends \
diff --git a/build/docker/ubuntu-bionic/Dockerfile b/build/docker/ubuntu-bionic/Dockerfile
index da574e1..795c086 100644
--- a/build/docker/ubuntu-bionic/Dockerfile
+++ b/build/docker/ubuntu-bionic/Dockerfile
@@ -15,7 +15,7 @@
 # Using all stock Ubuntu Bionic packaging except for:
 # - cl: want latest
 # - d: dmd does not come with Ubuntu
-# - dart: does not come with Ubuntu
+# - dart: does not come with Ubuntu. Pinned to last 1.x release
 # - dotnet: does not come with Ubuntu
 # - go: want latest
 # - nodejs: want v8, bionic comes with v6
@@ -46,6 +46,7 @@ RUN apt-get update && \
 RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
     curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > \
       /etc/apt/sources.list.d/dart_stable.list
+ENV DART_VERSION 1.24.3-1
 
 # dotnet (netcore)
 RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \
@@ -119,7 +120,7 @@ RUN \
 
 RUN apt-get install -y --no-install-recommends \
       `# Dart dependencies` \
-      dart/stable
+      dart=$DART_VERSION
 ENV PATH /usr/lib/dart/bin:$PATH
 
 RUN apt-get install -y --no-install-recommends \