100%
diff --git a/README.md b/README.md
index 96af404..68c17a8 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,6 @@
 * **errors** - errors are proxied directly from couchdb: if you know couchdb
   you already know `nano`.
 
-
 ## installation
 
 1. install [npm][1]
@@ -23,45 +22,45 @@
 - [tutorials & screencasts](#tutorials-examples-in-the-wild--screencasts)
 - [configuration](#configuration)
 - [database functions](#database-functions)
-	- [nano.db.create(name, [callback])](#nanodbcreatename-callback)
-	- [nano.db.get(name, [callback])](#nanodbgetname-callback)
-	- [nano.db.destroy(name, [callback])](#nanodbdestroyname-callback)
-	- [nano.db.list([callback])](#nanodblistcallback)
-	- [nano.db.compact(name, [designname], [callback])](#nanodbcompactname-designname-callback)
-	- [nano.db.replicate(source, target, [opts], [callback])](#nanodbreplicatesource-target-opts-callback)
-	- [nano.db.changes(name, [params], [callback])](#nanodbchangesname-params-callback)
-	- [nano.db.follow(name, [params], [callback])](#nanodbfollowname-params-callback)
-	- [nano.use(name)](#nanousename)
-	- [nano.request(opts, [callback])](#nanorequestopts-callback)
-	- [nano.config](#nanoconfig)
-	- [nano.updates([params], [callback])](#nanoupdatesparams-callback)
-	- [nano.follow_updates([params], [callback])](#nanofollow_updatesparams-callback)
+  - [nano.db.create(name, [callback])](#nanodbcreatename-callback)
+  - [nano.db.get(name, [callback])](#nanodbgetname-callback)
+  - [nano.db.destroy(name, [callback])](#nanodbdestroyname-callback)
+  - [nano.db.list([callback])](#nanodblistcallback)
+  - [nano.db.compact(name, [designname], [callback])](#nanodbcompactname-designname-callback)
+  - [nano.db.replicate(source, target, [opts], [callback])](#nanodbreplicatesource-target-opts-callback)
+  - [nano.db.changes(name, [params], [callback])](#nanodbchangesname-params-callback)
+  - [nano.db.follow(name, [params], [callback])](#nanodbfollowname-params-callback)
+  - [nano.use(name)](#nanousename)
+  - [nano.request(opts, [callback])](#nanorequestopts-callback)
+  - [nano.config](#nanoconfig)
+  - [nano.updates([params], [callback])](#nanoupdatesparams-callback)
+  - [nano.followUpdates([params], [callback])](#nanofollowUpdatesparams-callback)
 - [document functions](#document-functions)
-	- [db.insert(doc, [params], [callback])](#dbinsertdoc-params-callback)
-	- [db.destroy(docname, rev, [callback])](#dbdestroydocname-rev-callback)
-	- [db.get(docname, [params], [callback])](#dbgetdocname-params-callback)
-	- [db.head(docname, [callback])](#dbheaddocname-callback)
-	- [db.copy(src_doc, dest_doc, opts, [callback])](#dbcopysrc_doc-dest_doc-opts-callback)
-	- [db.bulk(docs, [params], [callback])](#dbbulkdocs-params-callback)
-	- [db.list([params], [callback])](#dblistparams-callback)
-	- [db.fetch(docnames, [params], [callback])](#dbfetchdocnames-params-callback)
-  - [db.fetch_revs(docnames, [params], [callback])](#dbfetch_revsdocnames-params-callback)
+  - [db.insert(doc, [params], [callback])](#dbinsertdoc-params-callback)
+  - [db.destroy(docname, rev, [callback])](#dbdestroydocname-rev-callback)
+  - [db.get(docname, [params], [callback])](#dbgetdocname-params-callback)
+  - [db.head(docname, [callback])](#dbheaddocname-callback)
+  - [db.copy(src_doc, dest_doc, opts, [callback])](#dbcopysrc_doc-dest_doc-opts-callback)
+  - [db.bulk(docs, [params], [callback])](#dbbulkdocs-params-callback)
+  - [db.list([params], [callback])](#dblistparams-callback)
+  - [db.fetch(docnames, [params], [callback])](#dbfetchdocnames-params-callback)
+  - [db.fetchRevs(docnames, [params], [callback])](#dbfetchRevsdocnames-params-callback)
 - [multipart functions](#multipart-functions)
-	- [db.multipart.insert(doc, attachments, [params], [callback])](#dbmultipartinsertdoc-attachments-params-callback)
-	- [db.multipart.get(docname, [params], [callback])](#dbmultipartgetdocname-params-callback)
+  - [db.multipart.insert(doc, attachments, [params], [callback])](#dbmultipartinsertdoc-attachments-params-callback)
+  - [db.multipart.get(docname, [params], [callback])](#dbmultipartgetdocname-params-callback)
 - [attachments functions](#attachments-functions)
-	- [db.attachment.insert(docname, attname, att, contenttype, [params], [callback])](#dbattachmentinsertdocname-attname-att-contenttype-params-callback)
-	- [db.attachment.get(docname, attname, [params], [callback])](#dbattachmentgetdocname-attname-params-callback)
-	- [db.attachment.destroy(docname, attname, rev, [callback])](#dbattachmentdestroydocname-attname-rev-callback)
+  - [db.attachment.insert(docname, attname, att, contenttype, [params], [callback])](#dbattachmentinsertdocname-attname-att-contenttype-params-callback)
+  - [db.attachment.get(docname, attname, [params], [callback])](#dbattachmentgetdocname-attname-params-callback)
+  - [db.attachment.destroy(docname, attname, [params], [callback])](#dbattachmentdestroydocname-attname-rev-callback)
 - [views and design functions](#views-and-design-functions)
-	- [db.view(designname, viewname, [params], [callback])](#dbviewdesignname-viewname-params-callback)
-	- [db.show(designname, showname, doc_id, [params], [callback])](#dbshowdesignname-showname-doc_id-params-callback)
-	- [db.atomic(designname, updatename, docname, [body], [callback])](#dbatomicdesignname-updatename-docname-body-callback)
-	- [db.search(designname, viewname, [params], [callback])](#dbsearchdesignname-searchname-params-callback)
+  - [db.view(designname, viewname, [params], [callback])](#dbviewdesignname-viewname-params-callback)
+  - [db.show(designname, showname, doc_id, [params], [callback])](#dbshowdesignname-showname-doc_id-params-callback)
+  - [db.atomic(designname, updatename, docname, [body], [callback])](#dbatomicdesignname-updatename-docname-body-callback)
+  - [db.search(designname, viewname, [params], [callback])](#dbsearchdesignname-searchname-params-callback)
 - [using cookie authentication](#using-cookie-authentication)
 - [advanced features](#advanced-features)
-	- [extending nano](#extending-nano)
-	- [pipes](#pipes)
+  - [extending nano](#extending-nano)
+  - [pipes](#pipes)
 - [tests](#tests)
 
 ## getting started
@@ -354,7 +353,7 @@
 ### nano.updates([params], [callback])
 
 listen to db updates, the available `params` are:
-  
+
 * `params.feed` – Type of feed. Can be one of
  * `longpoll`: Closes the connection after the first event.
  * `continuous`: Send a line of JSON per event. Keeps the socket open until timeout.
@@ -363,14 +362,16 @@
 * `params.heartbeat` – Whether CouchDB will send a newline character (\n) on timeout. Default is true.
 
 
-### nano.follow_updates([params], [callback])
+### nano.followUpdates([params], [callback])
+
+** changed in version 6 **
 
 uses [follow](https://github.com/iriscouch/follow) to create a solid
 [`_db_updates`](http://docs.couchdb.org/en/latest/api/server/common.html?highlight=db_updates#get--_db_updates) feed.
 please consult follow documentation for more information as this is a very complete api on it's own
 
 ```js
-var feed = nano.follow_updates({since: "now"});
+var feed = nano.followUpdates({since: "now"});
 feed.on('change', function (change) {
   console.log("change: ", change);
 });
@@ -467,7 +468,9 @@
 additional query string `params` can be specified, `include_docs` is always set
 to `true`.
 
-### db.fetch_revs(docnames, [params], [callback])
+### db.fetchRevs(docnames, [params], [callback])
+
+** changed in version 6 **
 
 bulk fetch of the revisions of the database documents, `docnames` are specified as per
 [couchdb doc](http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API).
@@ -564,13 +567,15 @@
 alice.attachment.get('rabbit', 'rabbit.png').pipe(fs.createWriteStream('rabbit.png'));
 ```
 
-### db.attachment.destroy(docname, attname, rev, [callback])
+### db.attachment.destroy(docname, attname, [params], [callback])
+
+**changed in version 6**
 
 destroy attachment `attname` of `docname`'s revision `rev`.
 
 ``` js
 alice.attachment.destroy('rabbit', 'rabbit.png',
-    '1-4701d73a08ce5c2f2983bf7c9ffd3320', function(err, body) {
+    {rev: '1-4701d73a08ce5c2f2983bf7c9ffd3320'}, function(err, body) {
       if (!err)
         console.log(body);
 });
diff --git a/lib/nano.js b/lib/nano.js
index b8e0dbd..8c540fa 100644
--- a/lib/nano.js
+++ b/lib/nano.js
@@ -29,7 +29,7 @@
 
   var httpAgent = (typeof cfg.request === 'function') ? cfg.request :
     request.defaults(cfg.requestDefaults);
-
+  var followAgent = (typeof cfg.follow === 'function') ? cfg.follow : follow;
   var log = typeof cfg.log === 'function' ? cfg.log : logger(cfg);
 
   function relax(opts, callback) {
@@ -60,13 +60,14 @@
       uri: cfg.url
     };
 
-    var statusCode;
     var parsed;
     var rh;
 
     // https://github.com/mikeal/request#requestjar
-    if (opts.jar) {
-      req.jar = opts.jar;
+    var isJar = opts.jar || cfg.jar;
+
+    if (isJar) {
+      req.jar = isJar;
     }
 
     // http://wiki.apache.org/couchdb/HTTP_database_API#Naming_and_Addressing
@@ -156,18 +157,17 @@
     }
 
     return httpAgent(req, function(e, h, b) {
-      rh = (h && h.headers || {});
-      rh.statusCode = (h && h.statusCode || 500);
+      rh = h && h.headers || {};
+      rh.statusCode = h && h.statusCode || 500;
       rh.uri = req.uri;
 
       if (e) {
         log({err: 'socket', body: b, headers: rh});
-        errs.handle(errs.merge(e, {
+        return callback(errs.merge(e, {
           message: 'error happened in your connection',
           scope: 'socket',
           errid: 'request'
-        }), callback);
-        return;
+        }));
       }
 
       delete rh.server;
@@ -181,35 +181,31 @@
 
       if (rh.statusCode >= 200 && rh.statusCode < 400) {
         log({err: null, body: parsed, headers: rh});
-
-        callback(null, parsed, rh);
+        return callback(null, parsed, rh);
       }
-      else { // proxy the error directly from couchdb
-        log({err: 'couch', body: parsed, headers: rh});
 
-        if (!parsed) {
-          parsed = {};
-        }
+      log({err: 'couch', body: parsed, headers: rh});
 
-        // cloudant stacktrace
-        if (typeof parsed === 'string') {
-          parsed = {message: parsed};
-        }
-        if (!parsed.message && (parsed.reason || parsed.error)) {
-          parsed.message = (parsed.reason || parsed.error);
-        }
-        // fix cloudant issues where they give an erlang stacktrace as js
-        delete parsed.stack;
-
-        errs.handle(errs.merge(errs.create(parsed), {
-          scope: 'couch',
-          statusCode: rh.statusCode,
-          request: req,
-          headers: rh,
-          errid: 'non_200',
-          message: parsed.reason || 'couch returned ' + statusCode
-        }), callback);
+      // cloudant stacktrace
+      if (typeof parsed === 'string') {
+        parsed = {message: parsed};
       }
+
+      if (!parsed.message && (parsed.reason || parsed.error)) {
+        parsed.message = (parsed.reason || parsed.error);
+      }
+
+      // fix cloudant issues where they give an erlang stacktrace as js
+      delete parsed.stack;
+
+      callback(errs.merge({
+        message: 'couch returned ' + rh.statusCode,
+        scope: 'couch',
+        statusCode: rh.statusCode,
+        request: req,
+        headers: rh,
+        errid: 'non_200'
+      }, errs.create(parsed)));
     });
   }
 
@@ -295,13 +291,12 @@
       qs = {};
     }
 
-    qs = qs || {};
     qs.db = u.resolve(cfg.url, encodeURIComponent(dbName));
 
     if (typeof callback === 'function') {
-      return follow(qs, callback);
+      return followAgent(qs, callback);
     } else {
-      return new follow.Feed(qs);
+      return new followAgent.Feed(qs);
     }
   }
 
@@ -328,6 +323,7 @@
 
   function docModule(dbName) {
     var docScope = {};
+    dbName = decodeURIComponent(dbName);
 
     // http://docs.couchdb.org/en/latest/api/document/common.html#put--db-docid
     // http://docs.couchdb.org/en/latest/api/database/common.html#post--db
@@ -455,14 +451,13 @@
       }, callback);
     }
 
-    // http://docs.couchdb.org/en/latest/api/ddoc/views.html#post--db-_design-ddoc-_view-view
-    function viewDocs(ddoc, viewName, qs, callback) {
+    function view(ddoc, viewName, meta, qs, callback) {
       if (typeof qs === 'function') {
         callback = qs;
         qs = {};
       }
 
-      var viewPath = '_design/' + ddoc + '/_view/'  + viewName;
+      var viewPath = '_design/' + ddoc + '/_' + meta.type + '/'  + viewName;
 
       if (qs && qs.keys) {
         var body = {keys: qs.keys};
@@ -474,62 +469,57 @@
           qs: qs,
           body: body
         }, callback);
+      } else {
+        var req = {
+          db: dbName,
+          method: meta.method || 'GET',
+          path: viewPath,
+          qs: qs
+        };
+
+        if (meta.body) {
+          req.body = meta.body;
+        }
+
+        return relax(req, callback);
       }
-      else {
-        return relax({db: dbName, path: viewPath, qs: qs}, callback);
-      }
+    }
+
+    // http://docs.couchdb.org/en/latest/api/ddoc/views.html#post--db-_design-ddoc-_view-view
+    function viewDocs(ddoc, viewName, qs, callback) {
+      return view(ddoc, viewName, {type: 'view'}, qs, callback);
     }
 
     // geocouch
     function viewSpatial(ddoc, viewName, qs, callback) {
-      if (typeof qs === 'function') {
-        callback = qs;
-        qs = {};
-      }
-
-      var viewPath = '_design/' + ddoc + '/_spatial/'  + viewName;
-
-      return relax({db: dbName, path: viewPath, qs: qs}, callback);
+      return view(ddoc, viewName, {type: 'spatial'}, qs, callback);
     }
 
     // cloudant
-    function viewSearch(ddoc, searchName, qs, callback) {
-      if (typeof qs === 'function') {
-        callback = qs;
-        qs = {};
-      }
-
-      var viewPath = '_design/' + ddoc + '/_search/' + searchName;
-
-      return relax({db: dbName, path: viewPath, qs: qs}, callback);
+    function viewSearch(ddoc, viewName, qs, callback) {
+      return view(ddoc, viewName, {type: 'search'}, qs, callback);
     }
 
     // http://docs.couchdb.org/en/latest/api/ddoc/render.html#get--db-_design-ddoc-_show-func
-    function showDoc(ddoc, fn, docId, qs, callback) {
-      if (typeof qs === 'function') {
-        callback = qs;
-        qs = {};
-      }
-
-      var show = '_design/' + ddoc + '/_show/'  + fn + '/' + docId;
-
-      return relax({db: dbName, path: show, qs: qs}, callback);
+    function showDoc(ddoc, viewName, docName, qs, callback) {
+      return view(ddoc, viewName + '/' + docName, {type: 'show'}, qs, callback);
     }
 
     // http://docs.couchdb.org/en/latest/api/ddoc/render.html#put--db-_design-ddoc-_update-func-docid
-    function updateWithHandler(ddoc, updateName, docName, body, callback) {
-
-      var updatePath = '_design/' + ddoc + '/_update/' + updateName +
-        '/' + encodeURIComponent(docName);
-
-      return relax({
-       db: dbName,
-       path: updatePath,
-       method: 'PUT',
-       body: body
+    function updateWithHandler(ddoc, viewName, docName, body, callback) {
+      return view(ddoc, viewName + '/' + encodeURIComponent(docName), {
+        type: 'update',
+        method: 'PUT',
+        body: body
       }, callback);
     }
 
+    function viewWithList(ddoc, viewName, listName, qs, callback) {
+      return view(ddoc, listName + '/' + viewName, {
+        type: 'list'
+      }, qs, callback);
+    }
+
     // http://docs.couchdb.org/en/latest/api/database/bulk-api.html#post--db-_bulksDoc
     function bulksDoc(docs, qs, callback) {
       if (typeof qs === 'function') {
@@ -634,41 +624,16 @@
       }, callback);
     }
 
-    function destroyAtt(docName, attName, rev, callback) {
+    function destroyAtt(docName, attName, qs, callback) {
       return relax({
         db: dbName,
         att: attName,
         method: 'DELETE',
         doc: docName,
-        qs: {rev: rev}
+        qs: qs
       }, callback);
     }
 
-    function viewWithList(ddoc, viewName, listName, qs, callback) {
-
-      var listPath = '_design/' + ddoc + '/_list/' +
-        listName + '/' + viewName;
-
-      if (qs && qs.keys) {
-        var body = {keys: qs.keys};
-        delete qs.keys;
-        return relax({
-          db: dbName,
-          path: listPath,
-          method: 'POST',
-          qs: qs,
-          body: body
-        }, callback);
-      }
-      else {
-        return relax({
-          db: dbName,
-          path: listPath,
-          qs: qs
-        }, callback);
-      }
-    }
-
     // db level exports
     docScope = {
       info: function(cb) {
@@ -735,7 +700,9 @@
       compact: compactDb,
       replicate: replicateDb,
       changes: changesDb,
-      follow: followDb
+      follow: followDb,
+      followUpdates: followUpdates,
+      updates: updates
     },
     use: docModule,
     scope: docModule,
@@ -755,7 +722,7 @@
 
     auth = path.auth ? path.auth : '';
     var port = path.port ? ':' + path.port : '';
-    var db = cfg.db ? cfg.db : decodeURIComponent(pathArray[0]);
+    var db = pathArray[0];
 
     var format = {
       protocol: path.protocol,
@@ -766,10 +733,6 @@
       format.auth = auth;
     }
 
-    if (cfg.db) {
-      format.pathname = path.pathname + '/';
-    }
-
     cfg.url = u.format(format);
 
     return docModule(db);
diff --git a/tests/fixtures/shared/log.json b/tests/fixtures/shared/log.json
new file mode 100644
index 0000000..6ed417e
--- /dev/null
+++ b/tests/fixtures/shared/log.json
@@ -0,0 +1,11 @@
+[
+  { "method"   : "put"
+  , "path"     : "/shared_log"
+  , "status"   : 201
+  , "response" : "{ \"ok\": true }"
+  }
+, { "method"   : "delete"
+  , "path"     : "/shared_log"
+  , "response" : "{ \"ok\": true }"
+  }
+]
diff --git a/tests/helpers/index.js b/tests/helpers/index.js
new file mode 100644
index 0000000..dd177b3
--- /dev/null
+++ b/tests/helpers/index.js
@@ -0,0 +1,28 @@
+'use strict';
+
+var path = require('path');
+var fs = require('fs');
+var url = require('url');
+var nano = require('../../lib/nano');
+
+var helpers = exports;
+var cfg = helpers.cfg = require('../fixtures/cfg');
+var auth = url.parse(cfg.admin).auth.split(':');
+
+helpers.timeout = cfg.timeout;
+helpers.nano = nano(cfg.couch);
+helpers.Nano = nano;
+helpers.couch = cfg.couch;
+helpers.admin = cfg.admin;
+helpers.pixel = 'Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BABgAAAAA' +
+  'AAAAAAATCwAAEwsAAAAAAAAAAAAAWm2CAA==';
+
+helpers.username = auth[0];
+helpers.password = auth[1];
+
+helpers.loadFixture = function helpersLoadFixture(filename, json) {
+  var contents = fs.readFileSync(
+    path.join(__dirname, '..', 'fixtures', filename), (json ? 'ascii' : null));
+  return json ? JSON.parse(contents) : contents;
+};
+
diff --git a/tests/helpers.js b/tests/helpers/integration.js
similarity index 77%
rename from tests/helpers.js
rename to tests/helpers/integration.js
index 4a005b9..1b5e1ba 100644
--- a/tests/helpers.js
+++ b/tests/helpers/integration.js
@@ -1,35 +1,13 @@
 'use strict';
 
 var async = require('async');
-var path = require('path');
-var fs = require('fs');
-var url = require('url');
-var harness = require('tape-it');
 var debug = require('debug');
 var path = require('path');
+var harness = require('tape-it');
 var endsWith = require('endswith');
-var cfg = require('./fixtures/cfg');
-var nano = require('../lib/nano');
-var helpers = exports;
-
-var auth = url.parse(cfg.admin).auth.split(':');
-
-helpers.timeout = cfg.timeout;
-helpers.nano = nano(cfg.couch);
-helpers.Nano = nano;
-helpers.couch = cfg.couch;
-helpers.admin = cfg.admin;
-helpers.pixel = 'Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BABgAAAAA' +
-  'AAAAAAATCwAAEwsAAAAAAAAAAAAAWm2CAA==';
-
-helpers.username = auth[0];
-helpers.password = auth[1];
-
-helpers.loadFixture = function helpersLoadFixture(filename, json) {
-  var contents = fs.readFileSync(
-    path.join(__dirname, 'fixtures', filename), (json ? 'ascii' : null));
-  return json ? JSON.parse(contents) : contents;
-};
+var cfg = require('../fixtures/cfg');
+var nano = require('../../lib/nano');
+var helpers = require('./');
 
 helpers.setup = function() {
   var self = this;
@@ -60,27 +38,20 @@
   };
 };
 
-helpers.noopTest = function (assert) {
-  assert.pass('werk werk werk');
-  assert.end();
-};
-
-helpers.harness = function(name, unit) {
-  unit = !!unit;
-
+helpers.harness = function(name) {
   var parent = name || module.parent.filename;
   var fileName = path.basename(parent).split('.')[0];
   var parentDir = path.dirname(parent)
     .split(path.sep).reverse()[0];
   var shortPath = path.join(parentDir, fileName);
-  var log = debug(path.join('nano', 'tests', shortPath));
+  var log = debug(path.join('nano', 'tests', 'integration', shortPath));
   var dbName = shortPath.replace('/', '_');
   var nanoLog = nano({
     url: cfg.couch,
     log: log
   });
 
-  var mock = unit ? null : helpers.nock(helpers.couch, shortPath, log);
+  var mock = helpers.nock(helpers.couch, shortPath, log);
   var db   = nanoLog.use(dbName);
   var locals = {
     mock: mock,
@@ -93,14 +64,14 @@
     timeout: helpers.timeout,
     checkLeaks: !!process.env.LEAKS,
     locals: locals,
-    setup: unit ? helpers.noopTest : helpers.setup.call(locals, dbName),
-    teardown: unit ? helpers.noopTest : helpers.teardown.call(locals, dbName)
+    setup: helpers.setup.call(locals, dbName),
+    teardown: helpers.teardown.call(locals, dbName)
   });
 };
 
 helpers.nock = function helpersNock(url, fixture, log) {
   var nock = require('nock');
-  var nockDefs = require('./fixtures/' + fixture + '.json');
+  var nockDefs = require('../fixtures/' + fixture + '.json');
 
   nockDefs.forEach(function(n) {
     var headers = n.headers || {};
@@ -204,3 +175,6 @@
 
 helpers.unmocked = (process.env.NOCK_OFF === 'true');
 helpers.mocked = !helpers.unmocked;
+
+module.exports = helpers;
+
diff --git a/tests/helpers/unit.js b/tests/helpers/unit.js
new file mode 100644
index 0000000..c47a30c
--- /dev/null
+++ b/tests/helpers/unit.js
@@ -0,0 +1,139 @@
+'use strict';
+
+var helpers = require('./');
+var Client = require('../../lib/nano');
+var test  = require('tape');
+var _ = require('underscore');
+
+helpers.unit = function(method, error) {
+  var unitName = 'nano/tests/unit/' + method.join('/');
+  var debug = require('debug')(unitName);
+
+  function log(data) {
+    debug({ got: data.body });
+  }
+
+  var cli = helpers.mockClientOk(log, error);
+
+  //
+  // allow database creation and other server stuff
+  //
+  if(method[1].match(/follow/)) {
+    if(method[0] === 'database') {
+      cli.server = helpers.mockClientFollow(log, error);
+    } else {
+      cli = helpers.mockClientFollow(log, error);
+    }
+  } else {
+    cli.server = helpers.mockClientDb(log, error);
+  }
+
+  var testNr = 1;
+
+  return function() {
+    var args = Array.prototype.slice.call(arguments);
+    var stub = args.pop();
+
+    test(unitName + ':' + testNr++,
+    function(assert) {
+      var f;
+      assert.ok(typeof stub, 'object');
+
+      //
+      // document functions and database functions
+      // are at the top level in nano
+      //
+      if(method[0] === 'database') {
+        f = cli.server.db[method[1]];
+      } else if(method[0] === 'view' && method[1] === 'compact') {
+        f = cli.view.compact;
+      } else if(!~['multipart', 'attachment'].indexOf(method[0])) {
+        f = cli[method[1]];
+      } else {
+        f = cli[method[0]][method[1]];
+      }
+      assert.ok(typeof f, 'function');
+
+      args.push(function(err, req, response) {
+        if (error) {
+          assert.ok(err);
+          return assert.end();
+        }
+
+        assert.equal(response.statusCode, 200);
+        if(stub.uri) {
+          stub.uri = helpers.couch + stub.uri;
+        } else {
+          stub.db = helpers.couch + stub.db;
+        }
+
+        assert.deepEqual(req, stub);
+        assert.end();
+      });
+
+      f.apply(null, args);
+    });
+  };
+};
+
+function mockClient(code, path, extra) {
+  return function(debug, error) {
+    extra = extra || {};
+    var opts = _.extend(extra, {
+      url: helpers.couch + path,
+      log: debug,
+      request: function(req, cb) {
+        if(error) {
+          return cb(error);
+        }
+
+        if(code === 500) {
+          cb(new Error('omg connection failed'));
+        } else {
+          cb(null, {
+            statusCode: code,
+            headers: {}
+          }, req); }
+        }
+    });
+
+    return Client(opts);
+  };
+}
+
+function mockClientUnparsedError() {
+  return function(debug, body) {
+    return Client({
+      url: helpers.couch,
+      log: debug,
+      request: function(_, cb) {
+        return cb(null, {statusCode: 500}, body || '<b> Error happened </b>');
+      }
+    });
+  };
+}
+
+function mockClientFollow() {
+  return function(debug, error) {
+    return Client({
+      url: helpers.couch,
+      log: debug,
+      follow: function(qs, cb) {
+        if(error) {
+          return cb(error);
+        }
+
+        return cb(null, qs,  {statusCode: 200});
+      }
+    });
+  };
+}
+
+
+helpers.mockClientFollow = mockClientFollow();
+helpers.mockClientUnparsedError = mockClientUnparsedError();
+helpers.mockClientDb = mockClient(200, '');
+helpers.mockClientOk = mockClient(200, '/mock');
+helpers.mockClientFail = mockClient(500, '');
+helpers.mockClientJar = mockClient(300, '', {jar: 'is set'});
+module.exports = helpers;
diff --git a/tests/integration/attachment/destroy.js b/tests/integration/attachment/destroy.js
index be0fc1f..30209fe 100644
--- a/tests/integration/attachment/destroy.js
+++ b/tests/integration/attachment/destroy.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
@@ -11,8 +11,8 @@
     assert.equal(error, null, 'store the attachment');
     assert.equal(att.ok, true, 'response ok');
     assert.ok(att.rev, 'have a revision number');
-    db.attachment.destroy('new', 'att',
-    att.rev, function(error, response) {
+    db.attachment.destroy('new', 'att', {rev: att.rev},
+    function(error, response) {
       assert.equal(error, null, 'delete the attachment');
       assert.equal(response.ok, true, 'response ok');
       assert.equal(response.id, 'new', '`id` should be `new`');
diff --git a/tests/integration/attachment/get.js b/tests/integration/attachment/get.js
index 2b4c556..7e642ac 100644
--- a/tests/integration/attachment/get.js
+++ b/tests/integration/attachment/get.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/attachment/insert.js b/tests/integration/attachment/insert.js
index 0e214d1..883bdcf 100644
--- a/tests/integration/attachment/insert.js
+++ b/tests/integration/attachment/insert.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/attachment/pipe.js b/tests/integration/attachment/pipe.js
index da3284b..5b9f7f9 100644
--- a/tests/integration/attachment/pipe.js
+++ b/tests/integration/attachment/pipe.js
@@ -2,7 +2,7 @@
 
 var fs = require('fs');
 var path = require('path');
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var db = harness.locals.db;
 var it = harness.it;
diff --git a/tests/integration/attachment/update.js b/tests/integration/attachment/update.js
index 39d8d26..bf0fc73 100644
--- a/tests/integration/attachment/update.js
+++ b/tests/integration/attachment/update.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var pixel = helpers.pixel;
 var harness = helpers.harness(__filename);
 var db = harness.locals.db;
diff --git a/tests/integration/database/changes.js b/tests/integration/database/changes.js
index 4082854..8d5f831 100644
--- a/tests/integration/database/changes.js
+++ b/tests/integration/database/changes.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var db = harness.locals.db;
 var it = harness.it;
diff --git a/tests/integration/database/compact.js b/tests/integration/database/compact.js
index 18616ec..770772b 100644
--- a/tests/integration/database/compact.js
+++ b/tests/integration/database/compact.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/database/create-and-destroy.js b/tests/integration/database/create-and-destroy.js
index f50264b..899097b 100644
--- a/tests/integration/database/create-and-destroy.js
+++ b/tests/integration/database/create-and-destroy.js
@@ -1,7 +1,7 @@
 'use strict';
 
 var async = require('async');
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var nano = harness.locals.nano;
diff --git a/tests/integration/database/follow.js b/tests/integration/database/follow.js
index 318105f..628c934 100644
--- a/tests/integration/database/follow.js
+++ b/tests/integration/database/follow.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/database/get.js b/tests/integration/database/get.js
index ca7808b..9f01985 100644
--- a/tests/integration/database/get.js
+++ b/tests/integration/database/get.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var nano = harness.locals.nano;
diff --git a/tests/integration/database/list.js b/tests/integration/database/list.js
index 32df911..d632d7d 100644
--- a/tests/integration/database/list.js
+++ b/tests/integration/database/list.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var nano = harness.locals.nano;
diff --git a/tests/integration/database/replicate.js b/tests/integration/database/replicate.js
index 732a775..95d4d0d 100644
--- a/tests/integration/database/replicate.js
+++ b/tests/integration/database/replicate.js
@@ -1,13 +1,14 @@
 'use strict';
 
 var async = require('async');
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
 var nano = harness.locals.nano;
 
-var replica, replica2;
+var replica;
+var replica2;
 
 it('should insert a bunch of items', helpers.insertThree);
 
diff --git a/tests/integration/design/atomic.js b/tests/integration/design/atomic.js
index f1c342a..53e801a 100644
--- a/tests/integration/design/atomic.js
+++ b/tests/integration/design/atomic.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/design/compact.js b/tests/integration/design/compact.js
index f83e322..caeefed 100644
--- a/tests/integration/design/compact.js
+++ b/tests/integration/design/compact.js
@@ -1,7 +1,7 @@
 'use strict';
 
 var async = require('async');
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/design/list.js b/tests/integration/design/list.js
index 89eb018..d3cdac1 100644
--- a/tests/integration/design/list.js
+++ b/tests/integration/design/list.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/design/multiple.js b/tests/integration/design/multiple.js
index 7224a23..c1c8031 100644
--- a/tests/integration/design/multiple.js
+++ b/tests/integration/design/multiple.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/design/query.js b/tests/integration/design/query.js
index 0996f90..1333cf9 100644
--- a/tests/integration/design/query.js
+++ b/tests/integration/design/query.js
@@ -1,7 +1,7 @@
 'use strict';
 
 var async = require('async');
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/design/search.js b/tests/integration/design/search.js
index 41209b6..996b47a 100644
--- a/tests/integration/design/search.js
+++ b/tests/integration/design/search.js
@@ -1,7 +1,7 @@
 'use strict';
 
 var async = require('async');
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/design/show.js b/tests/integration/design/show.js
index e1e0c55..ce9f87e 100644
--- a/tests/integration/design/show.js
+++ b/tests/integration/design/show.js
@@ -1,7 +1,7 @@
 'use strict';
 
 var async = require('async');
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/document/bulk.js b/tests/integration/document/bulk.js
index ca0198e..2ef13ad 100644
--- a/tests/integration/document/bulk.js
+++ b/tests/integration/document/bulk.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/document/copy.js b/tests/integration/document/copy.js
index f12f848..a32128e 100644
--- a/tests/integration/document/copy.js
+++ b/tests/integration/document/copy.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/document/destroy.js b/tests/integration/document/destroy.js
index 03ecdc6..d39b63c 100644
--- a/tests/integration/document/destroy.js
+++ b/tests/integration/document/destroy.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var db = harness.locals.db;
diff --git a/tests/integration/document/fetch.js b/tests/integration/document/fetch.js
index bd12354..85c95d3 100644
--- a/tests/integration/document/fetch.js
+++ b/tests/integration/document/fetch.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var db = harness.locals.db;
 var it = harness.it;
diff --git a/tests/integration/document/fetch_revs.js b/tests/integration/document/fetch_revs.js
index 194c7c3..c25af3a 100644
--- a/tests/integration/document/fetch_revs.js
+++ b/tests/integration/document/fetch_revs.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var db = harness.locals.db;
 var it = harness.it;
diff --git a/tests/integration/document/get.js b/tests/integration/document/get.js
index c0cb0b8..20a6671 100644
--- a/tests/integration/document/get.js
+++ b/tests/integration/document/get.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var db = harness.locals.db;
 var it = harness.it;
diff --git a/tests/integration/document/head.js b/tests/integration/document/head.js
index 61e69c4..9f6cc20 100644
--- a/tests/integration/document/head.js
+++ b/tests/integration/document/head.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var db = harness.locals.db;
 var it = harness.it;
diff --git a/tests/integration/document/insert.js b/tests/integration/document/insert.js
index 33d1491..1a0caab 100644
--- a/tests/integration/document/insert.js
+++ b/tests/integration/document/insert.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var db = harness.locals.db;
 var it = harness.it;
diff --git a/tests/integration/document/list.js b/tests/integration/document/list.js
index 56c003b..d76c3a3 100644
--- a/tests/integration/document/list.js
+++ b/tests/integration/document/list.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var db = harness.locals.db;
 var nano = harness.locals.nano;
diff --git a/tests/integration/document/update.js b/tests/integration/document/update.js
index fa6a307..e259744 100644
--- a/tests/integration/document/update.js
+++ b/tests/integration/document/update.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var db = harness.locals.db;
 var it = harness.it;
diff --git a/tests/integration/multipart/get.js b/tests/integration/multipart/get.js
index a15644e..f0158c7 100644
--- a/tests/integration/multipart/get.js
+++ b/tests/integration/multipart/get.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var db = harness.locals.db;
 var it = harness.it;
diff --git a/tests/integration/multipart/insert.js b/tests/integration/multipart/insert.js
index 4c1a86b..04ff1b3 100644
--- a/tests/integration/multipart/insert.js
+++ b/tests/integration/multipart/insert.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var db = harness.locals.db;
 var it = harness.it;
diff --git a/tests/integration/shared/config.js b/tests/integration/shared/config.js
index 4e18500..23089b6 100644
--- a/tests/integration/shared/config.js
+++ b/tests/integration/shared/config.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var nano = harness.locals.nano;
 var Nano = helpers.Nano;
diff --git a/tests/integration/shared/cookie.js b/tests/integration/shared/cookie.js
index 204955c..e99a3cb 100644
--- a/tests/integration/shared/cookie.js
+++ b/tests/integration/shared/cookie.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var nano = harness.locals.nano;
 var Nano = helpers.Nano;
diff --git a/tests/integration/shared/error.js b/tests/integration/shared/error.js
index 80b0eff..1ee80bb 100644
--- a/tests/integration/shared/error.js
+++ b/tests/integration/shared/error.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var nano = harness.locals.nano;
 var Nano = helpers.Nano;
@@ -34,7 +34,7 @@
   nano.db.destroy('say_wat_wat', function(error) {
     assert.ok(error, 'an error');
     assert.ok(error.message, 'a note');
-    assert.equal(error.description, 'missing', 'is missing');
+    assert.equal(error.message, 'missing', 'is missing');
     assert.end();
   });
 });
diff --git a/tests/integration/shared/headers.js b/tests/integration/shared/headers.js
index bcfd734..9ca43e8 100644
--- a/tests/integration/shared/headers.js
+++ b/tests/integration/shared/headers.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var nano = harness.locals.nano;
 var db = harness.locals.db;
diff --git a/tests/unit/shared/log.js b/tests/integration/shared/log.js
similarity index 76%
rename from tests/unit/shared/log.js
rename to tests/integration/shared/log.js
index bf23038..ff7e3b3 100644
--- a/tests/unit/shared/log.js
+++ b/tests/integration/shared/log.js
@@ -1,17 +1,18 @@
+'use strict';
+
 var logger = require('../../../lib/logger');
 
 var helpers = require('../../helpers');
 var harness = helpers.harness(__filename, true);
 var it = harness.it;
 
-it('should be able to instantiate a log', function (assert) {
+it('should be able to instantiate a log', function(assert) {
   var log = logger({
-    log: function (id, msg) {
+    log: function(id, msg) {
       assert.equal(typeof id, 'string', 'id is set `' + id + '`');
       assert.equal(msg[0], 'testing 1234');
       assert.end();
     }
   })();
-  debugger
   log('testing 1234');
 });
diff --git a/tests/integration/shared/nano.js b/tests/integration/shared/nano.js
index 3ae1e69..ea011fe 100644
--- a/tests/integration/shared/nano.js
+++ b/tests/integration/shared/nano.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var Nano = helpers.Nano;
 var it = harness.it;
diff --git a/tests/integration/shared/updates.js b/tests/integration/shared/updates.js
index e44e76e..7c12a4c 100644
--- a/tests/integration/shared/updates.js
+++ b/tests/integration/shared/updates.js
@@ -1,6 +1,6 @@
 'use strict';
 
-var helpers = require('../../helpers');
+var helpers = require('../../helpers/integration');
 var harness = helpers.harness(__filename);
 var it = harness.it;
 var nano = harness.locals.nano;
diff --git a/tests/unit/attachment/destroy.js b/tests/unit/attachment/destroy.js
new file mode 100644
index 0000000..56488ba
--- /dev/null
+++ b/tests/unit/attachment/destroy.js
@@ -0,0 +1,16 @@
+'use strict';
+
+var destroyAttachment = require('../../helpers/unit').unit([
+  'attachment',
+  'destroy'
+]);
+
+destroyAttachment('airplane-design', 'wings.pdf', {rev: '3'}, {
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'DELETE',
+  qs: {rev: '3'},
+  uri: '/mock/airplane-design/wings.pdf'
+});
diff --git a/tests/unit/attachment/get.js b/tests/unit/attachment/get.js
new file mode 100644
index 0000000..c4c7510
--- /dev/null
+++ b/tests/unit/attachment/get.js
@@ -0,0 +1,21 @@
+'use strict';
+
+var getAttachment = require('../../helpers/unit').unit([
+  'attachment',
+  'get'
+]);
+
+getAttachment('airplane-design', 'wings.pdf', {rev: 'rev-3'}, {
+  encoding: null,
+  headers: {},
+  method: 'GET',
+  qs: {rev: 'rev-3'},
+  uri: '/mock/airplane-design/wings.pdf'
+});
+
+getAttachment('airplane-design', 'wings.pdf', {
+  encoding: null,
+  headers: {},
+  method: 'GET',
+  uri: '/mock/airplane-design/wings.pdf'
+});
diff --git a/tests/unit/attachment/insert.js b/tests/unit/attachment/insert.js
new file mode 100644
index 0000000..c30870e
--- /dev/null
+++ b/tests/unit/attachment/insert.js
@@ -0,0 +1,34 @@
+'use strict';
+
+var helpers = require('../../helpers/unit');
+var insertAttachment = helpers.unit(['attachment', 'insert']);
+
+var buffer = new Buffer(helpers.pixel, 'base64');
+
+insertAttachment('pixels', 'pixel.bmp', buffer, 'image/bmp', {
+  body: buffer,
+  headers: {
+    'content-type': 'image/bmp'
+  },
+  method: 'PUT',
+  uri: '/mock/pixels/pixel.bmp'
+});
+
+insertAttachment('pixels', 'meta.txt', 'brown', 'text/plain', {
+  body: 'brown',
+  headers: {
+    'content-type': 'text/plain'
+  },
+  method: 'PUT',
+  uri: '/mock/pixels/meta.txt'
+});
+
+insertAttachment('pixels', 'meta.txt', 'white', 'text/plain', {rev: '2'}, {
+  body: 'white',
+  headers: {
+    'content-type': 'text/plain'
+  },
+  method: 'PUT',
+  uri: '/mock/pixels/meta.txt',
+  qs: {rev: '2'}
+});
diff --git a/tests/unit/database/changes.js b/tests/unit/database/changes.js
new file mode 100644
index 0000000..75e2bca
--- /dev/null
+++ b/tests/unit/database/changes.js
@@ -0,0 +1,25 @@
+'use strict';
+
+var changesDatabase = require('../../helpers/unit').unit([
+  'database',
+  'changes'
+]);
+
+changesDatabase('mock', {since: '10'}, {
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'GET',
+  qs: {since: '10'},
+  uri: '/mock/_changes'
+});
+
+changesDatabase('mock', {
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'GET',
+  uri: '/mock/_changes'
+});
diff --git a/tests/unit/database/compact.js b/tests/unit/database/compact.js
new file mode 100644
index 0000000..14688c3
--- /dev/null
+++ b/tests/unit/database/compact.js
@@ -0,0 +1,15 @@
+'use strict';
+
+var compactDatabase = require('../../helpers/unit').unit([
+  'database',
+  'compact'
+]);
+
+compactDatabase('mock', {
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'POST',
+  uri: '/mock/_compact'
+});
diff --git a/tests/unit/database/create.js b/tests/unit/database/create.js
new file mode 100644
index 0000000..b238956
--- /dev/null
+++ b/tests/unit/database/create.js
@@ -0,0 +1,24 @@
+'use strict';
+
+var createDatabase = require('../../helpers/unit').unit([
+  'database',
+  'create'
+]);
+
+createDatabase('mock', {
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'PUT',
+  uri: '/mock'
+});
+
+createDatabase('az09_$()+-/', {
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'PUT',
+  uri: '/az09_%24()%2B-%2F'
+});
diff --git a/tests/unit/database/destroy.js b/tests/unit/database/destroy.js
new file mode 100644
index 0000000..9ba02b1
--- /dev/null
+++ b/tests/unit/database/destroy.js
@@ -0,0 +1,15 @@
+'use strict';
+
+var destroyDatabase = require('../../helpers/unit').unit([
+  'database',
+  'destroy'
+]);
+
+destroyDatabase('mock', {
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'DELETE',
+  uri: '/mock'
+});
diff --git a/tests/unit/database/follow.js b/tests/unit/database/follow.js
new file mode 100644
index 0000000..73a18c8
--- /dev/null
+++ b/tests/unit/database/follow.js
@@ -0,0 +1,8 @@
+'use strict';
+
+var followDatabase = require('../../helpers/unit').unit([
+  'database',
+  'follow'
+]);
+
+followDatabase('space', {db: '/space'});
diff --git a/tests/unit/database/get.js b/tests/unit/database/get.js
new file mode 100644
index 0000000..3faa1df
--- /dev/null
+++ b/tests/unit/database/get.js
@@ -0,0 +1,15 @@
+'use strict';
+
+var getDatabase = require('../../helpers/unit').unit([
+  'database',
+  'get'
+]);
+
+getDatabase('space', {
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'GET',
+  uri: '/space'
+});
diff --git a/tests/unit/database/list.js b/tests/unit/database/list.js
new file mode 100644
index 0000000..1579d00
--- /dev/null
+++ b/tests/unit/database/list.js
@@ -0,0 +1,15 @@
+'use strict';
+
+var listDatabases = require('../../helpers/unit').unit([
+  'database',
+  'list'
+]);
+
+listDatabases({
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'GET',
+  uri: '/_all_dbs'
+});
diff --git a/tests/unit/database/replicate.js b/tests/unit/database/replicate.js
new file mode 100644
index 0000000..87c3196
--- /dev/null
+++ b/tests/unit/database/replicate.js
@@ -0,0 +1,26 @@
+'use strict';
+
+var replicateDatabase = require('../../helpers/unit').unit([
+  'database',
+  'replicate'
+]);
+
+replicateDatabase('baa', 'baashep', {
+  body: '{"source":"baa","target":"baashep"}',
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'POST',
+  uri: '/_replicate'
+});
+
+replicateDatabase('molly', 'anne', {some: 'params'}, {
+  body: '{"some":"params","source":"molly","target":"anne"}',
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'POST',
+  uri: '/_replicate'
+});
diff --git a/tests/unit/database/updates.js b/tests/unit/database/updates.js
new file mode 100644
index 0000000..f5bb3e1
--- /dev/null
+++ b/tests/unit/database/updates.js
@@ -0,0 +1,25 @@
+'use strict';
+
+var updatesDatabase = require('../../helpers/unit').unit([
+  'database',
+  'updates'
+]);
+
+updatesDatabase({
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'GET',
+  uri: '/_db_updates'
+});
+
+updatesDatabase({since: 1}, {
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'GET',
+  qs: {since: 1},
+  uri: '/_db_updates'
+});
diff --git a/tests/unit/design/atomic.js b/tests/unit/design/atomic.js
new file mode 100644
index 0000000..0829314
--- /dev/null
+++ b/tests/unit/design/atomic.js
@@ -0,0 +1,19 @@
+'use strict';
+
+var atomicDesign = require('../../helpers/unit').unit([
+  'view',
+  'atomic'
+]);
+
+atomicDesign('update', 'inplace', 'foobar', {
+    field: 'foo',
+    value: 'bar'
+  }, {
+  body: '{"field":"foo","value":"bar"}',
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'PUT',
+  uri: '/mock/_design/update/_update/inplace/foobar'
+});
diff --git a/tests/unit/design/compact.js b/tests/unit/design/compact.js
new file mode 100644
index 0000000..cbb3c9b
--- /dev/null
+++ b/tests/unit/design/compact.js
@@ -0,0 +1,15 @@
+'use strict';
+
+var compactDesign = require('../../helpers/unit').unit([
+  'view',
+  'compact'
+]);
+
+compactDesign('alice', {
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'POST',
+  uri: '/mock/_compact/alice'
+});
diff --git a/tests/unit/design/list.js b/tests/unit/design/list.js
new file mode 100644
index 0000000..e48ece7
--- /dev/null
+++ b/tests/unit/design/list.js
@@ -0,0 +1,23 @@
+'use strict';
+
+var listDesign = require('../../helpers/unit').unit([
+  'view',
+  'viewWithList'
+]);
+
+listDesign('people', 'by_name_and_city', 'my_list', {
+    key: [
+      'Derek',
+      'San Francisco'
+    ]
+  }, {
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'GET',
+  qs: {
+    'key': '["Derek","San Francisco"]'
+  },
+  uri: '/mock/_design/people/_list/my_list/by_name_and_city'
+});
diff --git a/tests/unit/design/search.js b/tests/unit/design/search.js
new file mode 100644
index 0000000..977577f
--- /dev/null
+++ b/tests/unit/design/search.js
@@ -0,0 +1,18 @@
+'use strict';
+
+var searchDesign = require('../../helpers/unit').unit([
+  'view',
+  'search'
+]);
+
+searchDesign('alice', 'by_id', {
+  keys: 'dawg'
+}, {
+  body: '{"keys":"dawg"}',
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'POST',
+  uri: '/mock/_design/alice/_search/by_id'
+});
diff --git a/tests/unit/design/show.js b/tests/unit/design/show.js
new file mode 100644
index 0000000..c184865
--- /dev/null
+++ b/tests/unit/design/show.js
@@ -0,0 +1,15 @@
+'use strict';
+
+var showDesign = require('../../helpers/unit').unit([
+  'view',
+  'show'
+]);
+
+showDesign('people', 'singleDoc', 'p_clemens', {
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'GET',
+  uri: '/mock/_design/people/_show/singleDoc/p_clemens'
+});
diff --git a/tests/unit/design/spatial.js b/tests/unit/design/spatial.js
new file mode 100644
index 0000000..7e5810b
--- /dev/null
+++ b/tests/unit/design/spatial.js
@@ -0,0 +1,16 @@
+'use strict';
+
+var geoDesign = require('../../helpers/unit').unit([
+  'view',
+  'spatial'
+]);
+
+geoDesign('people', 'byArea', {x: '1'}, {
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'GET',
+  qs: {x: '1'},
+  uri: '/mock/_design/people/_spatial/byArea'
+});
diff --git a/tests/unit/design/view.js b/tests/unit/design/view.js
new file mode 100644
index 0000000..1f80a63
--- /dev/null
+++ b/tests/unit/design/view.js
@@ -0,0 +1,22 @@
+'use strict';
+
+var viewDesign = require('../../helpers/unit').unit([
+  'view',
+  'view'
+]);
+
+viewDesign('alice', 'by_id', {
+  keys: ['foobar', 'barfoo'],
+  'include_docs': true
+}, {
+  body: '{"keys":["foobar","barfoo"]}',
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'POST',
+  qs: {
+    'include_docs': true
+  },
+  uri: '/mock/_design/alice/_view/by_id'
+});
diff --git a/tests/unit/document/bulk.js b/tests/unit/document/bulk.js
new file mode 100644
index 0000000..6727a48
--- /dev/null
+++ b/tests/unit/document/bulk.js
@@ -0,0 +1,34 @@
+'use strict';
+
+var bulkDocument = require('../../helpers/unit').unit([
+  'document',
+  'bulk'
+]);
+
+bulkDocument({
+  docs: [
+    {key: 'baz', name: 'bazzel'},
+    {key: 'bar', name: 'barry'}
+  ]
+}, {
+  body: '{"docs":[{"key":"baz","name":"bazzel"},{"key":"bar","name":"barry"}]}',
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'POST',
+  uri: '/mock/_bulk_docs'
+});
+
+bulkDocument({
+  docs: []
+}, {wat: 'izlove'}, {
+  body: '{"docs":[]}',
+  headers: {
+    accept: 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'POST',
+  qs: {wat: 'izlove'},
+  uri: '/mock/_bulk_docs'
+});
diff --git a/tests/unit/document/copy.js b/tests/unit/document/copy.js
new file mode 100644
index 0000000..822cefc
--- /dev/null
+++ b/tests/unit/document/copy.js
@@ -0,0 +1,25 @@
+'use strict';
+
+var copyDocument = require('../../helpers/unit').unit([
+  'document',
+  'copy'
+]);
+
+var copyDocumentFail = require('../../helpers/unit').unit([
+  'document',
+  'copy'
+], new Error('OMG This sucks'));
+
+copyDocument('excel', 'numbers', {
+  headers: {
+    'Destination': 'numbers',
+    'accept': 'application/json',
+    'content-type': 'application/json'
+  },
+  method: 'COPY',
+  uri: '/mock/excel'
+});
+
+copyDocumentFail('excel', 'numbers', {overwrite: 'yes'}, {
+
+});
diff --git a/tests/unit/multipart/get.js b/tests/unit/multipart/get.js
new file mode 100644
index 0000000..68d2c51
--- /dev/null
+++ b/tests/unit/multipart/get.js
@@ -0,0 +1,14 @@
+'use strict';
+
+var getMultipart = require('../../helpers/unit').unit([
+  'multipart',
+  'get'
+]);
+
+getMultipart('space', {extra: 'stuff'}, {
+  encoding: null,
+  headers: {'content-type': 'multipart/related'},
+  method: 'GET',
+  qs: {attachments: true, extra: 'stuff'},
+  uri: '/mock/space'
+});
diff --git a/tests/unit/multipart/insert.js b/tests/unit/multipart/insert.js
new file mode 100644
index 0000000..be197bf
--- /dev/null
+++ b/tests/unit/multipart/insert.js
@@ -0,0 +1,26 @@
+'use strict';
+
+var insertMultipart = require('../../helpers/unit').unit([
+  'multipart',
+  'insert'
+]);
+
+insertMultipart({hey: 1}, [{
+    name: 'att',
+    data: 'some',
+    'content_type': 'text/plain'
+  }], {extra: 'stuff'}, {
+  headers: {
+    'content-type': 'multipart/related'
+  },
+  method: 'PUT',
+  multipart: [
+    {
+      body: '{"_attachments":{"att":{"follows":true,"length":4}},"hey":1}',
+      'content-type': 'application/json'
+    },
+    {body: 'some'}
+  ],
+  qs: {extra: 'stuff'},
+  uri: '/mock'
+});
diff --git a/tests/unit/shared/error.js b/tests/unit/shared/error.js
new file mode 100644
index 0000000..67d7eeb
--- /dev/null
+++ b/tests/unit/shared/error.js
@@ -0,0 +1,45 @@
+'use strict';
+
+var helpers = require('../../helpers/unit');
+var test  = require('tape');
+var debug = require('debug')('nano/tests/unit/shared/error');
+
+var cli = helpers.mockClientFail(debug);
+var cli2 = helpers.mockClientUnparsedError(debug);
+var cli3 = helpers.mockClientUnparsedError(debug, JSON.stringify({
+  error: 'not a reason'
+}));
+
+var cli4 = helpers.mockClientUnparsedError(debug, JSON.stringify({
+  stack: new Error('foo').stack
+}));
+
+test('it should be able to set a jar box', function(assert) {
+  cli.relax({}, function(err) {
+    assert.equal(err.message, 'error happened in your connection');
+    assert.end();
+  });
+});
+
+test('should be able to deal with html errors bad couches', function(assert) {
+  cli2.relax({}, function(err) {
+    assert.equal(err.message, '<b> Error happened </b>');
+    assert.end();
+  });
+});
+
+test('should be capable of using `error`', function(assert) {
+  cli3.relax({}, function(err) {
+    assert.equal(err.message, 'not a reason');
+    assert.end();
+  });
+});
+
+test('should remove cloudant stacktraces', function(assert) {
+  cli4.relax({}, function(err) {
+    var msg = err.stack.split('\n')[0];
+    assert.notEqual(msg, 'Error: foo');
+    assert.equal(msg, 'Error: Unspecified error');
+    assert.end();
+  });
+});
diff --git a/tests/unit/shared/follow-updates.js b/tests/unit/shared/follow-updates.js
new file mode 100644
index 0000000..e48a002
--- /dev/null
+++ b/tests/unit/shared/follow-updates.js
@@ -0,0 +1,9 @@
+'use strict';
+
+var followUpdates = require('../../helpers/unit').unit([
+  'server',
+  'followUpdates'
+]);
+
+followUpdates({db: '/_db_updates'});
+followUpdates({since: 1}, {db: '/_db_updates', since: 1});
diff --git a/tests/unit/shared/jar.js b/tests/unit/shared/jar.js
new file mode 100644
index 0000000..affd9aa
--- /dev/null
+++ b/tests/unit/shared/jar.js
@@ -0,0 +1,18 @@
+'use strict';
+
+var helpers = require('../../helpers/unit');
+var test  = require('tape');
+var debug = require('debug')('nano/tests/unit/shared/jar');
+
+var cli = helpers.mockClientJar(debug);
+
+test('it should be able to set a jar box', function(assert) {
+  assert.equal(cli.config.jar, 'is set');
+  cli.relax({}, function(_, req) {
+    assert.equal(req.jar, 'is set');
+    cli.relax({jar: 'changed'}, function(_, req) {
+      assert.equal(req.jar, 'changed');
+      assert.end();
+    });
+  });
+});