Add sleep as a test suite function

This adds a class of test suite functions that are only available when a
command line switch is passed to couchjs. This so that the JavaScript
test suite has access to some helpful additional functions that aren't
part of the JavaScript language.

This particular change only adds a single `sleep` function which takes a
single argument as the number of milliseconds to sleep.

COUCHDB-3057
diff --git a/priv/couch_js/help.h b/priv/couch_js/help.h
index f4ddb24..7601e9d 100644
--- a/priv/couch_js/help.h
+++ b/priv/couch_js/help.h
@@ -48,6 +48,8 @@
     "  -V          display version information and exit\n"
     "  -H          enable %s cURL bindings (only avaiable\n"
     "              if package was built with cURL available)\n"
+    "  -T          enable test suite specific functions (these\n"
+    "              should not be enabled for production systems)\n"
     "  -S SIZE     specify that the runtime should allow at\n"
     "              most SIZE bytes of memory to be allocated\n"
     "  -u FILE     path to a .uri file containing the address\n"
diff --git a/priv/couch_js/main.c b/priv/couch_js/main.c
index 1f1bb1d..b2cd210 100644
--- a/priv/couch_js/main.c
+++ b/priv/couch_js/main.c
@@ -14,6 +14,13 @@
 #include <stdio.h>
 #include <string.h>
 
+#ifdef XP_WIN
+#include <windows.h>
+#include <mapiwin.h>
+#else
+#include <unistd.h>
+#endif
+
 #include <jsapi.h>
 #include "config.h"
 #include "http.h"
@@ -275,6 +282,25 @@
 }
 
 
+static JSBool
+js_sleep(JSContext* cx, uintN argc, jsval* vp)
+{
+    jsval* argv = JS_ARGV(cx, vp);
+    int duration = 0;
+    if(!JS_ConvertArguments(cx, argc, argv, "/i", &duration)) {
+        return JS_FALSE;
+    }
+
+#ifdef XP_WIN
+    Sleep(duration);
+#else
+    usleep(duration * 1000);
+#endif
+
+    return JS_TRUE;
+}
+
+
 JSClass CouchHTTPClass = {
     "CouchHTTP",
     JSCLASS_HAS_PRIVATE
@@ -307,6 +333,12 @@
 };
 
 
+JSFunctionSpec TestSuiteFunctions[] = {
+    JS_FS("sleep", js_sleep, 1, 0),
+    JS_FS_END
+};
+
+
 static JSFunctionSpec global_functions[] = {
     JS_FS("evalcx", evalcx, 0, 0),
     JS_FS("gc", gc, 0, 0),
@@ -387,6 +419,11 @@
         }
     } 
 
+    if(args->use_test_funs) {
+        if(couch_load_funcs(cx, global, TestSuiteFunctions) != JS_TRUE)
+            return 1;
+    }
+
     for(i = 0 ; args->scripts[i] ; i++) {
         // Convert script source to jschars.
         scriptsrc = couch_readfile(cx, args->scripts[i]);
diff --git a/priv/couch_js/util.c b/priv/couch_js/util.c
index b4700de..2f2a2a7 100644
--- a/priv/couch_js/util.c
+++ b/priv/couch_js/util.c
@@ -88,6 +88,8 @@
             exit(0);
         } else if(strcmp("-H", argv[i]) == 0) {
             args->use_http = 1;
+        } else if(strcmp("-T", argv[i]) == 0) {
+            args->use_test_funs = 1;
         } else if(strcmp("-S", argv[i]) == 0) {
             args->stack_size = atoi(argv[++i]);
             if(args->stack_size <= 0) {
diff --git a/priv/couch_js/util.h b/priv/couch_js/util.h
index 65a2a06..3c71f69 100644
--- a/priv/couch_js/util.h
+++ b/priv/couch_js/util.h
@@ -17,6 +17,7 @@
 
 typedef struct {
     int          use_http;
+    int          use_test_funs;
     int          stack_size;
     const char** scripts;
     const char*  uri_file;