You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by gl...@apache.org on 2020/02/12 11:25:48 UTC

[couchdb-nano] branch jest created (now 4d1122a)

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

glynnbird pushed a change to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git.


      at 4d1122a  standard styling of examples

This branch includes the following new commits:

     new 29773e1  use new url.URL instead of url.parse/url.reslove
     new 563e7d8  remove mocha tests
     new 5fbf353  add jest framework. Remove tape/mocha/istanbul.
     new 92163e6  first jest tests
     new ea90dc1  finished top level tests
     new 286db83  document tests complete
     new 47c985b  design functions
     new bb5428f  multipart tests
     new c472a7e  attachment tests
     new e033ba0  tidy up
     new 21597ff  auth/session/uuids
     new 35ede5e  100% coverage
     new 62e318f  partitioned functions and tests
     new a7ba759  tidy up
     new 4d1122a  standard styling of examples

The 15 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.



[couchdb-nano] 07/15: design functions

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit 47c985b042fb80c4fd05ba318b99d794c2ba0edd
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Fri Feb 7 10:18:49 2020 +0000

    design functions
---
 lib/nano.js                        |  53 ++++++++++--
 test/design.atomic.test.js         |  94 +++++++++++++++++++++
 test/design.createIndex.test.js    |  82 +++++++++++++++++++
 test/design.find.test.js           |  83 +++++++++++++++++++
 test/design.findAsStream.test.js   |  56 +++++++++++++
 test/design.search.test.js         |  72 ++++++++++++++++
 test/design.searchAsStream.test.js |  46 +++++++++++
 test/design.show.test.js           |  66 +++++++++++++++
 test/design.view.test.js           | 164 +++++++++++++++++++++++++++++++++++++
 test/design.viewAsStream.test.js   |  43 ++++++++++
 10 files changed, 753 insertions(+), 6 deletions(-)

diff --git a/lib/nano.js b/lib/nano.js
index 7b63bc3..6af0e37 100644
--- a/lib/nano.js
+++ b/lib/nano.js
@@ -677,8 +677,8 @@ module.exports = exports = function dbScope (cfg) {
       const { opts, callback } = getCallback(qs0, callback0)
 
       if (!docNames || typeof docNames !== 'object' ||
-      !docNames.keys || !Array.isArray(docNames.keys) ||
-      docNames.keys.length === 0) {
+          !docNames.keys || !Array.isArray(docNames.keys) ||
+          docNames.keys.length === 0) {
         const e = new Error('Invalid keys')
         if (callback) {
           return callback(e, null)
@@ -698,6 +698,15 @@ module.exports = exports = function dbScope (cfg) {
     function view (ddoc, viewName, meta, qs0, callback0) {
       const { opts, callback } = getCallback(qs0, callback0)
 
+      if (!ddoc || !viewName) {
+        const e = new Error('Invalid view')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
+
       if (typeof meta.stream !== 'boolean') {
         meta.stream = false
       }
@@ -776,6 +785,14 @@ module.exports = exports = function dbScope (cfg) {
 
     // http://docs.couchdb.org/en/latest/api/ddoc/render.html#get--db-_design-ddoc-_show-func
     function showDoc (ddoc, viewName, docName, qs, callback) {
+      if (!ddoc || !viewName || !docName) {
+        const e = new Error('Invalid show')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
       return view(ddoc, viewName + '/' + docName, { type: 'show' }, qs, callback)
     }
 
@@ -785,6 +802,14 @@ module.exports = exports = function dbScope (cfg) {
         callback = body
         body = undefined
       }
+      if (!ddoc || !viewName || !docName) {
+        const e = new Error('Invalid update')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
       return view(ddoc, viewName + '/' + encodeURIComponent(docName), {
         type: 'update',
         method: 'PUT',
@@ -925,26 +950,42 @@ module.exports = exports = function dbScope (cfg) {
       }, callback)
     }
 
-    function find (selector, callback) {
+    function find (query, callback) {
+      if (!query || typeof query !== 'object') {
+        const e = new Error('Invalid query')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
       return relax({
         db: dbName,
         path: '_find',
         method: 'POST',
-        body: selector
+        body: query
       }, callback)
     }
 
-    function findAsStream (selector) {
+    function findAsStream (query) {
       return relax({
         db: dbName,
         path: '_find',
         method: 'POST',
-        body: selector,
+        body: query,
         stream: true
       })
     }
 
     function createIndex (indexDef, callback) {
+      if (!indexDef || typeof indexDef !== 'object') {
+        const e = new Error('Invalid index definition')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
       return relax({
         db: dbName,
         path: '_index',
diff --git a/test/design.atomic.test.js b/test/design.atomic.test.js
new file mode 100644
index 0000000..95c37fa
--- /dev/null
+++ b/test/design.atomic.test.js
@@ -0,0 +1,94 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to use an update function - PUT /db/_design/ddoc/_update/updatename/docid - db.atomic', async () => {
+  const updateFunction = function (doc, req) {
+    if (doc) {
+      doc.ts = new Date().getTime()
+    }
+    return [doc, { json: { status: 'ok' } }]
+  }
+  const response = updateFunction({})[1].json
+
+  // mocks
+  const scope = nock(COUCH_URL)
+    .put('/db/_design/ddoc/_update/updatename/docid')
+    .reply(200, response)
+
+  // test POST /db/_find
+  const db = nano.db.use('db')
+  const p = await db.atomic('ddoc', 'updatename', 'docid')
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to use an update function with body - PUT /db/_design/ddoc/_update/updatename/docid - db.atomic', async () => {
+  const updateFunction = function (doc, req) {
+    if (doc) {
+      doc.ts = new Date().getTime()
+    }
+    return [doc, { json: { status: 'ok' } }]
+  }
+  const body = { a: 1, b: 2 }
+  const response = updateFunction({})[1].json
+
+  // mocks
+  const scope = nock(COUCH_URL)
+    .put('/db/_design/ddoc/_update/updatename/docid', body)
+    .reply(200, response)
+
+  // test POST /db/_find
+  const db = nano.db.use('db')
+  const p = await db.atomic('ddoc', 'updatename', 'docid', body)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 404 - db.atomic', async () => {
+  // mocks
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const body = { a: 1, b: 2 }
+  const scope = nock(COUCH_URL)
+    .put('/db/_design/ddoc/_update/updatename/docid', body)
+    .reply(404, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  await expect(db.atomic('ddoc', 'updatename', 'docid', body)).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing parameters - db.update', async () => {
+  const db = nano.db.use('db')
+  await expect(db.atomic()).rejects.toThrow('Invalid update')
+  await expect(db.atomic('ddoc')).rejects.toThrow('Invalid update')
+  await expect(db.atomic('ddoc', 'updatename')).rejects.toThrow('Invalid update')
+  await expect(db.atomic('', 'updatename', 'docid')).rejects.toThrow('Invalid update')
+})
+
+test('should detect missing parameters (callback) - db.update', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.atomic('', '', '', {}, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/design.createIndex.test.js b/test/design.createIndex.test.js
new file mode 100644
index 0000000..1c7e7a5
--- /dev/null
+++ b/test/design.createIndex.test.js
@@ -0,0 +1,82 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to create an index - POST /db/_index - db.index', async () => {
+  // mocks
+  const indexDef = {
+    index: {
+      fields: ['town', 'surname']
+    },
+    type: 'json',
+    name: 'townsurnameindex',
+    partitioned: false
+  }
+  const response = {
+    result: 'created',
+    id: '_design/a5f4711fc9448864a13c81dc71e660b524d7410c',
+    name: 'foo-index'
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_index', indexDef)
+    .reply(200, response)
+
+  // test POST /db/_index
+  const db = nano.db.use('db')
+  const p = await db.createIndex(indexDef)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should handle 404 - POST /db/_index - db.index', async () => {
+  // mocks
+  const indexDef = {
+    index: {
+      fields: ['town', 'surname']
+    },
+    type: 'json',
+    name: 'townsurnameindex',
+    partitioned: false
+  }
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_index', indexDef)
+    .reply(404, response)
+
+  // test POST /db/_index
+  const db = nano.db.use('db')
+  await expect(db.createIndex(indexDef)).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing index - db.createIndex', async () => {
+  const db = nano.db.use('db')
+  await expect(db.createIndex()).rejects.toThrow('Invalid index definition')
+  await expect(db.createIndex('myindex')).rejects.toThrow('Invalid index definition')
+})
+
+test('should detect missing index (callback) - db.createIndex', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.createIndex('', (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/design.find.test.js b/test/design.find.test.js
new file mode 100644
index 0000000..39bf9d3
--- /dev/null
+++ b/test/design.find.test.js
@@ -0,0 +1,83 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to query an index - POST /db/_find - db.find', async () => {
+  // mocks
+  const query = {
+    selector: {
+      $and: {
+        date: {
+          $gt: '2018'
+        },
+        name: 'Susan'
+      }
+    },
+    fields: ['name', 'date', 'orderid']
+  }
+  const response = {
+    docs: [
+      { name: 'Susan', date: '2019-01-02', orderid: '4411' },
+      { name: 'Susan', date: '2019-01-03', orderid: '8523' }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_find', query)
+    .reply(200, response)
+
+  // test POST /db/_find
+  const db = nano.db.use('db')
+  const p = await db.find(query)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should handle 404 - POST /db/_find - db.find', async () => {
+  // mocks
+  const query = {
+    selector: {
+      name: 'Susan'
+    }
+  }
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_find', query)
+    .reply(404, response)
+
+  // test POST /db/_find
+  const db = nano.db.use('db')
+  await expect(db.find(query)).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing query - db.find', async () => {
+  const db = nano.db.use('db')
+  await expect(db.find()).rejects.toThrow('Invalid query')
+  await expect(db.find('susan')).rejects.toThrow('Invalid query')
+})
+
+test('should detect missing query (callback) - db.find', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.find('', (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/design.findAsStream.test.js b/test/design.findAsStream.test.js
new file mode 100644
index 0000000..b330779
--- /dev/null
+++ b/test/design.findAsStream.test.js
@@ -0,0 +1,56 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to query an index as a stream- POST /db/_find - db.findAsStream', async () => {
+  // mocks
+  const query = {
+    selector: {
+      $and: {
+        date: {
+          $gt: '2018'
+        },
+        name: 'Susan'
+      }
+    },
+    fields: ['name', 'date', 'orderid']
+  }
+  const response = {
+    docs: [
+      { name: 'Susan', date: '2019-01-02', orderid: '4411' },
+      { name: 'Susan', date: '2019-01-03', orderid: '8523' }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_find', query)
+    .reply(200, response)
+
+  return new Promise((resolve, reject) => {
+    // test POST /db/_find
+    const db = nano.db.use('db')
+    const s = db.findAsStream(query)
+    expect(typeof s).toBe('object')
+    let buffer = ''
+    s.on('data', (chunk) => {
+      buffer += chunk.toString()
+    })
+    s.on('end', () => {
+      expect(buffer).toBe(JSON.stringify(response))
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
diff --git a/test/design.search.test.js b/test/design.search.test.js
new file mode 100644
index 0000000..92be672
--- /dev/null
+++ b/test/design.search.test.js
@@ -0,0 +1,72 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to access a search index - GET /db/_design/ddoc/_search/searchname - db.search', async () => {
+  // mocks
+  const response = {
+    total_rows: 100000,
+    bookmark: 'g123',
+    rows: [
+      { a: 1, b: 2 }
+    ]
+  }
+  const params = { q: '*:*' }
+  const scope = nock(COUCH_URL)
+    .post('/db/_design/ddoc/_search/searchname', params)
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.search('ddoc', 'searchname', params)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 404 - db.search', async () => {
+  // mocks
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const params = { q: '*:*' }
+  const scope = nock(COUCH_URL)
+    .post('/db/_design/ddoc/_search/searchname', params)
+    .reply(404, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  await expect(db.search('ddoc', 'searchname', params)).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing parameters - db.search', async () => {
+  const db = nano.db.use('db')
+  await expect(db.search()).rejects.toThrow('Invalid view')
+  await expect(db.search('susan')).rejects.toThrow('Invalid view')
+  await expect(db.search('susan', '')).rejects.toThrow('Invalid view')
+  await expect(db.search('', 'susan')).rejects.toThrow('Invalid view')
+})
+
+test('should detect missing parameters (callback) - db.search', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.search('', '', (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/design.searchAsStream.test.js b/test/design.searchAsStream.test.js
new file mode 100644
index 0000000..d86f35d
--- /dev/null
+++ b/test/design.searchAsStream.test.js
@@ -0,0 +1,46 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to access a search index as a stream - POST /db/_design/ddoc/_search/searchname - db.searchAsStream', async () => {
+  // mocks
+  const response = {
+    total_rows: 100000,
+    bookmark: 'g123',
+    rows: [
+      { a: 1, b: 2 }
+    ]
+  }
+  const params = { q: '*:*' }
+  const scope = nock(COUCH_URL)
+    .post('/db/_design/ddoc/_search/searchname', params)
+    .reply(200, response)
+
+  return new Promise((resolve, reject) => {
+    const db = nano.db.use('db')
+    const s = db.searchAsStream('ddoc', 'searchname', params)
+    expect(typeof s).toBe('object')
+    let buffer = ''
+    s.on('data', (chunk) => {
+      buffer += chunk.toString()
+    })
+    s.on('end', () => {
+      expect(buffer).toBe(JSON.stringify(response))
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
diff --git a/test/design.show.test.js b/test/design.show.test.js
new file mode 100644
index 0000000..258f1bb
--- /dev/null
+++ b/test/design.show.test.js
@@ -0,0 +1,66 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to use a show function - GET /db/_design/ddoc/_show/showname/docid - db.show', async () => {
+  const showFunction = function (doc, req) {
+    return 'Hello, world!'
+  }
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/_design/ddoc/_show/showname/docid')
+    .reply(200, showFunction(), { 'Content-type': 'text/plain' })
+
+  // test POST /db/_find
+  const db = nano.db.use('db')
+  const p = await db.show('ddoc', 'showname', 'docid')
+  expect(p).toStrictEqual(showFunction())
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 404 - db.show', async () => {
+  // mocks
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_design/ddoc/_show/showname/docid')
+    .reply(404, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  await expect(db.show('ddoc', 'showname', 'docid')).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing parameters - db.show', async () => {
+  const db = nano.db.use('db')
+  await expect(db.show()).rejects.toThrow('Invalid show')
+  await expect(db.show('ddoc')).rejects.toThrow('Invalid show')
+  await expect(db.show('ddoc', 'showname')).rejects.toThrow('Invalid show')
+  await expect(db.show('', 'showname', 'docid')).rejects.toThrow('Invalid show')
+})
+
+test('should detect missing parameters (callback) - db.show', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.show('', '', '', {}, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/design.view.test.js b/test/design.view.test.js
new file mode 100644
index 0000000..767b4f9
--- /dev/null
+++ b/test/design.view.test.js
@@ -0,0 +1,164 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to access a MapReduce view - GET /db/_design/ddoc/_view/viewname - db.view', async () => {
+  // mocks
+  const response = {
+    rows: [
+      { key: null, value: 23515 }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_design/ddoc/_view/viewname')
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.view('ddoc', 'viewname')
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to access a MapReduce view with opts - GET /db/_design/ddoc/_view/viewname - db.view', async () => {
+  // mocks
+  const response = {
+    rows: [
+      { key: 'BA', value: 21 },
+      { key: 'BB', value: 1 },
+      { key: 'BD', value: 98 },
+      { key: 'BE', value: 184 },
+      { key: 'BF', value: 32 },
+      { key: 'BG', value: 55 },
+      { key: 'BH', value: 8 },
+      { key: 'BI', value: 10 },
+      { key: 'BJ', value: 29 },
+      { key: 'BL', value: 1 },
+      { key: 'BM', value: 1 },
+      { key: 'BN', value: 4 },
+      { key: 'BO', value: 27 },
+      { key: 'BQ', value: 1 }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_design/ddoc/_view/viewname?group=true&startkey="BA"&endkey="BQ"')
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.view('ddoc', 'viewname', { group: true, startkey: 'BA', endkey: 'BQ' })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to access a MapReduce view with keys - POST /db/_design/ddoc/_view/viewname - db.view', async () => {
+  // mocks
+  const keys = ['BA', 'BD']
+  const response = {
+    rows: [
+      { key: 'BA', value: 21 },
+      { key: 'BB', value: 1 }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_design/ddoc/_view/viewname', { keys: keys })
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.view('ddoc', 'viewname', { keys: keys })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to access a MapReduce view with queries - POST /db/_design/ddoc/_view/viewname - db.view', async () => {
+  // mocks
+  const opts = {
+    queries: [
+      {
+        keys: [
+          'BA',
+          'BD'
+        ]
+      },
+      {
+        limit: 1,
+        skip: 2,
+        reduce: false
+      }
+    ]
+  }
+  const response = {
+    results: [
+      {
+        rows: [
+          { key: 'BA', value: 21 },
+          { key: 'BB', value: 1 }
+        ]
+      },
+      {
+        total_rows: 23515,
+        offset: 2,
+        rows: [
+          { id: '290594', key: 'AE', value: 1 }
+        ]
+      }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_design/ddoc/_view/viewname', { queries: opts.queries })
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.view('ddoc', 'viewname', opts)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 404 - db.view', async () => {
+  // mocks
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_design/ddoc/_view/viewname?group=true&startkey="BA"&endkey="BQ"')
+    .reply(404, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  await expect(db.view('ddoc', 'viewname', { group: true, startkey: 'BA', endkey: 'BQ' })).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing parameters - db.view', async () => {
+  const db = nano.db.use('db')
+  await expect(db.view()).rejects.toThrow('Invalid view')
+  await expect(db.view('susan')).rejects.toThrow('Invalid view')
+  await expect(db.view('susan', '')).rejects.toThrow('Invalid view')
+  await expect(db.view('', 'susan')).rejects.toThrow('Invalid view')
+})
+
+test('should detect missing parameters (callback) - db.view', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.view('', '', (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/design.viewAsStream.test.js b/test/design.viewAsStream.test.js
new file mode 100644
index 0000000..e332897
--- /dev/null
+++ b/test/design.viewAsStream.test.js
@@ -0,0 +1,43 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to access a MapReduce view as a stream - GET /db/_design/ddoc/_view/viewname - db.viewAsStream', async () => {
+  // mocks
+  const response = {
+    rows: [
+      { key: null, value: 23515 }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_design/ddoc/_view/viewname')
+    .reply(200, response)
+
+  return new Promise((resolve, reject) => {
+    const db = nano.db.use('db')
+    const s = db.viewAsStream('ddoc', 'viewname')
+    expect(typeof s).toBe('object')
+    let buffer = ''
+    s.on('data', (chunk) => {
+      buffer += chunk.toString()
+    })
+    s.on('end', () => {
+      expect(buffer).toBe(JSON.stringify(response))
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})


[couchdb-nano] 08/15: multipart tests

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit bb5428f0c532131675883c592e8b7c682149a10f
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Fri Feb 7 14:09:57 2020 +0000

    multipart tests
---
 lib/nano.js                   |  18 +++++++
 test/design.search.test.js    |   2 +-
 test/multipart.get.test.js    |  93 ++++++++++++++++++++++++++++++++++++
 test/multipart.insert.test.js | 108 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 220 insertions(+), 1 deletion(-)

diff --git a/lib/nano.js b/lib/nano.js
index 6af0e37..3bbf7bc 100644
--- a/lib/nano.js
+++ b/lib/nano.js
@@ -845,6 +845,15 @@ module.exports = exports = function dbScope (cfg) {
       const docName = qs.docName
       delete qs.docName
 
+      if (!doc || !attachments || !docName) {
+        const e = new Error('Invalid parameters')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
+
       doc = Object.assign({ _attachments: {} }, doc)
 
       const multipart = []
@@ -879,6 +888,15 @@ module.exports = exports = function dbScope (cfg) {
       const { opts, callback } = getCallback(qs0, callback0)
       opts.attachments = true
 
+      if (!docName) {
+        const e = new Error('Invalid parameters')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
+
       return relax({
         db: dbName,
         doc: docName,
diff --git a/test/design.search.test.js b/test/design.search.test.js
index 92be672..7be860c 100644
--- a/test/design.search.test.js
+++ b/test/design.search.test.js
@@ -15,7 +15,7 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
-test('should be able to access a search index - GET /db/_design/ddoc/_search/searchname - db.search', async () => {
+test('should be able to access a search index - POST /db/_design/ddoc/_search/searchname - db.search', async () => {
   // mocks
   const response = {
     total_rows: 100000,
diff --git a/test/multipart.get.test.js b/test/multipart.get.test.js
new file mode 100644
index 0000000..6383367
--- /dev/null
+++ b/test/multipart.get.test.js
@@ -0,0 +1,93 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+const multipartResponse = ''.concat(
+  '--e89b3e29388aef23453450d10e5aaed0',
+  'Content-Type: application/json',
+  '',
+  '{"_id":"secret","_rev":"2-c1c6c44c4bc3c9344b037c8690468605","_attachments":{"recipe.txt":{"content_type":"text/plain","revpos":2,"digest":"md5-HV9aXJdEnu0xnMQYTKgOFA==","length":86,"follows":true}}}',
+  '--e89b3e29388aef23453450d10e5aaed0',
+  'Content-Disposition: attachment; filename="recipe.txt"',
+  'Content-Type: text/plain',
+  'Content-Length: 86',
+  '',
+  '1. Take R',
+  '2. Take E',
+  '3. Mix with L',
+  '4. Add some A',
+  '5. Serve with X',
+  '',
+  '--e89b3e29388aef23453450d10e5aaed0--')
+
+test('should be able to fetch a document with attachments - multipart GET /db - db.multipart.get', async () => {
+  // mocks
+  const scope = nock(COUCH_URL, { reqheaders: { accept: 'multipart/related' } })
+    .get('/db/docid?attachments=true')
+    .reply(200, multipartResponse, { 'content-type': 'multipart/related; boundary="e89b3e29388aef23453450d10e5aaed0"' })
+
+  // test POST /db
+  const db = nano.db.use('db')
+  const p = await db.multipart.get('docid')
+  expect(p.toString()).toStrictEqual(multipartResponse)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to fetch a document with attachments with opts - multipart GET /db - db.multipart.get', async () => {
+  // mocks
+  const scope = nock(COUCH_URL, { reqheaders: { accept: 'multipart/related' } })
+    .get('/db/docid?attachments=true&conflicts=true')
+    .reply(200, multipartResponse, { 'content-type': 'multipart/related; boundary="e89b3e29388aef23453450d10e5aaed0"' })
+
+  // test POST /db
+  const db = nano.db.use('db')
+  const p = await db.multipart.get('docid', { conflicts: true })
+  expect(p.toString()).toStrictEqual(multipartResponse)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 404 - db.search', async () => {
+  // mocks
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL, { reqheaders: { accept: 'multipart/related' } })
+    .get('/db/docid?attachments=true')
+    .reply(404, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  await expect(db.multipart.get('docid')).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing docName - db.multipart.get', async () => {
+  const db = nano.db.use('db')
+  await expect(db.multipart.get()).rejects.toThrow('Invalid parameters')
+  await expect(db.multipart.get('')).rejects.toThrow('Invalid parameters')
+  await expect(db.multipart.get(undefined, { conflicts: true })).rejects.toThrow('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.multipart.get', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.multipart.get(undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/multipart.insert.test.js b/test/multipart.insert.test.js
new file mode 100644
index 0000000..2982bc5
--- /dev/null
+++ b/test/multipart.insert.test.js
@@ -0,0 +1,108 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+const image1 = Buffer.from(''.concat(
+  'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAsV',
+  'BMVEUAAAD////////////////////////5ur3rEBn////////////////wDBL/',
+  'AADuBAe9EB3IEBz/7+//X1/qBQn2AgP/f3/ilpzsDxfpChDtDhXeCA76AQH/v7',
+  '/84eLyWV/uc3bJPEf/Dw/uw8bRWmP1h4zxSlD6YGHuQ0f6g4XyQkXvCA36MDH6',
+  'wMH/z8/yAwX64ODeh47BHiv/Ly/20dLQLTj98PDXWmP/Pz//39/wGyJ7Iy9JAA',
+  'AADHRSTlMAbw8vf08/bz+Pv19jK/W3AAAAg0lEQVR4Xp3LRQ4DQRBD0QqTm4Y5',
+  'zMxw/4OleiJlHeUtv2X6RbNO1Uqj9g0RMCuQO0vBIg4vMFeOpCWIWmDOw82fZx',
+  'vaND1c8OG4vrdOqD8YwgpDYDxRgkSm5rwu0nQVBJuMg++pLXZyr5jnc1BaH4GT',
+  'LvEliY253nA3pVhQqdPt0f/erJkMGMB8xucAAAAASUVORK5CYII='), 'base64')
+const image2 = Buffer.from('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', 'base64')
+const images = [
+  { name: 'logo.jpg', data: image1, content_type: 'image/jpg' },
+  { name: 'transparent.gif', data: image2, content_type: 'image/gif' }
+]
+const doc = {
+  a: 1,
+  b: 2,
+  _attachments: {
+    'logo.jpg': {
+      follows: true,
+      content_type: 'image/jpg',
+      length: image1.length
+    },
+    'transparent.gif': {
+      follows: true,
+      content_type: 'image/gif',
+      length: image2.length
+    }
+  }
+}
+
+test('should be able to insert a document with attachments #1 - multipart POST /db - db.multipart.insert', async () => {
+  // mocks
+  const response = { ok: true, id: '8s8g8h8h9', rev: '1-123' }
+  const scope = nock(COUCH_URL, { reqheaders: { 'content-type': h => h.includes('multipart/related') } })
+    .put('/db/docid')
+    .reply(200, response)
+
+  // test POST /db
+  const db = nano.db.use('db')
+  const p = await db.multipart.insert(doc, images, 'docid')
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to insert a document with attachments #2 - multipart POST /db - db.multipart.insert', async () => {
+  const response = { ok: true, id: '8s8g8h8h9', rev: '1-123' }
+  const scope = nock(COUCH_URL, { reqheaders: { 'content-type': h => h.includes('multipart/related') } })
+    .put('/db/docid')
+    .reply(200, response)
+
+  // test POST /db
+  const db = nano.db.use('db')
+  const p = await db.multipart.insert(doc, images, { docName: 'docid' })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 404 - db.multipart.insert', async () => {
+  // mocks
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL, { reqheaders: { 'content-type': h => h.includes('multipart/related') } })
+    .put('/db/docid')
+    .reply(404, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  await expect(db.multipart.insert(doc, images, { docName: 'docid' })).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing docName - db.multipart.insert', async () => {
+  const db = nano.db.use('db')
+  await expect(db.multipart.insert()).rejects.toThrow('Invalid parameters')
+  await expect(db.multipart.insert({ a: 1 }, [{}])).rejects.toThrow('Invalid parameters')
+  await expect(db.multipart.insert({ a: 1 }, [{}], {})).rejects.toThrow('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.multipart.insert', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.multipart.insert(undefined, undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})


[couchdb-nano] 02/15: remove mocha tests

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit 563e7d807113b74024389e4292d0e15368d060cd
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Wed Feb 5 14:14:31 2020 +0000

    remove mocha tests
---
 tests/fixtures/attachment/destroy.json           |  29 ----
 tests/fixtures/attachment/get.json               |  32 ----
 tests/fixtures/attachment/insert.json            |  18 ---
 tests/fixtures/attachment/pipe.json              |  35 ----
 tests/fixtures/attachment/update.json            |  35 ----
 tests/fixtures/cfg.json                          |   4 -
 tests/fixtures/database/changes.json             |  42 -----
 tests/fixtures/database/compact.json             |  34 ----
 tests/fixtures/database/create-and-destroy.json  |  39 -----
 tests/fixtures/database/follow.json              |  30 ----
 tests/fixtures/database/get.json                 |  15 --
 tests/fixtures/database/list.json                |  15 --
 tests/fixtures/database/replicate.json           |  76 ---------
 tests/fixtures/database/replicator.json          | 117 --------------
 tests/fixtures/design/atomic.json                |  43 -----
 tests/fixtures/design/compact.json               |  38 -----
 tests/fixtures/design/list.json                  |  40 -----
 tests/fixtures/design/multiple.json              |  46 ------
 tests/fixtures/design/query.json                 |  50 ------
 tests/fixtures/design/search.json                |  12 --
 tests/fixtures/design/show.json                  |  44 -----
 tests/fixtures/document/bulk.json                |  16 --
 tests/fixtures/document/copy.json                |  43 -----
 tests/fixtures/document/create_index.json        |  24 ---
 tests/fixtures/document/destroy.json             |  21 ---
 tests/fixtures/document/fetch.json               |  45 ------
 tests/fixtures/document/fetch_revs.json          |  45 ------
 tests/fixtures/document/find.json                |  36 -----
 tests/fixtures/document/get.json                 |  20 ---
 tests/fixtures/document/head.json                |  25 ---
 tests/fixtures/document/insert.json              |  42 -----
 tests/fixtures/document/list.json                |  54 -------
 tests/fixtures/document/update.json              |  22 ---
 tests/fixtures/logo.png                          | Bin 5081 -> 0 bytes
 tests/fixtures/multipart/get.json                |  23 ---
 tests/fixtures/multipart/insert.json             |  50 ------
 tests/fixtures/shared/config.json                |  20 ---
 tests/fixtures/shared/cookie.json                |  35 ----
 tests/fixtures/shared/error.json                 |  19 ---
 tests/fixtures/shared/headers.json               |  29 ----
 tests/fixtures/shared/log.json                   |  11 --
 tests/fixtures/shared/nano.json                  |  11 --
 tests/fixtures/shared/updates.json               |  19 ---
 tests/fixtures/util/uuid.json                    |  22 ---
 tests/helpers/harness.js                         |  70 --------
 tests/helpers/index.js                           |  40 -----
 tests/helpers/integration.js                     | 194 -----------------------
 tests/helpers/unit.js                            | 167 -------------------
 tests/integration/attachment/destroy.js          |  46 ------
 tests/integration/attachment/get.js              |  44 -----
 tests/integration/attachment/insert.js           |  28 ----
 tests/integration/attachment/pipe.js             |  65 --------
 tests/integration/attachment/update.js           |  43 -----
 tests/integration/database/changes.js            |  61 -------
 tests/integration/database/compact.js            |  64 --------
 tests/integration/database/create-and-destroy.js |  62 --------
 tests/integration/database/follow.js             |  50 ------
 tests/integration/database/get.js                |  48 ------
 tests/integration/database/list.js               |  56 -------
 tests/integration/database/replicate.js          |  80 ----------
 tests/integration/database/replicator.js         | 140 ----------------
 tests/integration/design/atomic.js               |  77 ---------
 tests/integration/design/compact.js              |  42 -----
 tests/integration/design/list.js                 |  37 -----
 tests/integration/design/multiple.js             |  78 ---------
 tests/integration/design/query.js                |  73 ---------
 tests/integration/design/search.js               |  49 ------
 tests/integration/design/show.js                 |  99 ------------
 tests/integration/document/bulk.js               |  37 -----
 tests/integration/document/copy.js               |  66 --------
 tests/integration/document/create_index.js       |  35 ----
 tests/integration/document/destroy.js            |  54 -------
 tests/integration/document/fetch.js              |  59 -------
 tests/integration/document/fetch_revs.js         |  63 --------
 tests/integration/document/find.js               |  50 ------
 tests/integration/document/get.js                |  34 ----
 tests/integration/document/head.js               |  40 -----
 tests/integration/document/insert.js             |  82 ----------
 tests/integration/document/list.js               | 130 ---------------
 tests/integration/document/update.js             |  46 ------
 tests/integration/multipart/get.js               |  49 ------
 tests/integration/multipart/insert.js            |  77 ---------
 tests/integration/shared/config.js               | 141 ----------------
 tests/integration/shared/cookie.js               |  59 -------
 tests/integration/shared/error.js                |  55 -------
 tests/integration/shared/headers.js              |  46 ------
 tests/integration/shared/log.js                  |  29 ----
 tests/integration/util/uuid.js                   |  46 ------
 tests/intercept/design/search.js                 |  65 --------
 tests/unit/attachment/destroy.js                 |  28 ----
 tests/unit/attachment/get.js                     |  33 ----
 tests/unit/attachment/insert.js                  |  46 ------
 tests/unit/database/changes.js                   |  37 -----
 tests/unit/database/compact.js                   |  27 ----
 tests/unit/database/create.js                    |  36 -----
 tests/unit/database/destroy.js                   |  27 ----
 tests/unit/database/follow.js                    |  20 ---
 tests/unit/database/get.js                       |  27 ----
 tests/unit/database/list.js                      |  27 ----
 tests/unit/database/replicate.js                 |  38 -----
 tests/unit/database/replicator.js                |  38 -----
 tests/unit/database/updates.js                   |  37 -----
 tests/unit/design/atomic.js                      |  31 ----
 tests/unit/design/compact.js                     |  27 ----
 tests/unit/design/find.js                        |  31 ----
 tests/unit/design/list.js                        |  35 ----
 tests/unit/design/search.js                      |  30 ----
 tests/unit/design/show.js                        |  27 ----
 tests/unit/design/view.js                        |  50 ------
 tests/unit/document/bulk.js                      |  46 ------
 tests/unit/document/copy.js                      |  37 -----
 tests/unit/document/get.js                       |  41 -----
 tests/unit/document/head.js                      |  37 -----
 tests/unit/multipart/get.js                      |  26 ---
 tests/unit/multipart/insert.js                   |  41 -----
 tests/unit/shared/error.js                       |  57 -------
 tests/unit/shared/follow-updates.js              |  21 ---
 tests/unit/shared/jar.js                         |  30 ----
 118 files changed, 5390 deletions(-)

diff --git a/tests/fixtures/attachment/destroy.json b/tests/fixtures/attachment/destroy.json
deleted file mode 100644
index 20491f2..0000000
--- a/tests/fixtures/attachment/destroy.json
+++ /dev/null
@@ -1,29 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/attachment_destroy"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/attachment_destroy/new/att"
-  , "body"     : "Hello World!"
-  , "status"   : 201
-  , "response" : "{\"ok\": true, \"id\": \"new\", \"rev\": \"1-921bd51\" }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/attachment_destroy/new/att?rev=1-921bd51"
-  , "response" : "{ \"ok\": true, \"id\": \"new\" }"
-  , "status"   : 201
-  }
-, { "method"   : "put"
-  , "path"     : "/attachment_destroy/new2/att2"
-  , "body"     : "Hello World!"
-  , "status"   : 201
-  , "response" : "{\"ok\": true, \"id\": \"new\", \"rev\": \"1-921bd51\" }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/attachment_destroy"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/attachment/get.json b/tests/fixtures/attachment/get.json
deleted file mode 100644
index 3c4381c..0000000
--- a/tests/fixtures/attachment/get.json
+++ /dev/null
@@ -1,32 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/attachment_get"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/attachment_get/new_string/att"
-  , "body"     : "Hello"
-  , "status"   : 201
-  , "response" : "{\"ok\":true,\"id\":\"new_string\",\"rev\":\"1-5142a2\"}"
-  }
-, { "path"     : "/attachment_get/new_string/att"
-  , "status"   : 200
-  , "response" : "Hello"
-  }
-, { "method"   : "put"
-  , "path"     : "/attachment_get/new_binary/att"
-  , "base64"   : "MTIz"
-  , "status"   : 201
-  , "response" : "{\"ok\":true,\"id\":\"new_binary\",\"rev\":\"1-5142ff\"}"
-  }
-, { "path"     : "/attachment_get/new_binary/att"
-  , "status"   : 200
-  , "buffer"   : "MTIz"
-  }
-, { "method"   : "delete"
-  , "path"     : "/attachment_get"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/attachment/insert.json b/tests/fixtures/attachment/insert.json
deleted file mode 100644
index d167435..0000000
--- a/tests/fixtures/attachment/insert.json
+++ /dev/null
@@ -1,18 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/attachment_insert"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/attachment_insert/new/att"
-  , "body"     : "Hello World!"
-  , "status"   : 201
-  , "response" : "{\"ok\": true, \"id\": \"new\", \"rev\": \"1-921bd51\" }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/attachment_insert"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/attachment/pipe.json b/tests/fixtures/attachment/pipe.json
deleted file mode 100644
index ba58014..0000000
--- a/tests/fixtures/attachment/pipe.json
+++ /dev/null
@@ -1,35 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/attachment_pipe"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/attachment_pipe/new/att"
-  , "body"     : "*"
-  , "status"   : 201
-  , "response" : "{\"ok\":true,\"id\":\"new\",\"rev\":\"1-3b1f88\"}\n"
-  }
-, { "path"     : "/attachment_pipe/new/att?rev=1-3b1f88"
-  , "status"   : 200
-  , "buffer"   : "Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BABgAAAAAAAAAAAATCwAAEwsAAAAAAAAAAAAAWm2CAA=="
-  }
-, { "path"     : "/attachment_pipe/new/att"
-  , "status"   : 200
-  , "buffer"   : "Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BABgAAAAAAAAAAAATCwAAEwsAAAAAAAAAAAAAWm2CAA=="
-  }
-, { "method"   : "put"
-  , "path"     : "/attachment_pipe/nodejs/logo.png"
-  , "body"     : "*"
-  , "response" : "{ \"ok\": true, \"id\": \"new\", \"rev\": \"1-64b327\" }"
-  }
-, { "method"   : "get"
-  , "path"     : "/attachment_pipe/nodejs/logo.png"
-  , "buffer"   : "logo.png"
-  }
-, { "method"   : "delete"
-  , "path"     : "/attachment_pipe"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/attachment/update.json b/tests/fixtures/attachment/update.json
deleted file mode 100644
index c66111c..0000000
--- a/tests/fixtures/attachment/update.json
+++ /dev/null
@@ -1,35 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/attachment_update"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/attachment_update/new/att"
-  , "body"     : "Hello"
-  , "status"   : 201
-  , "response" : "{\"ok\":true,\"id\":\"new\",\"rev\":\"1-5142a2\"}"
-  }
-, { "method"   : "put"
-  , "path"     : "/attachment_update/new/att?rev=1-5142a2"
-  , "body"     : "*"
-  , "status"   : 201
-  , "response" : "{\"ok\":true,\"id\":\"new\",\"rev\":\"2-3b1f88\"}\n"
-  }
-, { "method"   : "get"
-  , "path"     : "/attachment_update/new"
-  , "status"   : 200
-  , "response" : "{ \"_id\": \"new\", \"_rev\": \"2-3b1f88\", \"_attachments\": { \"att\": { \"content_type\": \"image/bmp\", \"revpos\": 2, \"digest\": \"md5-Ow9j2dR0Qm58Qi3z8p2w3A==\", \"length\": 58, \"stub\": true }}}"
-  }
-, { "method"   : "put"
-  , "path"     : "/attachment_update/new"
-  , "status"   : 201
-  , "body"     : "{\"_id\":\"new\",\"_rev\":\"2-3b1f88\",\"_attachments\":{\"att\":{\"content_type\":\"image/bmp\",\"revpos\":2,\"digest\":\"md5-Ow9j2dR0Qm58Qi3z8p2w3A==\",\"length\":58,\"stub\":true}},\"works\":true}"
-  , "response" : "{\"ok\":true,\"id\":\"new\",\"rev\":\"3-19e2de\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/attachment_update"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/cfg.json b/tests/fixtures/cfg.json
deleted file mode 100644
index cd5539f..0000000
--- a/tests/fixtures/cfg.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{ "timeout" : 5000
-, "couch"   : "http://localhost:5984"
-, "admin"   : "http://admin:password@localhost:5984"
-}
diff --git a/tests/fixtures/database/changes.json b/tests/fixtures/database/changes.json
deleted file mode 100644
index 5771771..0000000
--- a/tests/fixtures/database/changes.json
+++ /dev/null
@@ -1,42 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/database_changes"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/database_changes/foobar"
-  , "body"     : "{\"foo\":\"bar\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/database_changes/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/database_changes/barfoo"
-  , "body"     : "{\"bar\":\"foo\"}"
-  , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}"
-  }
-, { "status"   : 200
-  , "path"     : "/database_changes/_changes?since=0"
-  , "response" : "{\"results\":[{\"seq\":\"1-abc\",\"id\":\"a\",\"changes\":[{\"rev\":\"1-abc\"}]},{\"seq\":\"2-abc\",\"id\":\"b\",\"changes\":[{\"rev\":\"1-abc\"}]},{\"seq\":\"3-abc\",\"id\":\"c\",\"changes\":[{\"rev\":\"1-abc\"}]}],\"last_seq\":\"3-abc\"}"
-  }
-, { "status"   : 200
-  , "path"     : "/database_changes/_changes?since=0"
-  , "response" : "{\"results\":[{\"seq\":\"1-abc\",\"id\":\"a\",\"changes\":[{\"rev\":\"1-abc\"}]},{\"seq\":\"2-abc\",\"id\":\"b\",\"changes\":[{\"rev\":\"1-abc\"}]},{\"seq\":\"3-abc\",\"id\":\"c\",\"changes\":[{\"rev\":\"1-abc\"}]}],\"last_seq\":\"3-abc\"}"
-  }
-, { "status"   : 200
-  , "path"     : "/database_changes/_changes"
-  , "response" : "{\"results\":[],\"last_seq\":\"3-abc\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_changes"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/database/compact.json b/tests/fixtures/database/compact.json
deleted file mode 100644
index 6cada59..0000000
--- a/tests/fixtures/database/compact.json
+++ /dev/null
@@ -1,34 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/database_compact"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/database_compact/goofy"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_compact/goofy?rev=1-611488"
-  , "response" : "{\"ok\":true}"
-  }
-, { "method"   : "post"
-  , "path"     : "/database_compact/_compact"
-  , "response" : "{\"ok\":true}"
-  , "status"   : 202
-  }
-, { "method"   : "get"
-  , "path"     : "/database_compact"
-  , "response" : "{ \"db_name\": \"db_compact\", \"doc_count\": 0, \"doc_del_count\": 1, \"update_seq\": 2, \"purge_seq\": 0, \"compact_running\": true, \"disk_size\": 523, \"instance_start_time\": \"1336855750104121\", \"disk_format_version\": 5, \"committed_update_seq\": 0 }"
-  }
-, { "method"   : "get"
-  , "path"     : "/database_compact"
-  , "response" : "{ \"db_name\": \"db_compact\", \"compact_running\": false }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_compact"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/database/create-and-destroy.json b/tests/fixtures/database/create-and-destroy.json
deleted file mode 100644
index fa96f3a..0000000
--- a/tests/fixtures/database/create-and-destroy.json
+++ /dev/null
@@ -1,39 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/database_create-and-destroy"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/az09_%24()%2B-%2F"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/newdb1"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/newdb2?q=1&n=3"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/with%2Fslash"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_create-and-destroy"
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/az09_%24()%2B-%2F"
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/with%2Fslash"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/database/follow.json b/tests/fixtures/database/follow.json
deleted file mode 100644
index eb72817..0000000
--- a/tests/fixtures/database/follow.json
+++ /dev/null
@@ -1,30 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/database_follow"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/database_follow/foobar"
-  , "body"     : "{\"foo\":\"bar\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/database_follow/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/database_follow/barfoo"
-  , "body"     : "{\"bar\":\"foo\"}"
-  , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_follow"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/database/get.json b/tests/fixtures/database/get.json
deleted file mode 100644
index 830f121..0000000
--- a/tests/fixtures/database/get.json
+++ /dev/null
@@ -1,15 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/database_get"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "get"
-  , "path"     : "/database_get"
-  , "response" : "{ \"db_name\": \"database_get\", \"doc_count\": 0}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_get"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/database/list.json b/tests/fixtures/database/list.json
deleted file mode 100644
index 08459b0..0000000
--- a/tests/fixtures/database/list.json
+++ /dev/null
@@ -1,15 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/database_list"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "get"
-  , "path"     : "/_all_dbs"
-  , "response" : "[\"database_list\", \"_users\", \"_replicator\"]"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_list"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/database/replicate.json b/tests/fixtures/database/replicate.json
deleted file mode 100644
index 397a38d..0000000
--- a/tests/fixtures/database/replicate.json
+++ /dev/null
@@ -1,76 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/database_replicate"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/database_replica"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/database_replica2"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/database_replicate/foobar"
-  , "body"     : "{\"foo\":\"bar\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/database_replicate/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/database_replicate/barfoo"
-  , "body"     : "{\"bar\":\"foo\"}"
-  , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}"
-  }
-, { "method"   : "post"
-  , "status"   : 201
-  , "path"     : "/_replicate"
-  , "body"     : "{\"source\":\"database_replicate\",\"target\":\"database_replica\"}"
-  , "response" : "{\"ok\":true}"
-  }
-, { "path"     : "/database_replica/_all_docs"
-  , "status"   : 200
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"rev\":\"1-41412c293dade3fe73279cba8b4cece4\"}},{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}},{\"id\":\"foobaz\",\"key\":\"foobaz\",\"value\":{\"rev\":\"1-cfa20dddac397da5bf0be2b50fb472fe\"}}]}"
-  }
-, { "method"   : "post"
-  , "status"   : 201
-  , "path"     : "/_replicate"
-  , "body"     : "{\"source\":\"http://localhost:5984/database_replicate\",\"target\":\"http://localhost:5984/database_replica2\"}"
-  , "response" : "{\"ok\":true}"
-  }
-, { "method"   : "post"
-  , "status"   : 201
-  , "path"     : "/_replicate"
-  , "body"     : "{\"source\":\"database_replicate\",\"target\":\"database_replica\"}"
-  , "response" : "{\"ok\":true}"
-  }
-, { "path"     : "/database_replica2/_all_docs"
-  , "status"   : 200
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"rev\":\"1-41412c293dade3fe73279cba8b4cece4\"}},{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}},{\"id\":\"foobaz\",\"key\":\"foobaz\",\"value\":{\"rev\":\"1-cfa20dddac397da5bf0be2b50fb472fe\"}}]}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_replicate"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_replica"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_replica2"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/database/replicator.json b/tests/fixtures/database/replicator.json
deleted file mode 100644
index f1f76d6..0000000
--- a/tests/fixtures/database/replicator.json
+++ /dev/null
@@ -1,117 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/database_replicator"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/database_replica"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/database_replica2"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/database_replica3"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/database_replicator/foobar"
-  , "body"     : "{\"foo\":\"bar\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/database_replicator/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/database_replicator/barfoo"
-  , "body"     : "{\"bar\":\"foo\"}"
-  , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}"
-  }
-, { "method"   : "post"
-  , "status"   : 201
-  , "path"     : "/_replicator"
-  , "body"     : "{\"source\":\"database_replicator\",\"target\":\"database_replica\"}"
-  , "response" : "{\"ok\":true, \"id\": \"632c186d2c10497410f8b46ef300016e\"}"
-  }
-, { "path"     : "/_replicator/632c186d2c10497410f8b46ef300016e"
-  , "status"   : 200
-  , "response" : "{ \"_id\": \"632c186d2c10497410f8b46ef300016e\", \"_rev\": \"3-c83884542204db29b34cd9ed9e5364e1\", \"source\": \"database_replicator\", \"target\": \"database_replica\", \"owner\": null, \"_replication_state\": \"triggered\", \"_replication_state_time\": \"2017-02-07T11:42:25+01:00\", \"_replication_id\": \"c1ed194ee95788f1fcade8cf5489bce9\", \"_replication_stats\": { \"revisions_checked\": 3, \"missing_revisions_found\": 3, \"docs_read\": 3, \"docs_written\": 3, \"doc_ [...]
-  }
-, { "path"     : "/database_replica/_all_docs"
-  , "status"   : 200
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"rev\":\"1-41412c293dade3fe73279cba8b4cece4\"}},{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}},{\"id\":\"foobaz\",\"key\":\"foobaz\",\"value\":{\"rev\":\"1-cfa20dddac397da5bf0be2b50fb472fe\"}}]}"
-  }
-, { "method"   : "delete"
-  , "status"   : 200
-  , "path"     : "/_replicator/632c186d2c10497410f8b46ef300016e?rev=3-c83884542204db29b34cd9ed9e5364e1"
-  , "response" : "{\"ok\":true, \"id\": \"632c186d2c10497410f8b46ef300016e\"}"
-  }
-, { "method"   : "post"
-  , "status"   : 201
-  , "path"     : "/_replicator"
-  , "body"     : "{\"source\":\"http://localhost:5984/database_replicator\",\"target\":\"database_replica2\"}"
-  , "response" : "{\"ok\":true, \"id\": \"632c186d2c10497410f8b46ef300018f\"}"
-  }
-, { "path"     : "/_replicator/632c186d2c10497410f8b46ef300018f"
-  , "status"   : 200
-  , "response" : "{ \"_id\": \"632c186d2c10497410f8b46ef300018f\", \"_rev\": \"3-c83884542204db29b34cd9ed9e5364e1\", \"source\": \"database_replicator\", \"target\": \"database_replica2\", \"owner\": null, \"_replication_state\": \"triggered\", \"_replication_state_time\": \"2017-02-07T11:42:25+01:00\", \"_replication_id\": \"c1ed194ee95788f1fcade8cf5489bce9\", \"_replication_stats\": { \"revisions_checked\": 3, \"missing_revisions_found\": 3, \"docs_read\": 3, \"docs_written\": 3, \"doc [...]
-  }
-, { "path"     : "/database_replica2/_all_docs"
-  , "status"   : 200
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"rev\":\"1-41412c293dade3fe73279cba8b4cece4\"}},{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}},{\"id\":\"foobaz\",\"key\":\"foobaz\",\"value\":{\"rev\":\"1-cfa20dddac397da5bf0be2b50fb472fe\"}}]}"
-  }
-, { "method"   : "delete"
-  , "status"   : 200
-  , "path"     : "/_replicator/632c186d2c10497410f8b46ef300018f?rev=3-c83884542204db29b34cd9ed9e5364e1"
-  , "response" : "{\"ok\":true, \"id\": \"632c186d2c10497410f8b46ef300018f\"}"
-  }
-, { "method"   : "post"
-  , "status"   : 201
-  , "path"     : "/_replicator"
-  , "body"     : "{\"source\":\"database_replicator\",\"target\":\"database_replica3\"}"
-  , "response" : "{\"ok\":true, \"id\": \"632c186d2c10497410f8b46ef3000200\"}"
-  }
-, { "path"     : "/_replicator/632c186d2c10497410f8b46ef3000200"
-  , "status"   : 200
-  , "response" : "{ \"_id\": \"632c186d2c10497410f8b46ef3000200\", \"_rev\": \"3-c83884542204db29b34cd9ed9e5364e1\", \"source\": \"database_replicator\", \"target\": \"database_replica3\", \"owner\": null, \"_replication_state\": \"triggered\", \"_replication_state_time\": \"2017-02-07T11:42:25+01:00\", \"_replication_id\": \"c1ed194ee95788f1fcade8cf5489bce9\", \"_replication_stats\": { \"revisions_checked\": 3, \"missing_revisions_found\": 3, \"docs_read\": 3, \"docs_written\": 3, \"doc [...]
-  }
-, { "path"     : "/database_replica3/_all_docs"
-  , "status"   : 200
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"rev\":\"1-41412c293dade3fe73279cba8b4cece4\"}},{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}},{\"id\":\"foobaz\",\"key\":\"foobaz\",\"value\":{\"rev\":\"1-cfa20dddac397da5bf0be2b50fb472fe\"}}]}"
-  }
-, { "method"   : "delete"
-  , "status"   : 200
-  , "path"     : "/_replicator/632c186d2c10497410f8b46ef3000200?rev=3-c83884542204db29b34cd9ed9e5364e1"
-  , "response" : "{\"ok\":true, \"id\": \"632c186d2c10497410f8b46ef3000200\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_replicator"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_replica"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_replica2"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/database_replica3"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/design/atomic.json b/tests/fixtures/design/atomic.json
deleted file mode 100644
index 5712da0..0000000
--- a/tests/fixtures/design/atomic.json
+++ /dev/null
@@ -1,43 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/design_atomic"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/design_atomic/_design/update"
-  , "body"     : "*"
-  , "status"   : 201
-  , "response" : "{\"ok\":true,\"id\":\"_design/update\",\"rev\":\"1-14e6bc\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_atomic/foobar"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "put"
-  , "path"     : "/design_atomic/_design/update/_update/inplace/foobar"
-  , "body"     : "{\"field\":\"foo\",\"value\":\"bar\"}"
-  , "response" : "{\"foo\": \"bar\"}"
-  }
-, { "method"   : "put"
-  , "path"     : "/design_atomic/_design/update/_update/addbaz/baz"
-  , "response" : "{\"baz\": \"biz\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_atomic/wat%2Fwat"
-  , "body"     : "{\"wat\":\"wat\"}"
-  , "response" : "{\"ok\":true,\"id\":\"wat%2Fwat\",\"rev\":\"1-511488\"}"
-  }
-, { "method"   : "put"
-  , "path"     : "/design_atomic/_design/update/_update/inplace/wat%2Fwat"
-  , "body"     : "{\"field\":\"wat\",\"value\":\"dawg\"}"
-  , "response" : "{\"wat\": \"dawg\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/design_atomic"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/design/compact.json b/tests/fixtures/design/compact.json
deleted file mode 100644
index 8fc44c7..0000000
--- a/tests/fixtures/design/compact.json
+++ /dev/null
@@ -1,38 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/design_compact"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/design_compact/_design/alice"
-  , "body"     : "*"
-  , "status"   : 201
-  , "response" : "{\"ok\":true,\"id\":\"_design/alice\",\"rev\":\"1-14e6bc\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_compact/foobaz"
-  , "body"     : "*"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/design_compact/foobaz?rev=1-611488"
-  , "response" : "{\"ok\":true}"
-  }
-, { "method"   : "post"
-  , "path"     : "/design_compact/_compact/alice"
-  , "response" : "{\"ok\":true}"
-  , "status"   : 202
-  }
-, { "path"     : "/design_compact"
-  , "response" : "{\"compact_running\": false}"
-  }
-, { "path"     : "/design_compact/_design/alice/_view/by_id"
-  , "response" : "{ \"total_rows\": 0, \"offset\": 0, \"rows\": [] }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/design_compact"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/design/list.json b/tests/fixtures/design/list.json
deleted file mode 100644
index 17129a9..0000000
--- a/tests/fixtures/design/list.json
+++ /dev/null
@@ -1,40 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/design_list"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/design_list/_design/people"
-  , "body"     : "*"
-  , "status"   : 201
-  , "response" : "{\"ok\":true,\"id\":\"_design/people\",\"rev\":\"1-14e6bc\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_list/p_derek"
-  , "body"     : "*"
-  , "response" : "{\"ok\":true,\"id\":\"p_derek\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_list/p_randall"
-  , "body"     : "*"
-  , "response" : "{\"ok\":true,\"id\":\"p_randall\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_list/p_nuno"
-  , "body"     : "*"
-  , "response" : "{\"ok\":true,\"id\":\"p_nuno\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "get"
-  , "path"     : "/design_list/_design/people/_list/my_list/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D"
-  , "response" : "Hello"
-  }
-, { "method"   : "delete"
-  , "path"     : "/design_list"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/design/multiple.json b/tests/fixtures/design/multiple.json
deleted file mode 100644
index 8127450..0000000
--- a/tests/fixtures/design/multiple.json
+++ /dev/null
@@ -1,46 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/design_multiple"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/design_multiple/_design/alice"
-  , "body"     : "*"
-  , "status"   : 201
-  , "response" : "{\"ok\":true,\"id\":\"_design/alice\",\"rev\":\"1-14e6bc\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_multiple/foobar"
-  , "body"     : "{\"foo\":\"bar\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_multiple/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_multiple/barfoo"
-  , "body"     : "{\"bar\":\"foo\"}"
-  , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}"
-  }
-, { "path"     : "/design_multiple/_design/alice/_view/by_id?include_docs=true"
-  , "body"     : "{\"keys\":[\"foobar\",\"barfoo\"]}"
-  , "method"   : "post"
-  , "response" : "{\"total_rows\":3,\"offset\":2,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"},\"doc\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba [...]
-  }
-, { "path"     : "/design_multiple/_design/alice/_view/by_id?include_docs=true"
-  , "body"     : "{\"keys\":[\"foobar\",\"barfoo\"]}"
-  , "method"   : "post"
-  , "response" : "{\"total_rows\":3,\"offset\":2,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"},\"doc\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba [...]
-  }
-, { "method"   : "delete"
-  , "path"     : "/design_multiple"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/design/query.json b/tests/fixtures/design/query.json
deleted file mode 100644
index 2a969c4..0000000
--- a/tests/fixtures/design/query.json
+++ /dev/null
@@ -1,50 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/design_query"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/design_query/_design/people"
-  , "body"     : "*"
-  , "status"   : 201
-  , "response" : "{\"ok\":true,\"id\":\"_design/people\",\"rev\":\"1-14e6bc\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_query/p_derek"
-  , "body"     : "*"
-  , "response" : "{\"ok\":true,\"id\":\"p_derek\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_query/p_randall"
-  , "body"     : "*"
-  , "response" : "{\"ok\":true,\"id\":\"p_randall\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_query/p_nuno"
-  , "body"     : "*"
-  , "response" : "{\"ok\":true,\"id\":\"p_nuno\",\"rev\":\"1-4c6114\"}"
-  }
-, { "path"     : "/design_query/_design/people/_view/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D"
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"p_derek\",\"key\":[\"Derek\",\"San Francisco\"],\"value\":\"p_derek\"}\r\n]}\n"
-  }
-, { "path"     : "/design_query/_design/people/_view/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D"
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"p_derek\",\"key\":[\"Derek\",\"San Francisco\"],\"value\":\"p_derek\"}\r\n]}\n"
-  }
-, { "path"     : "/design_query/_design/people/_view/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D"
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"p_derek\",\"key\":[\"Derek\",\"San Francisco\"],\"value\":\"p_derek\"}\r\n]}\n"
-  }
-, { "method"   : "post"
-  , "path"     : "/design_query/_design/people/_view/by_name_and_city"
-  , "body"     : "{\"queries\":[{\"keys\":[[\"Derek\",\"San Francisco\"],[\"Nuno\",\"London\"]]},{\"skip\":2,\"limit\":1}]}"
-  , "response" : "{\"results\":[{\"total_rows\":3,\"offset\":0,\"rows\":[{\"id\":\"p_derek\",\"key\":[\"Derek\",\"San Francisco\"],\"value\":\"p_derek\"},{\"id\":\"p_nuno\",\"key\":[\"Nuno\",\"London\"],\"value\":\"p_nuno\"}]},{\"total_rows\":3,\"offset\":2,\"rows\":[{\"id\":\"p_randall\",\"key\":[\"Randall\",\"San Francisco\"],\"value\":\"p_randall\"}]}]}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/design_query"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/design/search.json b/tests/fixtures/design/search.json
deleted file mode 100644
index 8a5451c..0000000
--- a/tests/fixtures/design/search.json
+++ /dev/null
@@ -1,12 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/design_search"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/design_search"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/design/show.json b/tests/fixtures/design/show.json
deleted file mode 100644
index 2ca4050..0000000
--- a/tests/fixtures/design/show.json
+++ /dev/null
@@ -1,44 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/design_show"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/design_show/_design/people"
-  , "body"     : "*"
-  , "status"   : 201
-  , "response" : "{\"ok\":true,\"id\":\"_design/people\",\"rev\":\"1-14e6bc\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_show/p_clemens"
-  , "body"     : "{\"name\":\"Clemens\",\"city\":\"Dresden\"}"
-  , "response" : "{\"ok\":true,\"id\":\"p_clemens\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_show/p_randall"
-  , "body"     : "{\"name\":\"Randall\",\"city\":\"San Francisco\"}"
-  , "response" : "{\"ok\":true,\"id\":\"p_randall\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/design_show/p_nuno"
-  , "body"     : "{\"name\":\"Nuno\",\"city\":\"New York\"}"
-  , "response" : "{\"ok\":true,\"id\":\"p_nuno\",\"rev\":\"1-4c6114\"}"
-  }
-, { "path"     : "/design_show/_design/people/_show/singleDoc/p_clemens"
-  , "response" : "{\"name\":\"Clemens\",\"city\":\"Dresden\",\"format\":\"json\"}\n"
-  , "headers"  : { "content-type": "application/json" }
-  }
-, { "path"     : "/design_show/_design/people/_show/singleDoc/p_clemens?format=html"
-  , "response" : "Hello Clemens!"
-  , "headers"  : { "content-type": "text/html" }
-  }
-, { "method"   : "delete"
-  , "path"     : "/design_show"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/document/bulk.json b/tests/fixtures/document/bulk.json
deleted file mode 100644
index 694f2a9..0000000
--- a/tests/fixtures/document/bulk.json
+++ /dev/null
@@ -1,16 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/document_bulk"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "post"
-  , "path"     : "/document_bulk/_bulk_docs"
-  , "body"     : "{\"docs\":[{\"key\":\"baz\",\"name\":\"bazzel\"},{\"key\":\"bar\",\"name\":\"barry\"}]}"
-  , "response" : "[{\"id\":\"84600661a1f8f8dd1428851bb5002449\",\"rev\": \"1-f5f3f3e496c72307975a69c73fd53d42\"},{\"id\":\"84600661a1f8f8dd1428851bb5002dd8\",\"rev\":\"1-8ad0e70d5e6edd474ec190eac2376bde\"}]"
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_bulk"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/document/copy.json b/tests/fixtures/document/copy.json
deleted file mode 100644
index 38b19a9..0000000
--- a/tests/fixtures/document/copy.json
+++ /dev/null
@@ -1,43 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/document_copy"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_copy/foo_src"
-  , "body"     : "*"
-  , "response" : "{\"ok\":true,\"id\":\"foo_src\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_copy/foo_dest"
-  , "body"     : "*"
-  , "response" : "{\"ok\":true,\"id\":\"foo_dest\",\"rev\":\"1-351431\"}"
-  }
-, { "method"   : "head"
-  , "status"   : 200
-  , "path"     : "/document_copy/foo_dest"
-  , "headers"  : {"etag": "\"1-aa43f0\""}
-  }
-, { "method"     : "copy"
-  , "path"       : "/document_copy/foo_src"
-  , "response"   : "{ \"id\": \"foo_dest\", \"rev\": \"2-e66edd\" }"
-  , "status"     : 201
-  }
-, { "method"     : "copy"
-  , "path"       : "/document_copy/foo_src"
-  , "response"   : "{ \"error\": \"conflict\", \"reason\": \"Document update conflict.\" }"
-  , "status"     : 409
-  }
-, { "method"     : "copy"
-  , "path"       : "/document_copy/foo_src"
-  , "response"   : "{ \"id\": \"baz_dest\", \"rev\": \"1-36645f\" }"
-  , "status"     : 201
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_copy"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/document/create_index.json b/tests/fixtures/document/create_index.json
deleted file mode 100644
index 720fe56..0000000
--- a/tests/fixtures/document/create_index.json
+++ /dev/null
@@ -1,24 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/document_create_index"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_create_index/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "post"
-  , "path"     : "/document_create_index/_index"
-  , "status"   : 200
-  , "body"     : "{\"name\":\"fooindex\",\"index\":{\"fields\":[\"foo\"]}}"
-  , "response" : "{\"result\":\"created\",\"id\":\"_design/a7ee061f1a2c0c6882258b2f1e148b714e79ccea\",\"name\": \"fooindex\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_create_index"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-]
\ No newline at end of file
diff --git a/tests/fixtures/document/destroy.json b/tests/fixtures/document/destroy.json
deleted file mode 100644
index 0d65bf1..0000000
--- a/tests/fixtures/document/destroy.json
+++ /dev/null
@@ -1,21 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/document_destroy"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_destroy/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_destroy/foobaz?rev=1-611488"
-  , "response" : "{\"ok\":true}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_destroy"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/document/fetch.json b/tests/fixtures/document/fetch.json
deleted file mode 100644
index 3594ec9..0000000
--- a/tests/fixtures/document/fetch.json
+++ /dev/null
@@ -1,45 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/document_fetch"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_fetch/foobar"
-  , "body"     : "{\"foo\":\"bar\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_fetch/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_fetch/barfoo"
-  , "body"     : "{\"bar\":\"foo\"}"
-  , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}"
-  }
-, { "method"   : "post"
-  , "path"     : "/document_fetch/_all_docs?include_docs=true"
-  , "body"     : "{\"keys\":[\"foobar\"]}"
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}}\r\n]}\n"
-  }
-, { "method"   : "post"
-  , "path"     : "/document_fetch/_all_docs?not=important&include_docs=true"
-  , "body"     : "{\"keys\":[\"foobar\"]}"
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}}\r\n]}\n"
-  }
-, { "method"   : "post"
-  , "path"     : "/document_fetch/_all_docs?include_docs=true"
-  , "body"     : "{\"keys\":[\"foobar\",\"barfoo\"]}"
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"rev\":\"1-41412c293dade3fe73279cba8b4cece4\"},\"doc\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"}}\r\n]}\n"
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_fetch"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/document/fetch_revs.json b/tests/fixtures/document/fetch_revs.json
deleted file mode 100644
index b83b0e6..0000000
--- a/tests/fixtures/document/fetch_revs.json
+++ /dev/null
@@ -1,45 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/document_fetch_revs"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_fetch_revs/foobar"
-  , "body"     : "{\"foo\":\"bar\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_fetch_revs/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_fetch_revs/barfoo"
-  , "body"     : "{\"bar\":\"foo\"}"
-  , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}"
-  }
-, { "method"   : "post"
-  , "path"     : "/document_fetch_revs/_all_docs"
-  , "body"     : "{\"keys\":[\"foobar\"]}"
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}}\r\n]}\n"
-  }
-, { "method"   : "post"
-  , "path"     : "/document_fetch_revs/_all_docs"
-  , "body"     : "{\"keys\":[\"foobar\",\"barfoo\"]}"
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"rev\":\"1-41412c293dade3fe73279cba8b4cece4\"}}\r\n]}\n"
-  }
-, { "method"   : "post"
-  , "path"     : "/document_fetch_revs/_all_docs?still=no"
-  , "body"     : "{\"keys\":[\"foobar\"]}"
-  , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}}\r\n]}\n"
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_fetch_revs"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/document/find.json b/tests/fixtures/document/find.json
deleted file mode 100644
index bb23e76..0000000
--- a/tests/fixtures/document/find.json
+++ /dev/null
@@ -1,36 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/document_find"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_find/foobar"
-  , "body"     : "{\"foo\":\"bar\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_find/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_find/barfoo"
-  , "body"     : "{\"bar\":\"foo\"}"
-  , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}"
-  }
-, { "path"     : "/document_find/_find"
-  , "response" : "{ \"docs\" : [ { \"_id\":  \"foobaz\", \"rev\":\"1-611488\", \"foo\":\"baz\" }]}"
-  }
-, { "path"     : "/document_find/_find"
-  , "response" : "{ \"docs\" : [ { \"_id\":  \"foobaz\", \"rev\":\"1-611488\", \"foo\":\"baz\" }]}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_find"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/document/get.json b/tests/fixtures/document/get.json
deleted file mode 100644
index 6a2281d..0000000
--- a/tests/fixtures/document/get.json
+++ /dev/null
@@ -1,20 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/document_get"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_get/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "path"     : "/document_get/foobaz?revs_info=true"
-  , "response" : "{\"_id\":\"foobaz\", \"_rev\": \"1-611488\", \"foo\": \"baz\", \"_revs_info\": [] }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_get"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/document/head.json b/tests/fixtures/document/head.json
deleted file mode 100644
index 7d56f8a..0000000
--- a/tests/fixtures/document/head.json
+++ /dev/null
@@ -1,25 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/document_head"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_head/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "path"     : "/document_head/foobaz"
-  , "method"   : "head"
-  , "headers"  : { "statusCode" : 200 }
-  }
-, { "path"     : "/document_head/foobaz"
-  , "method"   : "head"
-  , "headers"  : { "statusCode" : 200 }
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_head"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/document/insert.json b/tests/fixtures/document/insert.json
deleted file mode 100644
index b87a638..0000000
--- a/tests/fixtures/document/insert.json
+++ /dev/null
@@ -1,42 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/document_insert"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_insert/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 409
-  , "path"     : "/document_insert/foobaz"
-  , "body"     : "*"
-  , "response" : "{\"error\":\"conflict\",\"reason\":\"Document update conflict.\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_insert/foobaz?new_edits=false"
-  , "body"     : "{\"foo\":\"baz\",\"_rev\":\"1-611488\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"2-123456\"}"
-  }
-, { "method"   : "post"
-  , "status"   : 201
-  , "path"     : "/document_insert"
-  , "body"     : "*"
-  , "response" : "{\"ok\":true,\"id\":\"123\",\"rev\":\"1-611488\"}"
-  }
-, { "path"     : "/document_insert/123"
-  , "response" : "{\"fn\":\"function() { return true; }\",\"fn2\":\"function() { return true; }\",\"id\":\"123\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_insert/foobaz?rev=1-611488"
-  , "response" : "{\"ok\":true}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_insert"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/document/list.json b/tests/fixtures/document/list.json
deleted file mode 100644
index 0405931..0000000
--- a/tests/fixtures/document/list.json
+++ /dev/null
@@ -1,54 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/document_list"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_list/foobar"
-  , "body"     : "{\"foo\":\"bar\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_list/foobaz"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobaz\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_list/barfoo"
-  , "body"     : "{\"bar\":\"foo\"}"
-  , "response" : "{\"ok\":true,\"id\":\"barfoo\",\"rev\":\"1-3cde10\"}"
-  }
-, { "path"     : "/document_list/_all_docs"
-  , "response" : "{\"total_rows\":3,\"offset\": 0, \"rows\": []}"
-  }
-, { "path"     : "/document_list/_all_docs?limit=1"
-  , "response" : "{\"total_rows\":3,\"offset\": 0,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}}]}"
-  }
-, { "path"     : "/document_list/_all_docs?startkey=%22c%22"
-  , "response" : "{\"total_rows\":3,\"offset\": 1,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"},\"doc\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cb [...]
-  }
-, { "path"     : "/document_list/_all_docs?start_key=%22c%22"
-  , "response" : "{\"total_rows\":3,\"offset\": 1,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"},\"doc\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cb [...]
-  }
-, { "path"     : "/document_list/_all_docs?endkey=%22s%22"
-  , "response" : "{\"total_rows\":3,\"offset\": 1,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"},\"doc\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cb [...]
-  }
-, { "path"     : "/document_list/_all_docs?end_key=%22s%22"
-  , "response" : "{\"total_rows\":3,\"offset\": 1,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"},\"doc\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cb [...]
-  }
-, { "path"     : "/document_list/_all_docs"
-  , "response" : "{\"total_rows\":3,\"offset\": 1,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"},\"doc\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cb [...]
-  }
-, { "path"     : "/document_list/_all_docs?end_key=%22s%22"
-  , "response" : "{\"total_rows\":3,\"offset\": 1,\"rows\":[\r\n{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"},\"doc\":{\"_id\":\"foobar\",\"_rev\":\"1-4c6114c65e295552ab1019e2b046b10e\",\"foo\":\"bar\"}},\r\n{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cba8b4cece4\",\"bar\":\"foo\"},\"doc\":{\"_id\":\"barfoo\",\"_rev\":\"1-41412c293dade3fe73279cb [...]
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_list"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/document/update.json b/tests/fixtures/document/update.json
deleted file mode 100644
index a6dfb54..0000000
--- a/tests/fixtures/document/update.json
+++ /dev/null
@@ -1,22 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/document_update"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "status"   : 201
-  , "path"     : "/document_update/foobar"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-611488\"}"
-  }
-, { "method"   : "put"
-  , "path"     : "/document_update/foobar"
-  , "response" : "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"2-2ff408\"}"
-  , "body"     : "{\"foo\":\"bar\",\"_rev\":\"1-611488\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/document_update"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/logo.png b/tests/fixtures/logo.png
deleted file mode 100644
index ef3494e..0000000
Binary files a/tests/fixtures/logo.png and /dev/null differ
diff --git a/tests/fixtures/multipart/get.json b/tests/fixtures/multipart/get.json
deleted file mode 100644
index b9bb076..0000000
--- a/tests/fixtures/multipart/get.json
+++ /dev/null
@@ -1,23 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/multipart_get"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/multipart_get/foobaz"
-  , "body"     : "*"
-  , "status"   : 201
-  , "response" : "{\"ok\": true, \"id\": \"foobaz\", \"rev\": \"1-921bd51\" }"
-  }
-, { "path"     : "/multipart_get/foobaz?attachments=true"
-  , "status"   : 200
-  , "headers"  : { "content-type": "multipart\/related; boundary=\"33d91dba65f66463e14ac1ae75d79403\"" }
-  , "buffer"   : "LS0wN2ExNmJjYTNjYTA4MzA4YjQ4Njg3MjU3MDE1YjQ3YQ0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uDQoNCnsiX2lkIjoiZm9vYmF6IiwiX3JldiI6IjEtYzk0NjQ4MWI0MzI3NTc4ZTNmNDg4NmZiYzAwMjc3OTAiLCJmb28iOiJiYXoiLCJfYXR0YWNobWVudHMiOnsiYXR0Ijp7ImNvbnRlbnRfdHlwZSI6InRleHQvcGxhaW4iLCJyZXZwb3MiOjEsImRpZ2VzdCI6Im1kNS1qcmxBaXVQRmg5SFJCZmp5RHFqRlF3PT0iLCJsZW5ndGgiOjEyLCJmb2xsb3dzIjp0cnVlLCJlbmNvZGluZyI6Imd6aXAiLCJlbmNvZGVkX2xlbmd0aCI6MzJ9fX0NCi0tMDdhMTZiY2EzY2EwODMwOGI0ODY4NzI1NzAxNWI0N2ENCkNvbnRlbn [...]
-  }
-, { "method"   : "delete"
-  , "path"     : "/multipart_get"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/multipart/insert.json b/tests/fixtures/multipart/insert.json
deleted file mode 100644
index 4b7d342..0000000
--- a/tests/fixtures/multipart/insert.json
+++ /dev/null
@@ -1,50 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/multipart_insert"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/multipart_insert/foobaz"
-  , "body"     : "*"
-  , "status"   : 201
-  , "response" : "{\"ok\": true, \"id\": \"foobaz\", \"rev\": \"1-921bd51\" }"
-  }
-, { "method"   : "put"
-  , "path"     : "/multipart_insert/foobar"
-  , "body"     : "*"
-  , "status"   : 201
-  , "response" : "{\"ok\": true, \"id\": \"foobar\", \"rev\": \"1-921bd51\" }"
-  }
-, { "method"   : "put"
-  , "path"     : "/multipart_insert/mydoc/one"
-  , "body"     : "Hello World!"
-  , "status"   : 201
-  , "response" : "{\"ok\": true, \"id\": \"one\", \"rev\": \"1-921bd51\" }"
-  }
-, { "path"     : "/multipart_insert/mydoc"
-  , "status"   : 200
-  , "response" : "{\"_id\": \"mydoc\", \"_rev\": \"1-921bd51\", \"_attachments\": { \"one\": { \"stub\": true } } }"
-  }
-, { "method"   : "put"
-  , "path"     : "/multipart_insert/mydoc"
-  , "body"     : "*"
-  , "status"   : 201
-  , "response" : "{\"ok\": true, \"id\": \"mydoc\", \"rev\": \"2-921bd51\""
-  }
-, { "path"     : "/multipart_insert/mydoc"
-  , "status"   : 200
-  , "response" : "{\"_id\": \"mydoc\", \"_rev\": \"2-921bd51\", \"_attachments\": {  \"one\": { \"stub\": true }, \"two\": { \"stub\": true } } }"
-  }
-, { "method"   : "put"
-  , "path"     : "/multipart_insert/otherdoc"
-  , "body"     : "*"
-  , "status"   : 201
-  , "response" : "{\"ok\": true, \"id\": \"foobar\", \"rev\": \"1-921bd51\" }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/multipart_insert"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/shared/config.json b/tests/fixtures/shared/config.json
deleted file mode 100644
index 148e0c1..0000000
--- a/tests/fixtures/shared/config.json
+++ /dev/null
@@ -1,20 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/shared_config"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "path"     : "/"
-  , "response" : "{\"ok\": true, \"version\": \"1.1.0\"}"
-  }
-, { "path"     : "/"
-  , "response" : "{\"ok\": true, \"version\": \"1.1.0\"}"
-  }
-, { "path"     : "/_all_dbs"
-  , "response" : "{}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/shared_config"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/shared/cookie.json b/tests/fixtures/shared/cookie.json
deleted file mode 100644
index c1b9d48..0000000
--- a/tests/fixtures/shared/cookie.json
+++ /dev/null
@@ -1,35 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/shared_cookie"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "path"     : "/_users"
-  , "method"   : "post"
-  , "body"     : "*"
-  , "response" : "{\"ok\": true}"
-  }
-, { "method"   : "post"
-  , "path"     : "/_session"
-  , "body"     : "name=admin&password=password"
-  , "headers"  : {"set-cookie" : ["AuthSession=YWRtaW46NEZCMzFERDk6BJyusEcy3SgfI9xD4Mptl0N0gh0;Version=1;Path=/;HttpOnly"]}
-  , "status"   : 201
-  , "response" : "{ \"ok\": true,\"name\": null,\"roles\": [ \"_admin\" ] }"
-  }
-, { "method"   : "get"
-  , "path"     : "/_session"
-  , "headers"  : {"set-cookie" : ["AuthSession=YWRtaW46NEZCMzFERDk6BJyusEcy3SgfI9xD4Mptl0N0gh0;Version=1;Path=/;HttpOnly"]}
-  , "status"   : 201
-  , "response" : "{ \"ok\": true,\"userCtx\": {\"name\":\"admin\",\"roles\": [ \"_admin\" ]} }"
-  }
-, { "method"   : "post"
-  , "status"   : 201
-  , "path"     : "/shared_cookie"
-  , "body"     : "{\"foo\":\"baz\"}"
-  , "response" : "{\"ok\":true,\"id\":\"234\",\"rev\":\"1-333231\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/shared_cookie"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/shared/error.json b/tests/fixtures/shared/error.json
deleted file mode 100644
index 4210c2c..0000000
--- a/tests/fixtures/shared/error.json
+++ /dev/null
@@ -1,19 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/shared_error"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "path"     : "/"
-  , "response" : "{\"ok\": true, \"version\": \"1.1.0\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/say_wat_wat"
-  , "status"   : 404
-  , "response" : "{\"error\":\"not_found\",\"reason\":\"Database does not exist.\"}"
-  }
-, { "method"   : "delete"
-  , "path"     : "/shared_error"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/shared/headers.json b/tests/fixtures/shared/headers.json
deleted file mode 100644
index cf612d5..0000000
--- a/tests/fixtures/shared/headers.json
+++ /dev/null
@@ -1,29 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/shared_headers"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "put"
-  , "path"     : "/shared_headers/new/att"
-  , "body"     : "Hello"
-  , "status"   : 201
-  , "response" : "{\"ok\":true,\"id\":\"new\",\"rev\":\"1-5142a2\"}"
-  }
-, { "path"       : "/shared_headers/new"
-  , "status"     : 304
-  , "response"   : ""
-  , "reqheaders" : {
-      "If-None-Match": "\"1-5142a2\""
-    }
-  }
-, { "path"     : "/shared_headers/new/att"
-  , "status"   : 200
-  , "response" : "\"Hello\""
-  }
-, { "method"   : "delete"
-  , "path"     : "/shared_headers"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/shared/log.json b/tests/fixtures/shared/log.json
deleted file mode 100644
index 6ed417e..0000000
--- a/tests/fixtures/shared/log.json
+++ /dev/null
@@ -1,11 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/shared_log"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/shared_log"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/shared/nano.json b/tests/fixtures/shared/nano.json
deleted file mode 100644
index 1218583..0000000
--- a/tests/fixtures/shared/nano.json
+++ /dev/null
@@ -1,11 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/shared_nano"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/shared_nano"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/shared/updates.json b/tests/fixtures/shared/updates.json
deleted file mode 100644
index 3aa6f47..0000000
--- a/tests/fixtures/shared/updates.json
+++ /dev/null
@@ -1,19 +0,0 @@
-[
-  { "method"   : "delete"
-  , "path"     : "/mydb"
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "get"
-  , "path"     : "/_db_updates"
-  , "response" : "{\"ok\":true,\"type\":\"created\",\"db_name\":\"mydb\"}"
-  }
-, { "method"   : "put"
-  , "path"     : "/mydb"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/mydb"
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/fixtures/util/uuid.json b/tests/fixtures/util/uuid.json
deleted file mode 100644
index 0a64655..0000000
--- a/tests/fixtures/util/uuid.json
+++ /dev/null
@@ -1,22 +0,0 @@
-[
-  { "method"   : "put"
-  , "path"     : "/util_uuid"
-  , "status"   : 201
-  , "response" : "{ \"ok\": true }"
-  }
-, { "method"   : "get"
-  , "path"     : "/_uuids?count=3"
-  , "status"   : 200
-  , "response" : "{ \"uuids\": [\"1\",\"2\",\"3\"] }"
-  }
-, { "method"   : "get"
-  , "path"     : "/_uuids?count=1"
-  , "status"   : 200
-  , "response" : "{ \"uuids\": [\"1\"] }"
-  }
-, { "method"   : "delete"
-  , "path"     : "/util_uuid"
-  , "status"   : 200
-  , "response" : "{ \"ok\": true }"
-  }
-]
diff --git a/tests/helpers/harness.js b/tests/helpers/harness.js
deleted file mode 100644
index d0febd7..0000000
--- a/tests/helpers/harness.js
+++ /dev/null
@@ -1,70 +0,0 @@
-'use strict'
-
-var test = require('tape')
-
-var nextTick = typeof setImmediate !== 'undefined'
-  ? setImmediate : process.nextTick
-
-function noop () {}
-
-module.exports = function (opts) {
-  var invoked = false
-  var id = opts.id
-  var testPrefix = id || ''
-
-  var harness = {}
-
-  harness.tests = []
-  harness.checkLeaks = typeof opts.checkLeaks === 'boolean'
-    ? opts.checkLeaks : true
-  harness.globalCount = Object.keys(global).length
-
-  harness.timeout = +(opts.timeout || 200)
-  harness.locals = opts.locals || {}
-
-  //
-  // locals must be available here
-  //
-  harness.setup = opts.setup || noop
-  harness.teardown = opts.teardown || noop
-
-  function runTest (name, next, onEnd) {
-    test(testPrefix + '\n## ' + name, function (assert) {
-      nextTick(function () { next.call(harness.locals, assert) })
-
-      var tmout = setTimeout(function () {
-        assert.fail('timed out')
-        assert.end()
-      }, harness.timeout)
-
-      assert.on('end', function () {
-        if (onEnd) {
-          onEnd(assert)
-        }
-        clearTimeout(tmout)
-      })
-    })
-  }
-
-  harness.it = function (name, next) {
-    harness.tests.push({ name: name, next: next })
-    if (!invoked) {
-      invoked = true
-      nextTick(function () {
-        runTest('setup', harness.setup)
-        harness.tests.forEach(function (elem) {
-          runTest(elem.name, elem.next)
-        })
-        runTest('teardown', harness.teardown, function (assert) {
-          if (harness.checkLeaks) {
-            assert.deepEqual(Object.keys(global)
-              .splice(harness.globalCount, Number.MAX_VALUE),
-            [], 'No leaks')
-          }
-        })
-      })
-    }
-  }
-
-  return harness
-}
diff --git a/tests/helpers/index.js b/tests/helpers/index.js
deleted file mode 100644
index 0072502..0000000
--- a/tests/helpers/index.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const path = require('path')
-const fs = require('fs')
-const url = require('url')
-const nano = require('../../lib/nano')
-
-const helpers = exports
-const cfg = helpers.cfg = require('../fixtures/cfg')
-const auth = url.parse(cfg.admin).auth.split(':')
-
-helpers.noopTest = function (t) { t.end() }
-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) {
-  const contents = fs.readFileSync(
-    path.join(__dirname, '..', 'fixtures', filename), (json ? 'ascii' : null))
-  return json ? JSON.parse(contents) : contents
-}
diff --git a/tests/helpers/integration.js b/tests/helpers/integration.js
deleted file mode 100644
index e862baf..0000000
--- a/tests/helpers/integration.js
+++ /dev/null
@@ -1,194 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific end governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const async = require('async')
-const debug = require('debug')
-const path = require('path')
-const harness = require('./harness')
-const cfg = require('../fixtures/cfg')
-const nano = require('../../lib/nano')
-const helpers = require('./')
-
-helpers.setup = function () {
-  const self = this
-  const args = Array.prototype.slice.call(arguments)
-
-  return function (assert) {
-    args.push(function (err) {
-      assert.equal(err, null, 'create database')
-      assert.end()
-    })
-
-    self.nano.db.create.apply(this, args)
-  }
-}
-
-helpers.teardown = function () {
-  const self = this
-  const args = Array.prototype.slice.call(arguments)
-
-  return function (assert) {
-    args.push(function (err) {
-      assert.equal(err, null, 'destroy database')
-      assert.ok(self.mock.isDone(), 'mocks didn\'t run')
-      assert.end()
-    })
-
-    self.nano.db.destroy.apply(this, args)
-  }
-}
-
-helpers.harness = function (name, setup, teardown) {
-  const parent = name || module.parent.filename
-  const fileName = path.basename(parent).split('.')[0]
-  const parentDir = path.dirname(parent)
-    .split(path.sep).reverse()[0]
-  const shortPath = path.join(parentDir, fileName)
-  const log = debug(path.join('nano', 'tests', 'integration', shortPath))
-  const dbName = shortPath.replace('/', '_')
-  const nanoLog = nano({
-    url: cfg.couch,
-    log: log
-  })
-
-  const mock = helpers.nock(helpers.couch, shortPath, log)
-  const db = nanoLog.use(dbName)
-  const locals = {
-    mock: mock,
-    db: db,
-    nano: nanoLog
-  }
-
-  return harness({
-    id: shortPath,
-    timeout: helpers.timeout,
-    checkLeaks: !!process.env.LEAKS,
-    locals: locals,
-    setup: setup || helpers.setup.call(locals, dbName),
-    teardown: teardown || helpers.teardown.call(locals, dbName)
-  })
-}
-
-helpers.nock = function helpersNock (url, fixture, log) {
-  const nock = require('nock')
-  const nockDefs = require('../fixtures/' + fixture + '.json')
-
-  nockDefs.forEach(function (n) {
-    let headers = n.headers || {}
-    const response = n.buffer ? n.buffer.endsWith('.png')
-      ? helpers.loadFixture(n.buffer) : Buffer.from(n.buffer, 'base64')
-      : n.response || ''
-    const body = n.base64 ? Buffer.from(n.base64, 'base64').toString()
-      : n.body || ''
-
-    if (typeof headers === 'string' && headers.endsWith('.json')) {
-      headers = require(path.join(fixture, headers))
-    }
-
-    n.method = n.method || 'get'
-    n.options = { log: log }
-    n.scope = url
-    n.headers = headers
-    n.response = response
-    n.body = body
-
-    return n
-  })
-
-  nock.define(nockDefs)
-
-  return nock(url)
-}
-
-helpers.prepareAView = function (assert, search, db) {
-  search = search || ''
-  db = db || this.db
-
-  db.insert({
-    views: {
-      by_name_and_city: {
-        map: 'function(doc) { emit([doc.name, doc.city], doc._id); }'
-      }
-    },
-    lists: {
-      'my_list': 'function(head, req) { send(\'Hello\'); }'
-    }
-  }, '_design/people' + search, function (error, response) {
-    assert.equal(error, null, 'should create view')
-    assert.equal(response.ok, true, 'response is good')
-    async.parallel([
-      function (cb) {
-        db.insert({
-          name: 'Derek',
-          city: 'San Francisco'
-        }, 'p_derek', cb)
-      }, function (cb) {
-        db.insert({
-          name: 'Randall',
-          city: 'San Francisco'
-        }, 'p_randall', cb)
-      }, function (cb) {
-        db.insert({
-          name: 'Nuno',
-          city: 'London'
-        }, 'p_nuno', cb)
-      }
-    ], function (error) {
-      assert.equal(error, null, 'store the peeps')
-      assert.end()
-    })
-  })
-}
-
-helpers.viewDerek = function viewDerek (db, assert, opts, next, method) {
-  method = method || 'view'
-  db[method]('people', 'by_name_and_city', opts, function (error, view) {
-    assert.equal(error, null, 'no errors')
-    assert.equal(view.rows.length, 1)
-    assert.equal(view.rows.length, 1)
-    assert.equal(view.rows[0].id, 'p_derek')
-    assert.equal(view.rows[0].key[0], 'Derek')
-    assert.equal(view.rows[0].key[1], 'San Francisco')
-    next(error)
-  })
-}
-
-helpers.insertOne = function (assert) {
-  const db = this.db
-  db.insert({ 'foo': 'baz' }, 'foobaz', function (err) {
-    assert.equal(err, null, 'should store docs')
-    assert.end()
-  })
-}
-
-helpers.insertThree = function (assert) {
-  const db = this.db
-  async.parallel([
-    function (cb) { db.insert({ 'foo': 'bar' }, 'foobar', cb) },
-    function (cb) { db.insert({ 'bar': 'foo' }, 'barfoo', cb) },
-    function (cb) { db.insert({ 'foo': 'baz' }, 'foobaz', cb) }
-  ], function (error) {
-    assert.equal(error, null, 'should store docs')
-    assert.end()
-  })
-}
-
-helpers.unmocked = (process.env.NOCK_OFF === 'true')
-helpers.mocked = !helpers.unmocked
-
-helpers.isPromise = function (p) {
-  return (p && typeof p === 'object' && typeof p.then === 'function')
-}
-
-module.exports = helpers
diff --git a/tests/helpers/unit.js b/tests/helpers/unit.js
deleted file mode 100644
index a2f45e7..0000000
--- a/tests/helpers/unit.js
+++ /dev/null
@@ -1,167 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('./')
-const Client = require('../../lib/nano')
-const test = require('tape')
-
-helpers.unit = function (method, error) {
-  const unitName = 'nano/tests/unit/' + method.join('/')
-  const debug = require('debug')(unitName)
-
-  function log (data) {
-    debug({ got: data.body })
-  }
-
-  let 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)
-  }
-
-  let testNr = 1
-
-  return function () {
-    const args = Array.prototype.slice.call(arguments)
-    const stub = args.pop()
-
-    test(unitName + ':' + testNr++,
-      function (assert) {
-        let f
-        assert.ok(typeof stub, 'object')
-
-        //
-        // document functions and database functions
-        // are at the top level in nano
-        //
-        if (method[0] === 'database') {
-        //
-        // Due to the way this harness is designed we cannot differentiate between different methods
-        // when those methods are embedded on an object.
-        // We have two options, either we hardcode the resolution or we write a full harness that
-        // can differentiate between methods embedded on an object.
-        // I go the hardcoded route for now.
-        //
-          if (method[1] === 'replicator') {
-            f = cli.server.db.replication.enable
-          } else {
-            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
-          }
-
-          if (method[1] === 'follow' || method[1] === 'followUpdates') {
-            assert.ok(typeof req.httpAgent, 'object')
-            delete req.httpAgent // ignore 'httpAgent' in deep equal assert
-          }
-
-          // ignore qsStringifyOptions in object comparison
-          delete req.qsStringifyOptions
-
-          assert.deepEqual(req, stub)
-          assert.end()
-        })
-        f.apply(null, args)
-      })
-  }
-}
-
-function mockClient (code, path, extra) {
-  return function (debug, error) {
-    extra = extra || {}
-    const opts = Object.assign(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
deleted file mode 100644
index 5eceb87..0000000
--- a/tests/integration/attachment/destroy.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-
-it('should be able to insert a new plain text attachment', function (assert) {
-  const p = db.attachment.insert('new', 'att', 'Hello World!', 'text/plain')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (response) {
-    assert.equal(response.ok, true, 'response ok')
-    assert.ok(response.rev, 'have a revision number')
-    return db.attachment.destroy('new', 'att', { rev: response.rev })
-  }).then(function (response) {
-    assert.equal(response.ok, true, 'response ok')
-    assert.equal(response.id, 'new', '`id` should be `new`')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should fail destroying with a bad filename', function (assert) {
-  const p = db.attachment.destroy('new', false, true)
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function () {
-    assert.ok(false, 'Promise is resolved')
-    assert.end()
-  }).catch(function () {
-    assert.ok(true, 'Promise is rejected')
-    assert.end()
-  })
-})
diff --git a/tests/integration/attachment/get.js b/tests/integration/attachment/get.js
deleted file mode 100644
index 75ed2ce..0000000
--- a/tests/integration/attachment/get.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-
-it('should be able to fetch an attachment', function (assert) {
-  let p = db.attachment.insert('new_string', 'att', 'Hello', 'text/plain')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (hello) {
-    assert.equal(hello.ok, true, 'response ok')
-    assert.ok(hello.rev, 'should have a revision number')
-    return db.attachment.get('new_string', 'att')
-  }).then(function (helloWorld) {
-    assert.equal('Hello', helloWorld.toString(), 'string is reflexive')
-    assert.end()
-  })
-})
-
-it('should insert and fetch a binary file', function (assert) {
-  let p = db.attachment.insert('new_binary', 'att', Buffer.from('123'), 'text/plain')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (hello) {
-    assert.equal(hello.ok, true, 'response ok')
-    assert.ok(hello.rev, 'should have a revision number')
-    return db.attachment.get('new_binary', 'att')
-  }).then(function (binaryData) {
-    assert.equal('123', binaryData.toString(), 'binary data is reflexive')
-    assert.end()
-  })
-})
diff --git a/tests/integration/attachment/insert.js b/tests/integration/attachment/insert.js
deleted file mode 100644
index a2b09e5..0000000
--- a/tests/integration/attachment/insert.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-
-it('should be able to insert a simple attachment', function (assert) {
-  const p = db.attachment.insert('new', 'att', 'Hello World!', 'text/plain')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (att) {
-    assert.equal(att.ok, true, 'response ok')
-    assert.ok(att.rev, 'should have a revision')
-    assert.end()
-  })
-})
diff --git a/tests/integration/attachment/pipe.js b/tests/integration/attachment/pipe.js
deleted file mode 100644
index f0cb326..0000000
--- a/tests/integration/attachment/pipe.js
+++ /dev/null
@@ -1,65 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const fs = require('fs')
-const path = require('path')
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const it = harness.it
-const pixel = helpers.pixel
-
-it('should be able to pipe to a writeStream', function (assert) {
-  const buffer = Buffer.from(pixel, 'base64')
-  const filename = path.join(__dirname, '.temp.bmp')
-
-  db.attachment.insert('new', 'att', buffer, 'image/bmp')
-    .then(function (bmp) {
-      const ws = fs.createWriteStream(filename)
-
-      ws.on('close', function () {
-        assert.equal(fs.readFileSync(filename).toString('base64'), pixel)
-        fs.unlinkSync(filename)
-        assert.end()
-      })
-      db.attachment.getAsStream('new', 'att', { rev: bmp.rev }).pipe(ws)
-    })
-})
-
-it('should be able to pipe to a writeStream', function (assert) {
-  const ws = fs.createWriteStream('/dev/null')
-  const rs = db.attachment.getAsStream('new', 'att')
-  rs.pipe(ws)
-  rs.on('end', function () {
-    assert.end()
-  })
-})
-
-it('should be able to pipe from a readStream', function (assert) {
-  const logo = path.join(__dirname, '..', '..', 'fixtures', 'logo.png')
-  const rs = fs.createReadStream(logo)
-  const is = db.attachment.insertAsStream('nodejs', 'logo.png', null, 'image/png')
-
-  is.on('end', function () {
-    db.attachment.get('nodejs', 'logo.png', function (err, buffer) {
-      assert.equal(err, null, 'should get the logo')
-      assert.equal(
-        fs.readFileSync(logo).toString('base64'), buffer.toString('base64'),
-        'logo should remain unchanged')
-      assert.end()
-    })
-  })
-
-  rs.pipe(is)
-})
diff --git a/tests/integration/attachment/update.js b/tests/integration/attachment/update.js
deleted file mode 100644
index 1af111a..0000000
--- a/tests/integration/attachment/update.js
+++ /dev/null
@@ -1,43 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const pixel = helpers.pixel
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const it = harness.it
-
-it('should be able to insert and update attachments', function (assert) {
-  const buffer = Buffer.from(pixel, 'base64')
-  const p = db.attachment.insert('new', 'att', 'Hello', 'text/plain')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (hello) {
-    assert.equal(hello.ok, true, 'response ok')
-    assert.ok(hello.rev, 'should have a revision')
-    return db.attachment.insert('new', 'att', buffer, 'image/bmp', { rev: hello.rev })
-  }).then(function (bmp) {
-    assert.ok(bmp.rev, 'should store a revision')
-    assert.end()
-  })
-})
-
-it('should be able to fetch the updated pixel', function (assert) {
-  db.get('new').then(function (newDoc) {
-    newDoc.works = true
-    return db.insert(newDoc, 'new')
-  }).then(function (response) {
-    assert.equal(response.ok, true, 'response ok')
-    assert.end()
-  })
-})
diff --git a/tests/integration/database/changes.js b/tests/integration/database/changes.js
deleted file mode 100644
index c8571c9..0000000
--- a/tests/integration/database/changes.js
+++ /dev/null
@@ -1,61 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const it = harness.it
-
-it('should be able to insert three documents', helpers.insertThree)
-
-it('should be able to receive changes since seq:0', function (assert) {
-  const p = db.changes({ since: 0 })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (response) {
-    assert.equal(response.results.length, 3, 'gets three results')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to receive changes since seq:0 as stream', function (assert) {
-  const resp = []
-  const p = db.changesAsStream({ since: 0 })
-    .on('data', function (part) {
-      resp.push(part)
-    })
-    .on('error', function (error) {
-      assert.ifError(error)
-    })
-    .on('end', function () {
-      const response = JSON.parse(Buffer.concat(resp).toString('utf8'))
-      assert.equal(response.results.length, 3, 'gets three results')
-      assert.end()
-    })
-  assert.ok(!helpers.isPromise(p), 'returns Promise')
-  assert.equal(p.constructor.name, 'Request', 'returns a Request')
-})
-
-it('should be able to receive changes - no params - stream', function (assert) {
-  const p = db.changesAsStream()
-    .on('error', function (error) {
-      assert.ifError(error)
-    })
-    .on('end', function () {
-      assert.end()
-    })
-  assert.ok(!helpers.isPromise(p), 'returns Promise')
-  assert.equal(p.constructor.name, 'Request', 'returns a Request')
-})
diff --git a/tests/integration/database/compact.js b/tests/integration/database/compact.js
deleted file mode 100644
index 4a08b65..0000000
--- a/tests/integration/database/compact.js
+++ /dev/null
@@ -1,64 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-
-it('should store and delete `goofy`', function (assert) {
-  let p = db.insert({ 'foo': 'baz' }, 'goofy')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (foo) {
-    assert.equal(foo.ok, true, 'response should be ok')
-    return db.destroy('goofy', foo.rev)
-  }).then(function (response) {
-    assert.equal(response.ok, true, 'response ok')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should have run the compaction', function (assert) {
-  const p = db.compact()
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function () {
-    return db.info()
-  }).then(function (info) {
-    assert.equal(info['doc_count'], 0, 'document count is not 3')
-    assert.equal(info['doc_del_count'], 1, 'document should be deleted')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should finish compaction before ending', function (assert) {
-  function nextWhenFinished () {
-    db.info(function (err, info) {
-      if (err) {
-        return
-      }
-      if (info['compact_running']) {
-        return
-      }
-      clearTimeout(task)
-      assert.pass('compaction is complete')
-      assert.end()
-    })
-  }
-
-  const task = setInterval(nextWhenFinished, 100)
-})
diff --git a/tests/integration/database/create-and-destroy.js b/tests/integration/database/create-and-destroy.js
deleted file mode 100644
index 031e5b3..0000000
--- a/tests/integration/database/create-and-destroy.js
+++ /dev/null
@@ -1,62 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const async = require('async')
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const nano = harness.locals.nano
-
-it('should be able to create `az09_$()+-/` database', function (assert) {
-  nano.db.create('az09_$()+-/').then(function () {
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to create a database without query parameters', function (assert) {
-  nano.db.create('newdb1').then(function (body) {
-    assert.ok(body.ok)
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to create a database with query parameters', function (assert) {
-  nano.db.create('newdb2', { q: 1, n: 3 }).then(function (body) {
-    assert.ok(body.ok)
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to use config from a nano object to create a db',
-  function (assert) {
-    const config = helpers.Nano(
-      helpers.couch + '/' + encodeURIComponent('with/slash')).config
-    helpers.Nano(config.url).db.create(config.db, function (err) {
-      assert.equal(err, null, 'should create database')
-      assert.end()
-    })
-  })
-
-it('must destroy the databases we created', function (assert) {
-  async.forEach(['az09_$()+-/', 'with/slash'], nano.db.destroy, function (err) {
-    assert.equal(err, null, 'should destroy all dbs')
-    assert.end()
-  })
-})
diff --git a/tests/integration/database/follow.js b/tests/integration/database/follow.js
deleted file mode 100644
index 613699d..0000000
--- a/tests/integration/database/follow.js
+++ /dev/null
@@ -1,50 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-
-if (helpers.unmocked) {
-  it('should insert a bunch of items', helpers.insertThree)
-
-  let feed1
-
-  it('should be able to get the changes feed', function (assert) {
-    let i = 3
-
-    feed1 = db.follow({ since: '0' })
-
-    feed1.on('change', function (change) {
-      assert.ok(change, 'change existed')
-      // assert.equal(change.seq, i + 1, 'seq is set correctly');
-      ++i
-      if (i === 4) {
-        assert.end()
-      }
-    })
-
-    feed1.follow()
-
-    setTimeout(function () {
-      db.insert({ 'bar': 'baz' }, 'barbaz')
-    }, 100)
-  })
-
-  it('should clear changes feed', function (assert) {
-    feed1.die()
-    assert.end()
-  })
-}
diff --git a/tests/integration/database/get.js b/tests/integration/database/get.js
deleted file mode 100644
index 53139e7..0000000
--- a/tests/integration/database/get.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const nano = harness.locals.nano
-
-it('should be able to fetch the database', function (assert) {
-  const p = nano.db.get('database_get')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (response) {
-    assert.equal(response['doc_count'], 0, 'should be empty')
-    assert.equal(response['db_name'], 'database_get', 'name')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('resolves db URL correctly for http://app.com/_couchdb', function (assert) {
-  const nano = require('../../../lib/nano')
-
-  const couch = nano({
-    url: 'http://app.com/_couchdb/',
-    parseUrl: false,
-    request: function (options) {
-      assert.equal(
-        options.uri,
-        'http://app.com/_couchdb/mydb/mydoc',
-        'should get doc at prefixed path'
-      )
-      assert.end()
-    }
-  })
-  couch.use('mydb').get('mydoc')
-})
diff --git a/tests/integration/database/list.js b/tests/integration/database/list.js
deleted file mode 100644
index fdbf575..0000000
--- a/tests/integration/database/list.js
+++ /dev/null
@@ -1,56 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const nano = harness.locals.nano
-
-it('should create _replicator', function (assert) {
-  nano.db.create('_replicator').then(function () {
-    assert.end()
-  }).catch(function () {
-    assert.end()
-  })
-})
-
-it('should destroy _users', function (assert) {
-  nano.db.destroy('_users').then(function () {
-    assert.end()
-  }).catch(function () {
-    assert.end()
-  })
-})
-
-it('should crestr _users', function (assert) {
-  nano.db.create('_users').then(function () {
-    assert.end()
-  }).catch(function () {
-    assert.end()
-  })
-})
-
-it('should list the correct databases', function (assert) {
-  const p = nano.db.list()
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (list) {
-    const filtered = list.filter(function (e) {
-      return e === 'database_list' || e === '_replicator' || e === '_users'
-    })
-    assert.equal(filtered.length, 3, 'should have exactly 3 dbs')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
diff --git a/tests/integration/database/replicate.js b/tests/integration/database/replicate.js
deleted file mode 100644
index b140ca4..0000000
--- a/tests/integration/database/replicate.js
+++ /dev/null
@@ -1,80 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const async = require('async')
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-const nano = harness.locals.nano
-
-let replica
-let replica2
-
-it('should insert a bunch of items', helpers.insertThree)
-
-it('creates a bunch of database replicas', function (assert) {
-  async.forEach(['database_replica', 'database_replica2'],
-    nano.db.create, function (error) {
-      assert.equal(error, null, 'created database(s)')
-      assert.end()
-    })
-})
-
-it('should be able to replicate three docs', function (assert) {
-  replica = nano.use('database_replica')
-  const p = db.replicate('database_replica')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function () {
-    return replica.list()
-  }).then(function (list) {
-    assert.equal(list['total_rows'], 3, 'and have three documents')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to replicate to a `nano` object', function (assert) {
-  replica2 = nano.use('database_replica2')
-  let p = nano.db.replicate(db, replica2)
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function () {
-    return replica2.list()
-  }).then(function (list) {
-    assert.equal(list['total_rows'], 3, 'and have three documents')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to replicate with params', function (assert) {
-  const p = db.replicate('database_replica', {})
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function () {
-    assert.ok(true, 'Promise is resolved')
-    assert.end()
-  }).catch(function (e) {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should destroy the extra databases', function (assert) {
-  async.forEach(['database_replica', 'database_replica2'],
-    nano.db.destroy, function (error) {
-      assert.equal(error, null, 'deleted databases')
-      assert.end()
-    })
-})
diff --git a/tests/integration/database/replicator.js b/tests/integration/database/replicator.js
deleted file mode 100644
index b22aa8b..0000000
--- a/tests/integration/database/replicator.js
+++ /dev/null
@@ -1,140 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const async = require('async')
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-// const db = harness.locals.db
-const nano = harness.locals.nano
-
-// let replica
-// let replica2
-// let replica3
-
-it('should insert a bunch of items', helpers.insertThree)
-
-it('creates a bunch of database replicas', function (assert) {
-  async.forEach(['database_replica', 'database_replica2', 'database_replica3'],
-    nano.db.create, function (error) {
-      assert.equal(error, null, 'created database(s)')
-      assert.end()
-    })
-})
-/*
-it('should be able to replicate (replicator) three docs', function (assert) {
-  assert.timeoutAfter(10000)
-  replica = nano.use('database_replica')
-  db.replication.enable('database_replica', function (error, data) {
-    assert.equal(error, null, 'replication should not fail')
-    assert.true(data, 'replication should be scheduled')
-    assert.true(data.ok, 'replication should be scheduled')
-    assert.true(data.id, 'replication should return the id to query back')
-    function waitForReplication () {
-      setTimeout(function () {
-        db.replication.query(data.id, function (error, reply) {
-          assert.equal(error, null, 'replication should not fail')
-          // assert.equal(reply.target, 'database_replica', 'target db should match')
-          assert.equal(reply._replication_state, 'completed', 'replication should have triggered')
-          replica.list(function (error, list) {
-            assert.equal(error, null, 'should be able to invoke list')
-            assert.equal(list['total_rows'], 3, 'and have three documents')
-            db.replication.disable(reply._id, reply._rev, function (error, disabled) {
-              assert.equal(error, null, 'replication should not fail')
-              assert.true(disabled, 'should not be null')
-              assert.true(disabled.ok, 'should have stopped the replication')
-              assert.end()
-            })
-          })
-        })
-      },
-      4500)
-    }
-    waitForReplication()
-  })
-})
-*/
-/*
-it('should be able to replicate (replicator) to a `nano` object', function (assert) {
-  replica2 = nano.use('database_replica2')
-  nano.db.replication.enable(db, 'database_replica2', function (error, data) {
-    assert.equal(error, null, 'replication should not fail')
-    assert.true(data, 'replication should be scheduled')
-    assert.true(data.ok, 'replication should be scheduled')
-    assert.true(data.id, 'replication should return the id to query back')
-    function waitForReplication () {
-      setTimeout(function () {
-        nano.db.replication.query(data.id, function (error, reply) {
-          assert.equal(error, null, 'replication should not fail')
-          // assert.equal(reply.target, 'database_replica2', 'target db should match')
-          assert.equal(reply._replication_state, 'completed', 'replication should have triggered')
-          replica2.list(function (error, list) {
-            assert.equal(error, null, 'should be able to invoke list')
-            assert.equal(list['total_rows'], 3, 'and have three documents')
-            nano.db.replication.disable(reply._id, reply._rev, function (error, disabled) {
-              assert.equal(error, null, 'replication should not fail')
-              assert.true(disabled, 'should not be null')
-              assert.true(disabled.ok, 'should have stopped the replication')
-              assert.end()
-            })
-          })
-        })
-      },
-      4500)
-    }
-    waitForReplication()
-  })
-})
-*/
-/*
-it('should be able to replicate (replicator) with params', function (assert) {
-  assert.timeoutAfter(10000)
-  replica3 = nano.use('database_replica3')
-  db.replication.enable('database_replica3', {}, function (error, data) {
-    assert.equal(error, null, 'replication should not fail')
-    assert.true(data, 'replication should be scheduled')
-    assert.true(data.ok, 'replication should be scheduled')
-    assert.true(data.id, 'replication should return the id to query back')
-    function waitForReplication () {
-      setTimeout(function () {
-        db.replication.query(data.id, function (error, reply) {
-          assert.equal(error, null, 'replication should not fail')
-          // assert.equal(reply.target, 'database_replica3', 'target db should match')
-          assert.equal(reply._replication_state, 'completed', 'replication should have triggered')
-          replica3.list(function (error, list) {
-            assert.equal(error, null, 'should be able to invoke list')
-            assert.equal(list['total_rows'], 3, 'and have three documents')
-            db.replication.disable(reply._id, reply._rev, function (error, disabled) {
-              assert.equal(error, null, 'replication should not fail')
-              assert.true(disabled, 'should not be null')
-              assert.true(disabled.ok, 'should have stopped the replication')
-              assert.end()
-            })
-          })
-        })
-      },
-      8500)
-    }
-    waitForReplication()
-  })
-})
-*/
-
-it('should destroy the extra databases', function (assert) {
-  async.forEach(['database_replica', 'database_replica2', 'database_replica3'],
-    nano.db.destroy, function (error) {
-      assert.equal(error, null, 'deleted databases')
-      assert.end()
-    })
-})
diff --git a/tests/integration/design/atomic.js b/tests/integration/design/atomic.js
deleted file mode 100644
index 77fdf34..0000000
--- a/tests/integration/design/atomic.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-
-it('should be able to insert an atomic design doc', function (assert) {
-  const p = db.insert({
-    updates: {
-      inplace: function (doc, req) {
-        const body = JSON.parse(req.body)
-        doc[body.field] = body.value
-        return [doc, JSON.stringify(doc)]
-      },
-      addbaz: function (doc) {
-        doc.baz = 'biz'
-        return [doc, JSON.stringify(doc)]
-      }
-    }
-  }, '_design/update')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function () {
-    return db.insert({ 'foo': 'baz' }, 'foobar')
-  }).then(function (foo) {
-    assert.equal(foo.ok, true, 'does not have an attitude')
-    assert.ok(foo.rev, 'got the revisions')
-    assert.end()
-  })
-})
-
-it('should be able to insert atomically', function (assert) {
-  const p = db.atomic('update', 'inplace', 'foobar', {
-    field: 'foo',
-    value: 'bar'
-  })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (response) {
-    assert.equal(response.foo, 'bar', 'and the right value was set')
-    assert.end()
-  })
-})
-
-it('should be able to update atomically without a body', function (assert) {
-  const p = db.insert({}, 'baz')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function () {
-    return db.atomic('update', 'addbaz', 'baz')
-  }).then(function (response) {
-    assert.equal(response.baz, 'biz', 'and the new field is present')
-    assert.end()
-  })
-})
-
-it('should be able to update with slashes on the id', function (assert) {
-  const p = db.insert({ 'wat': 'wat' }, 'wat/wat')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (foo) {
-    assert.equal(foo.ok, true, 'response ok')
-    return db.atomic('update', 'inplace', 'wat/wat', { field: 'wat', value: 'dawg' })
-  }).then(function (response) {
-    assert.equal(response.wat, 'dawg', 'with the right copy')
-    assert.end()
-  })
-})
diff --git a/tests/integration/design/compact.js b/tests/integration/design/compact.js
deleted file mode 100644
index 9d83c0d..0000000
--- a/tests/integration/design/compact.js
+++ /dev/null
@@ -1,42 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const async = require('async')
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-
-it('should insert `alice` the design doc', function (assert) {
-  async.waterfall([
-    function (next) {
-      db.insert({
-        views: {
-          'by_id': {
-            map: 'function(doc) { emit(doc._id, doc); }'
-          }
-        }
-      }, '_design/alice', next)
-    },
-    function (data, _, next) {
-      db.insert({ 'foo': 'baz' }, 'foobaz', next)
-    },
-    function (foo, _, next) {
-      db.destroy('foobaz', foo.rev, next)
-    }
-  ], function (err) {
-    assert.equal(err, null, 'it should destroy the foo')
-    assert.end()
-  })
-})
diff --git a/tests/integration/design/list.js b/tests/integration/design/list.js
deleted file mode 100644
index 5195dbd..0000000
--- a/tests/integration/design/list.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-
-it('should create a ddoc and insert some docs', helpers.prepareAView)
-
-it('should get the people by running the ddoc', function (assert) {
-  const p = db.viewWithList('people', 'by_name_and_city', 'my_list', {
-    key: [
-      'Derek',
-      'San Francisco'
-    ]
-  })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (list) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(list, 'Hello', 'and list should be `hello`')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
diff --git a/tests/integration/design/multiple.js b/tests/integration/design/multiple.js
deleted file mode 100644
index 1c86a10..0000000
--- a/tests/integration/design/multiple.js
+++ /dev/null
@@ -1,78 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-
-it('should be able to insert docs and design doc', function (assert) {
-  const p = db.insert({
-    views: {
-      'by_id': {
-        map: 'function(doc) { emit(doc._id, doc); }'
-      }
-    }
-  }, '_design/alice')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (response) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(response.ok, true, 'response ok')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should insert a bunch of items', helpers.insertThree)
-
-it('get multiple docs with a composed key', function (assert) {
-  const p = db.view('alice', 'by_id', {
-    keys: ['foobar', 'barfoo'],
-    'include_docs': true
-  })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (view) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(view.rows.length, 2, 'has more or less than two rows')
-    assert.equal(view.rows[0].id, 'foobar', 'foo is not the first id')
-    assert.equal(view.rows[1].id, 'barfoo', 'bar is not the second id')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('get multiple docs with a composed key as a stream', function (assert) {
-  const resp = []
-  const p = db.viewAsStream('alice', 'by_id', {
-    keys: ['foobar', 'barfoo'],
-    'include_docs': true
-  })
-    .on('data', function (part) {
-      resp.push(part)
-    })
-    .on('error', function (error) {
-      assert.ifError(error)
-    })
-    .on('end', function () {
-      const view = JSON.parse(Buffer.concat(resp).toString('utf8'))
-      assert.equal(view.rows.length, 2, 'has more or less than two rows')
-      assert.equal(view.rows[0].id, 'foobar', 'foo is not the first id')
-      assert.equal(view.rows[1].id, 'barfoo', 'bar is not the second id')
-      assert.end()
-    })
-  assert.ok(!helpers.isPromise(p), 'does not returns Promise')
-  assert.equal(p.constructor.name, 'Request', 'returns a Request')
-})
diff --git a/tests/integration/design/query.js b/tests/integration/design/query.js
deleted file mode 100644
index 790e9ba..0000000
--- a/tests/integration/design/query.js
+++ /dev/null
@@ -1,73 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const async = require('async')
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-const viewDerek = helpers.viewDerek
-
-const opts = { key: ['Derek', 'San Francisco'] }
-
-it('should create a ddoc and insert some docs', helpers.prepareAView)
-
-it('should respond with derek when asked for derek', function (assert) {
-  viewDerek(db, assert, opts, assert.end)
-})
-
-it('should have no cloning issues when doing queries', function (assert) {
-  async.waterfall([
-    function (next) { viewDerek(db, assert, opts, next) },
-    function (next) { viewDerek(db, assert, opts, next) }
-  ], function (err) {
-    assert.equal(err, null, 'no errors')
-    assert.ok(Array.isArray(opts.key))
-    assert.equal(opts.key[0], 'Derek')
-    assert.equal(opts.key[1], 'San Francisco')
-    assert.end()
-  })
-})
-
-var multipleQueryOpts = {
-  queries: [
-    {
-      keys: [
-        ['Derek', 'San Francisco'],
-        ['Nuno', 'London']
-      ]
-    },
-    {
-      skip: 2,
-      limit: 1
-    }
-  ]
-}
-
-var expectedResults =
-  [
-    { total_rows: 3, offset: 0, rows: [{ id: 'p_derek', key: ['Derek', 'San Francisco'], value: 'p_derek' }, { id: 'p_nuno', key: ['Nuno', 'London'], value: 'p_nuno' }] },
-    { total_rows: 3, offset: 2, rows: [{ id: 'p_randall', key: ['Randall', 'San Francisco'], value: 'p_randall' }] }
-  ]
-
-it('should support multiple view queries', function (assert) {
-  db.view('people', 'by_name_and_city', multipleQueryOpts, function (error, response) {
-    assert.equal(error, null, 'no errors')
-    assert.ok(response.results, 'should return query results')
-    assert.ok(Array.isArray(response.results), 'query results should be array')
-    assert.equal(response.results.length, 2, 'should return results to both queries')
-    assert.deepEqual(response.results, expectedResults, 'should be expected query results')
-    assert.end()
-  })
-})
diff --git a/tests/integration/design/search.js b/tests/integration/design/search.js
deleted file mode 100644
index e406657..0000000
--- a/tests/integration/design/search.js
+++ /dev/null
@@ -1,49 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const async = require('async')
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-const viewDerek = helpers.viewDerek
-
-//
-// these are cloudant only
-// tests do no run without mocks
-//
-if (helpers.mocked) {
-  const opts = { key: ['Derek', 'San Francisco'] }
-
-  it('should create a ddoc and insert some docs', function (assert) {
-    helpers.prepareAView(assert, '/_search', db)
-  })
-
-  it('should respond with derek when asked for derek', function (assert) {
-    viewDerek(db, assert, opts, assert.end, 'search')
-  })
-
-  it('should have no cloning issues when doing queries', function (assert) {
-    async.waterfall([
-      function (next) { viewDerek(db, assert, opts, next, 'search') },
-      function (next) { viewDerek(db, assert, opts, next, 'search') }
-    ], function (err) {
-      assert.equal(err, null, 'no errors')
-      assert.ok(Array.isArray(opts.key))
-      assert.equal(opts.key[0], 'Derek')
-      assert.equal(opts.key[1], 'San Francisco')
-      assert.end()
-    })
-  })
-}
diff --git a/tests/integration/design/show.js b/tests/integration/design/show.js
deleted file mode 100644
index 8d7c33e..0000000
--- a/tests/integration/design/show.js
+++ /dev/null
@@ -1,99 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const async = require('async')
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-
-it('should insert a show ddoc', function (assert) {
-  db.insert({
-    shows: {
-      singleDoc: function (doc, req) {
-        if (req.query.format === 'json' || !req.query.format) {
-          return {
-            body: JSON.stringify({
-              name: doc.name,
-              city: doc.city,
-              format: 'json'
-            }),
-            headers: {
-              'Content-Type': 'application/json'
-            }
-          }
-        }
-        if (req.query.format === 'html') {
-          return {
-            body: 'Hello Clemens!',
-            headers: {
-              'Content-Type': 'text/html'
-            }
-          }
-        }
-      }
-    }
-  }, '_design/people', function (error, response) {
-    assert.equal(error, null, 'should start the show')
-    assert.equal(response.ok, true, 'response ok')
-    async.parallel([
-      function (cb) {
-        db.insert({
-          name: 'Clemens',
-          city: 'Dresden'
-        }, 'p_clemens', cb)
-      },
-      function (cb) {
-        db.insert({
-          name: 'Randall',
-          city: 'San Francisco'
-        }, 'p_randall', cb)
-      }, function (cb) {
-        db.insert({
-          name: 'Nuno',
-          city: 'New York'
-        }, 'p_nuno', cb)
-      }
-    ], function (error) {
-      assert.equal(error, null, 'stores docs')
-      assert.end()
-    })
-  })
-})
-
-it('should show the amazing clemens in json', function (assert) {
-  const p = db.show('people', 'singleDoc', 'p_clemens')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (doc) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(doc.name, 'Clemens')
-    assert.equal(doc.city, 'Dresden')
-    assert.equal(doc.format, 'json')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should show the amazing clemens in html', function (assert) {
-  db.show('people', 'singleDoc', 'p_clemens', { format: 'html' },
-    function (error, doc, rh) {
-      assert.equal(error, null, 'should work')
-      if (helpers.unmocked) {
-        assert.equal(rh['content-type'], 'text/html')
-      }
-      assert.equal(doc, 'Hello Clemens!')
-      assert.end()
-    })
-})
diff --git a/tests/integration/document/bulk.js b/tests/integration/document/bulk.js
deleted file mode 100644
index 5ee9f57..0000000
--- a/tests/integration/document/bulk.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-
-it('should be able to bulk insert two docs', function (assert) {
-  const p = db.bulk({
-    'docs': [
-      { 'key': 'baz', 'name': 'bazzel' },
-      { 'key': 'bar', 'name': 'barry' }
-    ]
-  })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (response) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(response.length, 2, 'has two docs')
-    assert.ok(response[0].id, 'first got id')
-    assert.ok(response[1].id, 'other also got id')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
diff --git a/tests/integration/document/copy.js b/tests/integration/document/copy.js
deleted file mode 100644
index 935e314..0000000
--- a/tests/integration/document/copy.js
+++ /dev/null
@@ -1,66 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-
-it('must insert two docs before the tests start', function (assert) {
-  db.insert({ 'foo': 'baz' }, 'foo_src', function (error, src) {
-    assert.equal(error, null, 'stores src')
-    assert.equal(src.ok, true, 'response ok')
-    assert.ok(src.rev, 'haz rev')
-    db.insert({ 'bar': 'qux' }, 'foo_dest', function (error, dest) {
-      assert.equal(error, null, 'stores dest')
-      assert.equal(dest.ok, true, 'oki doki')
-      assert.ok(dest.rev, 'response has rev')
-      assert.end()
-    })
-  })
-})
-
-it('should be able to copy and overwrite a document', function (assert) {
-  const p = db.copy('foo_src', 'foo_dest', { overwrite: true })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function () {
-    assert.ok(true, 'Promise is resolved')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('copy without overwrite should return conflict for exists docs',
-  function (assert) {
-    const p = db.copy('foo_src', 'foo_dest')
-    assert.ok(helpers.isPromise(p), 'returns Promise')
-    p.then(function () {
-      assert.ok(false, 'Promise is resolved')
-    }).catch(function () {
-      assert.ok(true, 'Promise is rejected')
-      assert.end()
-    })
-  })
-
-it('copy to a new destination should work', function (assert) {
-  const p = db.copy('foo_src', 'baz_dest')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function () {
-    assert.ok(true, 'Promise is resolved')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
diff --git a/tests/integration/document/create_index.js b/tests/integration/document/create_index.js
deleted file mode 100644
index 4327463..0000000
--- a/tests/integration/document/create_index.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const it = harness.it
-
-it('should insert a one item', helpers.insertOne)
-
-it('Should create one simple index', function (assert) {
-  const p = db.createIndex({
-    name: 'fooindex',
-    index: { fields: ['foo'] }
-  })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (foo) {
-    assert.equal(foo.result, 'created', 'index should be created')
-    assert.equal(foo.name, 'fooindex', 'index should have correct name')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
diff --git a/tests/integration/document/destroy.js b/tests/integration/document/destroy.js
deleted file mode 100644
index 7e29bb3..0000000
--- a/tests/integration/document/destroy.js
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-const db = harness.locals.db
-
-let rev
-
-it('should insert a document', function (assert) {
-  db.insert({ 'foo': 'baz' }, 'foobaz', function (error, foo) {
-    assert.equal(error, null, 'stores foo')
-    assert.equal(foo.ok, true, 'ok response')
-    assert.ok(foo.rev, 'response with rev')
-    rev = foo.rev
-    assert.end()
-  })
-})
-
-it('should not delete a db', function (assert) {
-  const p = db.destroy(undefined, undefined)
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function () {
-    assert.ok(false, 'Promise is resolved')
-    assert.end()
-  }).catch(function () {
-    assert.ok(true, 'Promise is rejected')
-    assert.end()
-  })
-})
-
-it('should delete a document', function (assert) {
-  const p = db.destroy('foobaz', rev)
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (response) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(response.ok, true, 'ok!')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
diff --git a/tests/integration/document/fetch.js b/tests/integration/document/fetch.js
deleted file mode 100644
index 8e5963f..0000000
--- a/tests/integration/document/fetch.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const it = harness.it
-
-it('should insert a bunch of items', helpers.insertThree)
-
-it('should be able to fetch with one key', function (assert) {
-  const p = db.fetch({ keys: ['foobar'] })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (docs) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(docs.rows.length, 1, 'and get one row')
-    assert.equal(docs['total_rows'], 3, 'out of 3')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to fetch with multiple keys', function (assert) {
-  const p = db.fetch({ keys: ['foobar', 'barfoo'] })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (docs) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(docs.rows.length, 2, 'two rows')
-    assert.equal(docs['total_rows'], 3, 'out of 3')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to fetch with params', function (assert) {
-  const p = db.fetch({ keys: ['foobar'] }, { not: 'important' })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (docs) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(docs.rows.length, 1, 'and get one row')
-    assert.equal(docs['total_rows'], 3, 'out of 3')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
diff --git a/tests/integration/document/fetch_revs.js b/tests/integration/document/fetch_revs.js
deleted file mode 100644
index 992f3f6..0000000
--- a/tests/integration/document/fetch_revs.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const it = harness.it
-
-it('should insert a bunch of items', helpers.insertThree)
-
-it('should be able to fetch with one key', function (assert) {
-  const p = db.fetchRevs({ keys: ['foobar'] })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (docs) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(docs.rows.length, 1, 'and get one row')
-    assert.equal(docs['total_rows'], 3, 'out of 3')
-    assert.equal(docs.rows[0].doc, undefined, 'rev should not return key')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to fetch with multiple keys', function (assert) {
-  const p = db.fetchRevs({ keys: ['foobar', 'barfoo'] })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (docs) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(docs.rows.length, 2, 'two rows')
-    assert.equal(docs['total_rows'], 3, 'out of 3')
-    assert.equal(docs.rows[0].doc, undefined, 'no doc in 1')
-    assert.equal(docs.rows[1].doc, undefined, 'no doc in 2')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to fetch with params', function (assert) {
-  const p = db.fetchRevs({ keys: ['foobar'] }, { still: 'no' })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (docs) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(docs.rows.length, 1, 'and get one row')
-    assert.equal(docs['total_rows'], 3, 'out of 3')
-    assert.equal(docs.rows[0].doc, undefined, 'rev should not return key')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
diff --git a/tests/integration/document/find.js b/tests/integration/document/find.js
deleted file mode 100644
index 0d07c50..0000000
--- a/tests/integration/document/find.js
+++ /dev/null
@@ -1,50 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const it = harness.it
-
-it('should insert a bunch of items', helpers.insertThree)
-
-it('should be to do a mango query', function (assert) {
-  const p = db.find({ selector: { foo: 'baz' } })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (response) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(response.docs.length, 1, 'and get one row')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be to do a mango query with streams', function (assert) {
-  const resp = []
-  const p = db.findAsStream({ selector: { foo: 'baz' } })
-    .on('data', function (part) {
-      resp.push(part)
-    })
-    .on('error', function (error) {
-      assert.ifError(error)
-    })
-    .on('end', function () {
-      const response = JSON.parse(Buffer.concat(resp).toString('utf8'))
-      assert.equal(response.docs.length, 1, 'and get one row')
-      assert.end()
-    })
-  assert.ok(!helpers.isPromise(p), 'does not return Promise')
-  assert.equal(p.constructor.name, 'Request', 'returns a Request')
-})
diff --git a/tests/integration/document/get.js b/tests/integration/document/get.js
deleted file mode 100644
index 5886e07..0000000
--- a/tests/integration/document/get.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const it = harness.it
-
-it('should insert a one item', helpers.insertOne)
-
-it('should get the document', function (assert) {
-  const p = db.get('foobaz', { 'revs_info': true })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (foobaz) {
-    assert.ok(true, 'Promise is resolved')
-    assert.ok(foobaz['_revs_info'], 'got revs info')
-    assert.equal(foobaz._id, 'foobaz', 'id is food')
-    assert.equal(foobaz.foo, 'baz', 'baz is in foo')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
diff --git a/tests/integration/document/head.js b/tests/integration/document/head.js
deleted file mode 100644
index a55dc8e..0000000
--- a/tests/integration/document/head.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const it = harness.it
-
-it('should insert a one item', helpers.insertOne)
-
-it('should get a status code when you do head - promises', function (assert) {
-  const p = db.head('foobaz')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (docs) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(docs['statusCode'], 200, 'and is ok')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should get a status code when you do head - callbacks', function (assert) {
-  db.head('foobaz', function (error, body, headers) {
-    assert.equal(error, null, 'should get the head of foobaz')
-    assert.equal(headers['statusCode'], 200, 'and is ok')
-    assert.end()
-  })
-})
diff --git a/tests/integration/document/insert.js b/tests/integration/document/insert.js
deleted file mode 100644
index ff6272c..0000000
--- a/tests/integration/document/insert.js
+++ /dev/null
@@ -1,82 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const it = harness.it
-
-let rev
-
-it('should insert one simple document', function (assert) {
-  const p = db.insert({ 'foo': 'baz' }, 'foobaz')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (foo) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(foo.ok, true, 'response should be ok')
-    assert.ok(foo.rev, 'response should have rev')
-    rev = foo.rev
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should fail to insert again since it already exists', function (assert) {
-  const p = db.insert({}, 'foobaz')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function () {
-    assert.ok(false, 'Promise is resolved')
-  }).catch(function (error) {
-    assert.ok(true, 'Promise is rejected')
-    assert.equal(error.scope, 'couch', 'scope is couch')
-    assert.equal(error.error, 'conflict', 'type is conflict')
-    assert.end()
-  })
-})
-
-it('should be able to use custom params in insert', function (assert) {
-  const p = db.insert({
-    foo: 'baz',
-    _rev: rev
-  }, {
-    docName: 'foobaz',
-    'new_edits': false
-  })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (foo) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(foo.ok, true, 'response should be ok')
-    assert.ok(foo.rev, 'response should have rev')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to insert functions in docs', function (assert) {
-  db.insert({
-    fn: function () { return true },
-    fn2: 'function () { return true }'
-  }).then(function (fns) {
-    assert.equal(fns.ok, true, 'response should be ok')
-    assert.ok(fns.rev, 'response should have rev')
-    return db.get(fns.id)
-  }).then(function (fns) {
-    assert.equal(fns.fn, fns.fn2, 'fn matches fn2')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
diff --git a/tests/integration/document/list.js b/tests/integration/document/list.js
deleted file mode 100644
index 0ebc8f5..0000000
--- a/tests/integration/document/list.js
+++ /dev/null
@@ -1,130 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const nano = harness.locals.nano
-const it = harness.it
-
-it('should insert a bunch of items', helpers.insertThree)
-
-it('should list the three documents', function (assert) {
-  const p = db.list()
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (docs) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(docs['total_rows'], 3, 'with total three rows')
-    assert.ok(docs.rows, 'and the rows themselves')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to list using the `relax` function', function (assert) {
-  nano.relax({
-    db: 'document_list',
-    doc: '_all_docs',
-    method: 'GET',
-    qs: { limit: 1 }
-  }, function (error, docs) {
-    assert.equal(error, null, 'not relaxed')
-    assert.ok(docs.rows, 'got meh rows')
-    assert.equal(docs.rows.length, 1, 'but its only one #sadpanda')
-    assert.equal(docs['total_rows'], 3, 'out of three')
-    assert.end()
-  })
-})
-
-it('should be able to list with a start_key', function (assert) {
-  const p = db.list({ start_key: 'c' })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (docs) {
-    assert.ok(true, 'Promise is resolved')
-    assert.ok(docs.rows, 'get the rows')
-    assert.equal(docs.rows.length, 2, 'starts in row two')
-    assert.equal(docs['total_rows'], 3, 'out of three rows')
-    assert.equal(docs.offset, 1, 'offset is 1')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to list with a startkey', function (assert) {
-  const p = db.list({ startkey: 'c' })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (docs) {
-    assert.ok(true, 'Promise is resolved')
-    assert.ok(docs.rows, 'get the rows')
-    assert.equal(docs.rows.length, 2, 'starts in row two')
-    assert.equal(docs['total_rows'], 3, 'out of three rows')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to list with a endkey', function (assert) {
-  const p = db.list({ endkey: 's' })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (docs) {
-    assert.ok(true, 'Promise is resolved')
-    assert.ok(docs.rows, 'get the rows')
-    assert.equal(docs.rows.length, 3, 'starts in row two')
-    assert.equal(docs['total_rows'], 3, 'out of three rows')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to list with a end_key', function (assert) {
-  const p = db.list({ end_key: 's' })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (docs) {
-    assert.ok(true, 'Promise is resolved')
-    assert.ok(docs.rows, 'get the rows')
-    assert.equal(docs.rows.length, 3, 'starts in row two')
-    assert.equal(docs['total_rows'], 3, 'out of three rows')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to list as a stream', function (assert) {
-  const p = db.listAsStream()
-    .on('error', function (error) {
-      assert.ifError(error)
-    })
-    .on('end', function () {
-      assert.end()
-    })
-  assert.ok(!helpers.isPromise(p), 'does not return Promise')
-  assert.equal(p.constructor.name, 'Request', 'returns a Request')
-})
-
-it('should be able to list with params as a stream', function (assert) {
-  const p = db.listAsStream({ end_key: 's' })
-    .on('error', function (error) {
-      assert.ifError(error)
-    })
-    .on('end', function () {
-      assert.end()
-    })
-  assert.ok(!helpers.isPromise(p), 'does not return Promise')
-  assert.equal(p.constructor.name, 'Request', 'returns a Request')
-})
diff --git a/tests/integration/document/update.js b/tests/integration/document/update.js
deleted file mode 100644
index b0573a4..0000000
--- a/tests/integration/document/update.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const it = harness.it
-
-let rev
-
-it('should insert one doc', function (assert) {
-  const p = db.insert({ 'foo': 'baz' }, 'foobar')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (foo) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(foo.ok, true, 'response ok')
-    assert.ok(foo.rev, 'withs rev')
-    rev = foo.rev
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should update the document', function (assert) {
-  const p = db.insert({ foo: 'bar', '_rev': rev }, 'foobar')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (response) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(response.ok, true, 'response should be ok')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
diff --git a/tests/integration/multipart/get.js b/tests/integration/multipart/get.js
deleted file mode 100644
index 5e7783d..0000000
--- a/tests/integration/multipart/get.js
+++ /dev/null
@@ -1,49 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const it = harness.it
-
-it('should be able to insert a doc with att', function (assert) {
-  const att = {
-    name: 'att',
-    data: 'Hello World!',
-    'content_type': 'text/plain'
-  }
-  const p = db.multipart.insert({ 'foo': 'baz' }, [att], 'foobaz')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (foo) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(foo.ok, true, 'response should be ok')
-    assert.equal(foo.id, 'foobaz', 'id is foobaz')
-    assert.ok(foo.rev, 'has rev')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to get the document with the attachment', function (assert) {
-  db.multipart.get('foobaz', function (error, foobaz, headers) {
-    assert.equal(error, null, 'should get foobaz')
-    if (helpers.unmocked) {
-      assert.ok(headers['content-type'], 'should have content type')
-      assert.equal(headers['content-type'].split(';')[0], 'multipart/related')
-    }
-    assert.equal(typeof foobaz, 'object', 'foobaz should be a buffer')
-    assert.end()
-  })
-})
diff --git a/tests/integration/multipart/insert.js b/tests/integration/multipart/insert.js
deleted file mode 100644
index a1a23bf..0000000
--- a/tests/integration/multipart/insert.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const db = harness.locals.db
-const it = harness.it
-
-it('should handle crazy encodings', function (assert) {
-  const att = {
-    name: 'att',
-    data: 'काचं शक्नोम्यत्तुम् । नोपहिनस्ति माम् ॥',
-    'content_type': 'text/plain'
-  }
-  const p = db.multipart.insert({ 'foo': 'bar' }, [att], 'foobar')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (foo) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(foo.ok, true, 'response should be ok')
-    assert.ok(foo.rev, 'response should have rev')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should test with presence of attachment', function (assert) {
-  const att = {
-    name: 'two',
-    data: 'Hello World!',
-    'content_type': 'text/plain'
-  }
-
-  db.attachment.insert('mydoc', 'one', 'Hello World!', 'text/plain',
-    function (err) {
-      assert.equal(err, null, 'should have stored the thingy')
-      db.get('mydoc', function (_, doc) {
-        db.multipart.insert(doc, [att], 'mydoc', function () {
-          db.get('mydoc', function (error, two) {
-            assert.equal(error, null, 'should get the doc')
-            assert.equal(Object.keys(two._attachments).length, 2,
-              'both attachments should be present')
-            assert.end()
-          })
-        })
-      })
-    })
-})
-
-it('should work with attachment as a buffer', function (assert) {
-  const att = {
-    name: 'att',
-    data: Buffer.from('foo'),
-    'content_type': 'text/plain'
-  }
-  const p = db.multipart.insert({ 'foo': 'bar' }, [att], 'otherdoc')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (foo) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(foo.ok, true, 'response should be ok')
-    assert.ok(foo.rev, 'response should have rev')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
diff --git a/tests/integration/shared/config.js b/tests/integration/shared/config.js
deleted file mode 100644
index 709ef84..0000000
--- a/tests/integration/shared/config.js
+++ /dev/null
@@ -1,141 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const nano = harness.locals.nano
-const Nano = helpers.Nano
-
-const it = harness.it
-
-it('should serve the root when no path is specified', function (assert) {
-  nano.dinosaur('').then(function (response) {
-    assert.ok(response.version, 'version is defined')
-    return nano.relax()
-  }).then(function (response) {
-    assert.ok(response.version, 'had version')
-    assert.end()
-  })
-})
-
-it('should be able to parse urls', function (assert) {
-  const baseUrl = 'http://someurl.com'
-  assert.equal(
-    Nano(baseUrl).config.url,
-    baseUrl,
-    'simple url')
-
-  assert.equal(
-    Nano(baseUrl + '/').config.url,
-    baseUrl + '/',
-    'simple with trailing')
-
-  assert.equal(
-    Nano('http://a:b@someurl.com:5984').config.url,
-    'http://a:b@someurl.com:5984',
-    'with authentication')
-
-  assert.equal(
-    Nano('http://a:b%20c%3F@someurl.com:5984/mydb').config.url,
-    'http://a:b%20c%3F@someurl.com:5984',
-    'with escaped auth')
-
-  assert.equal(
-    Nano('http://a:b%20c%3F@someurl.com:5984/my%2Fdb').config.url,
-    'http://a:b%20c%3F@someurl.com:5984',
-    'with dbname containing encoded slash')
-
-  assert.equal(
-    Nano('http://mydb-a:b%20c%3F@someurl.com:5984/mydb').config.url,
-    'http://mydb-a:b%20c%3F@someurl.com:5984',
-    'with repeating dbname')
-
-  assert.equal(
-    Nano('http://a:b%20c%3F@someurl.com:5984/prefix/mydb').config.url,
-    'http://a:b%20c%3F@someurl.com:5984/prefix',
-    'with subdir')
-
-  assert.equal(
-    Nano(baseUrl + ':5984/a').config.url,
-    baseUrl + ':5984',
-    'with port')
-
-  assert.equal(
-    Nano(baseUrl + '/a').config.url,
-    baseUrl,
-    '`a` database')
-
-  assert.end()
-})
-
-it('should not parse urls when parseURL flag set to false', function (assert) {
-  const url = 'http://someurl.com/path'
-
-  assert.equal(
-    Nano({
-      url: url,
-      parseUrl: false
-    }).config.url,
-    url,
-    'the untouched url')
-
-  assert.end()
-})
-
-it('should accept and handle customer http headers', function (assert) {
-  const nanoWithDefaultHeaders = Nano({
-    url: helpers.couch,
-    defaultHeaders: {
-      'x-custom-header': 'custom',
-      'x-second-header': 'second'
-    }
-  })
-
-  const req = nanoWithDefaultHeaders.db.listAsStream()
-    .on('error', function (error) {
-      assert.ifError(error)
-    })
-    .on('end', function () {
-      assert.end()
-    })
-
-  assert.equal(
-    req.headers['x-custom-header'],
-    'custom',
-    'header `x-second-header` honored')
-
-  assert.equal(
-    req.headers['x-second-header'],
-    'second',
-    'headers `x-second-header` honored')
-})
-
-it('should prevent shallow object copies', function (assert) {
-  const config = {
-    url: 'http://someurl.com'
-  }
-
-  assert.equal(
-    Nano(config).config.url,
-    config.url,
-    'simple url')
-
-  assert.ok(
-    Nano(config).config.requestDefaults,
-    '`requestDefaults` should be set')
-  assert.ok(!config.requestDefaults,
-    'should not be re-using the same object')
-
-  assert.end()
-})
diff --git a/tests/integration/shared/cookie.js b/tests/integration/shared/cookie.js
deleted file mode 100644
index 85c2c4c..0000000
--- a/tests/integration/shared/cookie.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const nano = require('../../../lib/nano.js')({ url: 'http://localhost:5984', requestDefaults: { jar: true } })
-const it = harness.it
-
-it('should be able to create a user', function (assert) {
-  nano.relax({
-    method: 'POST',
-    path: '_users',
-    body: {
-      _id: 'org.couchdb.user:' + helpers.username,
-      type: 'user',
-      name: helpers.username,
-      roles: ['admin'],
-      password: helpers.password
-    }
-  }).then(function () {
-    return nano.auth(helpers.username, helpers.password)
-  }).then(function (data) {
-    assert.ok(data.ok)
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to insert with a cookie', function (assert) {
-  const db = nano.db.use('shared_cookie')
-  const p = db.insert({ 'foo': 'baz' })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (response) {
-    assert.equal(response.ok, true, 'response should be ok')
-    assert.ok(response.rev, 'response should have rev')
-    assert.end()
-  }).catch(function () {
-    assert.ok(false, 'Promise is rejected')
-  })
-})
-
-it('should be able to get the session', function (assert) {
-  nano.session().then(function (session) {
-    assert.equal(session.userCtx.name, helpers.username)
-    assert.end()
-  })
-})
diff --git a/tests/integration/shared/error.js b/tests/integration/shared/error.js
deleted file mode 100644
index f058bc9..0000000
--- a/tests/integration/shared/error.js
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const nano = harness.locals.nano
-const Nano = helpers.Nano
-const it = harness.it
-
-it('should throw when initialize fails', function (assert) {
-  try {
-    Nano('Not a url')
-  } catch (err) {
-    assert.ok(err, 'should have throw')
-    assert.ok(err.message, 'with a description')
-  }
-  try {
-    Nano({})
-  } catch (err2) {
-    assert.ok(err2, 'should have throw')
-    assert.ok(err2.message, 'with a message')
-  }
-  assert.end()
-})
-
-it('should be able to stream the simplest request', function (assert) {
-  const root = nano.request({ stream: true })
-  root.on('end', function () {
-    assert.pass('request worked')
-    assert.end()
-  })
-})
-
-it('should error when destroying a db that does not exist', function (assert) {
-  const p = nano.db.destroy('say_wat_wat')
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function () {
-    assert.ok(false, 'Promise is resolved')
-  }).catch(function (error) {
-    assert.ok(true, 'Promise is rejected')
-    assert.equal(error.message, 'Database does not exist.', 'is missing')
-    assert.end()
-  })
-})
diff --git a/tests/integration/shared/headers.js b/tests/integration/shared/headers.js
deleted file mode 100644
index ddb0538..0000000
--- a/tests/integration/shared/headers.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const nano = harness.locals.nano
-const db = harness.locals.db
-const it = harness.it
-
-it('should get headers', function (assert) {
-  db.attachment.insert('new', 'att', 'Hello', 'text/plain',
-    function (error, hello) {
-      console.log('!!!', error, hello)
-      assert.equal(error, null, 'should store hello')
-      assert.equal(hello.ok, true, 'response should be ok')
-      assert.ok(hello.rev, 'should have a revision number')
-      nano.request({
-        db: 'shared_headers',
-        doc: 'new',
-        headers: { 'If-None-Match': JSON.stringify(hello.rev) }
-      }, function (error, helloWorld, rh) {
-        assert.equal(error, null, 'should get the hello')
-        assert.equal(rh['statusCode'], 304, 'status is not modified')
-        nano.request({
-          db: 'shared_headers',
-          doc: 'new',
-          att: 'att'
-        }, function (error, helloWorld, rh) {
-          assert.equal(error, null, 'should get the hello')
-          assert.equal(rh['statusCode'], 200, 'status is `ok`')
-          assert.end()
-        })
-      })
-    })
-})
diff --git a/tests/integration/shared/log.js b/tests/integration/shared/log.js
deleted file mode 100644
index 4f89df6..0000000
--- a/tests/integration/shared/log.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const logger = require('../../../lib/logger')
-const helpers = require('../../helpers')
-const harness = helpers.harness(__filename)
-const it = harness.it
-
-it('should be able to instantiate a log', function (assert) {
-  const log = logger({
-    log: function (id, msg) {
-      assert.equal(typeof id, 'string', 'id is set `' + id + '`')
-      assert.equal(msg[0], 'testing 1234')
-      assert.end()
-    }
-  })()
-  log('testing 1234')
-})
diff --git a/tests/integration/util/uuid.js b/tests/integration/util/uuid.js
deleted file mode 100644
index 0761b51..0000000
--- a/tests/integration/util/uuid.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const nano = helpers.nano
-const it = harness.it
-
-it('should generate three uuids', function (assert) {
-  const p = nano.uuids(3)
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (data) {
-    assert.ok(true, 'Promise is resolved')
-    assert.ok(data, 'got response')
-    assert.ok(data.uuids, 'got uuids')
-    assert.equal(data.uuids.length, 3, 'got 3')
-    assert.end()
-  }).catch(function () {
-    assert.ok(true, 'Promise is rejected')
-  })
-})
-
-it('should generate one uuid', function (assert) {
-  const p = nano.uuids()
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (data) {
-    assert.ok(true, 'Promise is resolved')
-    assert.ok(data, 'got response')
-    assert.ok(data.uuids, 'got uuid')
-    assert.equal(data.uuids.length, 1, 'got 1')
-    assert.end()
-  }).catch(function () {
-    assert.ok(true, 'Promise is rejected')
-  })
-})
diff --git a/tests/intercept/design/search.js b/tests/intercept/design/search.js
deleted file mode 100644
index 129525d..0000000
--- a/tests/intercept/design/search.js
+++ /dev/null
@@ -1,65 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/integration')
-const harness = helpers.harness(__filename)
-const it = harness.it
-
-const nano = require('../../../lib/nano.js')
-const fakeRequest = function (r, callback) {
-  if (callback) {
-    callback(null, { statusCode: 200 }, r)
-  } else {
-    return r
-  }
-}
-// by passing in a fake Request object, we can intercept the request
-// and see how Nano is pre-processing the parameters
-const n = nano({ url: 'http://localhost:5984', request: fakeRequest })
-const db = n.db.use('fake')
-
-it('should allow custom request object to be supplied', function (assert) {
-  const p = db.info()
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (data) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(data.method, 'GET')
-    assert.equal(typeof data.headers, 'object')
-    assert.end()
-  }).catch(function () {
-    assert.ok(true, 'Promise is rejected')
-  })
-})
-
-it('should submit all search queries via a POST request', function (assert) {
-  const p = db.search('fake', 'fake', { drilldown: [['colour', 'red'], ['category', 'cake']] })
-  assert.ok(helpers.isPromise(p), 'returns Promise')
-  p.then(function (data) {
-    assert.ok(true, 'Promise is resolved')
-    assert.equal(data.method, 'POST')
-    assert.equal(typeof data.headers, 'object')
-    assert.equal(data.body, '{"drilldown":[["colour","red"],["category","cake"]]}')
-    assert.end()
-  }).catch(function () {
-    assert.ok(true, 'Promise is rejected')
-  })
-})
-
-it('should allow search results to be streamed', function (assert) {
-  const req = db.searchAsStream('fake', 'fake', { q: 'foo:bar' })
-  assert.equal(req.method, 'POST')
-  assert.equal(typeof req.headers, 'object')
-  assert.equal(req.body, '{"q":"foo:bar"}')
-  assert.end()
-})
diff --git a/tests/unit/attachment/destroy.js b/tests/unit/attachment/destroy.js
deleted file mode 100644
index d59e7fd..0000000
--- a/tests/unit/attachment/destroy.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index 90277d2..0000000
--- a/tests/unit/attachment/get.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index 3986de1..0000000
--- a/tests/unit/attachment/insert.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/unit')
-const insertAttachment = helpers.unit(['attachment', 'insert'])
-
-const buffer = Buffer.from(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
deleted file mode 100644
index c7d866a..0000000
--- a/tests/unit/database/changes.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index 20f2b1b..0000000
--- a/tests/unit/database/compact.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index ff0d1f7..0000000
--- a/tests/unit/database/create.js
+++ /dev/null
@@ -1,36 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index af36d02..0000000
--- a/tests/unit/database/destroy.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index ed16472..0000000
--- a/tests/unit/database/follow.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index e478772..0000000
--- a/tests/unit/database/get.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index b5bf435..0000000
--- a/tests/unit/database/list.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index c07e844..0000000
--- a/tests/unit/database/replicate.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const replicateDatabase = require('../../helpers/unit').unit([
-  'database',
-  'replicate'
-])
-
-replicateDatabase('baa', 'baashep', {
-  body: '{"source":"http://localhost:5984/baa","target":"http://localhost:5984/baashep"}',
-  headers: {
-    accept: 'application/json',
-    'content-type': 'application/json'
-  },
-  method: 'POST',
-  uri: '/_replicate'
-})
-
-replicateDatabase('molly', 'anne', { some: 'params' }, {
-  body: '{"some":"params","source":"http://localhost:5984/molly","target":"http://localhost:5984/anne"}',
-  headers: {
-    accept: 'application/json',
-    'content-type': 'application/json'
-  },
-  method: 'POST',
-  uri: '/_replicate'
-})
diff --git a/tests/unit/database/replicator.js b/tests/unit/database/replicator.js
deleted file mode 100644
index 7eea693..0000000
--- a/tests/unit/database/replicator.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const replicator = require('../../helpers/unit').unit([
-  'database',
-  'replicator'
-])
-
-replicator('baa', 'baashep', {
-  body: '{"source":"http://localhost:5984/baa","target":"http://localhost:5984/baashep"}',
-  headers: {
-    accept: 'application/json',
-    'content-type': 'application/json'
-  },
-  method: 'POST',
-  uri: '/_replicator'
-})
-
-replicator('molly', 'anne', { some: 'params' }, {
-  body: '{"some":"params","source":"http://localhost:5984/molly","target":"http://localhost:5984/anne"}',
-  headers: {
-    accept: 'application/json',
-    'content-type': 'application/json'
-  },
-  method: 'POST',
-  uri: '/_replicator'
-})
diff --git a/tests/unit/database/updates.js b/tests/unit/database/updates.js
deleted file mode 100644
index d5455de..0000000
--- a/tests/unit/database/updates.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index 1c926cc..0000000
--- a/tests/unit/design/atomic.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index aa08009..0000000
--- a/tests/unit/design/compact.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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/find.js b/tests/unit/design/find.js
deleted file mode 100644
index c3afe38..0000000
--- a/tests/unit/design/find.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-const findDesign = require('../../helpers/unit').unit([
-  'find',
-  'find'
-])
-
-findDesign({
-  selector: {
-    name: 'foobar'
-  }
-}, {
-  body: '{"selector":{"name":"foobar"}}',
-  headers: {
-    accept: 'application/json',
-    'content-type': 'application/json'
-  },
-  method: 'POST',
-  uri: '/mock/_find'
-})
diff --git a/tests/unit/design/list.js b/tests/unit/design/list.js
deleted file mode 100644
index 991830a..0000000
--- a/tests/unit/design/list.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index cfea4a9..0000000
--- a/tests/unit/design/search.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index e435d2a..0000000
--- a/tests/unit/design/show.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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/view.js b/tests/unit/design/view.js
deleted file mode 100644
index 907a080..0000000
--- a/tests/unit/design/view.js
+++ /dev/null
@@ -1,50 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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'
-})
-
-viewDesign('alice', 'by_id', {
-  queries: [{ keys: ['foobar', 'barfoo'] }, { limit: 3, skip: 2 }],
-  include_docs: true
-}, {
-  body: '{"queries":[{"keys":["foobar","barfoo"]},{"limit":3,"skip":2}]}',
-  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
deleted file mode 100644
index b90a102..0000000
--- a/tests/unit/document/bulk.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index bf252be..0000000
--- a/tests/unit/document/copy.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const copyDocument = require('../../helpers/unit').unit([
-  'document',
-  'copy'
-])
-
-const 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/document/get.js b/tests/unit/document/get.js
deleted file mode 100644
index 219b3a8..0000000
--- a/tests/unit/document/get.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/unit')
-const test = require('tape')
-const debug = require('debug')('nano/tests/unit/shared/error')
-
-const cli = helpers.mockClientDb(debug)
-const db = cli.use('foo')
-
-test('it should not return db info if docName undefined', function (assert) {
-  db.get(undefined, function (err) {
-    assert.equal(err.toString(), 'Error: Invalid doc id')
-    assert.end()
-  })
-})
-
-test('it should not return db info if docName null', function (assert) {
-  db.get(null, function (err) {
-    assert.equal(err.toString(), 'Error: Invalid doc id')
-    assert.end()
-  })
-})
-
-test('it should not return db info if docName empty string', function (assert) {
-  db.get('', function (err) {
-    assert.equal(err.toString(), 'Error: Invalid doc id')
-    assert.end()
-  })
-})
diff --git a/tests/unit/document/head.js b/tests/unit/document/head.js
deleted file mode 100644
index 4fca606..0000000
--- a/tests/unit/document/head.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/unit')
-const test = require('tape')
-const debug = require('debug')('nano/tests/unit/shared/error')
-
-const cli = helpers.mockClientDb(debug)
-const db = cli.use('foo')
-
-test('it should return a promise when no callback is specified', function (assert) {
-  var p = db.head('doc')
-  p.then((headers) => {
-    assert.equal(headers.statusCode, 200)
-    assert.end()
-  })
-})
-
-test('it should not return a promise when a callback is specified', function (assert) {
-  var p = db.head('doc', function (err, body, headers) {
-    assert.ifError(err)
-    assert.equal(headers.statusCode, 200)
-    assert.end()
-  })
-  assert.equal(typeof p, 'undefined')
-})
diff --git a/tests/unit/multipart/get.js b/tests/unit/multipart/get.js
deleted file mode 100644
index d43e99c..0000000
--- a/tests/unit/multipart/get.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const getMultipart = require('../../helpers/unit').unit([
-  'multipart',
-  'get'
-])
-
-getMultipart('space', { extra: 'stuff' }, {
-  encoding: null,
-  headers: { 'accept': '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
deleted file mode 100644
index f019f10..0000000
--- a/tests/unit/multipart/insert.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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,"content_type":"text/plain"}}' +
-        ',"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
deleted file mode 100644
index 2fdac66..0000000
--- a/tests/unit/shared/error.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/unit')
-const test = require('tape')
-const debug = require('debug')('nano/tests/unit/shared/error')
-
-const cli = helpers.mockClientFail(debug)
-const cli2 = helpers.mockClientUnparsedError(debug)
-const cli3 = helpers.mockClientUnparsedError(debug, JSON.stringify({
-  error: 'not a reason'
-}))
-
-const 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) {
-    const 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
deleted file mode 100644
index 86655a9..0000000
--- a/tests/unit/shared/follow-updates.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const 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
deleted file mode 100644
index 9072883..0000000
--- a/tests/unit/shared/jar.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-'use strict'
-
-const helpers = require('../../helpers/unit')
-const test = require('tape')
-const debug = require('debug')('nano/tests/unit/shared/jar')
-
-const 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()
-    })
-  })
-})


[couchdb-nano] 11/15: auth/session/uuids

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit 21597ff991ee6597ffd02ca18386329a66cdc4d9
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Fri Feb 7 17:09:20 2020 +0000

    auth/session/uuids
---
 lib/nano.js               |  2 +-
 test/nano.auth.test.js    | 31 ++++++++++++++++++++++++++++
 test/nano.session.test.js | 29 ++++++++++++++++++++++++++
 test/nano.uuids.test.js   | 52 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/lib/nano.js b/lib/nano.js
index eb07b2d..0ca315f 100644
--- a/lib/nano.js
+++ b/lib/nano.js
@@ -469,8 +469,8 @@ module.exports = exports = function dbScope (cfg) {
   function uuids (count, callback) {
     if (typeof count === 'function') {
       callback = count
-      count = 1
     }
+    count = count || 1
     return relax({ method: 'GET', path: '_uuids', qs: { count: count } }, callback)
   }
 
diff --git a/test/nano.auth.test.js b/test/nano.auth.test.js
new file mode 100644
index 0000000..f952887
--- /dev/null
+++ b/test/nano.auth.test.js
@@ -0,0 +1,31 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to authenticate - POST /_session - nano.auth', async () => {
+  // mocks
+  const username = 'u'
+  const password = 'p'
+  const response = { ok: true, name: 'admin', roles: ['_admin', 'admin'] }
+  const scope = nock(COUCH_URL)
+    .post('/_session', 'name=u&password=p', { 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' })
+    .reply(200, response)
+
+  // test GET /_uuids
+  const p = await nano.auth(username, password)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/nano.session.test.js b/test/nano.session.test.js
new file mode 100644
index 0000000..ca2eb97
--- /dev/null
+++ b/test/nano.session.test.js
@@ -0,0 +1,29 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to check your session - GET /_session - nano.auth', async () => {
+  // mocks
+  const response = { ok: true, userCtx: { name: null, roles: [] }, info: { authentication_db: '_users', authentication_handlers: ['cookie', 'default'] } }
+  const scope = nock(COUCH_URL)
+    .get('/_session')
+    .reply(200, response)
+
+  // test GET /_uuids
+  const p = await nano.session()
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/nano.uuids.test.js b/test/nano.uuids.test.js
new file mode 100644
index 0000000..ea004f1
--- /dev/null
+++ b/test/nano.uuids.test.js
@@ -0,0 +1,52 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to fetch uuids - GET /_uuids - nano.uuids', async () => {
+  // mocks
+  const response = {
+    uuids: [
+      'c42ddf1272c7d05b2dc45b696200145f'
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/_uuids?count=1')
+    .reply(200, response)
+
+  // test GET /_uuids
+  const p = await nano.uuids()
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to fetch more uuids - GET /_uuids?count=3 - nano.uuids', async () => {
+  // mocks
+  const response = {
+    uuids: [
+      'c42ddf1272c7d05b2dc45b69620023df',
+      'c42ddf1272c7d05b2dc45b6962002616',
+      'c42ddf1272c7d05b2dc45b69620028cf'
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/_uuids?count=3')
+    .reply(200, response)
+
+  // test GET /_uuids
+  const p = await nano.uuids(3)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})


[couchdb-nano] 04/15: first jest tests

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit 92163e681d71baa05a26363b7e42e8fa43b2e4f1
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Wed Feb 5 14:15:49 2020 +0000

    first jest tests
---
 test/database.changes.test.js             | 84 ++++++++++++++++++++++++++
 test/database.changesAsStream.test.js     | 79 +++++++++++++++++++++++++
 test/database.compact.test.js             | 53 +++++++++++++++++
 test/database.create.test.js              | 70 ++++++++++++++++++++++
 test/database.destroy.test.js             | 56 ++++++++++++++++++
 test/database.follow.test.js              |  0
 test/database.get.test.js                 | 97 +++++++++++++++++++++++++++++++
 test/database.list.test.js                | 29 +++++++++
 test/database.listAsStream.test.js        | 39 +++++++++++++
 test/database.replicate.test.js           | 88 ++++++++++++++++++++++++++++
 test/database.replication.disable.test.js | 70 ++++++++++++++++++++++
 test/database.replication.enable.test.js  | 82 ++++++++++++++++++++++++++
 test/database.replication.query.test.js   | 90 ++++++++++++++++++++++++++++
 13 files changed, 837 insertions(+)

diff --git a/test/database.changes.test.js b/test/database.changes.test.js
new file mode 100644
index 0000000..4fb1e48
--- /dev/null
+++ b/test/database.changes.test.js
@@ -0,0 +1,84 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const response = {
+  results: [
+    {
+      seq: '1-nC1J',
+      id: 'c42ddf1272c7d05b2dc45b6962000b10',
+      changes: [
+        {
+          rev: '1-23202479633c2b380f79507a776743d5'
+        }
+      ]
+    }
+  ],
+  last_seq: '1-C1J',
+  pending: 0
+}
+const errResponse = {
+  error: 'not_found',
+  reason: 'Database does not exist.'
+}
+
+test('should be able to fetch the changes - GET /db/_changes - nano.db.changes', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/_changes')
+    .reply(200, response)
+
+  // test GET /db/_changes
+  const p = await nano.db.changes('db')
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to fetch the changes with opts - GET /db/_changes - nano.db.changes', async () => {
+  // mocks
+  const opts = { include_docs: true, feed: 'continuous' }
+  const scope = nock(COUCH_URL)
+    .get('/db/_changes')
+    .query(opts)
+    .reply(200, response)
+
+  // test GET /db/_changes
+  const p = await nano.db.changes('db', opts)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle a missing database - GET /db/_changes - nano.db.changes', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/_changes')
+    .reply(404, errResponse)
+
+  // test GET /db/_changes
+  await expect(nano.db.changes('db')).rejects.toThrow('Database does not exist')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should not attempt with empty dbName - nano.db.changes', async () => {
+  expect(() => {
+    nano.db.changes('')
+  }).toThrowError('missing dbName')
+})
+
+test('should not attempt with missing dbName - nano.db.changes', async () => {
+  expect(() => {
+    nano.db.changes()
+  }).toThrowError('missing dbName')
+})
diff --git a/test/database.changesAsStream.test.js b/test/database.changesAsStream.test.js
new file mode 100644
index 0000000..adedbe8
--- /dev/null
+++ b/test/database.changesAsStream.test.js
@@ -0,0 +1,79 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const response = {
+  results: [
+    {
+      seq: '1-nC1J',
+      id: 'c42ddf1272c7d05b2dc45b6962000b10',
+      changes: [
+        {
+          rev: '1-23202479633c2b380f79507a776743d5'
+        }
+      ]
+    }
+  ],
+  last_seq: '1-C1J',
+  pending: 0
+}
+
+test('should get a streamed list of changes - GET /_changes - nano.db.changesAsStream', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/_changes')
+    .reply(200, response)
+
+  return new Promise((resolve, reject) => {
+    // test GET /db/_changes
+    const db = nano.db.use('db')
+    const s = db.changesAsStream()
+    expect(typeof s).toBe('object')
+    let buffer = ''
+    s.on('data', (chunk) => {
+      buffer += chunk.toString()
+    })
+    s.on('end', () => {
+      expect(buffer).toBe(JSON.stringify(response))
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
+
+test('should get a streamed list of changes with opts - GET /_changes - nano.db.changesAsStream', async () => {
+  // mocks
+  const opts = { include_docs: true }
+  const scope = nock(COUCH_URL)
+    .get('/db/_changes')
+    .query(opts)
+    .reply(200, response)
+
+  return new Promise((resolve, reject) => {
+    // test GET /db/_changes
+    const db = nano.db.use('db')
+    const s = db.changesAsStream(opts)
+    expect(typeof s).toBe('object')
+    let buffer = ''
+    s.on('data', (chunk) => {
+      buffer += chunk.toString()
+    })
+    s.on('end', () => {
+      expect(buffer).toBe(JSON.stringify(response))
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
diff --git a/test/database.compact.test.js b/test/database.compact.test.js
new file mode 100644
index 0000000..331e359
--- /dev/null
+++ b/test/database.compact.test.js
@@ -0,0 +1,53 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const response = { ok: true }
+
+test('should be able to send compaction request - POST /db/_compact - nano.db.compact', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .post('/db/_compact')
+    .reply(200, response)
+
+  // test POST /db/_compact
+  const p = await nano.db.compact('db')
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to send compaction request with design doc - POST /db/_compact - nano.db.compact', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .post('/db/_compact/ddoc')
+    .reply(200, response)
+
+  // test POST /db/_compact/ddoc
+  const p = await nano.db.compact('db', 'ddoc')
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should not attempt compact with empty dbName - nano.db.compact', async () => {
+  expect(() => {
+    nano.db.compact('')
+  }).toThrowError('missing dbName')
+})
+
+test('should not attempt compact with missing dbName - nano.db.compact', async () => {
+  expect(() => {
+    nano.db.compact()
+  }).toThrowError('missing dbName')
+})
diff --git a/test/database.create.test.js b/test/database.create.test.js
new file mode 100644
index 0000000..9feae75
--- /dev/null
+++ b/test/database.create.test.js
@@ -0,0 +1,70 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const response = { ok: true }
+
+test('should create a database - PUT /db - nano.db.create', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .put('/db')
+    .reply(200, response)
+
+  // test GET /db
+  const p = await nano.db.create('db')
+  expect(typeof p).toBe('object')
+  expect(p.ok).toBe(true)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should create a database with parameters - PUT /db?partitioned=true - nano.db.create', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .put('/db')
+    .query({ partitioned: 'true', q: '1' })
+    .reply(200, response)
+
+  // test GET /db
+  const p = await nano.db.create('db', { partitioned: true, q: 1 })
+  expect(typeof p).toBe('object')
+  expect(p.ok).toBe(true)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should handle pre-existing database - PUT /db - nano.db.create', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .put('/db')
+    .reply(412, {
+      error: 'file_exists',
+      reason: 'The database could not be created, the file already exists.'
+    })
+
+  // test PUT /db
+  await expect(nano.db.create('db')).rejects.toThrow('The database could not be created')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should not attempt to create database with empty database name - nano.db.create', async () => {
+  expect(() => {
+    nano.db.create('')
+  }).toThrowError('missing dbName')
+})
+
+test('should not attempt to create database with missing database name - nano.db.create', async () => {
+  expect(() => {
+    nano.db.create()
+  }).toThrowError('missing dbName')
+})
diff --git a/test/database.destroy.test.js b/test/database.destroy.test.js
new file mode 100644
index 0000000..17f8189
--- /dev/null
+++ b/test/database.destroy.test.js
@@ -0,0 +1,56 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const response = { ok: true }
+
+test('should destroy a database - DELETE /db - nano.db.destroy', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .delete('/db')
+    .reply(200, response)
+
+  // test DELETE /db
+  const p = await nano.db.destroy('db')
+  expect(typeof p).toBe('object')
+  expect(p.ok).toBe(true)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should handle non-existant database - DELETE /db - nano.db.create', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .delete('/db')
+    .reply(404, {
+      error: 'not_found',
+      reason: 'Database does not exist.'
+    })
+
+  // test DELETE /db
+  await expect(nano.db.destroy('db')).rejects.toThrow('Database does not exist')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should not attempt to destroy database with empty database name - nano.db.destroy', async () => {
+  expect(() => {
+    nano.db.destroy('')
+  }).toThrowError('missing dbName')
+})
+
+test('should not attempt to destroy database with missing database name - nano.db.destroy', async () => {
+  expect(() => {
+    nano.db.destroy()
+  }).toThrowError('missing dbName')
+})
diff --git a/test/database.follow.test.js b/test/database.follow.test.js
new file mode 100644
index 0000000..e69de29
diff --git a/test/database.get.test.js b/test/database.get.test.js
new file mode 100644
index 0000000..1098abc
--- /dev/null
+++ b/test/database.get.test.js
@@ -0,0 +1,97 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const response = {
+  db_name: 'db',
+  purge_seq: '0-8KhNZEiqhyjKAgBm5Rxs',
+  update_seq: '23523-gUFPHo-6PQIAJ_EdrA',
+  sizes: {
+    file: 18215344,
+    external: 5099714,
+    active: 6727596
+  },
+  other: {
+    data_size: 5099714
+  },
+  doc_del_count: 23000,
+  doc_count: 0,
+  disk_size: 18215344,
+  disk_format_version: 7,
+  data_size: 6727596,
+  compact_running: false,
+  cluster: {
+    q: 2,
+    n: 1,
+    w: 1,
+    r: 1
+  },
+  instance_start_time: '0'
+}
+
+test('should be able to fetch the database info - GET /db - nano.db.get', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db')
+    .reply(200, response)
+
+  // test GET /db
+  const p = await nano.db.get('db')
+  expect(typeof p).toBe('object')
+  expect(p.doc_count).toBe(0)
+  expect(p.db_name).toBe('db')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to fetch the database info - GET /db - db.info', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db')
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.info()
+  expect(typeof p).toBe('object')
+  expect(p.doc_count).toBe(0)
+  expect(p.db_name).toBe('db')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should handle missing database - PUT /db - nano.db.create', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db')
+    .reply(404, {
+      error: 'not_found',
+      reason: 'Database does not exist.'
+    })
+
+  // test GET /db
+  await expect(nano.db.get('db')).rejects.toThrow('Database does not exist')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should not attempt info fetch with empty dbName - nano.db.get', async () => {
+  expect(() => {
+    nano.db.get('')
+  }).toThrowError('missing dbName')
+})
+
+test('should not attempt info fetch with missing dbName - nano.db.get', async () => {
+  expect(() => {
+    nano.db.get()
+  }).toThrowError('missing dbName')
+})
diff --git a/test/database.list.test.js b/test/database.list.test.js
new file mode 100644
index 0000000..f83dc74
--- /dev/null
+++ b/test/database.list.test.js
@@ -0,0 +1,29 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const response = ['rita', 'sue', 'bob']
+
+test('should be to get list of databases - GET /_all_dbs - nano.db.list', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/_all_dbs')
+    .reply(200, response)
+
+  // test GET /db/_all_dbs
+  const p = await nano.db.list()
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/database.listAsStream.test.js b/test/database.listAsStream.test.js
new file mode 100644
index 0000000..6568e26
--- /dev/null
+++ b/test/database.listAsStream.test.js
@@ -0,0 +1,39 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const response = ['rita', 'sue', 'bob']
+
+test('should get a streamed list of databases - GET /_all_dbs - nano.db.listAsStream', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/_all_dbs')
+    .reply(200, response)
+
+  return new Promise((resolve, reject) => {
+    // test GET /db/_all_dbs
+    const s = nano.db.listAsStream()
+    expect(typeof s).toBe('object')
+    let buffer = ''
+    s.on('data', (chunk) => {
+      buffer += chunk.toString()
+    })
+    s.on('end', () => {
+      expect(buffer).toBe(JSON.stringify(response))
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
diff --git a/test/database.replicate.test.js b/test/database.replicate.test.js
new file mode 100644
index 0000000..e2e86b2
--- /dev/null
+++ b/test/database.replicate.test.js
@@ -0,0 +1,88 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const response = {
+  history: [],
+  ok: true,
+  replication_id_version: 3,
+  session_id: '142a35854a08e205c47174d91b1f9628',
+  source_last_seq: 28
+}
+
+test('should be able to send replication request with local database names- POST /_replicate - nano.db.replicate', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .post('/_replicate', { source: COUCH_URL + '/source', target: COUCH_URL + '/target' })
+    .reply(200, response)
+
+  // test POST /_replicate
+  const p = await nano.db.replicate('source', 'target')
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to send replication request with URLs - POST /_replicate - nano.db.replicate', async () => {
+  // mocks
+  const source = 'http://mydomain1.com/source'
+  const target = 'https://mydomain2.com/target'
+  const scope = nock(COUCH_URL)
+    .post('/_replicate', { source: source, target: target })
+    .reply(200, response)
+
+  // test POST /_replicate
+  const p = await nano.db.replicate(source, target)
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to supply additional parameters - POST /_replicate - nano.db.replicate', async () => {
+  // mocks
+  const source = 'http://mydomain1.com/source'
+  const target = 'https://mydomain2.com/target'
+  const opts = { filter: 'ddoc/func', continuous: true }
+  const scope = nock(COUCH_URL)
+    .post('/_replicate', Object.assign(opts, { source: source, target: target }))
+    .reply(200, response)
+
+  // test POST /_replicate
+  const p = await nano.db.replicate(source, target, opts)
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should not attempt compact with empty source - nano.db.replicate', async () => {
+  expect(() => {
+    nano.db.replicate('')
+  }).toThrowError('missing source')
+})
+
+test('should not attempt compact with missing source - nano.db.replicate', async () => {
+  expect(() => {
+    nano.db.replicate(undefined, 'target')
+  }).toThrowError('missing source')
+})
+
+test('should not attempt compact with empty target - nano.db.replicate', async () => {
+  expect(() => {
+    nano.db.replicate('', 'target')
+  }).toThrowError('missing source')
+})
+
+test('should not attempt compact with missing target - nano.db.replicate', async () => {
+  expect(() => {
+    nano.db.replicate(undefined, 'target')
+  }).toThrowError('missing source')
+})
diff --git a/test/database.replication.disable.test.js b/test/database.replication.disable.test.js
new file mode 100644
index 0000000..d01eec3
--- /dev/null
+++ b/test/database.replication.disable.test.js
@@ -0,0 +1,70 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const response = { ok: true, id: 'rep1', rev: '2-123' }
+const errResponse = {
+  error: 'not_found',
+  reason: 'missing'
+}
+
+test('should be able to delete a replication - DELETE /_replicator - nano.db.replication.disable', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .delete('/_replicator/rep1')
+    .query({ rev: '1-456' })
+    .reply(200, response)
+
+  // test DELETE /_replicator/id
+  const p = await nano.db.replication.disable('rep1', '1-456')
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle a 404 - DELETE /_replicator - nano.db.replication.disable', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .delete('/_replicator/rep1')
+    .query({ rev: '1-456' })
+    .reply(404, errResponse)
+
+  // test DELETE /_replicator/id
+  await expect(nano.db.replication.disable('rep1', '1-456')).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should not to try to disable with missing id - nano.db.replication.disable', async () => {
+  expect(() => {
+    nano.db.replication.disable(undefined, '1-456')
+  }).toThrowError('missing id')
+})
+
+test('should not to try to disable with empty id - nano.db.replication.disable', async () => {
+  expect(() => {
+    nano.db.replication.disable('', '1-456')
+  }).toThrowError('missing id')
+})
+
+test('should not to try to disable with missing rev - nano.db.replication.disable', async () => {
+  expect(() => {
+    nano.db.replication.disable('rep1')
+  }).toThrowError('missing rev')
+})
+
+test('should not to try to disable with empty rev - nano.db.replication.disable', async () => {
+  expect(() => {
+    nano.db.replication.disable('rep1', '')
+  }).toThrowError('missing rev')
+})
diff --git a/test/database.replication.enable.test.js b/test/database.replication.enable.test.js
new file mode 100644
index 0000000..4c7aebd
--- /dev/null
+++ b/test/database.replication.enable.test.js
@@ -0,0 +1,82 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const response = { ok: true, id: 'abc', rev: '1-123' }
+
+test('should be able to send replication request with local database names - POST /_replicator - nano.db.replication.enable', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .post('/_replicator', { source: COUCH_URL + '/source', target: COUCH_URL + '/target' })
+    .reply(200, response)
+
+  // test POST /_replicator
+  const p = await nano.db.replication.enable('source', 'target')
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to send replication request with URLs - POST /_replicator - nano.db.replication.enable', async () => {
+  // mocks
+  const source = 'http://mydomain1.com/source'
+  const target = 'https://mydomain2.com/target'
+  const scope = nock(COUCH_URL)
+    .post('/_replicator', { source: source, target: target })
+    .reply(200, response)
+
+  // test POST /_replicator
+  const p = await nano.db.replication.enable(source, target)
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to supply additional parameters - POST /_replicator - nano.db.replication.enable', async () => {
+  // mocks
+  const source = 'http://mydomain1.com/source'
+  const target = 'https://mydomain2.com/target'
+  const opts = { filter: 'ddoc/func', continuous: true }
+  const scope = nock(COUCH_URL)
+    .post('/_replicator', Object.assign(opts, { source: source, target: target }))
+    .reply(200, response)
+
+  // test POST /_replicator
+  const p = await nano.db.replication.enable(source, target, opts)
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should not attempt compact with empty source - nano.db.replication.enable', async () => {
+  expect(() => {
+    nano.db.replication.enable('')
+  }).toThrowError('missing source')
+})
+
+test('should not attempt compact with missing source - nano.db.replication.enable', async () => {
+  expect(() => {
+    nano.db.replication.enable(undefined, 'target')
+  }).toThrowError('missing source')
+})
+
+test('should not attempt compact with empty target - nano.db.replication.enable', async () => {
+  expect(() => {
+    nano.db.replication.enable('', 'target')
+  }).toThrowError('missing source')
+})
+
+test('should not attempt compact with missing target - nano.db.replication.enable', async () => {
+  expect(() => {
+    nano.db.replication.enable(undefined, 'target')
+  }).toThrowError('missing source')
+})
diff --git a/test/database.replication.query.test.js b/test/database.replication.query.test.js
new file mode 100644
index 0000000..0e36bb9
--- /dev/null
+++ b/test/database.replication.query.test.js
@@ -0,0 +1,90 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const response = {
+  _id: 'rep1',
+  _rev: '2-05a9e090e2bb0977c06b870c870153c5',
+  source: 'http://localhost:5984/cities',
+  target: 'http://localhost:5984/cities2',
+  create_target: true,
+  continuous: false,
+  owner: 'admin',
+  _replication_state: 'completed',
+  _replication_state_time: '2019-11-06T13:20:17Z',
+  _replication_stats: {
+    revisions_checked: 23519,
+    missing_revisions_found: 23519,
+    docs_read: 23519,
+    docs_written: 23519,
+    changes_pending: 5127,
+    doc_write_failures: 0,
+    checkpointed_source_seq: '23523-g1AAAACheJzLYWBgYMpgTmEQTM4vTc5ISXLIyU9OzMnILy7JAUklMiTV____PyuDOYmBQU8-FyjGnphilJRqbIpNDx6T8liAJEMDkPoPN1D3CNhAc2NzU1MzI2xaswBdZzGv',
+    start_time: '2019-11-06T13:19:39Z'
+  }
+}
+const errResponse = {
+  error: 'not_found',
+  reason: 'missing'
+}
+
+test('should be able to query a replication - GET /_replicator/id - nano.db.replication.query', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/_replicator/rep1')
+    .reply(200, response)
+
+  // test GET /_replicator/id
+  const p = await nano.db.replication.query('rep1')
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to query a replication with opts - GET /_replicator/id?confilicts=true - nano.db.replication.query', async () => {
+  // mocks
+  const opts = { conflicts: true }
+  const scope = nock(COUCH_URL)
+    .get('/_replicator/rep1')
+    .query(opts)
+    .reply(200, response)
+
+  // test GET /_replicator/id
+  const p = await nano.db.replication.query('rep1', opts)
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to query a replication and handle 404 - GET /_replicator/id - nano.db.replication.query', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/_replicator/rep1')
+    .reply(404, errResponse)
+
+  // test GET /_replicator/id
+  await expect(nano.db.replication.query('rep1')).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should not attempt info fetch with empty id - nano.db.replication.query', async () => {
+  expect(() => {
+    nano.db.replication.query('')
+  }).toThrowError('missing id')
+})
+
+test('should not attempt info fetch with missing id - nano.db.replication.query', async () => {
+  expect(() => {
+    nano.db.replication.query()
+  }).toThrowError('missing id')
+})


[couchdb-nano] 01/15: use new url.URL instead of url.parse/url.reslove

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit 29773e156e11101dffcf24bdc8c99e21183ed6be
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Wed Feb 5 14:13:19 2020 +0000

    use new url.URL instead of url.parse/url.reslove
---
 lib/nano.js | 66 +++++++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 51 insertions(+), 15 deletions(-)

diff --git a/lib/nano.js b/lib/nano.js
index d73e634..6e6e535 100644
--- a/lib/nano.js
+++ b/lib/nano.js
@@ -10,9 +10,7 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-'use strict'
-
-const u = require('url')
+const URL = require('url').URL
 const assert = require('assert')
 const querystring = require('querystring')
 const request = require('request')
@@ -63,8 +61,8 @@ module.exports = exports = function dbScope (cfg) {
       return
     }
 
-    const path = u.parse(cfg.url)
-    let pathArray = path.pathname.split('/').filter(function (e) { return e })
+    const path = new URL(cfg.url)
+    const pathArray = path.pathname.split('/').filter(function (e) { return e })
     const db = pathArray.pop()
     const rootPath = path.pathname.replace(/\/?$/, '/..')
 
@@ -144,7 +142,7 @@ module.exports = exports = function dbScope (cfg) {
         req.headers.cookie = 'XXXXXXX'
       }
 
-      let errors = errs.merge({
+      const errors = errs.merge({
         message: 'couch returned ' + responseHeaders.statusCode,
         scope: 'couch',
         statusCode: responseHeaders.statusCode,
@@ -238,7 +236,7 @@ module.exports = exports = function dbScope (cfg) {
     }
 
     if (opts.accept) {
-      req.headers['accept'] = opts.accept
+      req.headers.accept = opts.accept
     }
 
     // http://guide.couchdb.org/draft/security.html#cookies
@@ -332,17 +330,26 @@ module.exports = exports = function dbScope (cfg) {
 
   // http://docs.couchdb.org/en/latest/api/database/common.html#put--db
   function createDb (dbName, qs0, callback0) {
+    if (!dbName) {
+      throw new Error('missing dbName')
+    }
     const { opts, callback } = getCallback(qs0, callback0)
     return relax({ db: dbName, method: 'PUT', qs: opts }, callback)
   }
 
   // http://docs.couchdb.org/en/latest/api/database/common.html#delete--db
   function destroyDb (dbName, callback) {
+    if (!dbName) {
+      throw new Error('missing dbName')
+    }
     return relax({ db: dbName, method: 'DELETE' }, callback)
   }
 
   // http://docs.couchdb.org/en/latest/api/database/common.html#get--db
   function getDb (dbName, callback) {
+    if (!dbName) {
+      throw new Error('missing dbName')
+    }
     return relax({ db: dbName }, callback)
   }
 
@@ -358,6 +365,9 @@ module.exports = exports = function dbScope (cfg) {
 
   // http://docs.couchdb.org/en/latest/api/database/compact.html#post--db-_compact
   function compactDb (dbName, ddoc, callback) {
+    if (!dbName) {
+      throw new Error('missing dbName')
+    }
     if (typeof ddoc === 'function') {
       callback = ddoc
       ddoc = null
@@ -373,6 +383,9 @@ module.exports = exports = function dbScope (cfg) {
   // http://docs.couchdb.org/en/latest/api/database/changes.html#get--db-_changes
   function changesDb (dbName, qs0, callback0) {
     const { opts, callback } = getCallback(qs0, callback0)
+    if (!dbName) {
+      throw new Error('missing dbName')
+    }
     return relax({ db: dbName, path: '_changes', qs: opts }, callback)
   }
 
@@ -395,10 +408,12 @@ module.exports = exports = function dbScope (cfg) {
     if (typeof db === 'object' && db.config && db.config.url && db.config.db) {
       return urlResolveFix(db.config.url, encodeURIComponent(db.config.db))
     } else {
-      const parsed = u.parse(db)
-      if (parsed.protocol) {
-        return db
-      } else {
+      try {
+        // if it parses, return it
+        const parsed = new URL(db)
+        return parsed.toString()
+      } catch (e) {
+        // otherwise treat it as a database name
         return urlResolveFix(cfg.url, encodeURIComponent(db))
       }
     }
@@ -407,6 +422,12 @@ module.exports = exports = function dbScope (cfg) {
   // http://docs.couchdb.org/en/latest/api/server/common.html#post--_replicate
   function replicateDb (source, target, opts0, callback0) {
     const { opts, callback } = getCallback(opts0, callback0)
+    if (!source) {
+      throw new Error('missing source')
+    }
+    if (!target) {
+      throw new Error('missing target')
+    }
 
     // _replicate
     opts.source = _serializeAsUrl(source)
@@ -427,6 +448,12 @@ module.exports = exports = function dbScope (cfg) {
   // http://guide.couchdb.org/draft/replication.html
   function enableReplication (source, target, opts0, callback0) {
     const { opts, callback } = getCallback(opts0, callback0)
+    if (!source) {
+      throw new Error('missing source')
+    }
+    if (!target) {
+      throw new Error('missing target')
+    }
 
     // _replicator
     opts.source = _serializeAsUrl(source)
@@ -438,12 +465,21 @@ module.exports = exports = function dbScope (cfg) {
   // http://guide.couchdb.org/draft/replication.html
   function queryReplication (id, opts0, callback0) {
     const { opts, callback } = getCallback(opts0, callback0)
+    if (!id) {
+      throw new Error('missing id')
+    }
     return relax({ db: '_replicator', method: 'GET', path: id, qs: opts }, callback)
   }
 
   // http://guide.couchdb.org/draft/replication.html
   function disableReplication (id, rev, opts0, callback0) {
     const { opts, callback } = getCallback(opts0, callback0)
+    if (!id) {
+      throw new Error('missing id')
+    }
+    if (!rev) {
+      throw new Error('missing rev')
+    }
     const req = {
       db: '_replicator',
       method: 'DELETE',
@@ -547,7 +583,7 @@ module.exports = exports = function dbScope (cfg) {
         db: dbName,
         doc: docSrc,
         method: 'COPY',
-        headers: { 'Destination': docDest }
+        headers: { Destination: docDest }
       }
 
       if (opts.overwrite) {
@@ -593,7 +629,7 @@ module.exports = exports = function dbScope (cfg) {
     // http://docs.couchdb.org/en/latest/api/database/bulk-api.html#post--db-_all_docs
     function fetchDocs (docNames, qs0, callback0) {
       const { opts, callback } = getCallback(qs0, callback0)
-      opts['include_docs'] = true
+      opts.include_docs = true
 
       return relax({
         db: dbName,
@@ -750,7 +786,7 @@ module.exports = exports = function dbScope (cfg) {
           length: Buffer.isBuffer(att.data)
             ? att.data.length : Buffer.byteLength(att.data),
           /* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
-          'content_type': att.content_type
+          content_type: att.content_type
         }
         multipart.push({ body: att.data })
       })
@@ -1004,5 +1040,5 @@ function urlResolveFix (couchUrl, dbName) {
   if (/[^/]$/.test(couchUrl)) {
     couchUrl += '/'
   }
-  return u.resolve(couchUrl, dbName)
+  return new URL(dbName, couchUrl).toString()
 }


[couchdb-nano] 05/15: finished top level tests

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit ea90dc1d52bc3e29808086d09aca9408ab9198c9
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Thu Feb 6 08:55:10 2020 +0000

    finished top level tests
---
 test/database.follow.test.js    |  22 ++++++++
 test/nano.config.test.js        |  63 +++++++++++++++++++++++
 test/nano.followUpdates.test.js |  21 ++++++++
 test/nano.request.test.js       | 110 ++++++++++++++++++++++++++++++++++++++++
 test/nano.updates.test.js       |  75 +++++++++++++++++++++++++++
 test/nano.use.test.js           |  31 +++++++++++
 6 files changed, 322 insertions(+)

diff --git a/test/database.follow.test.js b/test/database.follow.test.js
index e69de29..870a7bf 100644
--- a/test/database.follow.test.js
+++ b/test/database.follow.test.js
@@ -0,0 +1,22 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+
+test('should be able to follow changes feed - nano.db.follow', () => {
+  const db = nano.db.use('db')
+  const feed = db.follow({ since: 'now' })
+  expect(feed.constructor.name).toBe('Feed')
+  // no need to test the changes feed follower - it has its own tests
+})
diff --git a/test/nano.config.test.js b/test/nano.config.test.js
new file mode 100644
index 0000000..72de445
--- /dev/null
+++ b/test/nano.config.test.js
@@ -0,0 +1,63 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+
+test('should be able to supply HTTP url - nano.config', () => {
+  const HTTP_URL = 'http://localhost:5984'
+  const nano = Nano(HTTP_URL)
+  expect(nano.config.url).toBe(HTTP_URL)
+})
+
+test('should be able to supply URL with database name - nano.config', () => {
+  const HTTP_URL = 'http://localhost:5984/db'
+  const nano = Nano(HTTP_URL)
+  expect(nano.config.url).toBe('http://localhost:5984')
+  expect(nano.config.db).toBe('db')
+})
+
+test('should be able to supply HTTPS url - nano.config', () => {
+  const HTTPS_URL = 'https://mydomain.com'
+  const nano = Nano(HTTPS_URL)
+  expect(nano.config.url).toBe(HTTPS_URL)
+})
+
+test('should be able to supply HTTP url with cookie jar - nano.config', () => {
+  const HTTP_URL = 'http://localhost:5984'
+  const nano = Nano({ url: HTTP_URL, jar: true })
+  expect(nano.config.url).toBe(HTTP_URL)
+  expect(nano.config.jar).toBe(true)
+})
+
+test('should be able to supply HTTPS url with auth credentials - nano.config', () => {
+  const HTTPS_URL = 'https://myusername:mypassword@mydomain.com'
+  const nano = Nano(HTTPS_URL)
+  expect(nano.config.url).toBe(HTTPS_URL)
+})
+
+test('should be able to supply requestDefaults - nano.config', () => {
+  const HTTPS_URL = 'https://myusername:mypassword@mydomain.com'
+  const defaults = { proxy: 'http://localproxy.com' }
+  const nano = Nano({ url: HTTPS_URL, requestDefaults: defaults })
+  expect(nano.config.url).toBe(HTTPS_URL)
+  expect(nano.config.requestDefaults).toBe(defaults)
+})
+
+test('should be able to supply logging function - nano.config', () => {
+  const HTTPS_URL = 'https://myusername:mypassword@mydomain.com'
+  const logger = (id, args) => {
+    console.log(id, args)
+  }
+  const nano = Nano({ url: HTTPS_URL, log: logger })
+  expect(nano.config.url).toBe(HTTPS_URL)
+  expect(typeof nano.config.log).toBe('function')
+})
diff --git a/test/nano.followUpdates.test.js b/test/nano.followUpdates.test.js
new file mode 100644
index 0000000..001b3a3
--- /dev/null
+++ b/test/nano.followUpdates.test.js
@@ -0,0 +1,21 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+
+test('should be able to follow db updates- nano.followUpdates', () => {
+  const feed = nano.followUpdates()
+  expect(feed.constructor.name).toBe('Feed')
+  // no need to test the changes feed follower - it has its own tests
+})
diff --git a/test/nano.request.test.js b/test/nano.request.test.js
new file mode 100644
index 0000000..dc23da1
--- /dev/null
+++ b/test/nano.request.test.js
@@ -0,0 +1,110 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('check request can do GET requests - nano.request', async () => {
+  // mocks
+  const response = { ok: true }
+  const scope = nock(COUCH_URL)
+    .get('/mydb?a=1&b=2')
+    .reply(200, response)
+
+  // test GET /db
+  const req = {
+    method: 'get',
+    db: 'mydb',
+    qs: { a: 1, b: 2 }
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request can do POST requests - nano.request', async () => {
+  // mocks
+  const response = { ok: true }
+  const scope = nock(COUCH_URL)
+    .post('/mydb', { _id: '1', a: true })
+    .reply(200, response)
+
+  // test GET /db
+  const req = {
+    method: 'post',
+    db: 'mydb',
+    body: { _id: '1', a: true }
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request can do PUT requests - nano.request', async () => {
+  // mocks
+  const response = { ok: true }
+  const scope = nock(COUCH_URL)
+    .put('/mydb/1', { _id: '1', a: true })
+    .reply(200, response)
+
+  // test GET /db
+  const req = {
+    method: 'put',
+    db: 'mydb',
+    path: '1',
+    body: { _id: '1', a: true }
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request can do DELETE requests - nano.request', async () => {
+  // mocks
+  const response = { ok: true }
+  const scope = nock(COUCH_URL)
+    .delete('/mydb/mydoc')
+    .query({ rev: '1-123' })
+    .reply(200, response)
+
+  // test GET /db
+  const req = {
+    method: 'delete',
+    db: 'mydb',
+    path: 'mydoc',
+    qs: { rev: '1-123' }
+
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request can do HEAD requests - nano.request', async () => {
+  // mocks
+  const response = ''
+  const scope = nock(COUCH_URL)
+    .head('/mydb/mydoc')
+    .reply(200, '')
+
+  // test GET /db
+  const req = {
+    method: 'head',
+    db: 'mydb',
+    path: 'mydoc'
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/nano.updates.test.js b/test/nano.updates.test.js
new file mode 100644
index 0000000..127041e
--- /dev/null
+++ b/test/nano.updates.test.js
@@ -0,0 +1,75 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const response = {
+  results: [
+    {
+      db_name: 'firehosetarget',
+      type: 'updated',
+      seq: '1678-g1AAAACheJzLYWBgYMpgTmEQTM4vTc5ISXLIyU9OzMnILy7JAUklMiTV____PyuDOQnIi8gFirGnmKQaJhqZY9ODx6Q8FiDJ0ACk_sMNZDGDGGhubJCWmopNaxYASRExkg'
+    },
+    {
+      db_name: 'bob',
+      type: 'created',
+      seq: '1679-g1AAAACheJzLYWBgYMpgTmEQTM4vTc5ISXLIyU9OzMnILy7JAUklMiTV____PyuDOQnIi8gFirGnmKQaJhqZY9ODx6Q8FiDJ0ACk_sMNZDGHGGhubJCWmopNaxYASTMxkw'
+    },
+    {
+      db_name: 'bob',
+      type: 'updated',
+      seq: '1680-g1AAAACheJzLYWBgYMpgTmEQTM4vTc5ISXLIyU9OzMnILy7JAUklMiTV____PyuDOQnIi8gFirGnmKQaJhqZY9ODx6Q8FiDJ0ACk_sMNZLGAGGhubJCWmopNaxYASVUxlA'
+    }
+  ],
+  last_seq: '1680-g1AAAACheJzLYWBgYMpgTmEQTM4vTc5ISXLIyU9OzMnILy7JAUklMiTV____PyuDOQnIi8gFirGnmKQaJhqZY9ODx6Q8FiDJ0ACk_sMNZLGAGGhubJCWmopNaxYASVUxlA'
+}
+const errResponse = {
+  error: 'not_found',
+  reason: 'Database does not exist.'
+}
+
+test('should be able to fetch db updates - GET /_db_updates - nano.updates', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/_db_updates')
+    .reply(200, response)
+
+  // test GET /db
+  const p = await nano.updates()
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to fetch db updates with options - GET /_db_updates - nano.updates', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/_db_updates?timeout=10000')
+    .reply(200, response)
+
+  // test GET /db
+  const p = await nano.updates({ timeout: 10000 })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should handle 404 - GET /_db_updates - nano.updates', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/_db_updates')
+    .reply(404, errResponse)
+
+  // test GET /db
+  await expect(nano.db.updates()).rejects.toThrow('Database does not exist.')
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/nano.use.test.js b/test/nano.use.test.js
new file mode 100644
index 0000000..ba73044
--- /dev/null
+++ b/test/nano.use.test.js
@@ -0,0 +1,31 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+
+test('should be able to use a database - nano.db.use', () => {
+  const db = nano.db.use('db1')
+  expect(typeof db).toBe('object')
+  expect(typeof db.get).toBe('function')
+  expect(typeof db.replication).toBe('object')
+  expect(db.config.db).toBe('db1')
+})
+
+test('should be able to use a database - nano.use', () => {
+  const db = nano.use('db2')
+  expect(typeof db).toBe('object')
+  expect(typeof db.get).toBe('function')
+  expect(typeof db.replication).toBe('object')
+  expect(db.config.db).toBe('db2')
+})


[couchdb-nano] 03/15: add jest framework. Remove tape/mocha/istanbul.

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit 5fbf353f1a2aec8b4ad60404581407f32c44aa5c
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Wed Feb 5 14:15:28 2020 +0000

    add jest framework. Remove tape/mocha/istanbul.
---
 package-lock.json | 7805 +++++++++++++++++++++++++++++++++++++++++++----------
 package.json      |   30 +-
 2 files changed, 6430 insertions(+), 1405 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 5267567..18f6963 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,491 +1,651 @@
 {
   "name": "nano",
-  "version": "8.1.0",
+  "version": "8.2.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
-    "@types/caseless": {
-      "version": "0.12.1",
-      "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.1.tgz",
-      "integrity": "sha512-FhlMa34NHp9K5MY1Uz8yb+ZvuX0pnvn3jScRSNAb75KHGB8d3rEU6hqMs3Z2vjuytcMfRg6c5CHMc3wtYyD2/A=="
-    },
-    "@types/form-data": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz",
-      "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==",
+    "@babel/code-frame": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
+      "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
+      "dev": true,
       "requires": {
-        "@types/node": "*"
+        "@babel/highlight": "^7.8.3"
       }
     },
-    "@types/node": {
-      "version": "10.7.0",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.7.0.tgz",
-      "integrity": "sha512-dmYIvoQEZWnyQfgrwPCoxztv/93NYQGEiOoQhuI56rJahv9de6Q2apZl3bufV46YJ0OAXdaktIuw4RIRl4DTeA=="
-    },
-    "@types/request": {
-      "version": "2.47.1",
-      "resolved": "https://registry.npmjs.org/@types/request/-/request-2.47.1.tgz",
-      "integrity": "sha512-TV3XLvDjQbIeVxJ1Z3oCTDk/KuYwwcNKVwz2YaT0F5u86Prgc4syDAp6P96rkTQQ4bIdh+VswQIC9zS6NjY7/g==",
+    "@babel/core": {
+      "version": "7.8.4",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz",
+      "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==",
+      "dev": true,
       "requires": {
-        "@types/caseless": "*",
-        "@types/form-data": "*",
-        "@types/node": "*",
-        "@types/tough-cookie": "*"
+        "@babel/code-frame": "^7.8.3",
+        "@babel/generator": "^7.8.4",
+        "@babel/helpers": "^7.8.4",
+        "@babel/parser": "^7.8.4",
+        "@babel/template": "^7.8.3",
+        "@babel/traverse": "^7.8.4",
+        "@babel/types": "^7.8.3",
+        "convert-source-map": "^1.7.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.1",
+        "json5": "^2.1.0",
+        "lodash": "^4.17.13",
+        "resolve": "^1.3.2",
+        "semver": "^5.4.1",
+        "source-map": "^0.5.0"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "resolve": {
+          "version": "1.15.0",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz",
+          "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==",
+          "dev": true,
+          "requires": {
+            "path-parse": "^1.0.6"
+          }
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
       }
     },
-    "@types/tough-cookie": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.3.tgz",
-      "integrity": "sha512-MDQLxNFRLasqS4UlkWMSACMKeSm1x4Q3TxzUC7KQUsh6RK1ZrQ0VEyE3yzXcBu+K8ejVj4wuX32eUG02yNp+YQ=="
+    "@babel/generator": {
+      "version": "7.8.4",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz",
+      "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.8.3",
+        "jsesc": "^2.5.1",
+        "lodash": "^4.17.13",
+        "source-map": "^0.5.0"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
     },
-    "abbrev": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
-      "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
-      "dev": true
+    "@babel/helper-function-name": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz",
+      "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-get-function-arity": "^7.8.3",
+        "@babel/template": "^7.8.3",
+        "@babel/types": "^7.8.3"
+      }
     },
-    "acorn": {
-      "version": "6.1.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/acorn/-/acorn-6.1.1.tgz",
-      "integrity": "sha1-fSWuBbuK0fm2mRCOEJTs14hK3B8=",
-      "dev": true
+    "@babel/helper-get-function-arity": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
+      "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.8.3"
+      }
     },
-    "acorn-jsx": {
-      "version": "5.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/acorn-jsx/-/acorn-jsx-5.0.1.tgz",
-      "integrity": "sha1-MqBk/ZJUKSFqCbFBECv90YX65A4=",
+    "@babel/helper-plugin-utils": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
+      "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
       "dev": true
     },
-    "ajv": {
-      "version": "5.5.2",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
-      "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+    "@babel/helper-split-export-declaration": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
+      "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
+      "dev": true,
       "requires": {
-        "co": "^4.6.0",
-        "fast-deep-equal": "^1.0.0",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.3.0"
+        "@babel/types": "^7.8.3"
       }
     },
-    "ajv-keywords": {
-      "version": "3.4.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ajv-keywords/-/ajv-keywords-3.4.0.tgz",
-      "integrity": "sha1-S4Mee1MUFafMUYzUBOc/YZPGNJ0=",
-      "dev": true
-    },
-    "amdefine": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
-      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+    "@babel/helpers": {
+      "version": "7.8.4",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz",
+      "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==",
       "dev": true,
-      "optional": true
+      "requires": {
+        "@babel/template": "^7.8.3",
+        "@babel/traverse": "^7.8.4",
+        "@babel/types": "^7.8.3"
+      }
     },
-    "ansi-escapes": {
-      "version": "3.2.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
-      "integrity": "sha1-h4C5j/nb9WOBUtHx/lwde0RCl2s=",
-      "dev": true
+    "@babel/highlight": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
+      "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.0.0",
+        "esutils": "^2.0.2",
+        "js-tokens": "^4.0.0"
+      },
+      "dependencies": {
+        "js-tokens": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+          "dev": true
+        }
+      }
     },
-    "ansi-regex": {
-      "version": "2.1.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ansi-regex/-/ansi-regex-2.1.1.tgz",
-      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+    "@babel/parser": {
+      "version": "7.8.4",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz",
+      "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==",
       "dev": true
     },
-    "ansi-styles": {
-      "version": "2.2.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ansi-styles/-/ansi-styles-2.2.1.tgz",
-      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-      "dev": true
+    "@babel/plugin-syntax-bigint": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+      "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
     },
-    "argparse": {
-      "version": "1.0.10",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+    "@babel/plugin-syntax-object-rest-spread": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+      "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
       "dev": true,
       "requires": {
-        "sprintf-js": "~1.0.2"
+        "@babel/helper-plugin-utils": "^7.8.0"
       }
     },
-    "array-includes": {
-      "version": "3.0.3",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/array-includes/-/array-includes-3.0.3.tgz",
-      "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
+    "@babel/template": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
+      "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
       "dev": true,
       "requires": {
-        "define-properties": "^1.1.2",
-        "es-abstract": "^1.7.0"
+        "@babel/code-frame": "^7.8.3",
+        "@babel/parser": "^7.8.3",
+        "@babel/types": "^7.8.3"
       }
     },
-    "asn1": {
-      "version": "0.2.4",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
-      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+    "@babel/traverse": {
+      "version": "7.8.4",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz",
+      "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==",
+      "dev": true,
       "requires": {
-        "safer-buffer": "~2.1.0"
+        "@babel/code-frame": "^7.8.3",
+        "@babel/generator": "^7.8.4",
+        "@babel/helper-function-name": "^7.8.3",
+        "@babel/helper-split-export-declaration": "^7.8.3",
+        "@babel/parser": "^7.8.4",
+        "@babel/types": "^7.8.3",
+        "debug": "^4.1.0",
+        "globals": "^11.1.0",
+        "lodash": "^4.17.13"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        }
       }
     },
-    "assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+    "@babel/types": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
+      "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
+      "dev": true,
+      "requires": {
+        "esutils": "^2.0.2",
+        "lodash": "^4.17.13",
+        "to-fast-properties": "^2.0.0"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        }
+      }
     },
-    "assertion-error": {
-      "version": "1.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/assertion-error/-/assertion-error-1.1.0.tgz",
-      "integrity": "sha1-5gtrDo8wG9l+U3UhW9pAbIURjAs=",
+    "@bcoe/v8-coverage": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+      "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
       "dev": true
     },
-    "async": {
-      "version": "2.6.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/async/-/async-2.6.2.tgz",
-      "integrity": "sha1-GDMOp+bjE4h/XS8qkEusb+TdU4E=",
+    "@cnakazawa/watch": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz",
+      "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==",
       "dev": true,
       "requires": {
-        "lodash": "^4.17.11"
+        "exec-sh": "^0.3.2",
+        "minimist": "^1.2.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
       }
     },
-    "asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
-    },
-    "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="
-    },
-    "aws4": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
-      "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
-    },
-    "babel-code-frame": {
-      "version": "6.26.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
-      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+    "@istanbuljs/load-nyc-config": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz",
+      "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==",
       "dev": true,
       "requires": {
-        "chalk": "^1.1.3",
-        "esutils": "^2.0.2",
-        "js-tokens": "^3.0.2"
+        "camelcase": "^5.3.1",
+        "find-up": "^4.1.0",
+        "js-yaml": "^3.13.1",
+        "resolve-from": "^5.0.0"
       },
       "dependencies": {
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+        "esprima": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+          "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+          "dev": true
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
           "dev": true,
           "requires": {
-            "ansi-styles": "^2.2.1",
-            "escape-string-regexp": "^1.0.2",
-            "has-ansi": "^2.0.0",
-            "strip-ansi": "^3.0.0",
-            "supports-color": "^2.0.0"
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
           }
         },
-        "strip-ansi": {
-          "version": "3.0.1",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/strip-ansi/-/strip-ansi-3.0.1.tgz",
-          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+        "js-yaml": {
+          "version": "3.13.1",
+          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+          "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
           "dev": true,
           "requires": {
-            "ansi-regex": "^2.0.0"
+            "argparse": "^1.0.7",
+            "esprima": "^4.0.0"
           }
         },
-        "supports-color": {
-          "version": "2.0.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/supports-color/-/supports-color-2.0.0.tgz",
-          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.2.2",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
+          "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+          "dev": true
+        },
+        "resolve-from": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+          "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
           "dev": true
         }
       }
     },
-    "balanced-match": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-      "dev": true
-    },
-    "bcrypt-pbkdf": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
-      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
-      "optional": true,
-      "requires": {
-        "tweetnacl": "^0.14.3"
-      }
-    },
-    "brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "dev": true,
-      "requires": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "browser-request": {
-      "version": "0.3.3",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/browser-request/-/browser-request-0.3.3.tgz",
-      "integrity": "sha1-ns5bWsqJopkyJC4Yv5M975h2zBc="
-    },
-    "caller-path": {
-      "version": "0.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/caller-path/-/caller-path-0.1.0.tgz",
-      "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
-      "dev": true,
-      "requires": {
-        "callsites": "^0.2.0"
-      }
-    },
-    "callsites": {
-      "version": "0.2.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/callsites/-/callsites-0.2.0.tgz",
-      "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+    "@istanbuljs/schema": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
+      "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==",
       "dev": true
     },
-    "caseless": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
-    },
-    "chai": {
-      "version": "4.2.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/chai/-/chai-4.2.0.tgz",
-      "integrity": "sha1-dgqnLPION5XoSxKHfODoNzeqKeU=",
-      "dev": true,
-      "requires": {
-        "assertion-error": "^1.1.0",
-        "check-error": "^1.0.2",
-        "deep-eql": "^3.0.1",
-        "get-func-name": "^2.0.0",
-        "pathval": "^1.1.0",
-        "type-detect": "^4.0.5"
-      }
-    },
-    "chalk": {
-      "version": "2.4.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/chalk/-/chalk-2.4.2.tgz",
-      "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
+    "@jest/console": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.1.0.tgz",
+      "integrity": "sha512-3P1DpqAMK/L07ag/Y9/Jup5iDEG9P4pRAuZiMQnU0JB3UOvCyYCjCoxr7sIA80SeyUCUKrr24fKAxVpmBgQonA==",
       "dev": true,
       "requires": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
+        "@jest/source-map": "^25.1.0",
+        "chalk": "^3.0.0",
+        "jest-util": "^25.1.0",
+        "slash": "^3.0.0"
       },
       "dependencies": {
         "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
           "dev": true,
           "requires": {
-            "color-convert": "^1.9.0"
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
           }
         },
-        "has-flag": {
+        "chalk": {
           "version": "3.0.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
           "dev": true
         },
         "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
           "dev": true,
           "requires": {
-            "has-flag": "^3.0.0"
+            "has-flag": "^4.0.0"
           }
         }
       }
     },
-    "chardet": {
-      "version": "0.4.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/chardet/-/chardet-0.4.2.tgz",
-      "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
-      "dev": true
-    },
-    "check-error": {
-      "version": "1.0.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/check-error/-/check-error-1.0.2.tgz",
-      "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
-      "dev": true
-    },
-    "circular-json": {
-      "version": "0.3.3",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/circular-json/-/circular-json-0.3.3.tgz",
-      "integrity": "sha1-gVyZ6oT2gJUp0vRXkb34JxE1LWY=",
-      "dev": true
-    },
-    "cli-cursor": {
-      "version": "2.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/cli-cursor/-/cli-cursor-2.1.0.tgz",
-      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
-      "dev": true,
-      "requires": {
-        "restore-cursor": "^2.0.0"
-      }
-    },
-    "cli-width": {
-      "version": "2.2.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/cli-width/-/cli-width-2.2.0.tgz",
-      "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
-      "dev": true
-    },
-    "cloudant-follow": {
-      "version": "0.18.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/cloudant-follow/-/cloudant-follow-0.18.1.tgz",
-      "integrity": "sha1-f0pUgUq85iwJmYf6G7ATHUVbx58=",
-      "requires": {
-        "browser-request": "~0.3.0",
-        "debug": "^4.0.1",
-        "request": "^2.88.0"
-      }
-    },
-    "co": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
-      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
-    },
-    "color-convert": {
-      "version": "1.9.3",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/color-convert/-/color-convert-1.9.3.tgz",
-      "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
-      "dev": true,
-      "requires": {
-        "color-name": "1.1.3"
-      }
-    },
-    "color-name": {
-      "version": "1.1.3",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-      "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=",
-      "requires": {
-        "delayed-stream": "~1.0.0"
-      }
-    },
-    "commander": {
-      "version": "2.19.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
-      "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
-      "dev": true,
-      "optional": true
-    },
-    "concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-      "dev": true
-    },
-    "contains-path": {
-      "version": "0.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/contains-path/-/contains-path-0.1.0.tgz",
-      "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
-      "dev": true
-    },
-    "core-util-is": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
-    },
-    "cross-spawn": {
-      "version": "6.0.5",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/cross-spawn/-/cross-spawn-6.0.5.tgz",
-      "integrity": "sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q=",
+    "@jest/core": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.1.0.tgz",
+      "integrity": "sha512-iz05+NmwCmZRzMXvMo6KFipW7nzhbpEawrKrkkdJzgytavPse0biEnCNr2wRlyCsp3SmKaEY+SGv7YWYQnIdig==",
       "dev": true,
       "requires": {
-        "nice-try": "^1.0.4",
-        "path-key": "^2.0.1",
-        "semver": "^5.5.0",
-        "shebang-command": "^1.2.0",
-        "which": "^1.2.9"
-      }
-    },
-    "dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
-      "requires": {
-        "assert-plus": "^1.0.0"
-      }
-    },
-    "debug": {
-      "version": "4.1.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/debug/-/debug-4.1.1.tgz",
-      "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=",
-      "requires": {
-        "ms": "^2.1.1"
+        "@jest/console": "^25.1.0",
+        "@jest/reporters": "^25.1.0",
+        "@jest/test-result": "^25.1.0",
+        "@jest/transform": "^25.1.0",
+        "@jest/types": "^25.1.0",
+        "ansi-escapes": "^4.2.1",
+        "chalk": "^3.0.0",
+        "exit": "^0.1.2",
+        "graceful-fs": "^4.2.3",
+        "jest-changed-files": "^25.1.0",
+        "jest-config": "^25.1.0",
+        "jest-haste-map": "^25.1.0",
+        "jest-message-util": "^25.1.0",
+        "jest-regex-util": "^25.1.0",
+        "jest-resolve": "^25.1.0",
+        "jest-resolve-dependencies": "^25.1.0",
+        "jest-runner": "^25.1.0",
+        "jest-runtime": "^25.1.0",
+        "jest-snapshot": "^25.1.0",
+        "jest-util": "^25.1.0",
+        "jest-validate": "^25.1.0",
+        "jest-watcher": "^25.1.0",
+        "micromatch": "^4.0.2",
+        "p-each-series": "^2.1.0",
+        "realpath-native": "^1.1.0",
+        "rimraf": "^3.0.0",
+        "slash": "^3.0.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "dependencies": {
+        "ansi-escapes": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz",
+          "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.8.1"
+          }
+        },
+        "ansi-regex": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "glob": {
+          "version": "7.1.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+          "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "graceful-fs": {
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+          "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "rimraf": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.1.tgz",
+          "integrity": "sha512-IQ4ikL8SjBiEDZfk+DFVwqRK8md24RWMEJkdSlgNLkyyAImcjf8SWvU1qFMDOb4igBClbTQ/ugPqXcRwdFTxZw==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        },
+        "strip-ansi": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
       }
     },
-    "debug-log": {
-      "version": "1.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/debug-log/-/debug-log-1.0.1.tgz",
-      "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=",
-      "dev": true
-    },
-    "deep-eql": {
-      "version": "3.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/deep-eql/-/deep-eql-3.0.1.tgz",
-      "integrity": "sha1-38lARACtHI/gI+faHfHBR8S0RN8=",
+    "@jest/environment": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.1.0.tgz",
+      "integrity": "sha512-cTpUtsjU4cum53VqBDlcW0E4KbQF03Cn0jckGPW/5rrE9tb+porD3+hhLtHAwhthsqfyF+bizyodTlsRA++sHg==",
       "dev": true,
       "requires": {
-        "type-detect": "^4.0.0"
+        "@jest/fake-timers": "^25.1.0",
+        "@jest/types": "^25.1.0",
+        "jest-mock": "^25.1.0"
       }
     },
-    "deep-equal": {
-      "version": "1.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/deep-equal/-/deep-equal-1.0.1.tgz",
-      "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
-      "dev": true
-    },
-    "deep-is": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
-      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
-      "dev": true
-    },
-    "define-properties": {
-      "version": "1.1.3",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/define-properties/-/define-properties-1.1.3.tgz",
-      "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=",
+    "@jest/fake-timers": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.1.0.tgz",
+      "integrity": "sha512-Eu3dysBzSAO1lD7cylZd/CVKdZZ1/43SF35iYBNV1Lvvn2Undp3Grwsv8PrzvbLhqwRzDd4zxrY4gsiHc+wygQ==",
       "dev": true,
       "requires": {
-        "object-keys": "^1.0.12"
+        "@jest/types": "^25.1.0",
+        "jest-message-util": "^25.1.0",
+        "jest-mock": "^25.1.0",
+        "jest-util": "^25.1.0",
+        "lolex": "^5.0.0"
       }
     },
-    "defined": {
-      "version": "1.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/defined/-/defined-1.0.0.tgz",
-      "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
-      "dev": true
-    },
-    "deglob": {
-      "version": "2.1.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/deglob/-/deglob-2.1.1.tgz",
-      "integrity": "sha1-0mjhaHJ3mYYujqwHBC4WWVfB874=",
+    "@jest/reporters": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.1.0.tgz",
+      "integrity": "sha512-ORLT7hq2acJQa8N+NKfs68ZtHFnJPxsGqmofxW7v7urVhzJvpKZG9M7FAcgh9Ee1ZbCteMrirHA3m5JfBtAaDg==",
       "dev": true,
       "requires": {
-        "find-root": "^1.0.0",
-        "glob": "^7.0.5",
-        "ignore": "^3.0.9",
-        "pkg-config": "^1.1.0",
-        "run-parallel": "^1.1.2",
-        "uniq": "^1.0.1"
+        "@bcoe/v8-coverage": "^0.2.3",
+        "@jest/console": "^25.1.0",
+        "@jest/environment": "^25.1.0",
+        "@jest/test-result": "^25.1.0",
+        "@jest/transform": "^25.1.0",
+        "@jest/types": "^25.1.0",
+        "chalk": "^3.0.0",
+        "collect-v8-coverage": "^1.0.0",
+        "exit": "^0.1.2",
+        "glob": "^7.1.2",
+        "istanbul-lib-coverage": "^3.0.0",
+        "istanbul-lib-instrument": "^4.0.0",
+        "istanbul-lib-report": "^3.0.0",
+        "istanbul-lib-source-maps": "^4.0.0",
+        "istanbul-reports": "^3.0.0",
+        "jest-haste-map": "^25.1.0",
+        "jest-resolve": "^25.1.0",
+        "jest-runtime": "^25.1.0",
+        "jest-util": "^25.1.0",
+        "jest-worker": "^25.1.0",
+        "node-notifier": "^6.0.0",
+        "slash": "^3.0.0",
+        "source-map": "^0.6.0",
+        "string-length": "^3.1.0",
+        "terminal-link": "^2.0.0",
+        "v8-to-istanbul": "^4.0.1"
       },
       "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
         "glob": {
-          "version": "7.1.3",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/glob/-/glob-7.1.3.tgz",
-          "integrity": "sha1-OWCDLT8VdBCDQtr9OmezMsCWnfE=",
+          "version": "7.1.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+          "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
           "dev": true,
           "requires": {
             "fs.realpath": "^1.0.0",
@@ -496,921 +656,4185 @@
             "path-is-absolute": "^1.0.0"
           }
         },
-        "ignore": {
-          "version": "3.3.10",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ignore/-/ignore-3.3.10.tgz",
-          "integrity": "sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM=",
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
           "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
         }
       }
     },
-    "delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
-    },
-    "doctrine": {
-      "version": "2.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/doctrine/-/doctrine-2.1.0.tgz",
-      "integrity": "sha1-XNAfwQFiG0LEzX9dGmYkNxbT850=",
+    "@jest/source-map": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.1.0.tgz",
+      "integrity": "sha512-ohf2iKT0xnLWcIUhL6U6QN+CwFWf9XnrM2a6ybL9NXxJjgYijjLSitkYHIdzkd8wFliH73qj/+epIpTiWjRtAA==",
       "dev": true,
       "requires": {
-        "esutils": "^2.0.2"
+        "callsites": "^3.0.0",
+        "graceful-fs": "^4.2.3",
+        "source-map": "^0.6.0"
+      },
+      "dependencies": {
+        "callsites": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+          "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+          "dev": true
+        },
+        "graceful-fs": {
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+          "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
       }
     },
-    "ecc-jsbn": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
-      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
-      "optional": true,
+    "@jest/test-result": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.1.0.tgz",
+      "integrity": "sha512-FZzSo36h++U93vNWZ0KgvlNuZ9pnDnztvaM7P/UcTx87aPDotG18bXifkf1Ji44B7k/eIatmMzkBapnAzjkJkg==",
+      "dev": true,
       "requires": {
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.1.0"
+        "@jest/console": "^25.1.0",
+        "@jest/transform": "^25.1.0",
+        "@jest/types": "^25.1.0",
+        "@types/istanbul-lib-coverage": "^2.0.0",
+        "collect-v8-coverage": "^1.0.0"
       }
     },
-    "error-ex": {
-      "version": "1.3.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/error-ex/-/error-ex-1.3.2.tgz",
-      "integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8=",
+    "@jest/test-sequencer": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.1.0.tgz",
+      "integrity": "sha512-WgZLRgVr2b4l/7ED1J1RJQBOharxS11EFhmwDqknpknE0Pm87HLZVS2Asuuw+HQdfQvm2aXL2FvvBLxOD1D0iw==",
       "dev": true,
       "requires": {
-        "is-arrayish": "^0.2.1"
-      }
-    },
-    "errs": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/errs/-/errs-0.3.2.tgz",
-      "integrity": "sha1-eYCZstvTfKK8dJ5TinwTB9C1BJk="
-    },
-    "es-abstract": {
-      "version": "1.13.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/es-abstract/-/es-abstract-1.13.0.tgz",
-      "integrity": "sha1-rIYUX91QmdjdSVWMy6Lq+biOJOk=",
-      "dev": true,
-      "requires": {
-        "es-to-primitive": "^1.2.0",
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "is-callable": "^1.1.4",
-        "is-regex": "^1.0.4",
-        "object-keys": "^1.0.12"
-      }
-    },
-    "es-to-primitive": {
-      "version": "1.2.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
-      "integrity": "sha1-7fckeAM0VujdqO8J4ArZZQcH83c=",
-      "dev": true,
-      "requires": {
-        "is-callable": "^1.1.4",
-        "is-date-object": "^1.0.1",
-        "is-symbol": "^1.0.2"
-      }
-    },
-    "escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-      "dev": true
-    },
-    "escodegen": {
-      "version": "1.8.1",
-      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
-      "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
-      "dev": true,
-      "requires": {
-        "esprima": "^2.7.1",
-        "estraverse": "^1.9.1",
-        "esutils": "^2.0.2",
-        "optionator": "^0.8.1",
-        "source-map": "~0.2.0"
+        "@jest/test-result": "^25.1.0",
+        "jest-haste-map": "^25.1.0",
+        "jest-runner": "^25.1.0",
+        "jest-runtime": "^25.1.0"
       }
     },
-    "eslint": {
-      "version": "5.4.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint/-/eslint-5.4.0.tgz",
-      "integrity": "sha1-0GjsAwBrueBrQp3IX35GwbafrGI=",
+    "@jest/transform": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.1.0.tgz",
+      "integrity": "sha512-4ktrQ2TPREVeM+KxB4zskAT84SnmG1vaz4S+51aTefyqn3zocZUnliLLm5Fsl85I3p/kFPN4CRp1RElIfXGegQ==",
       "dev": true,
       "requires": {
-        "ajv": "^6.5.0",
-        "babel-code-frame": "^6.26.0",
-        "chalk": "^2.1.0",
-        "cross-spawn": "^6.0.5",
-        "debug": "^3.1.0",
-        "doctrine": "^2.1.0",
-        "eslint-scope": "^4.0.0",
-        "eslint-utils": "^1.3.1",
-        "eslint-visitor-keys": "^1.0.0",
-        "espree": "^4.0.0",
-        "esquery": "^1.0.1",
-        "esutils": "^2.0.2",
-        "file-entry-cache": "^2.0.0",
-        "functional-red-black-tree": "^1.0.1",
-        "glob": "^7.1.2",
-        "globals": "^11.7.0",
-        "ignore": "^4.0.2",
-        "imurmurhash": "^0.1.4",
-        "inquirer": "^5.2.0",
-        "is-resolvable": "^1.1.0",
-        "js-yaml": "^3.11.0",
-        "json-stable-stringify-without-jsonify": "^1.0.1",
-        "levn": "^0.3.0",
-        "lodash": "^4.17.5",
-        "minimatch": "^3.0.4",
-        "mkdirp": "^0.5.1",
-        "natural-compare": "^1.4.0",
-        "optionator": "^0.8.2",
-        "path-is-inside": "^1.0.2",
-        "pluralize": "^7.0.0",
-        "progress": "^2.0.0",
-        "regexpp": "^2.0.0",
-        "require-uncached": "^1.0.3",
-        "semver": "^5.5.0",
-        "strip-ansi": "^4.0.0",
-        "strip-json-comments": "^2.0.1",
-        "table": "^4.0.3",
-        "text-table": "^0.2.0"
+        "@babel/core": "^7.1.0",
+        "@jest/types": "^25.1.0",
+        "babel-plugin-istanbul": "^6.0.0",
+        "chalk": "^3.0.0",
+        "convert-source-map": "^1.4.0",
+        "fast-json-stable-stringify": "^2.0.0",
+        "graceful-fs": "^4.2.3",
+        "jest-haste-map": "^25.1.0",
+        "jest-regex-util": "^25.1.0",
+        "jest-util": "^25.1.0",
+        "micromatch": "^4.0.2",
+        "pirates": "^4.0.1",
+        "realpath-native": "^1.1.0",
+        "slash": "^3.0.0",
+        "source-map": "^0.6.1",
+        "write-file-atomic": "^3.0.0"
       },
       "dependencies": {
-        "ajv": {
-          "version": "6.10.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ajv/-/ajv-6.10.0.tgz",
-          "integrity": "sha1-kNDVRDnaWHzX6EO/twRfUL0ivfE=",
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
           "dev": true,
           "requires": {
-            "fast-deep-equal": "^2.0.1",
-            "fast-json-stable-stringify": "^2.0.0",
-            "json-schema-traverse": "^0.4.1",
-            "uri-js": "^4.2.2"
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
           }
         },
-        "debug": {
-          "version": "3.2.6",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/debug/-/debug-3.2.6.tgz",
-          "integrity": "sha1-6D0X3hbYp++3cX7b5fsQE17uYps=",
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
           "dev": true,
           "requires": {
-            "ms": "^2.1.1"
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
           }
         },
-        "fast-deep-equal": {
+        "color-convert": {
           "version": "2.0.1",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
-          "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
-          "dev": true
-        },
-        "glob": {
-          "version": "7.1.3",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/glob/-/glob-7.1.3.tgz",
-          "integrity": "sha1-OWCDLT8VdBCDQtr9OmezMsCWnfE=",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
           "dev": true,
           "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^3.0.4",
-            "once": "^1.3.0",
-            "path-is-absolute": "^1.0.0"
+            "color-name": "~1.1.4"
           }
         },
-        "json-schema-traverse": {
-          "version": "0.4.1",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-          "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=",
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
           "dev": true
-        }
-      }
-    },
-    "eslint-config-standard": {
-      "version": "12.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz",
-      "integrity": "sha1-Y4tMZdsL1aQTGflruh8V3a0hB9k=",
-      "dev": true
-    },
-    "eslint-config-standard-jsx": {
-      "version": "6.0.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint-config-standard-jsx/-/eslint-config-standard-jsx-6.0.2.tgz",
-      "integrity": "sha1-kMmqFqwsT4lwwT/H78YIus0C2nA=",
-      "dev": true
-    },
-    "eslint-import-resolver-node": {
-      "version": "0.3.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz",
-      "integrity": "sha1-WPFfuDm40FdsqYBBNHaqskcttmo=",
-      "dev": true,
-      "requires": {
-        "debug": "^2.6.9",
-        "resolve": "^1.5.0"
-      },
-      "dependencies": {
-        "debug": {
-          "version": "2.6.9",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/debug/-/debug-2.6.9.tgz",
-          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
-          "dev": true,
-          "requires": {
-            "ms": "2.0.0"
-          }
         },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+        "graceful-fs": {
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+          "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
           "dev": true
         },
-        "resolve": {
-          "version": "1.10.1",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/resolve/-/resolve-1.10.1.tgz",
-          "integrity": "sha1-ZkhCrJYHlbvnWCIc3M2mH7ZLXxg=",
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
           "dev": true,
           "requires": {
-            "path-parse": "^1.0.6"
+            "has-flag": "^4.0.0"
           }
         }
       }
     },
-    "eslint-module-utils": {
-      "version": "2.4.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz",
-      "integrity": "sha1-i5NJnpsA6rgMy2YU5p8DZ46E4Jo=",
+    "@jest/types": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz",
+      "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==",
       "dev": true,
       "requires": {
-        "debug": "^2.6.8",
-        "pkg-dir": "^2.0.0"
+        "@types/istanbul-lib-coverage": "^2.0.0",
+        "@types/istanbul-reports": "^1.1.1",
+        "@types/yargs": "^15.0.0",
+        "chalk": "^3.0.0"
       },
       "dependencies": {
-        "debug": {
-          "version": "2.6.9",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/debug/-/debug-2.6.9.tgz",
-          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
           "dev": true,
           "requires": {
-            "ms": "2.0.0"
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
           }
         },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "dev": true
-        }
-      }
-    },
-    "eslint-plugin-es": {
-      "version": "1.4.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz",
-      "integrity": "sha1-R19luyDJk/wQ6Mj+d9HWAGgHLaY=",
-      "dev": true,
-      "requires": {
-        "eslint-utils": "^1.3.0",
-        "regexpp": "^2.0.1"
-      }
-    },
-    "eslint-plugin-import": {
-      "version": "2.14.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz",
-      "integrity": "sha1-axdibS4+atUs/OiAeoRdFeIhEag=",
-      "dev": true,
-      "requires": {
-        "contains-path": "^0.1.0",
-        "debug": "^2.6.8",
-        "doctrine": "1.5.0",
-        "eslint-import-resolver-node": "^0.3.1",
-        "eslint-module-utils": "^2.2.0",
-        "has": "^1.0.1",
-        "lodash": "^4.17.4",
-        "minimatch": "^3.0.3",
-        "read-pkg-up": "^2.0.0",
-        "resolve": "^1.6.0"
-      },
-      "dependencies": {
-        "debug": {
-          "version": "2.6.9",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/debug/-/debug-2.6.9.tgz",
-          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
           "dev": true,
           "requires": {
-            "ms": "2.0.0"
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
           }
         },
-        "doctrine": {
-          "version": "1.5.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/doctrine/-/doctrine-1.5.0.tgz",
-          "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
           "dev": true,
           "requires": {
-            "esutils": "^2.0.2",
-            "isarray": "^1.0.0"
+            "color-name": "~1.1.4"
           }
         },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
           "dev": true
         },
-        "resolve": {
-          "version": "1.10.1",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/resolve/-/resolve-1.10.1.tgz",
-          "integrity": "sha1-ZkhCrJYHlbvnWCIc3M2mH7ZLXxg=",
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
           "dev": true,
           "requires": {
-            "path-parse": "^1.0.6"
+            "has-flag": "^4.0.0"
           }
         }
       }
     },
-    "eslint-plugin-node": {
-      "version": "7.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint-plugin-node/-/eslint-plugin-node-7.0.1.tgz",
-      "integrity": "sha1-puBU5QGZsu3YVRi4m057MjyfNts=",
+    "@sinonjs/commons": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.0.tgz",
+      "integrity": "sha512-qbk9AP+cZUsKdW1GJsBpxPKFmCJ0T8swwzVje3qFd+AkQb74Q/tiuzrdfFg8AD2g5HH/XbE/I8Uc1KYHVYWfhg==",
       "dev": true,
       "requires": {
-        "eslint-plugin-es": "^1.3.1",
-        "eslint-utils": "^1.3.1",
-        "ignore": "^4.0.2",
-        "minimatch": "^3.0.4",
-        "resolve": "^1.8.1",
-        "semver": "^5.5.0"
-      },
-      "dependencies": {
-        "resolve": {
-          "version": "1.10.1",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/resolve/-/resolve-1.10.1.tgz",
-          "integrity": "sha1-ZkhCrJYHlbvnWCIc3M2mH7ZLXxg=",
-          "dev": true,
-          "requires": {
-            "path-parse": "^1.0.6"
-          }
-        }
+        "type-detect": "4.0.8"
       }
     },
-    "eslint-plugin-promise": {
-      "version": "4.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz",
-      "integrity": "sha1-LQdLZT81oj0bqJ2Ol2qYURfRxqI=",
-      "dev": true
+    "@types/babel__core": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz",
+      "integrity": "sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA==",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0",
+        "@types/babel__generator": "*",
+        "@types/babel__template": "*",
+        "@types/babel__traverse": "*"
+      }
     },
-    "eslint-plugin-react": {
-      "version": "7.11.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz",
-      "integrity": "sha1-wBp69vF1GUV9YRaqlPxtLMrVRDw=",
+    "@types/babel__generator": {
+      "version": "7.6.1",
+      "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz",
+      "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==",
       "dev": true,
       "requires": {
-        "array-includes": "^3.0.3",
-        "doctrine": "^2.1.0",
-        "has": "^1.0.3",
-        "jsx-ast-utils": "^2.0.1",
-        "prop-types": "^15.6.2"
+        "@babel/types": "^7.0.0"
       }
     },
-    "eslint-plugin-standard": {
-      "version": "4.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz",
-      "integrity": "sha1-+EW0UQnJnNkOd3lpQKNEVGyPa1w=",
-      "dev": true
+    "@types/babel__template": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz",
+      "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
     },
-    "eslint-scope": {
-      "version": "4.0.3",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint-scope/-/eslint-scope-4.0.3.tgz",
-      "integrity": "sha1-ygODMxD2iJoyZHgaqC5j65z+eEg=",
+    "@types/babel__traverse": {
+      "version": "7.0.8",
+      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.8.tgz",
+      "integrity": "sha512-yGeB2dHEdvxjP0y4UbRtQaSkXJ9649fYCmIdRoul5kfAoGCwxuCbMhag0k3RPfnuh9kPGm8x89btcfDEXdVWGw==",
       "dev": true,
       "requires": {
-        "esrecurse": "^4.1.0",
-        "estraverse": "^4.1.1"
-      },
-      "dependencies": {
-        "estraverse": {
-          "version": "4.2.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/estraverse/-/estraverse-4.2.0.tgz",
-          "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
-          "dev": true
-        }
+        "@babel/types": "^7.3.0"
       }
     },
-    "eslint-utils": {
-      "version": "1.3.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint-utils/-/eslint-utils-1.3.1.tgz",
-      "integrity": "sha1-moUbqJ7nxGA0b5fPiTnHKYgn5RI=",
+    "@types/caseless": {
+      "version": "0.12.2",
+      "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz",
+      "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w=="
+    },
+    "@types/color-name": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
+      "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
       "dev": true
     },
-    "eslint-visitor-keys": {
-      "version": "1.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
-      "integrity": "sha1-PzGA+y4pEBdxastMnW1bXDSmqB0=",
+    "@types/istanbul-lib-coverage": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz",
+      "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==",
       "dev": true
     },
-    "espree": {
-      "version": "4.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/espree/-/espree-4.1.0.tgz",
-      "integrity": "sha1-co1UUeD9FWwEOEp62J7VH/VOsl8=",
+    "@types/istanbul-lib-report": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+      "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
       "dev": true,
       "requires": {
-        "acorn": "^6.0.2",
-        "acorn-jsx": "^5.0.0",
-        "eslint-visitor-keys": "^1.0.0"
+        "@types/istanbul-lib-coverage": "*"
       }
     },
-    "esprima": {
-      "version": "2.7.3",
-      "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
-      "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
-      "dev": true
-    },
-    "esquery": {
-      "version": "1.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/esquery/-/esquery-1.0.1.tgz",
-      "integrity": "sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg=",
+    "@types/istanbul-reports": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz",
+      "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==",
       "dev": true,
       "requires": {
-        "estraverse": "^4.0.0"
+        "@types/istanbul-lib-coverage": "*",
+        "@types/istanbul-lib-report": "*"
+      }
+    },
+    "@types/node": {
+      "version": "13.7.0",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.0.tgz",
+      "integrity": "sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ=="
+    },
+    "@types/request": {
+      "version": "2.48.4",
+      "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.4.tgz",
+      "integrity": "sha512-W1t1MTKYR8PxICH+A4HgEIPuAC3sbljoEVfyZbeFJJDbr30guDspJri2XOaM2E+Un7ZjrihaDi7cf6fPa2tbgw==",
+      "requires": {
+        "@types/caseless": "*",
+        "@types/node": "*",
+        "@types/tough-cookie": "*",
+        "form-data": "^2.5.0"
       },
       "dependencies": {
-        "estraverse": {
-          "version": "4.2.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/estraverse/-/estraverse-4.2.0.tgz",
-          "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
-          "dev": true
+        "form-data": {
+          "version": "2.5.1",
+          "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
+          "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
+          "requires": {
+            "asynckit": "^0.4.0",
+            "combined-stream": "^1.0.6",
+            "mime-types": "^2.1.12"
+          }
         }
       }
     },
-    "esrecurse": {
-      "version": "4.2.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/esrecurse/-/esrecurse-4.2.1.tgz",
-      "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=",
+    "@types/stack-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
+      "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
+      "dev": true
+    },
+    "@types/tough-cookie": {
+      "version": "2.3.6",
+      "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.6.tgz",
+      "integrity": "sha512-wHNBMnkoEBiRAd3s8KTKwIuO9biFtTf0LehITzBhSco+HQI0xkXZbLOD55SW3Aqw3oUkHstkm5SPv58yaAdFPQ=="
+    },
+    "@types/yargs": {
+      "version": "15.0.3",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.3.tgz",
+      "integrity": "sha512-XCMQRK6kfpNBixHLyHUsGmXrpEmFFxzMrcnSXFMziHd8CoNJo8l16FkHyQq4x+xbM7E2XL83/O78OD8u+iZTdQ==",
       "dev": true,
       "requires": {
-        "estraverse": "^4.1.0"
-      },
-      "dependencies": {
-        "estraverse": {
-          "version": "4.2.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/estraverse/-/estraverse-4.2.0.tgz",
-          "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
-          "dev": true
-        }
+        "@types/yargs-parser": "*"
       }
     },
-    "estraverse": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
-      "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
+    "@types/yargs-parser": {
+      "version": "15.0.0",
+      "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz",
+      "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==",
       "dev": true
     },
-    "esutils": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
-      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+    "abab": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz",
+      "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==",
       "dev": true
     },
-    "extend": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
-      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+    "acorn": {
+      "version": "6.1.1",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/acorn/-/acorn-6.1.1.tgz",
+      "integrity": "sha1-fSWuBbuK0fm2mRCOEJTs14hK3B8=",
+      "dev": true
     },
-    "external-editor": {
-      "version": "2.2.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/external-editor/-/external-editor-2.2.0.tgz",
-      "integrity": "sha1-BFURz9jRM/OEZnPRBHwVTiFK09U=",
+    "acorn-globals": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
+      "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
       "dev": true,
       "requires": {
-        "chardet": "^0.4.0",
-        "iconv-lite": "^0.4.17",
-        "tmp": "^0.0.33"
+        "acorn": "^6.0.1",
+        "acorn-walk": "^6.0.1"
       }
     },
-    "extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
-    },
-    "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="
-    },
-    "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="
+    "acorn-jsx": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz",
+      "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==",
+      "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=",
+    "acorn-walk": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
+      "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
       "dev": true
     },
-    "figures": {
-      "version": "2.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/figures/-/figures-2.0.0.tgz",
-      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
-      "dev": true,
+    "ajv": {
+      "version": "5.5.2",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+      "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
       "requires": {
-        "escape-string-regexp": "^1.0.5"
+        "co": "^4.6.0",
+        "fast-deep-equal": "^1.0.0",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.3.0"
       }
     },
-    "file-entry-cache": {
-      "version": "2.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
-      "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
-      "dev": true,
-      "requires": {
-        "flat-cache": "^1.2.1",
-        "object-assign": "^4.0.1"
-      }
+    "ansi-escapes": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+      "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+      "dev": true
     },
-    "find-root": {
-      "version": "1.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/find-root/-/find-root-1.1.0.tgz",
-      "integrity": "sha1-q8/Iunb3CMQql7PWhbfpRQv7nOQ=",
+    "ansi-regex": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+      "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
       "dev": true
     },
-    "find-up": {
-      "version": "2.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/find-up/-/find-up-2.1.0.tgz",
-      "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+    "ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
       "dev": true,
       "requires": {
-        "locate-path": "^2.0.0"
+        "color-convert": "^1.9.0"
       }
     },
-    "flat-cache": {
-      "version": "1.3.4",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/flat-cache/-/flat-cache-1.3.4.tgz",
-      "integrity": "sha1-LC73dSXMKSkAff/6HdMUqpyd7m8=",
+    "anymatch": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+      "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
       "dev": true,
       "requires": {
-        "circular-json": "^0.3.1",
-        "graceful-fs": "^4.1.2",
-        "rimraf": "~2.6.2",
-        "write": "^0.2.1"
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
       }
     },
-    "for-each": {
-      "version": "0.3.3",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/for-each/-/for-each-0.3.3.tgz",
-      "integrity": "sha1-abRH6IoKXTLD5whPPxcQA0shN24=",
+    "argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
       "dev": true,
       "requires": {
-        "is-callable": "^1.1.3"
-      }
-    },
-    "forever-agent": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
-    },
-    "form-data": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
-      "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
-      "requires": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "1.0.6",
-        "mime-types": "^2.1.12"
+        "sprintf-js": "~1.0.2"
       }
     },
-    "fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+    "arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
       "dev": true
     },
-    "function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=",
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
       "dev": true
     },
-    "functional-red-black-tree": {
-      "version": "1.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
-      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
       "dev": true
     },
-    "get-func-name": {
-      "version": "2.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/get-func-name/-/get-func-name-2.0.0.tgz",
-      "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+    "array-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+      "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
       "dev": true
     },
-    "get-stdin": {
-      "version": "6.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/get-stdin/-/get-stdin-6.0.0.tgz",
-      "integrity": "sha1-ngm/cSs2CrkiXoEgSPcf3pyJZXs=",
+    "array-includes": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz",
+      "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0",
+        "is-string": "^1.0.5"
+      }
+    },
+    "array-unique": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
       "dev": true
     },
-    "getpass": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+    "asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
       "requires": {
-        "assert-plus": "^1.0.0"
+        "safer-buffer": "~2.1.0"
       }
     },
-    "glob": {
-      "version": "5.0.15",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
-      "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "astral-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+      "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+      "dev": true
+    },
+    "async": {
+      "version": "2.6.2",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/async/-/async-2.6.2.tgz",
+      "integrity": "sha1-GDMOp+bjE4h/XS8qkEusb+TdU4E=",
       "dev": true,
       "requires": {
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "2 || 3",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
+        "lodash": "^4.17.11"
       }
     },
-    "globals": {
-      "version": "11.12.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/globals/-/globals-11.12.0.tgz",
-      "integrity": "sha1-q4eVM4hooLq9hSV1gBjCp+uVxC4=",
-      "dev": true
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
     },
-    "graceful-fs": {
-      "version": "4.1.15",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/graceful-fs/-/graceful-fs-4.1.15.tgz",
-      "integrity": "sha1-/7cD4QZuig7qpMi4C6klPu77+wA=",
+    "atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
       "dev": true
     },
-    "handlebars": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.1.tgz",
-      "integrity": "sha512-3Zhi6C0euYZL5sM0Zcy7lInLXKQ+YLcF/olbN010mzGQ4XVm50JeyBnMqofHh696GrciGruC7kCcApPDJvVgwA==",
+    "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="
+    },
+    "aws4": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+      "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
+    },
+    "babel-jest": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.1.0.tgz",
+      "integrity": "sha512-tz0VxUhhOE2y+g8R2oFrO/2VtVjA1lkJeavlhExuRBg3LdNJY9gwQ+Vcvqt9+cqy71MCTJhewvTB7Qtnnr9SWg==",
       "dev": true,
       "requires": {
-        "neo-async": "^2.6.0",
-        "optimist": "^0.6.1",
-        "source-map": "^0.6.1",
-        "uglify-js": "^3.1.4"
+        "@jest/transform": "^25.1.0",
+        "@jest/types": "^25.1.0",
+        "@types/babel__core": "^7.1.0",
+        "babel-plugin-istanbul": "^6.0.0",
+        "babel-preset-jest": "^25.1.0",
+        "chalk": "^3.0.0",
+        "slash": "^3.0.0"
       },
       "dependencies": {
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
           "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
         }
       }
     },
-    "har-schema": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
-      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
-    },
-    "har-validator": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz",
-      "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==",
+    "babel-plugin-istanbul": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz",
+      "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==",
+      "dev": true,
       "requires": {
-        "ajv": "^5.3.0",
-        "har-schema": "^2.0.0"
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@istanbuljs/load-nyc-config": "^1.0.0",
+        "@istanbuljs/schema": "^0.1.2",
+        "istanbul-lib-instrument": "^4.0.0",
+        "test-exclude": "^6.0.0"
       }
     },
-    "has": {
-      "version": "1.0.3",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/has/-/has-1.0.3.tgz",
-      "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=",
+    "babel-plugin-jest-hoist": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.1.0.tgz",
+      "integrity": "sha512-oIsopO41vW4YFZ9yNYoLQATnnN46lp+MZ6H4VvPKFkcc2/fkl3CfE/NZZSmnEIEsJRmJAgkVEK0R7Zbl50CpTw==",
       "dev": true,
       "requires": {
-        "function-bind": "^1.1.1"
+        "@types/babel__traverse": "^7.0.6"
       }
     },
-    "has-ansi": {
-      "version": "2.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/has-ansi/-/has-ansi-2.0.0.tgz",
-      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+    "babel-preset-jest": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.1.0.tgz",
+      "integrity": "sha512-eCGn64olaqwUMaugXsTtGAM2I0QTahjEtnRu0ql8Ie+gDWAc1N6wqN0k2NilnyTunM69Pad7gJY7LOtwLimoFQ==",
       "dev": true,
       "requires": {
-        "ansi-regex": "^2.0.0"
+        "@babel/plugin-syntax-bigint": "^7.0.0",
+        "@babel/plugin-syntax-object-rest-spread": "^7.0.0",
+        "babel-plugin-jest-hoist": "^25.1.0"
       }
     },
-    "has-flag": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-      "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-      "dev": true
-    },
-    "has-symbols": {
+    "balanced-match": {
       "version": "1.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/has-symbols/-/has-symbols-1.0.0.tgz",
-      "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
-      "dev": true
-    },
-    "hosted-git-info": {
-      "version": "2.7.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
-      "integrity": "sha1-l/I2l3vW4SVAiTD/bePuxigewEc=",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
       "dev": true
     },
-    "http-signature": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
       "requires": {
-        "assert-plus": "^1.0.0",
-        "jsprim": "^1.2.2",
-        "sshpk": "^1.7.0"
+        "cache-base": "^1.0.1",
+        "class-utils": "^0.3.5",
+        "component-emitter": "^1.2.1",
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.1",
+        "mixin-deep": "^1.2.0",
+        "pascalcase": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
       }
     },
-    "iconv-lite": {
-      "version": "0.4.24",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/iconv-lite/-/iconv-lite-0.4.24.tgz",
-      "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=",
-      "dev": true,
-      "requires": {
-        "safer-buffer": ">= 2.1.2 < 3"
+    "bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "optional": true,
+      "requires": {
+        "tweetnacl": "^0.14.3"
       }
     },
-    "ignore": {
-      "version": "4.0.6",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ignore/-/ignore-4.0.6.tgz",
-      "integrity": "sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw=",
-      "dev": true
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
     },
-    "imurmurhash": {
-      "version": "0.1.4",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/imurmurhash/-/imurmurhash-0.1.4.tgz",
-      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+    "braces": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "dev": true,
+      "requires": {
+        "fill-range": "^7.0.1"
+      }
+    },
+    "browser-process-hrtime": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz",
+      "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==",
       "dev": true
     },
-    "inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+    "browser-request": {
+      "version": "0.3.3",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/browser-request/-/browser-request-0.3.3.tgz",
+      "integrity": "sha1-ns5bWsqJopkyJC4Yv5M975h2zBc="
+    },
+    "browser-resolve": {
+      "version": "1.11.3",
+      "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz",
+      "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==",
       "dev": true,
       "requires": {
-        "once": "^1.3.0",
-        "wrappy": "1"
+        "resolve": "1.1.7"
       }
     },
-    "inherits": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+    "bser": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+      "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+      "dev": true,
+      "requires": {
+        "node-int64": "^0.4.0"
+      }
+    },
+    "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
     },
-    "inquirer": {
-      "version": "5.2.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/inquirer/-/inquirer-5.2.0.tgz",
-      "integrity": "sha1-2zUMK3Paynf/EkOWLp8i8JloVyY=",
+    "cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
       "dev": true,
       "requires": {
-        "ansi-escapes": "^3.0.0",
-        "chalk": "^2.0.0",
-        "cli-cursor": "^2.1.0",
-        "cli-width": "^2.0.0",
-        "external-editor": "^2.1.0",
-        "figures": "^2.0.0",
-        "lodash": "^4.3.0",
-        "mute-stream": "0.0.7",
-        "run-async": "^2.2.0",
-        "rxjs": "^5.5.2",
-        "string-width": "^2.1.0",
-        "strip-ansi": "^4.0.0",
-        "through": "^2.3.6"
+        "collection-visit": "^1.0.0",
+        "component-emitter": "^1.2.1",
+        "get-value": "^2.0.6",
+        "has-value": "^1.0.0",
+        "isobject": "^3.0.1",
+        "set-value": "^2.0.0",
+        "to-object-path": "^0.3.0",
+        "union-value": "^1.0.0",
+        "unset-value": "^1.0.0"
       }
     },
-    "is-arrayish": {
-      "version": "0.2.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/is-arrayish/-/is-arrayish-0.2.1.tgz",
-      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+    "callsites": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
       "dev": true
     },
-    "is-callable": {
-      "version": "1.1.4",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/is-callable/-/is-callable-1.1.4.tgz",
-      "integrity": "sha1-HhrfIZ4e62hNaR+dagX/DTCiTXU=",
+    "camelcase": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
       "dev": true
     },
-    "is-date-object": {
-      "version": "1.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/is-date-object/-/is-date-object-1.0.1.tgz",
-      "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
+    "capture-exit": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
+      "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==",
+      "dev": true,
+      "requires": {
+        "rsvp": "^4.8.4"
+      }
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+    },
+    "chalk": {
+      "version": "2.4.2",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "chardet": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+      "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
       "dev": true
     },
-    "is-fullwidth-code-point": {
+    "ci-info": {
       "version": "2.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+      "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
       "dev": true
     },
-    "is-promise": {
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "define-property": "^0.2.5",
+        "isobject": "^3.0.0",
+        "static-extend": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "cli-cursor": {
       "version": "2.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/is-promise/-/is-promise-2.1.0.tgz",
-      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/cli-cursor/-/cli-cursor-2.1.0.tgz",
+      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+      "dev": true,
+      "requires": {
+        "restore-cursor": "^2.0.0"
+      }
+    },
+    "cli-width": {
+      "version": "2.2.0",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/cli-width/-/cli-width-2.2.0.tgz",
+      "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
       "dev": true
     },
-    "is-regex": {
-      "version": "1.0.4",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/is-regex/-/is-regex-1.0.4.tgz",
-      "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+    "cliui": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+      "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
       "dev": true,
       "requires": {
-        "has": "^1.0.1"
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^6.2.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+          "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.0"
+          }
+        }
+      }
+    },
+    "cloudant-follow": {
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/cloudant-follow/-/cloudant-follow-0.18.2.tgz",
+      "integrity": "sha512-qu/AmKxDqJds+UmT77+0NbM7Yab2K3w0qSeJRzsq5dRWJTEJdWeb+XpG4OpKuTE9RKOa/Awn2gR3TTnvNr3TeA==",
+      "requires": {
+        "browser-request": "~0.3.0",
+        "debug": "^4.0.1",
+        "request": "^2.88.0"
       }
     },
-    "is-resolvable": {
-      "version": "1.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/is-resolvable/-/is-resolvable-1.1.0.tgz",
-      "integrity": "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg=",
+    "co": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
+    },
+    "collect-v8-coverage": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.0.tgz",
+      "integrity": "sha512-VKIhJgvk8E1W28m5avZ2Gv2Ruv5YiF56ug2oclvaG9md69BuZImMG2sk9g7QNKLUbtYAKQjXjYxbYZVUlMMKmQ==",
       "dev": true
     },
-    "is-symbol": {
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "^1.0.0",
+        "object-visit": "^1.0.0"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "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=",
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "component-emitter": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+      "dev": true
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "contains-path": {
+      "version": "0.1.0",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/contains-path/-/contains-path-0.1.0.tgz",
+      "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
+      "dev": true
+    },
+    "convert-source-map": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+      "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.1.1"
+      }
+    },
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "core-util-is": {
       "version": "1.0.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/is-symbol/-/is-symbol-1.0.2.tgz",
-      "integrity": "sha1-oFX2rlcZLK7jKeeoYBGLSXqVDzg=",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+    },
+    "cross-spawn": {
+      "version": "6.0.5",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/cross-spawn/-/cross-spawn-6.0.5.tgz",
+      "integrity": "sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q=",
       "dev": true,
       "requires": {
-        "has-symbols": "^1.0.0"
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      }
+    },
+    "cssom": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
+      "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==",
+      "dev": true
+    },
+    "cssstyle": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.2.0.tgz",
+      "integrity": "sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA==",
+      "dev": true,
+      "requires": {
+        "cssom": "~0.3.6"
+      },
+      "dependencies": {
+        "cssom": {
+          "version": "0.3.8",
+          "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+          "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+          "dev": true
+        }
+      }
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "data-urls": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
+      "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
+      "dev": true,
+      "requires": {
+        "abab": "^2.0.0",
+        "whatwg-mimetype": "^2.2.0",
+        "whatwg-url": "^7.0.0"
+      }
+    },
+    "debug": {
+      "version": "4.1.1",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/debug/-/debug-4.1.1.tgz",
+      "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=",
+      "requires": {
+        "ms": "^2.1.1"
+      }
+    },
+    "debug-log": {
+      "version": "1.0.1",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/debug-log/-/debug-log-1.0.1.tgz",
+      "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=",
+      "dev": true
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true
+    },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
+    "deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "dev": true
+    },
+    "define-properties": {
+      "version": "1.1.3",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/define-properties/-/define-properties-1.1.3.tgz",
+      "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=",
+      "dev": true,
+      "requires": {
+        "object-keys": "^1.0.12"
+      }
+    },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "^1.0.2",
+        "isobject": "^3.0.1"
+      },
+      "dependencies": {
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "deglob": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/deglob/-/deglob-4.0.1.tgz",
+      "integrity": "sha512-/g+RDZ7yf2HvoW+E5Cy+K94YhgcFgr6C8LuHZD1O5HoNPkf3KY6RfXJ0DBGlB/NkLi5gml+G9zqRzk9S0mHZCg==",
+      "dev": true,
+      "requires": {
+        "find-root": "^1.0.0",
+        "glob": "^7.0.5",
+        "ignore": "^5.0.0",
+        "pkg-config": "^1.1.0",
+        "run-parallel": "^1.1.2",
+        "uniq": "^1.0.1"
+      },
+      "dependencies": {
+        "ignore": {
+          "version": "5.1.4",
+          "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
+          "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==",
+          "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="
+    },
+    "detect-newline": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+      "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+      "dev": true
+    },
+    "diff-sequences": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz",
+      "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==",
+      "dev": true
+    },
+    "doctrine": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+      "dev": true,
+      "requires": {
+        "esutils": "^2.0.2"
+      }
+    },
+    "domexception": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
+      "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
+      "dev": true,
+      "requires": {
+        "webidl-conversions": "^4.0.2"
+      }
+    },
+    "ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+      "optional": true,
+      "requires": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
+    },
+    "end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+      "dev": true,
+      "requires": {
+        "once": "^1.4.0"
+      }
+    },
+    "error-ex": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "errs": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/errs/-/errs-0.3.2.tgz",
+      "integrity": "sha1-eYCZstvTfKK8dJ5TinwTB9C1BJk="
+    },
+    "es-abstract": {
+      "version": "1.17.4",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
+      "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
+      "dev": true,
+      "requires": {
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.1.5",
+        "is-regex": "^1.0.5",
+        "object-inspect": "^1.7.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.0",
+        "string.prototype.trimleft": "^2.1.1",
+        "string.prototype.trimright": "^2.1.1"
+      },
+      "dependencies": {
+        "has-symbols": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+          "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+          "dev": true
+        }
+      }
+    },
+    "es-to-primitive": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+      "dev": true,
+      "requires": {
+        "is-callable": "^1.1.4",
+        "is-date-object": "^1.0.1",
+        "is-symbol": "^1.0.2"
+      }
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "dev": true
+    },
+    "eslint": {
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.4.0.tgz",
+      "integrity": "sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "ajv": "^6.10.0",
+        "chalk": "^2.1.0",
+        "cross-spawn": "^6.0.5",
+        "debug": "^4.0.1",
+        "doctrine": "^3.0.0",
+        "eslint-scope": "^5.0.0",
+        "eslint-utils": "^1.4.2",
+        "eslint-visitor-keys": "^1.1.0",
+        "espree": "^6.1.1",
+        "esquery": "^1.0.1",
+        "esutils": "^2.0.2",
+        "file-entry-cache": "^5.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "glob-parent": "^5.0.0",
+        "globals": "^11.7.0",
+        "ignore": "^4.0.6",
+        "import-fresh": "^3.0.0",
+        "imurmurhash": "^0.1.4",
+        "inquirer": "^6.4.1",
+        "is-glob": "^4.0.0",
+        "js-yaml": "^3.13.1",
+        "json-stable-stringify-without-jsonify": "^1.0.1",
+        "levn": "^0.3.0",
+        "lodash": "^4.17.14",
+        "minimatch": "^3.0.4",
+        "mkdirp": "^0.5.1",
+        "natural-compare": "^1.4.0",
+        "optionator": "^0.8.2",
+        "progress": "^2.0.0",
+        "regexpp": "^2.0.1",
+        "semver": "^6.1.2",
+        "strip-ansi": "^5.2.0",
+        "strip-json-comments": "^3.0.1",
+        "table": "^5.2.3",
+        "text-table": "^0.2.0",
+        "v8-compile-cache": "^2.0.3"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.11.0",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz",
+          "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==",
+          "dev": true,
+          "requires": {
+            "fast-deep-equal": "^3.1.1",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.4.1",
+            "uri-js": "^4.2.2"
+          }
+        },
+        "fast-deep-equal": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
+          "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
+          "dev": true
+        },
+        "json-schema-traverse": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+          "dev": true
+        },
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
+    "eslint-config-standard": {
+      "version": "14.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.0.tgz",
+      "integrity": "sha512-EF6XkrrGVbvv8hL/kYa/m6vnvmUT+K82pJJc4JJVMM6+Qgqh0pnwprSxdduDLB9p/7bIxD+YV5O0wfb8lmcPbA==",
+      "dev": true
+    },
+    "eslint-config-standard-jsx": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-8.1.0.tgz",
+      "integrity": "sha512-ULVC8qH8qCqbU792ZOO6DaiaZyHNS/5CZt3hKqHkEhVlhPEPN3nfBqqxJCyp59XrjIBZPu1chMYe9T2DXZ7TMw==",
+      "dev": true
+    },
+    "eslint-import-resolver-node": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz",
+      "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==",
+      "dev": true,
+      "requires": {
+        "debug": "^2.6.9",
+        "resolve": "^1.13.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        },
+        "resolve": {
+          "version": "1.15.0",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz",
+          "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==",
+          "dev": true,
+          "requires": {
+            "path-parse": "^1.0.6"
+          }
+        }
+      }
+    },
+    "eslint-module-utils": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz",
+      "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==",
+      "dev": true,
+      "requires": {
+        "debug": "^2.6.9",
+        "pkg-dir": "^2.0.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        }
+      }
+    },
+    "eslint-plugin-es": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz",
+      "integrity": "sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ==",
+      "dev": true,
+      "requires": {
+        "eslint-utils": "^1.4.2",
+        "regexpp": "^3.0.0"
+      },
+      "dependencies": {
+        "regexpp": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz",
+          "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==",
+          "dev": true
+        }
+      }
+    },
+    "eslint-plugin-import": {
+      "version": "2.18.2",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz",
+      "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==",
+      "dev": true,
+      "requires": {
+        "array-includes": "^3.0.3",
+        "contains-path": "^0.1.0",
+        "debug": "^2.6.9",
+        "doctrine": "1.5.0",
+        "eslint-import-resolver-node": "^0.3.2",
+        "eslint-module-utils": "^2.4.0",
+        "has": "^1.0.3",
+        "minimatch": "^3.0.4",
+        "object.values": "^1.1.0",
+        "read-pkg-up": "^2.0.0",
+        "resolve": "^1.11.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "doctrine": {
+          "version": "1.5.0",
+          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/doctrine/-/doctrine-1.5.0.tgz",
+          "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "isarray": "^1.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        },
+        "resolve": {
+          "version": "1.15.0",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz",
+          "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==",
+          "dev": true,
+          "requires": {
+            "path-parse": "^1.0.6"
+          }
+        }
+      }
+    },
+    "eslint-plugin-node": {
+      "version": "10.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz",
+      "integrity": "sha512-1CSyM/QCjs6PXaT18+zuAXsjXGIGo5Rw630rSKwokSs2jrYURQc4R5JZpoanNCqwNmepg+0eZ9L7YiRUJb8jiQ==",
+      "dev": true,
+      "requires": {
+        "eslint-plugin-es": "^2.0.0",
+        "eslint-utils": "^1.4.2",
+        "ignore": "^5.1.1",
+        "minimatch": "^3.0.4",
+        "resolve": "^1.10.1",
+        "semver": "^6.1.0"
+      },
+      "dependencies": {
+        "ignore": {
+          "version": "5.1.4",
+          "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
+          "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==",
+          "dev": true
+        },
+        "resolve": {
+          "version": "1.15.0",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz",
+          "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==",
+          "dev": true,
+          "requires": {
+            "path-parse": "^1.0.6"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
+    "eslint-plugin-promise": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz",
+      "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==",
+      "dev": true
+    },
+    "eslint-plugin-react": {
+      "version": "7.14.3",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz",
+      "integrity": "sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==",
+      "dev": true,
+      "requires": {
+        "array-includes": "^3.0.3",
+        "doctrine": "^2.1.0",
+        "has": "^1.0.3",
+        "jsx-ast-utils": "^2.1.0",
+        "object.entries": "^1.1.0",
+        "object.fromentries": "^2.0.0",
+        "object.values": "^1.1.0",
+        "prop-types": "^15.7.2",
+        "resolve": "^1.10.1"
+      },
+      "dependencies": {
+        "doctrine": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+          "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2"
+          }
+        },
+        "resolve": {
+          "version": "1.15.0",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz",
+          "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==",
+          "dev": true,
+          "requires": {
+            "path-parse": "^1.0.6"
+          }
+        }
+      }
+    },
+    "eslint-plugin-standard": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz",
+      "integrity": "sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==",
+      "dev": true
+    },
+    "eslint-scope": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
+      "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
+      "dev": true,
+      "requires": {
+        "esrecurse": "^4.1.0",
+        "estraverse": "^4.1.1"
+      }
+    },
+    "eslint-utils": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
+      "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
+      "dev": true,
+      "requires": {
+        "eslint-visitor-keys": "^1.1.0"
+      }
+    },
+    "eslint-visitor-keys": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
+      "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
+      "dev": true
+    },
+    "espree": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz",
+      "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==",
+      "dev": true,
+      "requires": {
+        "acorn": "^7.1.0",
+        "acorn-jsx": "^5.1.0",
+        "eslint-visitor-keys": "^1.1.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
+          "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==",
+          "dev": true
+        }
+      }
+    },
+    "esprima": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+      "dev": true
+    },
+    "esquery": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+      "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^4.0.0"
+      }
+    },
+    "esrecurse": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^4.1.0"
+      }
+    },
+    "estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "dev": true
+    },
+    "esutils": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+      "dev": true
+    },
+    "exec-sh": {
+      "version": "0.3.4",
+      "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz",
+      "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==",
+      "dev": true
+    },
+    "execa": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "^6.0.0",
+        "get-stream": "^4.0.0",
+        "is-stream": "^1.1.0",
+        "npm-run-path": "^2.0.0",
+        "p-finally": "^1.0.0",
+        "signal-exit": "^3.0.0",
+        "strip-eof": "^1.0.0"
+      }
+    },
+    "exit": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+      "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+      "dev": true
+    },
+    "expand-brackets": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "dev": true,
+      "requires": {
+        "debug": "^2.3.3",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "posix-character-classes": "^0.1.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        }
+      }
+    },
+    "expect": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/expect/-/expect-25.1.0.tgz",
+      "integrity": "sha512-wqHzuoapQkhc3OKPlrpetsfueuEiMf3iWh0R8+duCu9PIjXoP7HgD5aeypwTnXUAjC8aMsiVDaWwlbJ1RlQ38g==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^25.1.0",
+        "ansi-styles": "^4.0.0",
+        "jest-get-type": "^25.1.0",
+        "jest-matcher-utils": "^25.1.0",
+        "jest-message-util": "^25.1.0",
+        "jest-regex-util": "^25.1.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        }
+      }
+    },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+    },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "^1.0.0",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "external-editor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+      "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+      "dev": true,
+      "requires": {
+        "chardet": "^0.7.0",
+        "iconv-lite": "^0.4.24",
+        "tmp": "^0.0.33"
+      }
+    },
+    "extglob": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+      "dev": true,
+      "requires": {
+        "array-unique": "^0.3.2",
+        "define-property": "^1.0.0",
+        "expand-brackets": "^2.1.4",
+        "extend-shallow": "^2.0.1",
+        "fragment-cache": "^0.2.1",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+    },
+    "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="
+    },
+    "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="
+    },
+    "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
+    },
+    "fb-watchman": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
+      "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==",
+      "dev": true,
+      "requires": {
+        "bser": "2.1.1"
+      }
+    },
+    "figures": {
+      "version": "2.0.0",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/figures/-/figures-2.0.0.tgz",
+      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "^1.0.5"
+      }
+    },
+    "file-entry-cache": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+      "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+      "dev": true,
+      "requires": {
+        "flat-cache": "^2.0.1"
+      }
+    },
+    "fill-range": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "dev": true,
+      "requires": {
+        "to-regex-range": "^5.0.1"
+      }
+    },
+    "find-root": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+      "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
+      "dev": true
+    },
+    "find-up": {
+      "version": "2.1.0",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/find-up/-/find-up-2.1.0.tgz",
+      "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+      "dev": true,
+      "requires": {
+        "locate-path": "^2.0.0"
+      }
+    },
+    "flat-cache": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+      "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+      "dev": true,
+      "requires": {
+        "flatted": "^2.0.0",
+        "rimraf": "2.6.3",
+        "write": "1.0.3"
+      }
+    },
+    "flatted": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
+      "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
+      "dev": true
+    },
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+    },
+    "form-data": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
+      "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "1.0.6",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "requires": {
+        "map-cache": "^0.2.2"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "fsevents": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz",
+      "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
+      "dev": true,
+      "optional": true
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=",
+      "dev": true
+    },
+    "functional-red-black-tree": {
+      "version": "1.0.1",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+      "dev": true
+    },
+    "gensync": {
+      "version": "1.0.0-beta.1",
+      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
+      "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==",
+      "dev": true
+    },
+    "get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "dev": true
+    },
+    "get-stdin": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz",
+      "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==",
+      "dev": true
+    },
+    "get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "requires": {
+        "pump": "^3.0.0"
+      }
+    },
+    "get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "glob": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+      "dev": true,
+      "requires": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      }
+    },
+    "glob-parent": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
+      "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
+      "dev": true,
+      "requires": {
+        "is-glob": "^4.0.1"
+      }
+    },
+    "globals": {
+      "version": "11.12.0",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/globals/-/globals-11.12.0.tgz",
+      "integrity": "sha1-q4eVM4hooLq9hSV1gBjCp+uVxC4=",
+      "dev": true
+    },
+    "graceful-fs": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+      "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
+      "dev": true
+    },
+    "growly": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
+      "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
+      "dev": true,
+      "optional": true
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+    },
+    "har-validator": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz",
+      "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==",
+      "requires": {
+        "ajv": "^5.3.0",
+        "har-schema": "^2.0.0"
+      }
+    },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/has/-/has-1.0.3.tgz",
+      "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
+    "has-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/has-symbols/-/has-symbols-1.0.0.tgz",
+      "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
+      "dev": true
+    },
+    "has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "requires": {
+        "get-value": "^2.0.6",
+        "has-values": "^1.0.0",
+        "isobject": "^3.0.0"
+      }
+    },
+    "has-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "dev": true,
+      "requires": {
+        "is-number": "^3.0.0",
+        "kind-of": "^4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "hosted-git-info": {
+      "version": "2.8.5",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz",
+      "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==",
+      "dev": true
+    },
+    "html-encoding-sniffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
+      "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
+      "dev": true,
+      "requires": {
+        "whatwg-encoding": "^1.0.1"
+      }
+    },
+    "html-escaper": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz",
+      "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==",
+      "dev": true
+    },
+    "http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      }
+    },
+    "human-signals": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
+      "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
+      "dev": true
+    },
+    "iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=",
+      "dev": true,
+      "requires": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      }
+    },
+    "ignore": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+      "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+      "dev": true
+    },
+    "import-fresh": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
+      "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
+      "dev": true,
+      "requires": {
+        "parent-module": "^1.0.0",
+        "resolve-from": "^4.0.0"
+      }
+    },
+    "import-local": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz",
+      "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==",
+      "dev": true,
+      "requires": {
+        "pkg-dir": "^4.2.0",
+        "resolve-cwd": "^3.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.2.2",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
+          "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+          "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+          "dev": true,
+          "requires": {
+            "find-up": "^4.0.0"
+          }
+        }
+      }
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "requires": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+      "dev": true
+    },
+    "inquirer": {
+      "version": "6.5.2",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
+      "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "^3.2.0",
+        "chalk": "^2.4.2",
+        "cli-cursor": "^2.1.0",
+        "cli-width": "^2.0.0",
+        "external-editor": "^3.0.3",
+        "figures": "^2.0.0",
+        "lodash": "^4.17.12",
+        "mute-stream": "0.0.7",
+        "run-async": "^2.2.0",
+        "rxjs": "^6.4.0",
+        "string-width": "^2.1.0",
+        "strip-ansi": "^5.1.0",
+        "through": "^2.3.6"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        }
+      }
+    },
+    "ip-regex": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
+      "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
+      "dev": true
+    },
+    "is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "is-buffer": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+      "dev": true
+    },
+    "is-callable": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
+      "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
+      "dev": true
+    },
+    "is-ci": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+      "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+      "dev": true,
+      "requires": {
+        "ci-info": "^2.0.0"
+      }
+    },
+    "is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-date-object": {
+      "version": "1.0.1",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/is-date-object/-/is-date-object-1.0.1.tgz",
+      "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
+      "dev": true
+    },
+    "is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "requires": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "dev": true
+    },
+    "is-fullwidth-code-point": {
+      "version": "2.0.0",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+      "dev": true
+    },
+    "is-generator-fn": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+      "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+      "dev": true
+    },
+    "is-glob": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+      "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+      "dev": true,
+      "requires": {
+        "is-extglob": "^2.1.1"
+      }
+    },
+    "is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "dev": true
+    },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "is-promise": {
+      "version": "2.1.0",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/is-promise/-/is-promise-2.1.0.tgz",
+      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+      "dev": true
+    },
+    "is-regex": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
+      "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+      "dev": true,
+      "requires": {
+        "has": "^1.0.3"
+      }
+    },
+    "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-string": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
+      "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
+      "dev": true
+    },
+    "is-symbol": {
+      "version": "1.0.2",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/is-symbol/-/is-symbol-1.0.2.tgz",
+      "integrity": "sha1-oFX2rlcZLK7jKeeoYBGLSXqVDzg=",
+      "dev": true,
+      "requires": {
+        "has-symbols": "^1.0.0"
+      }
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+    },
+    "is-windows": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+      "dev": true
+    },
+    "is-wsl": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz",
+      "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==",
+      "dev": true,
+      "optional": true
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "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="
+    },
+    "istanbul-lib-coverage": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
+      "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
+      "dev": true
+    },
+    "istanbul-lib-instrument": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz",
+      "integrity": "sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.7.5",
+        "@babel/parser": "^7.7.5",
+        "@babel/template": "^7.7.4",
+        "@babel/traverse": "^7.7.4",
+        "@istanbuljs/schema": "^0.1.2",
+        "istanbul-lib-coverage": "^3.0.0",
+        "semver": "^6.3.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
+    "istanbul-lib-report": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+      "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+      "dev": true,
+      "requires": {
+        "istanbul-lib-coverage": "^3.0.0",
+        "make-dir": "^3.0.0",
+        "supports-color": "^7.1.0"
+      },
+      "dependencies": {
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "istanbul-lib-source-maps": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
+      "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.1",
+        "istanbul-lib-coverage": "^3.0.0",
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "istanbul-reports": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
+      "integrity": "sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A==",
+      "dev": true,
+      "requires": {
+        "html-escaper": "^2.0.0",
+        "istanbul-lib-report": "^3.0.0"
+      }
+    },
+    "jest": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest/-/jest-25.1.0.tgz",
+      "integrity": "sha512-FV6jEruneBhokkt9MQk0WUFoNTwnF76CLXtwNMfsc0um0TlB/LG2yxUd0KqaFjEJ9laQmVWQWS0sG/t2GsuI0w==",
+      "dev": true,
+      "requires": {
+        "@jest/core": "^25.1.0",
+        "import-local": "^3.0.2",
+        "jest-cli": "^25.1.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "jest-cli": {
+          "version": "25.1.0",
+          "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.1.0.tgz",
+          "integrity": "sha512-p+aOfczzzKdo3AsLJlhs8J5EW6ffVidfSZZxXedJ0mHPBOln1DccqFmGCoO8JWd4xRycfmwy1eoQkMsF8oekPg==",
+          "dev": true,
+          "requires": {
+            "@jest/core": "^25.1.0",
+            "@jest/test-result": "^25.1.0",
+            "@jest/types": "^25.1.0",
+            "chalk": "^3.0.0",
+            "exit": "^0.1.2",
+            "import-local": "^3.0.2",
+            "is-ci": "^2.0.0",
+            "jest-config": "^25.1.0",
+            "jest-util": "^25.1.0",
+            "jest-validate": "^25.1.0",
+            "prompts": "^2.0.1",
+            "realpath-native": "^1.1.0",
+            "yargs": "^15.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "jest-changed-files": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.1.0.tgz",
+      "integrity": "sha512-bdL1aHjIVy3HaBO3eEQeemGttsq1BDlHgWcOjEOIAcga7OOEGWHD2WSu8HhL7I1F0mFFyci8VKU4tRNk+qtwDA==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^25.1.0",
+        "execa": "^3.2.0",
+        "throat": "^5.0.0"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz",
+          "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.1.0",
+            "shebang-command": "^2.0.0",
+            "which": "^2.0.1"
+          }
+        },
+        "execa": {
+          "version": "3.4.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz",
+          "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.0",
+            "get-stream": "^5.0.0",
+            "human-signals": "^1.1.1",
+            "is-stream": "^2.0.0",
+            "merge-stream": "^2.0.0",
+            "npm-run-path": "^4.0.0",
+            "onetime": "^5.1.0",
+            "p-finally": "^2.0.0",
+            "signal-exit": "^3.0.2",
+            "strip-final-newline": "^2.0.0"
+          }
+        },
+        "get-stream": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
+          "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
+          "dev": true,
+          "requires": {
+            "pump": "^3.0.0"
+          }
+        },
+        "is-stream": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+          "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+          "dev": true
+        },
+        "mimic-fn": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+          "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+          "dev": true
+        },
+        "npm-run-path": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+          "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.0.0"
+          }
+        },
+        "onetime": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
+          "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
+          "dev": true,
+          "requires": {
+            "mimic-fn": "^2.1.0"
+          }
+        },
+        "p-finally": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
+          "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==",
+          "dev": true
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+          "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+          "dev": true,
+          "requires": {
+            "shebang-regex": "^3.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+          "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+          "dev": true
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
+      }
+    },
+    "jest-config": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.1.0.tgz",
+      "integrity": "sha512-tLmsg4SZ5H7tuhBC5bOja0HEblM0coS3Wy5LTCb2C8ZV6eWLewHyK+3qSq9Bi29zmWQ7ojdCd3pxpx4l4d2uGw==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.1.0",
+        "@jest/test-sequencer": "^25.1.0",
+        "@jest/types": "^25.1.0",
+        "babel-jest": "^25.1.0",
+        "chalk": "^3.0.0",
+        "glob": "^7.1.1",
+        "jest-environment-jsdom": "^25.1.0",
+        "jest-environment-node": "^25.1.0",
+        "jest-get-type": "^25.1.0",
+        "jest-jasmine2": "^25.1.0",
+        "jest-regex-util": "^25.1.0",
+        "jest-resolve": "^25.1.0",
+        "jest-util": "^25.1.0",
+        "jest-validate": "^25.1.0",
+        "micromatch": "^4.0.2",
+        "pretty-format": "^25.1.0",
+        "realpath-native": "^1.1.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "glob": {
+          "version": "7.1.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+          "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "jest-diff": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz",
+      "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==",
+      "dev": true,
+      "requires": {
+        "chalk": "^3.0.0",
+        "diff-sequences": "^25.1.0",
+        "jest-get-type": "^25.1.0",
+        "pretty-format": "^25.1.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "jest-docblock": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.1.0.tgz",
+      "integrity": "sha512-370P/mh1wzoef6hUKiaMcsPtIapY25suP6JqM70V9RJvdKLrV4GaGbfUseUVk4FZJw4oTZ1qSCJNdrClKt5JQA==",
+      "dev": true,
+      "requires": {
+        "detect-newline": "^3.0.0"
+      }
+    },
+    "jest-each": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.1.0.tgz",
+      "integrity": "sha512-R9EL8xWzoPySJ5wa0DXFTj7NrzKpRD40Jy+zQDp3Qr/2QmevJgkN9GqioCGtAJ2bW9P/MQRznQHQQhoeAyra7A==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^25.1.0",
+        "chalk": "^3.0.0",
+        "jest-get-type": "^25.1.0",
+        "jest-util": "^25.1.0",
+        "pretty-format": "^25.1.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "jest-environment-jsdom": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.1.0.tgz",
+      "integrity": "sha512-ILb4wdrwPAOHX6W82GGDUiaXSSOE274ciuov0lztOIymTChKFtC02ddyicRRCdZlB5YSrv3vzr1Z5xjpEe1OHQ==",
+      "dev": true,
+      "requires": {
+        "@jest/environment": "^25.1.0",
+        "@jest/fake-timers": "^25.1.0",
+        "@jest/types": "^25.1.0",
+        "jest-mock": "^25.1.0",
+        "jest-util": "^25.1.0",
+        "jsdom": "^15.1.1"
+      }
+    },
+    "jest-environment-node": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.1.0.tgz",
+      "integrity": "sha512-U9kFWTtAPvhgYY5upnH9rq8qZkj6mYLup5l1caAjjx9uNnkLHN2xgZy5mo4SyLdmrh/EtB9UPpKFShvfQHD0Iw==",
+      "dev": true,
+      "requires": {
+        "@jest/environment": "^25.1.0",
+        "@jest/fake-timers": "^25.1.0",
+        "@jest/types": "^25.1.0",
+        "jest-mock": "^25.1.0",
+        "jest-util": "^25.1.0"
+      }
+    },
+    "jest-get-type": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz",
+      "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==",
+      "dev": true
+    },
+    "jest-haste-map": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.1.0.tgz",
+      "integrity": "sha512-/2oYINIdnQZAqyWSn1GTku571aAfs8NxzSErGek65Iu5o8JYb+113bZysRMcC/pjE5v9w0Yz+ldbj9NxrFyPyw==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^25.1.0",
+        "anymatch": "^3.0.3",
+        "fb-watchman": "^2.0.0",
+        "fsevents": "^2.1.2",
+        "graceful-fs": "^4.2.3",
+        "jest-serializer": "^25.1.0",
+        "jest-util": "^25.1.0",
+        "jest-worker": "^25.1.0",
+        "micromatch": "^4.0.2",
+        "sane": "^4.0.3",
+        "walker": "^1.0.7"
+      },
+      "dependencies": {
+        "graceful-fs": {
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+          "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
+          "dev": true
+        }
+      }
+    },
+    "jest-jasmine2": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.1.0.tgz",
+      "integrity": "sha512-GdncRq7jJ7sNIQ+dnXvpKO2MyP6j3naNK41DTTjEAhLEdpImaDA9zSAZwDhijjSF/D7cf4O5fdyUApGBZleaEg==",
+      "dev": true,
+      "requires": {
+        "@babel/traverse": "^7.1.0",
+        "@jest/environment": "^25.1.0",
+        "@jest/source-map": "^25.1.0",
+        "@jest/test-result": "^25.1.0",
+        "@jest/types": "^25.1.0",
+        "chalk": "^3.0.0",
+        "co": "^4.6.0",
+        "expect": "^25.1.0",
+        "is-generator-fn": "^2.0.0",
+        "jest-each": "^25.1.0",
+        "jest-matcher-utils": "^25.1.0",
+        "jest-message-util": "^25.1.0",
+        "jest-runtime": "^25.1.0",
+        "jest-snapshot": "^25.1.0",
+        "jest-util": "^25.1.0",
+        "pretty-format": "^25.1.0",
+        "throat": "^5.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "jest-leak-detector": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.1.0.tgz",
+      "integrity": "sha512-3xRI264dnhGaMHRvkFyEKpDeaRzcEBhyNrOG5oT8xPxOyUAblIAQnpiR3QXu4wDor47MDTiHbiFcbypdLcLW5w==",
+      "dev": true,
+      "requires": {
+        "jest-get-type": "^25.1.0",
+        "pretty-format": "^25.1.0"
+      }
+    },
+    "jest-matcher-utils": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz",
+      "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "^3.0.0",
+        "jest-diff": "^25.1.0",
+        "jest-get-type": "^25.1.0",
+        "pretty-format": "^25.1.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "jest-message-util": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.1.0.tgz",
+      "integrity": "sha512-Nr/Iwar2COfN22aCqX0kCVbXgn8IBm9nWf4xwGr5Olv/KZh0CZ32RKgZWMVDXGdOahicM10/fgjdimGNX/ttCQ==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "@jest/test-result": "^25.1.0",
+        "@jest/types": "^25.1.0",
+        "@types/stack-utils": "^1.0.1",
+        "chalk": "^3.0.0",
+        "micromatch": "^4.0.2",
+        "slash": "^3.0.0",
+        "stack-utils": "^1.0.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "jest-mock": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.1.0.tgz",
+      "integrity": "sha512-28/u0sqS+42vIfcd1mlcg4ZVDmSUYuNvImP4X2lX5hRMLW+CN0BeiKVD4p+ujKKbSPKd3rg/zuhCF+QBLJ4vag==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^25.1.0"
+      }
+    },
+    "jest-pnp-resolver": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz",
+      "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==",
+      "dev": true
+    },
+    "jest-regex-util": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.1.0.tgz",
+      "integrity": "sha512-9lShaDmDpqwg+xAd73zHydKrBbbrIi08Kk9YryBEBybQFg/lBWR/2BDjjiSE7KIppM9C5+c03XiDaZ+m4Pgs1w==",
+      "dev": true
+    },
+    "jest-resolve": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.1.0.tgz",
+      "integrity": "sha512-XkBQaU1SRCHj2Evz2Lu4Czs+uIgJXWypfO57L7JYccmAXv4slXA6hzNblmcRmf7P3cQ1mE7fL3ABV6jAwk4foQ==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^25.1.0",
+        "browser-resolve": "^1.11.3",
+        "chalk": "^3.0.0",
+        "jest-pnp-resolver": "^1.2.1",
+        "realpath-native": "^1.1.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "jest-resolve-dependencies": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.1.0.tgz",
+      "integrity": "sha512-Cu/Je38GSsccNy4I2vL12ZnBlD170x2Oh1devzuM9TLH5rrnLW1x51lN8kpZLYTvzx9j+77Y5pqBaTqfdzVzrw==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^25.1.0",
+        "jest-regex-util": "^25.1.0",
+        "jest-snapshot": "^25.1.0"
+      }
+    },
+    "jest-runner": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.1.0.tgz",
+      "integrity": "sha512-su3O5fy0ehwgt+e8Wy7A8CaxxAOCMzL4gUBftSs0Ip32S0epxyZPDov9Znvkl1nhVOJNf4UwAsnqfc3plfQH9w==",
+      "dev": true,
+      "requires": {
+        "@jest/console": "^25.1.0",
+        "@jest/environment": "^25.1.0",
+        "@jest/test-result": "^25.1.0",
+        "@jest/types": "^25.1.0",
+        "chalk": "^3.0.0",
+        "exit": "^0.1.2",
+        "graceful-fs": "^4.2.3",
+        "jest-config": "^25.1.0",
+        "jest-docblock": "^25.1.0",
+        "jest-haste-map": "^25.1.0",
+        "jest-jasmine2": "^25.1.0",
+        "jest-leak-detector": "^25.1.0",
+        "jest-message-util": "^25.1.0",
+        "jest-resolve": "^25.1.0",
+        "jest-runtime": "^25.1.0",
+        "jest-util": "^25.1.0",
+        "jest-worker": "^25.1.0",
+        "source-map-support": "^0.5.6",
+        "throat": "^5.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "graceful-fs": {
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+          "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "jest-runtime": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.1.0.tgz",
+      "integrity": "sha512-mpPYYEdbExKBIBB16ryF6FLZTc1Rbk9Nx0ryIpIMiDDkOeGa0jQOKVI/QeGvVGlunKKm62ywcioeFVzIbK03bA==",
+      "dev": true,
+      "requires": {
+        "@jest/console": "^25.1.0",
+        "@jest/environment": "^25.1.0",
+        "@jest/source-map": "^25.1.0",
+        "@jest/test-result": "^25.1.0",
+        "@jest/transform": "^25.1.0",
+        "@jest/types": "^25.1.0",
+        "@types/yargs": "^15.0.0",
+        "chalk": "^3.0.0",
+        "collect-v8-coverage": "^1.0.0",
+        "exit": "^0.1.2",
+        "glob": "^7.1.3",
+        "graceful-fs": "^4.2.3",
+        "jest-config": "^25.1.0",
+        "jest-haste-map": "^25.1.0",
+        "jest-message-util": "^25.1.0",
+        "jest-mock": "^25.1.0",
+        "jest-regex-util": "^25.1.0",
+        "jest-resolve": "^25.1.0",
+        "jest-snapshot": "^25.1.0",
+        "jest-util": "^25.1.0",
+        "jest-validate": "^25.1.0",
+        "realpath-native": "^1.1.0",
+        "slash": "^3.0.0",
+        "strip-bom": "^4.0.0",
+        "yargs": "^15.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "glob": {
+          "version": "7.1.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+          "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "graceful-fs": {
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+          "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "strip-bom": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+          "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "jest-serializer": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.1.0.tgz",
+      "integrity": "sha512-20Wkq5j7o84kssBwvyuJ7Xhn7hdPeTXndnwIblKDR2/sy1SUm6rWWiG9kSCgJPIfkDScJCIsTtOKdlzfIHOfKA==",
+      "dev": true
+    },
+    "jest-snapshot": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.1.0.tgz",
+      "integrity": "sha512-xZ73dFYN8b/+X2hKLXz4VpBZGIAn7muD/DAg+pXtDzDGw3iIV10jM7WiHqhCcpDZfGiKEj7/2HXAEPtHTj0P2A==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.0.0",
+        "@jest/types": "^25.1.0",
+        "chalk": "^3.0.0",
+        "expect": "^25.1.0",
+        "jest-diff": "^25.1.0",
+        "jest-get-type": "^25.1.0",
+        "jest-matcher-utils": "^25.1.0",
+        "jest-message-util": "^25.1.0",
+        "jest-resolve": "^25.1.0",
+        "mkdirp": "^0.5.1",
+        "natural-compare": "^1.4.0",
+        "pretty-format": "^25.1.0",
+        "semver": "^7.1.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "semver": {
+          "version": "7.1.2",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.2.tgz",
+          "integrity": "sha512-BJs9T/H8sEVHbeigqzIEo57Iu/3DG6c4QoqTfbQB3BPA4zgzAomh/Fk9E7QtjWQ8mx2dgA9YCfSF4y9k9bHNpQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "jest-util": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.1.0.tgz",
+      "integrity": "sha512-7did6pLQ++87Qsj26Fs/TIwZMUFBXQ+4XXSodRNy3luch2DnRXsSnmpVtxxQ0Yd6WTipGpbhh2IFP1mq6/fQGw==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^25.1.0",
+        "chalk": "^3.0.0",
+        "is-ci": "^2.0.0",
+        "mkdirp": "^0.5.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "jest-validate": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.1.0.tgz",
+      "integrity": "sha512-kGbZq1f02/zVO2+t1KQGSVoCTERc5XeObLwITqC6BTRH3Adv7NZdYqCpKIZLUgpLXf2yISzQ465qOZpul8abXA==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^25.1.0",
+        "camelcase": "^5.3.1",
+        "chalk": "^3.0.0",
+        "jest-get-type": "^25.1.0",
+        "leven": "^3.1.0",
+        "pretty-format": "^25.1.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "jest-watcher": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.1.0.tgz",
+      "integrity": "sha512-Q9eZ7pyaIr6xfU24OeTg4z1fUqBF/4MP6J801lyQfg7CsnZ/TCzAPvCfckKdL5dlBBEKBeHV0AdyjFZ5eWj4ig==",
+      "dev": true,
+      "requires": {
+        "@jest/test-result": "^25.1.0",
+        "@jest/types": "^25.1.0",
+        "ansi-escapes": "^4.2.1",
+        "chalk": "^3.0.0",
+        "jest-util": "^25.1.0",
+        "string-length": "^3.1.0"
+      },
+      "dependencies": {
+        "ansi-escapes": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz",
+          "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.8.1"
+          }
+        },
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
       }
     },
-    "is-typedarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
-    },
-    "isarray": {
-      "version": "1.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
-    },
-    "isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "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="
-    },
-    "istanbul": {
-      "version": "0.4.5",
-      "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz",
-      "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=",
+    "jest-worker": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz",
+      "integrity": "sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg==",
       "dev": true,
       "requires": {
-        "abbrev": "1.0.x",
-        "async": "1.x",
-        "escodegen": "1.8.x",
-        "esprima": "2.7.x",
-        "glob": "^5.0.15",
-        "handlebars": "^4.0.1",
-        "js-yaml": "3.x",
-        "mkdirp": "0.5.x",
-        "nopt": "3.x",
-        "once": "1.x",
-        "resolve": "1.1.x",
-        "supports-color": "^3.1.0",
-        "which": "^1.1.1",
-        "wordwrap": "^1.0.0"
+        "merge-stream": "^2.0.0",
+        "supports-color": "^7.0.0"
       },
       "dependencies": {
-        "async": {
-          "version": "1.5.2",
-          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
           "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
         }
       }
     },
     "js-tokens": {
-      "version": "3.0.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/js-tokens/-/js-tokens-3.0.2.tgz",
-      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
       "dev": true
     },
     "js-yaml": {
-      "version": "3.12.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
-      "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
+      "version": "3.13.1",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+      "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
       "dev": true,
       "requires": {
         "argparse": "^1.0.7",
         "esprima": "^4.0.0"
+      }
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "optional": true
+    },
+    "jsdom": {
+      "version": "15.2.1",
+      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz",
+      "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==",
+      "dev": true,
+      "requires": {
+        "abab": "^2.0.0",
+        "acorn": "^7.1.0",
+        "acorn-globals": "^4.3.2",
+        "array-equal": "^1.0.0",
+        "cssom": "^0.4.1",
+        "cssstyle": "^2.0.0",
+        "data-urls": "^1.1.0",
+        "domexception": "^1.0.1",
+        "escodegen": "^1.11.1",
+        "html-encoding-sniffer": "^1.0.2",
+        "nwsapi": "^2.2.0",
+        "parse5": "5.1.0",
+        "pn": "^1.1.0",
+        "request": "^2.88.0",
+        "request-promise-native": "^1.0.7",
+        "saxes": "^3.1.9",
+        "symbol-tree": "^3.2.2",
+        "tough-cookie": "^3.0.1",
+        "w3c-hr-time": "^1.0.1",
+        "w3c-xmlserializer": "^1.1.2",
+        "webidl-conversions": "^4.0.2",
+        "whatwg-encoding": "^1.0.5",
+        "whatwg-mimetype": "^2.3.0",
+        "whatwg-url": "^7.0.0",
+        "ws": "^7.0.0",
+        "xml-name-validator": "^3.0.0"
       },
       "dependencies": {
+        "acorn": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
+          "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==",
+          "dev": true
+        },
+        "escodegen": {
+          "version": "1.13.0",
+          "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.13.0.tgz",
+          "integrity": "sha512-eYk2dCkxR07DsHA/X2hRBj0CFAZeri/LyDMc0C8JT1Hqi6JnVpMhJ7XFITbb0+yZS3lVkaPL2oCkZ3AVmeVbMw==",
+          "dev": true,
+          "requires": {
+            "esprima": "^4.0.1",
+            "estraverse": "^4.2.0",
+            "esutils": "^2.0.2",
+            "optionator": "^0.8.1",
+            "source-map": "~0.6.1"
+          }
+        },
         "esprima": {
           "version": "4.0.1",
           "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
           "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
           "dev": true
+        },
+        "estraverse": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+          "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+          "dev": true
+        },
+        "punycode": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+          "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true,
+          "optional": true
+        },
+        "tough-cookie": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
+          "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
+          "dev": true,
+          "requires": {
+            "ip-regex": "^2.1.0",
+            "psl": "^1.1.28",
+            "punycode": "^2.1.1"
+          }
         }
       }
     },
-    "jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-      "optional": true
+    "jsesc": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+      "dev": true
     },
     "json-parse-better-errors": {
       "version": "1.0.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
-      "integrity": "sha1-u4Z8+zRQ5pEHwTHRxRS6s9yLyqk=",
+      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
       "dev": true
     },
     "json-schema": {
@@ -1434,6 +4858,23 @@
       "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
       "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
     },
+    "json5": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz",
+      "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
     "jsprim": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -1446,14 +4887,33 @@
       }
     },
     "jsx-ast-utils": {
-      "version": "2.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/jsx-ast-utils/-/jsx-ast-utils-2.1.0.tgz",
-      "integrity": "sha1-DuTiyXH7lgHGe1ZBtxvoD67PCzY=",
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz",
+      "integrity": "sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA==",
       "dev": true,
       "requires": {
-        "array-includes": "^3.0.3"
+        "array-includes": "^3.0.3",
+        "object.assign": "^4.1.0"
       }
     },
+    "kind-of": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+      "dev": true
+    },
+    "kleur": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+      "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+      "dev": true
+    },
+    "leven": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+      "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+      "dev": true
+    },
     "levn": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
@@ -1487,20 +4947,92 @@
       }
     },
     "lodash": {
-      "version": "4.17.11",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/lodash/-/lodash-4.17.11.tgz",
-      "integrity": "sha1-s56mIp72B+zYniyN8SU2iRysm40=",
+      "version": "4.17.15",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+      "dev": true
+    },
+    "lodash.sortby": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+      "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
       "dev": true
     },
+    "lolex": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz",
+      "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==",
+      "dev": true,
+      "requires": {
+        "@sinonjs/commons": "^1.7.0"
+      }
+    },
     "loose-envify": {
       "version": "1.4.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/loose-envify/-/loose-envify-1.4.0.tgz",
-      "integrity": "sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8=",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
       "dev": true,
       "requires": {
         "js-tokens": "^3.0.0 || ^4.0.0"
       }
     },
+    "make-dir": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz",
+      "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==",
+      "dev": true,
+      "requires": {
+        "semver": "^6.0.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
+    "makeerror": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz",
+      "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=",
+      "dev": true,
+      "requires": {
+        "tmpl": "1.0.x"
+      }
+    },
+    "map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true
+    },
+    "map-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "dev": true,
+      "requires": {
+        "object-visit": "^1.0.0"
+      }
+    },
+    "merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
+    },
+    "micromatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+      "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+      "dev": true,
+      "requires": {
+        "braces": "^3.0.1",
+        "picomatch": "^2.0.5"
+      }
+    },
     "mime-db": {
       "version": "1.35.0",
       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz",
@@ -1516,8 +5048,8 @@
     },
     "mimic-fn": {
       "version": "1.2.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/mimic-fn/-/mimic-fn-1.2.0.tgz",
-      "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
       "dev": true
     },
     "minimatch": {
@@ -1530,11 +5062,32 @@
       }
     },
     "minimist": {
-      "version": "0.0.10",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
-      "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+      "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
       "dev": true
     },
+    "mixin-deep": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+      "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+      "dev": true,
+      "requires": {
+        "for-in": "^1.0.2",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
     "mkdirp": {
       "version": "0.5.1",
       "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
@@ -1563,18 +5116,31 @@
       "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
       "dev": true
     },
+    "nanomatch": {
+      "version": "1.2.13",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "fragment-cache": "^0.2.1",
+        "is-windows": "^1.0.2",
+        "kind-of": "^6.0.2",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      }
+    },
     "natural-compare": {
       "version": "1.4.0",
       "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/natural-compare/-/natural-compare-1.4.0.tgz",
       "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
       "dev": true
     },
-    "neo-async": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz",
-      "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==",
-      "dev": true
-    },
     "nice-try": {
       "version": "1.0.5",
       "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/nice-try/-/nice-try-1.0.5.tgz",
@@ -1582,35 +5148,65 @@
       "dev": true
     },
     "nock": {
-      "version": "10.0.6",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/nock/-/nock-10.0.6.tgz",
-      "integrity": "sha1-5tkO56aLjPwqt/YSfn2Zqn0T0RE=",
+      "version": "11.7.2",
+      "resolved": "https://registry.npmjs.org/nock/-/nock-11.7.2.tgz",
+      "integrity": "sha512-7swr5bL1xBZ5FctyubjxEVySXOSebyqcL7Vy1bx1nS9IUqQWj81cmKjVKJLr8fHhtzI1MV8nyCdENA/cGcY1+Q==",
       "dev": true,
       "requires": {
-        "chai": "^4.1.2",
         "debug": "^4.1.0",
-        "deep-equal": "^1.0.0",
         "json-stringify-safe": "^5.0.1",
-        "lodash": "^4.17.5",
+        "lodash": "^4.17.13",
         "mkdirp": "^0.5.0",
-        "propagate": "^1.0.0",
-        "qs": "^6.5.1",
-        "semver": "^5.5.0"
+        "propagate": "^2.0.0"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        }
       }
     },
-    "nopt": {
-      "version": "3.0.6",
-      "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
-      "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+    "node-int64": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+      "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=",
+      "dev": true
+    },
+    "node-modules-regexp": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
+      "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=",
+      "dev": true
+    },
+    "node-notifier": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz",
+      "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==",
       "dev": true,
+      "optional": true,
       "requires": {
-        "abbrev": "1"
+        "growly": "^1.3.0",
+        "is-wsl": "^2.1.1",
+        "semver": "^6.3.0",
+        "shellwords": "^0.1.1",
+        "which": "^1.3.1"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true,
+          "optional": true
+        }
       }
     },
     "normalize-package-data": {
       "version": "2.5.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
-      "integrity": "sha1-5m2xg4sgDB38IzIl0SyzZSDiNKg=",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
       "dev": true,
       "requires": {
         "hosted-git-info": "^2.1.4",
@@ -1620,9 +5216,9 @@
       },
       "dependencies": {
         "resolve": {
-          "version": "1.10.1",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/resolve/-/resolve-1.10.1.tgz",
-          "integrity": "sha1-ZkhCrJYHlbvnWCIc3M2mH7ZLXxg=",
+          "version": "1.15.0",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz",
+          "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==",
           "dev": true,
           "requires": {
             "path-parse": "^1.0.6"
@@ -1630,6 +5226,27 @@
         }
       }
     },
+    "normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true
+    },
+    "npm-run-path": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+      "dev": true,
+      "requires": {
+        "path-key": "^2.0.0"
+      }
+    },
+    "nwsapi": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
+      "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
+      "dev": true
+    },
     "oauth-sign": {
       "version": "0.9.0",
       "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@@ -1641,17 +5258,183 @@
       "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
       "dev": true
     },
-    "object-inspect": {
-      "version": "1.6.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/object-inspect/-/object-inspect-1.6.0.tgz",
-      "integrity": "sha1-xwtsv3LydKq0w0wMgvUWe/gs8Vs=",
-      "dev": true
+    "object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "requires": {
+        "copy-descriptor": "^0.1.0",
+        "define-property": "^0.2.5",
+        "kind-of": "^3.0.3"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "object-inspect": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
+      "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
+      "dev": true
+    },
+    "object-keys": {
+      "version": "1.1.1",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/object-keys/-/object-keys-1.1.1.tgz",
+      "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4=",
+      "dev": true
+    },
+    "object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.0"
+      }
+    },
+    "object.assign": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+      "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.2",
+        "function-bind": "^1.1.1",
+        "has-symbols": "^1.0.0",
+        "object-keys": "^1.0.11"
+      }
+    },
+    "object.entries": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz",
+      "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3"
+      }
+    },
+    "object.fromentries": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz",
+      "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3"
+      }
+    },
+    "object.getownpropertydescriptors": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
+      "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1"
+      },
+      "dependencies": {
+        "es-abstract": {
+          "version": "1.17.4",
+          "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
+          "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
+          "dev": true,
+          "requires": {
+            "es-to-primitive": "^1.2.1",
+            "function-bind": "^1.1.1",
+            "has": "^1.0.3",
+            "has-symbols": "^1.0.1",
+            "is-callable": "^1.1.5",
+            "is-regex": "^1.0.5",
+            "object-inspect": "^1.7.0",
+            "object-keys": "^1.1.1",
+            "object.assign": "^4.1.0",
+            "string.prototype.trimleft": "^2.1.1",
+            "string.prototype.trimright": "^2.1.1"
+          }
+        },
+        "es-to-primitive": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+          "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+          "dev": true,
+          "requires": {
+            "is-callable": "^1.1.4",
+            "is-date-object": "^1.0.1",
+            "is-symbol": "^1.0.2"
+          }
+        },
+        "has-symbols": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+          "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+          "dev": true
+        },
+        "is-callable": {
+          "version": "1.1.5",
+          "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
+          "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
+          "dev": true
+        },
+        "is-regex": {
+          "version": "1.0.5",
+          "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
+          "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+          "dev": true,
+          "requires": {
+            "has": "^1.0.3"
+          }
+        },
+        "object-inspect": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
+          "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
+          "dev": true
+        }
+      }
+    },
+    "object.pick": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
     },
-    "object-keys": {
+    "object.values": {
       "version": "1.1.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/object-keys/-/object-keys-1.1.1.tgz",
-      "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4=",
-      "dev": true
+      "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz",
+      "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.0-next.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3"
+      }
     },
     "once": {
       "version": "1.4.0",
@@ -1671,24 +5454,6 @@
         "mimic-fn": "^1.0.0"
       }
     },
-    "optimist": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
-      "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
-      "dev": true,
-      "requires": {
-        "minimist": "~0.0.1",
-        "wordwrap": "~0.0.2"
-      },
-      "dependencies": {
-        "wordwrap": {
-          "version": "0.0.3",
-          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
-          "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
-          "dev": true
-        }
-      }
-    },
     "optionator": {
       "version": "0.8.2",
       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
@@ -1709,10 +5474,22 @@
       "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
       "dev": true
     },
+    "p-each-series": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz",
+      "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==",
+      "dev": true
+    },
+    "p-finally": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "dev": true
+    },
     "p-limit": {
       "version": "1.3.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/p-limit/-/p-limit-1.3.0.tgz",
-      "integrity": "sha1-uGvV8MJWkJEcdZD8v8IBDVSzzLg=",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+      "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
       "dev": true,
       "requires": {
         "p-try": "^1.0.0"
@@ -1733,6 +5510,15 @@
       "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
       "dev": true
     },
+    "parent-module": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+      "dev": true,
+      "requires": {
+        "callsites": "^3.0.0"
+      }
+    },
     "parse-json": {
       "version": "2.2.0",
       "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/parse-json/-/parse-json-2.2.0.tgz",
@@ -1742,6 +5528,18 @@
         "error-ex": "^1.2.0"
       }
     },
+    "parse5": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
+      "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
+      "dev": true
+    },
+    "pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true
+    },
     "path-exists": {
       "version": "3.0.0",
       "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/path-exists/-/path-exists-3.0.0.tgz",
@@ -1754,12 +5552,6 @@
       "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
       "dev": true
     },
-    "path-is-inside": {
-      "version": "1.0.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/path-is-inside/-/path-is-inside-1.0.2.tgz",
-      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
-      "dev": true
-    },
     "path-key": {
       "version": "2.0.1",
       "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/path-key/-/path-key-2.0.1.tgz",
@@ -1781,45 +5573,98 @@
         "pify": "^2.0.0"
       }
     },
-    "pathval": {
-      "version": "1.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/pathval/-/pathval-1.1.0.tgz",
-      "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
-      "dev": true
-    },
     "performance-now": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
       "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
     },
+    "picomatch": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz",
+      "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==",
+      "dev": true
+    },
     "pify": {
       "version": "2.3.0",
       "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/pify/-/pify-2.3.0.tgz",
       "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
       "dev": true
     },
+    "pirates": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz",
+      "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==",
+      "dev": true,
+      "requires": {
+        "node-modules-regexp": "^1.0.0"
+      }
+    },
     "pkg-conf": {
-      "version": "2.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/pkg-conf/-/pkg-conf-2.1.0.tgz",
-      "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz",
+      "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==",
       "dev": true,
       "requires": {
-        "find-up": "^2.0.0",
-        "load-json-file": "^4.0.0"
+        "find-up": "^3.0.0",
+        "load-json-file": "^5.2.0"
       },
       "dependencies": {
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
         "load-json-file": {
-          "version": "4.0.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/load-json-file/-/load-json-file-4.0.0.tgz",
-          "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz",
+          "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==",
           "dev": true,
           "requires": {
-            "graceful-fs": "^4.1.2",
+            "graceful-fs": "^4.1.15",
             "parse-json": "^4.0.0",
-            "pify": "^3.0.0",
-            "strip-bom": "^3.0.0"
+            "pify": "^4.0.1",
+            "strip-bom": "^3.0.0",
+            "type-fest": "^0.3.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.2.2",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
+          "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
           }
         },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
         "parse-json": {
           "version": "4.0.0",
           "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/parse-json/-/parse-json-4.0.0.tgz",
@@ -1831,9 +5676,15 @@
           }
         },
         "pify": {
-          "version": "3.0.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/pify/-/pify-3.0.0.tgz",
-          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+          "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+          "dev": true
+        },
+        "type-fest": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz",
+          "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==",
           "dev": true
         }
       }
@@ -1858,10 +5709,16 @@
         "find-up": "^2.1.0"
       }
     },
-    "pluralize": {
-      "version": "7.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/pluralize/-/pluralize-7.0.0.tgz",
-      "integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c=",
+    "pn": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
+      "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
+      "dev": true
+    },
+    "posix-character-classes": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
       "dev": true
     },
     "prelude-ls": {
@@ -1870,16 +5727,77 @@
       "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
       "dev": true
     },
+    "pretty-format": {
+      "version": "25.1.0",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz",
+      "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==",
+      "dev": true,
+      "requires": {
+        "@jest/types": "^25.1.0",
+        "ansi-regex": "^5.0.0",
+        "ansi-styles": "^4.0.0",
+        "react-is": "^16.12.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "react-is": {
+          "version": "16.12.0",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz",
+          "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==",
+          "dev": true
+        }
+      }
+    },
     "progress": {
       "version": "2.0.3",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/progress/-/progress-2.0.3.tgz",
-      "integrity": "sha1-foz42PW48jnBvGi+tOt4Vn1XLvg=",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
       "dev": true
     },
+    "prompts": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.0.tgz",
+      "integrity": "sha512-NfbbPPg/74fT7wk2XYQ7hAIp9zJyZp5Fu19iRbORqqy1BhtrkZ0fPafBU+7bmn8ie69DpT0R6QpJIN2oisYjJg==",
+      "dev": true,
+      "requires": {
+        "kleur": "^3.0.3",
+        "sisteransi": "^1.0.3"
+      }
+    },
     "prop-types": {
       "version": "15.7.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/prop-types/-/prop-types-15.7.2.tgz",
-      "integrity": "sha1-UsQedbjIfnK52TYOAga5ncv/psU=",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
+      "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
       "dev": true,
       "requires": {
         "loose-envify": "^1.4.0",
@@ -1888,9 +5806,9 @@
       }
     },
     "propagate": {
-      "version": "1.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/propagate/-/propagate-1.0.0.tgz",
-      "integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
+      "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
       "dev": true
     },
     "psl": {
@@ -1898,6 +5816,16 @@
       "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz",
       "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ=="
     },
+    "pump": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
     "punycode": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
@@ -1909,9 +5837,9 @@
       "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
     },
     "react-is": {
-      "version": "16.8.6",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/react-is/-/react-is-16.8.6.tgz",
-      "integrity": "sha1-W7weLSkUHJ+9/tRWND/ivEMKahY=",
+      "version": "16.12.0",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz",
+      "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==",
       "dev": true
     },
     "read-pkg": {
@@ -1935,10 +5863,47 @@
         "read-pkg": "^2.0.0"
       }
     },
+    "realpath-native": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz",
+      "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==",
+      "dev": true,
+      "requires": {
+        "util.promisify": "^1.0.0"
+      }
+    },
+    "regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
     "regexpp": {
       "version": "2.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/regexpp/-/regexpp-2.0.1.tgz",
-      "integrity": "sha1-jRnTHPYySCtYkEn4KB+T28uk0H8=",
+      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+      "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+      "dev": true
+    },
+    "remove-trailing-separator": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+      "dev": true
+    },
+    "repeat-element": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+      "dev": true
+    },
+    "repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
       "dev": true
     },
     "request": {
@@ -1968,26 +5933,79 @@
         "uuid": "^3.3.2"
       }
     },
-    "require-uncached": {
-      "version": "1.0.3",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/require-uncached/-/require-uncached-1.0.3.tgz",
-      "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
+    "request-promise-core": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
+      "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.15"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        }
+      }
+    },
+    "request-promise-native": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz",
+      "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==",
       "dev": true,
       "requires": {
-        "caller-path": "^0.1.0",
-        "resolve-from": "^1.0.0"
+        "request-promise-core": "1.1.3",
+        "stealthy-require": "^1.1.1",
+        "tough-cookie": "^2.3.3"
       }
     },
+    "require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "dev": true
+    },
+    "require-main-filename": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+      "dev": true
+    },
     "resolve": {
       "version": "1.1.7",
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
       "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
       "dev": true
     },
+    "resolve-cwd": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+      "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+      "dev": true,
+      "requires": {
+        "resolve-from": "^5.0.0"
+      },
+      "dependencies": {
+        "resolve-from": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+          "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+          "dev": true
+        }
+      }
+    },
     "resolve-from": {
-      "version": "1.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/resolve-from/-/resolve-from-1.0.1.tgz",
-      "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+      "dev": true
+    },
+    "resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
       "dev": true
     },
     "restore-cursor": {
@@ -2000,80 +6018,261 @@
         "signal-exit": "^3.0.2"
       }
     },
-    "resumer": {
-      "version": "0.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/resumer/-/resumer-0.0.0.tgz",
-      "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=",
-      "dev": true,
-      "requires": {
-        "through": "~2.3.4"
-      }
+    "ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true
     },
     "rimraf": {
       "version": "2.6.3",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/rimraf/-/rimraf-2.6.3.tgz",
-      "integrity": "sha1-stEE/g2Psnz54KHNqCYt04M8bKs=",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+      "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
       "dev": true,
       "requires": {
         "glob": "^7.1.3"
+      }
+    },
+    "rsvp": {
+      "version": "4.8.5",
+      "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
+      "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==",
+      "dev": true
+    },
+    "run-async": {
+      "version": "2.3.0",
+      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/run-async/-/run-async-2.3.0.tgz",
+      "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+      "dev": true,
+      "requires": {
+        "is-promise": "^2.1.0"
+      }
+    },
+    "run-parallel": {
+      "version": "1.1.9",
+      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
+      "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
+      "dev": true
+    },
+    "rxjs": {
+      "version": "6.5.4",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
+      "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+    },
+    "safe-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "requires": {
+        "ret": "~0.1.10"
+      }
+    },
+    "safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+    },
+    "sane": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz",
+      "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==",
+      "dev": true,
+      "requires": {
+        "@cnakazawa/watch": "^1.0.3",
+        "anymatch": "^2.0.0",
+        "capture-exit": "^2.0.0",
+        "exec-sh": "^0.3.2",
+        "execa": "^1.0.0",
+        "fb-watchman": "^2.0.0",
+        "micromatch": "^3.1.4",
+        "minimist": "^1.1.1",
+        "walker": "~1.0.5"
       },
       "dependencies": {
-        "glob": {
-          "version": "7.1.3",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/glob/-/glob-7.1.3.tgz",
-          "integrity": "sha1-OWCDLT8VdBCDQtr9OmezMsCWnfE=",
+        "anymatch": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+          "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+          "dev": true,
+          "requires": {
+            "micromatch": "^3.1.4",
+            "normalize-path": "^2.1.1"
+          }
+        },
+        "braces": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+          "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+          "dev": true,
+          "requires": {
+            "arr-flatten": "^1.1.0",
+            "array-unique": "^0.3.2",
+            "extend-shallow": "^2.0.1",
+            "fill-range": "^4.0.0",
+            "isobject": "^3.0.1",
+            "repeat-element": "^1.1.2",
+            "snapdragon": "^0.8.1",
+            "snapdragon-node": "^2.0.1",
+            "split-string": "^3.0.2",
+            "to-regex": "^3.0.1"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "^0.1.0"
+              }
+            }
+          }
+        },
+        "fill-range": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+          "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "^2.0.1",
+            "is-number": "^3.0.0",
+            "repeat-string": "^1.6.1",
+            "to-regex-range": "^2.1.0"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "^0.1.0"
+              }
+            }
+          }
+        },
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "micromatch": {
+          "version": "3.1.10",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+          "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+          "dev": true,
+          "requires": {
+            "arr-diff": "^4.0.0",
+            "array-unique": "^0.3.2",
+            "braces": "^2.3.1",
+            "define-property": "^2.0.2",
+            "extend-shallow": "^3.0.2",
+            "extglob": "^2.0.4",
+            "fragment-cache": "^0.2.1",
+            "kind-of": "^6.0.2",
+            "nanomatch": "^1.2.9",
+            "object.pick": "^1.3.0",
+            "regex-not": "^1.0.0",
+            "snapdragon": "^0.8.1",
+            "to-regex": "^3.0.2"
+          }
+        },
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        },
+        "normalize-path": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+          "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+          "dev": true,
+          "requires": {
+            "remove-trailing-separator": "^1.0.1"
+          }
+        },
+        "to-regex-range": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+          "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
           "dev": true,
           "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^3.0.4",
-            "once": "^1.3.0",
-            "path-is-absolute": "^1.0.0"
+            "is-number": "^3.0.0",
+            "repeat-string": "^1.6.1"
           }
         }
       }
     },
-    "run-async": {
-      "version": "2.3.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/run-async/-/run-async-2.3.0.tgz",
-      "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
-      "dev": true,
-      "requires": {
-        "is-promise": "^2.1.0"
-      }
-    },
-    "run-parallel": {
-      "version": "1.1.9",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/run-parallel/-/run-parallel-1.1.9.tgz",
-      "integrity": "sha1-yd06fPn0ssS2JE4XOm7YZuYd1nk=",
-      "dev": true
-    },
-    "rxjs": {
-      "version": "5.5.12",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/rxjs/-/rxjs-5.5.12.tgz",
-      "integrity": "sha1-b6YbinfD15PbrycL7i9D9lLXQcw=",
+    "saxes": {
+      "version": "3.1.11",
+      "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz",
+      "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==",
       "dev": true,
       "requires": {
-        "symbol-observable": "1.0.1"
+        "xmlchars": "^2.1.1"
       }
     },
-    "safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
-    },
-    "safer-buffer": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
-    },
     "semver": {
       "version": "5.7.0",
       "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/semver/-/semver-5.7.0.tgz",
       "integrity": "sha1-eQp89v6lRZuslhELKbYEEtyP+Ws=",
       "dev": true
     },
+    "set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "dev": true
+    },
+    "set-value": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+      "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-extendable": "^0.1.1",
+        "is-plain-object": "^2.0.3",
+        "split-string": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
     "shebang-command": {
       "version": "1.2.0",
       "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -2089,35 +6288,211 @@
       "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
       "dev": true
     },
+    "shellwords": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
+      "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
+      "dev": true,
+      "optional": true
+    },
     "signal-exit": {
       "version": "3.0.2",
       "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/signal-exit/-/signal-exit-3.0.2.tgz",
       "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
       "dev": true
     },
+    "sisteransi": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.4.tgz",
+      "integrity": "sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig==",
+      "dev": true
+    },
+    "slash": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+      "dev": true
+    },
     "slice-ansi": {
-      "version": "1.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/slice-ansi/-/slice-ansi-1.0.0.tgz",
-      "integrity": "sha1-BE8aSdiEL/MHqta1Be0Xi9lQE00=",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+      "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
       "dev": true,
       "requires": {
+        "ansi-styles": "^3.2.0",
+        "astral-regex": "^1.0.0",
         "is-fullwidth-code-point": "^2.0.0"
       }
     },
-    "source-map": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
-      "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
+    "snapdragon": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+      "dev": true,
+      "requires": {
+        "base": "^0.11.1",
+        "debug": "^2.2.0",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "map-cache": "^0.2.2",
+        "source-map": "^0.5.6",
+        "source-map-resolve": "^0.5.0",
+        "use": "^3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
+    },
+    "snapdragon-node": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.0",
+        "snapdragon-util": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.2.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "source-map-resolve": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+      "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+      "dev": true,
+      "requires": {
+        "atob": "^2.1.2",
+        "decode-uri-component": "^0.2.0",
+        "resolve-url": "^0.2.1",
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
+      }
+    },
+    "source-map-support": {
+      "version": "0.5.16",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz",
+      "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==",
       "dev": true,
-      "optional": true,
       "requires": {
-        "amdefine": ">=0.0.4"
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
       }
     },
+    "source-map-url": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "dev": true
+    },
     "spdx-correct": {
       "version": "3.1.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/spdx-correct/-/spdx-correct-3.1.0.tgz",
-      "integrity": "sha1-+4PlBERSaPFUsHTiGMh8ADzTHfQ=",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
+      "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
       "dev": true,
       "requires": {
         "spdx-expression-parse": "^3.0.0",
@@ -2126,14 +6501,14 @@
     },
     "spdx-exceptions": {
       "version": "2.2.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
-      "integrity": "sha1-LqRQrudPKom/uUUZwH/Nb0EyKXc=",
+      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
+      "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
       "dev": true
     },
     "spdx-expression-parse": {
       "version": "3.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
-      "integrity": "sha1-meEZt6XaAOBUkcn6M4t5BII7QdA=",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+      "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
       "dev": true,
       "requires": {
         "spdx-exceptions": "^2.1.0",
@@ -2141,11 +6516,20 @@
       }
     },
     "spdx-license-ids": {
-      "version": "3.0.4",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz",
-      "integrity": "sha1-dezRqI3owYTvAV6vtRtbSL/RG7E=",
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
+      "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
       "dev": true
     },
+    "split-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.0"
+      }
+    },
     "sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -2168,77 +6552,149 @@
         "tweetnacl": "~0.14.0"
       }
     },
+    "stack-utils": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz",
+      "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==",
+      "dev": true
+    },
     "standard": {
-      "version": "12.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/standard/-/standard-12.0.1.tgz",
-      "integrity": "sha1-D8Woqmw0xUbFViquZEJCsk2uLmE=",
-      "dev": true,
-      "requires": {
-        "eslint": "~5.4.0",
-        "eslint-config-standard": "12.0.0",
-        "eslint-config-standard-jsx": "6.0.2",
-        "eslint-plugin-import": "~2.14.0",
-        "eslint-plugin-node": "~7.0.1",
-        "eslint-plugin-promise": "~4.0.0",
-        "eslint-plugin-react": "~7.11.1",
+      "version": "14.3.1",
+      "resolved": "https://registry.npmjs.org/standard/-/standard-14.3.1.tgz",
+      "integrity": "sha512-TUQwU7znlZLfgKH1Zwn/D84FitWZkUTfbxSiz/vFx+4c9GV+clSfG/qLiLZOlcdyzhw3oF5/pZydNjbNDfHPEw==",
+      "dev": true,
+      "requires": {
+        "eslint": "~6.4.0",
+        "eslint-config-standard": "14.1.0",
+        "eslint-config-standard-jsx": "8.1.0",
+        "eslint-plugin-import": "~2.18.0",
+        "eslint-plugin-node": "~10.0.0",
+        "eslint-plugin-promise": "~4.2.1",
+        "eslint-plugin-react": "~7.14.2",
         "eslint-plugin-standard": "~4.0.0",
-        "standard-engine": "~9.0.0"
+        "standard-engine": "^12.0.0"
       }
     },
     "standard-engine": {
-      "version": "9.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/standard-engine/-/standard-engine-9.0.0.tgz",
-      "integrity": "sha1-06PXTEwbkfUaHmY2JGUmHKdhAxY=",
+      "version": "12.0.0",
+      "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-12.0.0.tgz",
+      "integrity": "sha512-gJIIRb0LpL7AHyGbN9+hJ4UJns37lxmNTnMGRLC8CFrzQ+oB/K60IQjKNgPBCB2VP60Ypm6f8DFXvhVWdBOO+g==",
       "dev": true,
       "requires": {
-        "deglob": "^2.1.0",
-        "get-stdin": "^6.0.0",
+        "deglob": "^4.0.0",
+        "get-stdin": "^7.0.0",
         "minimist": "^1.1.0",
-        "pkg-conf": "^2.0.0"
+        "pkg-conf": "^3.1.0"
+      }
+    },
+    "static-extend": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "dev": true,
+      "requires": {
+        "define-property": "^0.2.5",
+        "object-copy": "^0.1.0"
       },
       "dependencies": {
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "stealthy-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+      "dev": true
+    },
+    "string-length": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz",
+      "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==",
+      "dev": true,
+      "requires": {
+        "astral-regex": "^1.0.0",
+        "strip-ansi": "^5.2.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
           "dev": true
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
         }
       }
     },
     "string-width": {
       "version": "2.1.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/string-width/-/string-width-2.1.1.tgz",
-      "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
       "dev": true,
       "requires": {
         "is-fullwidth-code-point": "^2.0.0",
         "strip-ansi": "^4.0.0"
+      },
+      "dependencies": {
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^3.0.0"
+          }
+        }
       }
     },
-    "string.prototype.trim": {
-      "version": "1.1.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz",
-      "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=",
+    "string.prototype.trimleft": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
+      "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
       "dev": true,
       "requires": {
-        "define-properties": "^1.1.2",
-        "es-abstract": "^1.5.0",
-        "function-bind": "^1.0.2"
+        "define-properties": "^1.1.3",
+        "function-bind": "^1.1.1"
+      }
+    },
+    "string.prototype.trimright": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
+      "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "function-bind": "^1.1.1"
       }
     },
     "strip-ansi": {
-      "version": "4.0.0",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/strip-ansi/-/strip-ansi-4.0.0.tgz",
-      "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
       "dev": true,
       "requires": {
-        "ansi-regex": "^3.0.0"
+        "ansi-regex": "^4.1.0"
       },
       "dependencies": {
         "ansi-regex": {
-          "version": "3.0.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ansi-regex/-/ansi-regex-3.0.0.tgz",
-          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
           "dev": true
         }
       }
@@ -2249,115 +6705,162 @@
       "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
       "dev": true
     },
+    "strip-eof": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+      "dev": true
+    },
+    "strip-final-newline": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+      "dev": true
+    },
     "strip-json-comments": {
-      "version": "2.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
-      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
+      "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
       "dev": true
     },
-    "supports-color": {
-      "version": "3.2.3",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-      "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+    "supports-hyperlinks": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.0.0.tgz",
+      "integrity": "sha512-bFhn0MQ8qefLyJ3K7PpHiPUTuTVPWw6RXfaMeV6xgJLXtBbszyboz1bvGTVv4R0YpQm2DqlXXn0fFHhxUHVE5w==",
       "dev": true,
       "requires": {
-        "has-flag": "^1.0.0"
+        "has-flag": "^4.0.0",
+        "supports-color": "^7.0.0"
+      },
+      "dependencies": {
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
       }
     },
-    "symbol-observable": {
-      "version": "1.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/symbol-observable/-/symbol-observable-1.0.1.tgz",
-      "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=",
+    "symbol-tree": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+      "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
       "dev": true
     },
     "table": {
-      "version": "4.0.3",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/table/-/table-4.0.3.tgz",
-      "integrity": "sha1-ALXitgLxeUuayvnKkIp2OGp4E7w=",
+      "version": "5.4.6",
+      "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
+      "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
       "dev": true,
       "requires": {
-        "ajv": "^6.0.1",
-        "ajv-keywords": "^3.0.0",
-        "chalk": "^2.1.0",
-        "lodash": "^4.17.4",
-        "slice-ansi": "1.0.0",
-        "string-width": "^2.1.1"
+        "ajv": "^6.10.2",
+        "lodash": "^4.17.14",
+        "slice-ansi": "^2.1.0",
+        "string-width": "^3.0.0"
       },
       "dependencies": {
         "ajv": {
-          "version": "6.10.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/ajv/-/ajv-6.10.0.tgz",
-          "integrity": "sha1-kNDVRDnaWHzX6EO/twRfUL0ivfE=",
+          "version": "6.11.0",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz",
+          "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==",
           "dev": true,
           "requires": {
-            "fast-deep-equal": "^2.0.1",
+            "fast-deep-equal": "^3.1.1",
             "fast-json-stable-stringify": "^2.0.0",
             "json-schema-traverse": "^0.4.1",
             "uri-js": "^4.2.2"
           }
         },
+        "emoji-regex": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+          "dev": true
+        },
         "fast-deep-equal": {
-          "version": "2.0.1",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
-          "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
+          "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
           "dev": true
         },
         "json-schema-traverse": {
           "version": "0.4.1",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-          "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+          "dev": true
+        },
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
           "dev": true
+        },
+        "string-width": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^7.0.1",
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^5.1.0"
+          }
         }
       }
     },
-    "tape": {
-      "version": "4.10.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/tape/-/tape-4.10.1.tgz",
-      "integrity": "sha1-9zvmCIjcsSDwi1f5R69lqClQal8=",
+    "terminal-link": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
+      "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
       "dev": true,
       "requires": {
-        "deep-equal": "~1.0.1",
-        "defined": "~1.0.0",
-        "for-each": "~0.3.3",
-        "function-bind": "~1.1.1",
-        "glob": "~7.1.3",
-        "has": "~1.0.3",
-        "inherits": "~2.0.3",
-        "minimist": "~1.2.0",
-        "object-inspect": "~1.6.0",
-        "resolve": "~1.10.0",
-        "resumer": "~0.0.0",
-        "string.prototype.trim": "~1.1.2",
-        "through": "~2.3.8"
+        "ansi-escapes": "^4.2.1",
+        "supports-hyperlinks": "^2.0.0"
       },
       "dependencies": {
-        "glob": {
-          "version": "7.1.3",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/glob/-/glob-7.1.3.tgz",
-          "integrity": "sha1-OWCDLT8VdBCDQtr9OmezMsCWnfE=",
+        "ansi-escapes": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz",
+          "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==",
           "dev": true,
           "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^3.0.4",
-            "once": "^1.3.0",
-            "path-is-absolute": "^1.0.0"
+            "type-fest": "^0.8.1"
           }
-        },
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
-          "dev": true
-        },
-        "resolve": {
-          "version": "1.10.1",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/resolve/-/resolve-1.10.1.tgz",
-          "integrity": "sha1-ZkhCrJYHlbvnWCIc3M2mH7ZLXxg=",
+        }
+      }
+    },
+    "test-exclude": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+      "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+      "dev": true,
+      "requires": {
+        "@istanbuljs/schema": "^0.1.2",
+        "glob": "^7.1.4",
+        "minimatch": "^3.0.4"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+          "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
           "dev": true,
           "requires": {
-            "path-parse": "^1.0.6"
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
           }
         }
       }
@@ -2368,6 +6871,12 @@
       "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
       "dev": true
     },
+    "throat": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz",
+      "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==",
+      "dev": true
+    },
     "through": {
       "version": "2.3.8",
       "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/through/-/through-2.3.8.tgz",
@@ -2376,13 +6885,66 @@
     },
     "tmp": {
       "version": "0.0.33",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/tmp/-/tmp-0.0.33.tgz",
-      "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
       "dev": true,
       "requires": {
         "os-tmpdir": "~1.0.2"
       }
     },
+    "tmpl": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
+      "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=",
+      "dev": true
+    },
+    "to-fast-properties": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+      "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+      "dev": true
+    },
+    "to-object-path": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "regex-not": "^1.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
+    "to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "dev": true,
+      "requires": {
+        "is-number": "^7.0.0"
+      }
+    },
     "tough-cookie": {
       "version": "2.4.3",
       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
@@ -2392,6 +6954,29 @@
         "punycode": "^1.4.1"
       }
     },
+    "tr46": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+      "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
+      "dev": true,
+      "requires": {
+        "punycode": "^2.1.0"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+          "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+          "dev": true
+        }
+      }
+    },
+    "tslib": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
+      "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
+      "dev": true
+    },
     "tunnel-agent": {
       "version": "0.6.0",
       "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -2421,24 +7006,31 @@
       "integrity": "sha1-dkb7XxiHHPu3dJ5pvTmmOI63RQw=",
       "dev": true
     },
-    "uglify-js": {
-      "version": "3.4.10",
-      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
-      "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==",
+    "type-fest": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+      "dev": true
+    },
+    "typedarray-to-buffer": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+      "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
       "dev": true,
-      "optional": true,
       "requires": {
-        "commander": "~2.19.0",
-        "source-map": "~0.6.1"
-      },
-      "dependencies": {
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-          "dev": true,
-          "optional": true
-        }
+        "is-typedarray": "^1.0.0"
+      }
+    },
+    "union-value": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+      "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "get-value": "^2.0.6",
+        "is-extendable": "^0.1.1",
+        "set-value": "^2.0.1"
       }
     },
     "uniq": {
@@ -2447,10 +7039,50 @@
       "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
       "dev": true
     },
+    "unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "requires": {
+        "has-value": "^0.3.1",
+        "isobject": "^3.0.0"
+      },
+      "dependencies": {
+        "has-value": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+          "dev": true,
+          "requires": {
+            "get-value": "^2.0.3",
+            "has-values": "^0.1.4",
+            "isobject": "^2.0.0"
+          },
+          "dependencies": {
+            "isobject": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+              "dev": true,
+              "requires": {
+                "isarray": "1.0.0"
+              }
+            }
+          }
+        },
+        "has-values": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+          "dev": true
+        }
+      }
+    },
     "uri-js": {
       "version": "4.2.2",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/uri-js/-/uri-js-4.2.2.tgz",
-      "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+      "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
       "dev": true,
       "requires": {
         "punycode": "^2.1.0"
@@ -2458,8 +7090,91 @@
       "dependencies": {
         "punycode": {
           "version": "2.1.1",
-          "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/punycode/-/punycode-2.1.1.tgz",
-          "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+          "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+          "dev": true
+        }
+      }
+    },
+    "urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "use": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+      "dev": true
+    },
+    "util.promisify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz",
+      "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.17.2",
+        "has-symbols": "^1.0.1",
+        "object.getownpropertydescriptors": "^2.1.0"
+      },
+      "dependencies": {
+        "es-abstract": {
+          "version": "1.17.4",
+          "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
+          "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
+          "dev": true,
+          "requires": {
+            "es-to-primitive": "^1.2.1",
+            "function-bind": "^1.1.1",
+            "has": "^1.0.3",
+            "has-symbols": "^1.0.1",
+            "is-callable": "^1.1.5",
+            "is-regex": "^1.0.5",
+            "object-inspect": "^1.7.0",
+            "object-keys": "^1.1.1",
+            "object.assign": "^4.1.0",
+            "string.prototype.trimleft": "^2.1.1",
+            "string.prototype.trimright": "^2.1.1"
+          }
+        },
+        "es-to-primitive": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+          "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+          "dev": true,
+          "requires": {
+            "is-callable": "^1.1.4",
+            "is-date-object": "^1.0.1",
+            "is-symbol": "^1.0.2"
+          }
+        },
+        "has-symbols": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+          "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+          "dev": true
+        },
+        "is-callable": {
+          "version": "1.1.5",
+          "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
+          "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
+          "dev": true
+        },
+        "is-regex": {
+          "version": "1.0.5",
+          "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
+          "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+          "dev": true,
+          "requires": {
+            "has": "^1.0.3"
+          }
+        },
+        "object-inspect": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
+          "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
           "dev": true
         }
       }
@@ -2469,10 +7184,35 @@
       "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
       "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
     },
+    "v8-compile-cache": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
+      "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
+      "dev": true
+    },
+    "v8-to-istanbul": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.0.1.tgz",
+      "integrity": "sha512-x0yZvZAkjJwdD3fPiJzYP37aod0ati4LlmD2RmpKjqewjKAov/u/ytZ8ViIZb07cN4cePKzl9ijiUi7C1LQ8hQ==",
+      "dev": true,
+      "requires": {
+        "@types/istanbul-lib-coverage": "^2.0.1",
+        "convert-source-map": "^1.6.0",
+        "source-map": "^0.7.3"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.7.3",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+          "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+          "dev": true
+        }
+      }
+    },
     "validate-npm-package-license": {
       "version": "3.0.4",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
-      "integrity": "sha1-/JH2uce6FchX9MssXe/uw51PQQo=",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
       "dev": true,
       "requires": {
         "spdx-correct": "^3.0.0",
@@ -2489,6 +7229,67 @@
         "extsprintf": "^1.2.0"
       }
     },
+    "w3c-hr-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
+      "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
+      "dev": true,
+      "requires": {
+        "browser-process-hrtime": "^0.1.2"
+      }
+    },
+    "w3c-xmlserializer": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz",
+      "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==",
+      "dev": true,
+      "requires": {
+        "domexception": "^1.0.1",
+        "webidl-conversions": "^4.0.2",
+        "xml-name-validator": "^3.0.0"
+      }
+    },
+    "walker": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
+      "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=",
+      "dev": true,
+      "requires": {
+        "makeerror": "1.0.x"
+      }
+    },
+    "webidl-conversions": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+      "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+      "dev": true
+    },
+    "whatwg-encoding": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
+      "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
+      "dev": true,
+      "requires": {
+        "iconv-lite": "0.4.24"
+      }
+    },
+    "whatwg-mimetype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
+      "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
+      "dev": true
+    },
+    "whatwg-url": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+      "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+      "dev": true,
+      "requires": {
+        "lodash.sortby": "^4.7.0",
+        "tr46": "^1.0.1",
+        "webidl-conversions": "^4.0.2"
+      }
+    },
     "which": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -2498,12 +7299,88 @@
         "isexe": "^2.0.0"
       }
     },
+    "which-module": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+      "dev": true
+    },
     "wordwrap": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
       "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
       "dev": true
     },
+    "wrap-ansi": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+          "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.0"
+          }
+        }
+      }
+    },
     "wrappy": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@@ -2511,19 +7388,167 @@
       "dev": true
     },
     "write": {
-      "version": "0.2.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/write/-/write-0.2.1.tgz",
-      "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+      "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
       "dev": true,
       "requires": {
         "mkdirp": "^0.5.1"
       }
     },
+    "write-file-atomic": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz",
+      "integrity": "sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw==",
+      "dev": true,
+      "requires": {
+        "imurmurhash": "^0.1.4",
+        "is-typedarray": "^1.0.0",
+        "signal-exit": "^3.0.2",
+        "typedarray-to-buffer": "^3.1.5"
+      }
+    },
+    "ws": {
+      "version": "7.2.1",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz",
+      "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A==",
+      "dev": true
+    },
+    "xml-name-validator": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+      "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+      "dev": true
+    },
+    "xmlchars": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+      "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+      "dev": true
+    },
     "xtend": {
-      "version": "4.0.1",
-      "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-wdp-npm-virtual/xtend/-/xtend-4.0.1.tgz",
-      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true
+    },
+    "y18n": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+      "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
       "dev": true
+    },
+    "yargs": {
+      "version": "15.1.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz",
+      "integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==",
+      "dev": true,
+      "requires": {
+        "cliui": "^6.0.0",
+        "decamelize": "^1.2.0",
+        "find-up": "^4.1.0",
+        "get-caller-file": "^2.0.1",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^4.2.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^16.1.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.2.2",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
+          "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+          "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.0"
+          }
+        }
+      }
+    },
+    "yargs-parser": {
+      "version": "16.1.0",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz",
+      "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==",
+      "dev": true,
+      "requires": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      }
     }
   }
 }
diff --git a/package.json b/package.json
index ba02fd9..7cf621d 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
   "license": "Apache-2.0",
   "homepage": "http://github.com/apache/couchdb-nano",
   "repository": "http://github.com/apache/couchdb-nano",
-  "version": "8.1.0",
+  "version": "8.2.0",
   "author": "Apache CouchDB <de...@couchdb.apache.org> (http://couchdb.apache.org)",
   "keywords": [
     "couchdb",
@@ -17,36 +17,36 @@
     "database"
   ],
   "dependencies": {
-    "@types/request": "^2.47.1",
-    "cloudant-follow": "^0.18.1",
+    "@types/request": "^2.48.4",
+    "cloudant-follow": "^0.18.2",
     "debug": "^4.1.1",
     "errs": "^0.3.2",
     "request": "^2.88.0"
   },
   "devDependencies": {
     "async": "^2.6.2",
-    "istanbul": "^0.4.5",
-    "nock": "^10.0.6",
-    "standard": "^12.0.1",
-    "tape": "^4.10.1"
+    "jest": "^25.1.0",
+    "nock": "^11.7.2",
+    "standard": "^14.3.1"
   },
   "scripts": {
     "standard": "standard --fix",
-    "test": "standard && npm run mocha",
-    "mocha": "NOCK_OFF=true istanbul cover tape tests/*/*/*.js",
-    "unmocked": "NOCK_OFF=true tape tests/*/*/*.js",
-    "mocked": "tape tests/*/*/*.js",
-    "coverage": "open coverage/lcov-report/index.html",
-    "checkcoverage": "istanbul check-coverage --statements 100 --functions 100 --lines 100 --branches 100"
+    "test": "standard && npm run jest",
+    "jest": "jest test/* --coverage"
   },
   "main": "./lib/nano.js",
   "types": "./lib/nano.d.ts",
   "engines": {
-    "node": ">=6"
+    "node": ">=10"
   },
   "pre-commit": [
     "mocked",
     "test",
     "checkcoverage"
-  ]
+  ],
+  "standard": {
+    "env": [
+      "jest"
+    ]
+  }
 }


[couchdb-nano] 10/15: tidy up

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit e033ba07f6716541fa3f71666c7e188fae016557
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Fri Feb 7 16:39:39 2020 +0000

    tidy up
---
 lib/nano.js                               | 119 ++++++++++++++++++++----------
 test/database.changes.test.js             |  18 +++--
 test/database.compact.test.js             |  18 +++--
 test/database.create.test.js              |  18 +++--
 test/database.destroy.test.js             |  18 +++--
 test/database.get.test.js                 |  18 +++--
 test/database.replicate.test.js           |  31 +++-----
 test/database.replication.disable.test.js |  31 +++-----
 test/database.replication.enable.test.js  |  32 +++-----
 test/database.replication.query.test.js   |  18 +++--
 test/design.atomic.test.js                |   8 +-
 test/design.createIndex.test.js           |   4 +-
 test/design.find.test.js                  |   4 +-
 test/design.search.test.js                |   8 +-
 test/design.show.test.js                  |   8 +-
 test/design.view.test.js                  |   8 +-
 test/document.copy.test.js                |  22 +++++-
 test/document.destroy.test.js             |  14 +++-
 test/document.fetch.test.js               |  22 ++++--
 test/document.fetchRevs.test.js           |  28 ++++---
 test/document.get.test.js                 |  12 ++-
 test/document.head.test.js                |  14 +++-
 22 files changed, 283 insertions(+), 190 deletions(-)

diff --git a/lib/nano.js b/lib/nano.js
index d396acf..eb07b2d 100644
--- a/lib/nano.js
+++ b/lib/nano.js
@@ -17,6 +17,7 @@ const request = require('request')
 const errs = require('errs')
 const follow = require('cloudant-follow')
 const logger = require('./logger')
+const INVALID_PARAMETERS_ERROR = new Error('Invalid parameters')
 
 function isEmpty (val) {
   return val == null || !(Object.keys(val) || val).length
@@ -330,17 +331,27 @@ module.exports = exports = function dbScope (cfg) {
 
   // http://docs.couchdb.org/en/latest/api/database/common.html#put--db
   function createDb (dbName, qs0, callback0) {
+    const { opts, callback } = getCallback(qs0, callback0)
     if (!dbName) {
-      throw new Error('missing dbName')
+      const e = INVALID_PARAMETERS_ERROR
+      if (callback) {
+        return callback(e, null)
+      } else {
+        return Promise.reject(e)
+      }
     }
-    const { opts, callback } = getCallback(qs0, callback0)
     return relax({ db: dbName, method: 'PUT', qs: opts }, callback)
   }
 
   // http://docs.couchdb.org/en/latest/api/database/common.html#delete--db
   function destroyDb (dbName, callback) {
     if (!dbName) {
-      throw new Error('missing dbName')
+      const e = INVALID_PARAMETERS_ERROR
+      if (callback) {
+        return callback(e, null)
+      } else {
+        return Promise.reject(e)
+      }
     }
     return relax({ db: dbName, method: 'DELETE' }, callback)
   }
@@ -348,7 +359,12 @@ module.exports = exports = function dbScope (cfg) {
   // http://docs.couchdb.org/en/latest/api/database/common.html#get--db
   function getDb (dbName, callback) {
     if (!dbName) {
-      throw new Error('missing dbName')
+      const e = INVALID_PARAMETERS_ERROR
+      if (callback) {
+        return callback(e, null)
+      } else {
+        return Promise.reject(e)
+      }
     }
     return relax({ db: dbName }, callback)
   }
@@ -365,13 +381,18 @@ module.exports = exports = function dbScope (cfg) {
 
   // http://docs.couchdb.org/en/latest/api/database/compact.html#post--db-_compact
   function compactDb (dbName, ddoc, callback) {
-    if (!dbName) {
-      throw new Error('missing dbName')
-    }
     if (typeof ddoc === 'function') {
       callback = ddoc
       ddoc = null
     }
+    if (!dbName) {
+      const e = INVALID_PARAMETERS_ERROR
+      if (callback) {
+        return callback(e, null)
+      } else {
+        return Promise.reject(e)
+      }
+    }
     return relax({
       db: dbName,
       doc: '_compact',
@@ -384,7 +405,12 @@ module.exports = exports = function dbScope (cfg) {
   function changesDb (dbName, qs0, callback0) {
     const { opts, callback } = getCallback(qs0, callback0)
     if (!dbName) {
-      throw new Error('missing dbName')
+      const e = INVALID_PARAMETERS_ERROR
+      if (callback) {
+        return callback(e, null)
+      } else {
+        return Promise.reject(e)
+      }
     }
     return relax({ db: dbName, path: '_changes', qs: opts }, callback)
   }
@@ -422,11 +448,14 @@ module.exports = exports = function dbScope (cfg) {
   // http://docs.couchdb.org/en/latest/api/server/common.html#post--_replicate
   function replicateDb (source, target, opts0, callback0) {
     const { opts, callback } = getCallback(opts0, callback0)
-    if (!source) {
-      throw new Error('missing source')
-    }
-    if (!target) {
-      throw new Error('missing target')
+
+    if (!source || !target) {
+      const e = INVALID_PARAMETERS_ERROR
+      if (callback) {
+        return callback(e, null)
+      } else {
+        return Promise.reject(e)
+      }
     }
 
     // _replicate
@@ -448,11 +477,14 @@ module.exports = exports = function dbScope (cfg) {
   // http://guide.couchdb.org/draft/replication.html
   function enableReplication (source, target, opts0, callback0) {
     const { opts, callback } = getCallback(opts0, callback0)
-    if (!source) {
-      throw new Error('missing source')
-    }
-    if (!target) {
-      throw new Error('missing target')
+
+    if (!source || !target) {
+      const e = INVALID_PARAMETERS_ERROR
+      if (callback) {
+        return callback(e, null)
+      } else {
+        return Promise.reject(e)
+      }
     }
 
     // _replicator
@@ -466,7 +498,12 @@ module.exports = exports = function dbScope (cfg) {
   function queryReplication (id, opts0, callback0) {
     const { opts, callback } = getCallback(opts0, callback0)
     if (!id) {
-      throw new Error('missing id')
+      const e = INVALID_PARAMETERS_ERROR
+      if (callback) {
+        return callback(e, null)
+      } else {
+        return Promise.reject(e)
+      }
     }
     return relax({ db: '_replicator', method: 'GET', path: id, qs: opts }, callback)
   }
@@ -474,11 +511,13 @@ module.exports = exports = function dbScope (cfg) {
   // http://guide.couchdb.org/draft/replication.html
   function disableReplication (id, rev, opts0, callback0) {
     const { opts, callback } = getCallback(opts0, callback0)
-    if (!id) {
-      throw new Error('missing id')
-    }
-    if (!rev) {
-      throw new Error('missing rev')
+    if (!id || !rev) {
+      const e = INVALID_PARAMETERS_ERROR
+      if (callback) {
+        return callback(e, null)
+      } else {
+        return Promise.reject(e)
+      }
     }
     const req = {
       db: '_replicator',
@@ -519,7 +558,7 @@ module.exports = exports = function dbScope (cfg) {
     // http://docs.couchdb.org/en/latest/api/document/common.html#delete--db-docid
     function destroyDoc (docName, rev, callback) {
       if (!docName) {
-        const e = new Error('Invalid doc id')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -540,7 +579,7 @@ module.exports = exports = function dbScope (cfg) {
       const { opts, callback } = getCallback(qs0, callback0)
 
       if (!docName) {
-        const e = new Error('Invalid doc id')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -554,7 +593,7 @@ module.exports = exports = function dbScope (cfg) {
     // http://docs.couchdb.org/en/latest/api/document/common.html#head--db-docid
     function headDoc (docName, callback) {
       if (!docName) {
-        const e = new Error('Invalid doc id')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -593,7 +632,7 @@ module.exports = exports = function dbScope (cfg) {
       const { opts, callback } = getCallback(opts0, callback0)
 
       if (!docSrc || !docDest) {
-        const e = new Error('Invalid doc id')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -656,7 +695,7 @@ module.exports = exports = function dbScope (cfg) {
       if (!docNames || typeof docNames !== 'object' ||
           !docNames.keys || !Array.isArray(docNames.keys) ||
           docNames.keys.length === 0) {
-        const e = new Error('Invalid keys')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -679,7 +718,7 @@ module.exports = exports = function dbScope (cfg) {
       if (!docNames || typeof docNames !== 'object' ||
           !docNames.keys || !Array.isArray(docNames.keys) ||
           docNames.keys.length === 0) {
-        const e = new Error('Invalid keys')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -699,7 +738,7 @@ module.exports = exports = function dbScope (cfg) {
       const { opts, callback } = getCallback(qs0, callback0)
 
       if (!ddoc || !viewName) {
-        const e = new Error('Invalid view')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -786,7 +825,7 @@ module.exports = exports = function dbScope (cfg) {
     // http://docs.couchdb.org/en/latest/api/ddoc/render.html#get--db-_design-ddoc-_show-func
     function showDoc (ddoc, viewName, docName, qs, callback) {
       if (!ddoc || !viewName || !docName) {
-        const e = new Error('Invalid show')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -803,7 +842,7 @@ module.exports = exports = function dbScope (cfg) {
         body = undefined
       }
       if (!ddoc || !viewName || !docName) {
-        const e = new Error('Invalid update')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -846,7 +885,7 @@ module.exports = exports = function dbScope (cfg) {
       delete qs.docName
 
       if (!doc || !attachments || !docName) {
-        const e = new Error('Invalid parameters')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -889,7 +928,7 @@ module.exports = exports = function dbScope (cfg) {
       opts.attachments = true
 
       if (!docName) {
-        const e = new Error('Invalid parameters')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -909,7 +948,7 @@ module.exports = exports = function dbScope (cfg) {
     function insertAtt (docName, attName, att, contentType, qs0, callback0) {
       const { opts, callback } = getCallback(qs0, callback0)
       if (!docName || !attName || !att || !contentType) {
-        const e = new Error('Invalid parameters')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -945,7 +984,7 @@ module.exports = exports = function dbScope (cfg) {
     function getAtt (docName, attName, qs0, callback0) {
       const { opts, callback } = getCallback(qs0, callback0)
       if (!docName || !attName) {
-        const e = new Error('Invalid parameters')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -976,7 +1015,7 @@ module.exports = exports = function dbScope (cfg) {
 
     function destroyAtt (docName, attName, qs, callback) {
       if (!docName || !attName) {
-        const e = new Error('Invalid parameters')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -994,7 +1033,7 @@ module.exports = exports = function dbScope (cfg) {
 
     function find (query, callback) {
       if (!query || typeof query !== 'object') {
-        const e = new Error('Invalid query')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
@@ -1021,7 +1060,7 @@ module.exports = exports = function dbScope (cfg) {
 
     function createIndex (indexDef, callback) {
       if (!indexDef || typeof indexDef !== 'object') {
-        const e = new Error('Invalid index definition')
+        const e = INVALID_PARAMETERS_ERROR
         if (callback) {
           return callback(e, null)
         } else {
diff --git a/test/database.changes.test.js b/test/database.changes.test.js
index 4fb1e48..d176bef 100644
--- a/test/database.changes.test.js
+++ b/test/database.changes.test.js
@@ -71,14 +71,16 @@ test('should be able to handle a missing database - GET /db/_changes - nano.db.c
   expect(scope.isDone()).toBe(true)
 })
 
-test('should not attempt with empty dbName - nano.db.changes', async () => {
-  expect(() => {
-    nano.db.changes('')
-  }).toThrowError('missing dbName')
+test('should not attempt invalid parameters - nano.db.changes', async () => {
+  await expect(nano.db.changes()).rejects.toThrowError('Invalid parameters')
+  await expect(nano.db.changes('')).rejects.toThrowError('Invalid parameters')
 })
 
-test('should not attempt with missing dbName - nano.db.changes', async () => {
-  expect(() => {
-    nano.db.changes()
-  }).toThrowError('missing dbName')
+test('should detect missing parameters (callback) - nano.db.changes', async () => {
+  return new Promise((resolve, reject) => {
+    nano.db.changes(undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })
diff --git a/test/database.compact.test.js b/test/database.compact.test.js
index 331e359..7fb3006 100644
--- a/test/database.compact.test.js
+++ b/test/database.compact.test.js
@@ -40,14 +40,16 @@ test('should be able to send compaction request with design doc - POST /db/_comp
   expect(scope.isDone()).toBe(true)
 })
 
-test('should not attempt compact with empty dbName - nano.db.compact', async () => {
-  expect(() => {
-    nano.db.compact('')
-  }).toThrowError('missing dbName')
+test('should not attempt compact with invalid parameters - nano.db.compact', async () => {
+  await expect(nano.db.compact('')).rejects.toThrowError('Invalid parameters')
+  await expect(nano.db.compact()).rejects.toThrowError('Invalid parameters')
 })
 
-test('should not attempt compact with missing dbName - nano.db.compact', async () => {
-  expect(() => {
-    nano.db.compact()
-  }).toThrowError('missing dbName')
+test('should detect missing parameters (callback) - nano.db.compact', async () => {
+  return new Promise((resolve, reject) => {
+    nano.db.compact(undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })
diff --git a/test/database.create.test.js b/test/database.create.test.js
index 9feae75..ae461df 100644
--- a/test/database.create.test.js
+++ b/test/database.create.test.js
@@ -57,14 +57,16 @@ test('should handle pre-existing database - PUT /db - nano.db.create', async ()
   expect(scope.isDone()).toBe(true)
 })
 
-test('should not attempt to create database with empty database name - nano.db.create', async () => {
-  expect(() => {
-    nano.db.create('')
-  }).toThrowError('missing dbName')
+test('should not attempt to create database with invalid parameters - nano.db.create', async () => {
+  await expect(nano.db.create()).rejects.toThrowError('Invalid parameters')
+  await expect(nano.db.create('')).rejects.toThrowError('Invalid parameters')
 })
 
-test('should not attempt to create database with missing database name - nano.db.create', async () => {
-  expect(() => {
-    nano.db.create()
-  }).toThrowError('missing dbName')
+test('should detect missing parameters (callback) - nano.db.create', async () => {
+  return new Promise((resolve, reject) => {
+    nano.db.create(undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })
diff --git a/test/database.destroy.test.js b/test/database.destroy.test.js
index 17f8189..659de5b 100644
--- a/test/database.destroy.test.js
+++ b/test/database.destroy.test.js
@@ -29,7 +29,7 @@ test('should destroy a database - DELETE /db - nano.db.destroy', async () => {
   expect(scope.isDone()).toBe(true)
 })
 
-test('should handle non-existant database - DELETE /db - nano.db.create', async () => {
+test('should handle non-existant database - DELETE /db - nano.db.destroy', async () => {
   // mocks
   const scope = nock(COUCH_URL)
     .delete('/db')
@@ -44,13 +44,15 @@ test('should handle non-existant database - DELETE /db - nano.db.create', async
 })
 
 test('should not attempt to destroy database with empty database name - nano.db.destroy', async () => {
-  expect(() => {
-    nano.db.destroy('')
-  }).toThrowError('missing dbName')
+  await expect(nano.db.destroy()).rejects.toThrowError('Invalid parameters')
+  await expect(nano.db.destroy('')).rejects.toThrowError('Invalid parameters')
 })
 
-test('should not attempt to destroy database with missing database name - nano.db.destroy', async () => {
-  expect(() => {
-    nano.db.destroy()
-  }).toThrowError('missing dbName')
+test('should detect missing parameters (callback) - nano.db.destroy', async () => {
+  return new Promise((resolve, reject) => {
+    nano.db.destroy(undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })
diff --git a/test/database.get.test.js b/test/database.get.test.js
index 1098abc..ae9e421 100644
--- a/test/database.get.test.js
+++ b/test/database.get.test.js
@@ -84,14 +84,16 @@ test('should handle missing database - PUT /db - nano.db.create', async () => {
   expect(scope.isDone()).toBe(true)
 })
 
-test('should not attempt info fetch with empty dbName - nano.db.get', async () => {
-  expect(() => {
-    nano.db.get('')
-  }).toThrowError('missing dbName')
+test('should not attempt info fetch with missing parameters - nano.db.get', async () => {
+  await expect(nano.db.get()).rejects.toThrowError('Invalid parameters')
+  await expect(nano.db.get('')).rejects.toThrowError('Invalid parameters')
 })
 
-test('should not attempt info fetch with missing dbName - nano.db.get', async () => {
-  expect(() => {
-    nano.db.get()
-  }).toThrowError('missing dbName')
+test('should detect missing parameters (callback) - nano.db.get', async () => {
+  return new Promise((resolve, reject) => {
+    nano.db.get(undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })
diff --git a/test/database.replicate.test.js b/test/database.replicate.test.js
index e2e86b2..19290d7 100644
--- a/test/database.replicate.test.js
+++ b/test/database.replicate.test.js
@@ -63,26 +63,17 @@ test('should be able to supply additional parameters - POST /_replicate - nano.d
   expect(scope.isDone()).toBe(true)
 })
 
-test('should not attempt compact with empty source - nano.db.replicate', async () => {
-  expect(() => {
-    nano.db.replicate('')
-  }).toThrowError('missing source')
+test('should not attempt compact invalid parameters - nano.db.replicate', async () => {
+  await expect(nano.db.replicate('')).rejects.toThrowError('Invalid parameters')
+  await expect(nano.db.replicate(undefined, 'target')).rejects.toThrowError('Invalid parameters')
+  await expect(nano.db.replicate('', 'target')).rejects.toThrowError('Invalid parameters')
 })
 
-test('should not attempt compact with missing source - nano.db.replicate', async () => {
-  expect(() => {
-    nano.db.replicate(undefined, 'target')
-  }).toThrowError('missing source')
-})
-
-test('should not attempt compact with empty target - nano.db.replicate', async () => {
-  expect(() => {
-    nano.db.replicate('', 'target')
-  }).toThrowError('missing source')
-})
-
-test('should not attempt compact with missing target - nano.db.replicate', async () => {
-  expect(() => {
-    nano.db.replicate(undefined, 'target')
-  }).toThrowError('missing source')
+test('should detect missing parameters (callback) - nano.db.replicate', async () => {
+  return new Promise((resolve, reject) => {
+    nano.db.replicate(undefined, undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })
diff --git a/test/database.replication.disable.test.js b/test/database.replication.disable.test.js
index d01eec3..51fff73 100644
--- a/test/database.replication.disable.test.js
+++ b/test/database.replication.disable.test.js
@@ -45,26 +45,17 @@ test('should be able to handle a 404 - DELETE /_replicator - nano.db.replication
   expect(scope.isDone()).toBe(true)
 })
 
-test('should not to try to disable with missing id - nano.db.replication.disable', async () => {
-  expect(() => {
-    nano.db.replication.disable(undefined, '1-456')
-  }).toThrowError('missing id')
+test('should not to try to disable with invalid parameters - nano.db.replication.disable', async () => {
+  await expect(nano.db.replication.disable(undefined, '1-456')).rejects.toThrowError('Invalid parameters')
+  await expect(nano.db.replication.disable('', '1-456')).rejects.toThrowError('Invalid parameters')
+  await expect(nano.db.replication.disable('rep1')).rejects.toThrowError('Invalid parameters')
 })
 
-test('should not to try to disable with empty id - nano.db.replication.disable', async () => {
-  expect(() => {
-    nano.db.replication.disable('', '1-456')
-  }).toThrowError('missing id')
-})
-
-test('should not to try to disable with missing rev - nano.db.replication.disable', async () => {
-  expect(() => {
-    nano.db.replication.disable('rep1')
-  }).toThrowError('missing rev')
-})
-
-test('should not to try to disable with empty rev - nano.db.replication.disable', async () => {
-  expect(() => {
-    nano.db.replication.disable('rep1', '')
-  }).toThrowError('missing rev')
+test('should detect missing parameters (callback) - nano.db.replication.disable', async () => {
+  return new Promise((resolve, reject) => {
+    nano.db.replication.disable(undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })
diff --git a/test/database.replication.enable.test.js b/test/database.replication.enable.test.js
index 4c7aebd..bb74f9a 100644
--- a/test/database.replication.enable.test.js
+++ b/test/database.replication.enable.test.js
@@ -57,26 +57,18 @@ test('should be able to supply additional parameters - POST /_replicator - nano.
   expect(scope.isDone()).toBe(true)
 })
 
-test('should not attempt compact with empty source - nano.db.replication.enable', async () => {
-  expect(() => {
-    nano.db.replication.enable('')
-  }).toThrowError('missing source')
+test('should not attempt compact with invalid parameters - nano.db.replication.enable', async () => {
+  await expect(nano.db.replication.enable(undefined, 'target')).rejects.toThrowError('Invalid parameters')
+  await expect(nano.db.replication.enable()).rejects.toThrowError('Invalid parameters')
+  await expect(nano.db.replication.enable('source')).rejects.toThrowError('Invalid parameters')
+  await expect(nano.db.replication.enable('source', '')).rejects.toThrowError('Invalid parameters')
 })
 
-test('should not attempt compact with missing source - nano.db.replication.enable', async () => {
-  expect(() => {
-    nano.db.replication.enable(undefined, 'target')
-  }).toThrowError('missing source')
-})
-
-test('should not attempt compact with empty target - nano.db.replication.enable', async () => {
-  expect(() => {
-    nano.db.replication.enable('', 'target')
-  }).toThrowError('missing source')
-})
-
-test('should not attempt compact with missing target - nano.db.replication.enable', async () => {
-  expect(() => {
-    nano.db.replication.enable(undefined, 'target')
-  }).toThrowError('missing source')
+test('should detect missing parameters (callback) - nano.db.replication.enable', async () => {
+  return new Promise((resolve, reject) => {
+    nano.db.replication.enable(undefined, undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })
diff --git a/test/database.replication.query.test.js b/test/database.replication.query.test.js
index 0e36bb9..deff494 100644
--- a/test/database.replication.query.test.js
+++ b/test/database.replication.query.test.js
@@ -77,14 +77,16 @@ test('should be able to query a replication and handle 404 - GET /_replicator/id
   expect(scope.isDone()).toBe(true)
 })
 
-test('should not attempt info fetch with empty id - nano.db.replication.query', async () => {
-  expect(() => {
-    nano.db.replication.query('')
-  }).toThrowError('missing id')
+test('should not attempt info fetch with invalid parameters - nano.db.replication.query', async () => {
+  await expect(nano.db.replication.query('')).rejects.toThrowError('Invalid parameters')
+  await expect(nano.db.replication.query()).rejects.toThrowError('Invalid parameters')
 })
 
-test('should not attempt info fetch with missing id - nano.db.replication.query', async () => {
-  expect(() => {
-    nano.db.replication.query()
-  }).toThrowError('missing id')
+test('should detect missing parameters (callback) - nano.db.replication.query', async () => {
+  return new Promise((resolve, reject) => {
+    nano.db.replication.query(undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })
diff --git a/test/design.atomic.test.js b/test/design.atomic.test.js
index 95c37fa..b0904aa 100644
--- a/test/design.atomic.test.js
+++ b/test/design.atomic.test.js
@@ -77,10 +77,10 @@ test('should be able to handle 404 - db.atomic', async () => {
 
 test('should detect missing parameters - db.update', async () => {
   const db = nano.db.use('db')
-  await expect(db.atomic()).rejects.toThrow('Invalid update')
-  await expect(db.atomic('ddoc')).rejects.toThrow('Invalid update')
-  await expect(db.atomic('ddoc', 'updatename')).rejects.toThrow('Invalid update')
-  await expect(db.atomic('', 'updatename', 'docid')).rejects.toThrow('Invalid update')
+  await expect(db.atomic()).rejects.toThrow('Invalid parameters')
+  await expect(db.atomic('ddoc')).rejects.toThrow('Invalid parameters')
+  await expect(db.atomic('ddoc', 'updatename')).rejects.toThrow('Invalid parameters')
+  await expect(db.atomic('', 'updatename', 'docid')).rejects.toThrow('Invalid parameters')
 })
 
 test('should detect missing parameters (callback) - db.update', async () => {
diff --git a/test/design.createIndex.test.js b/test/design.createIndex.test.js
index 1c7e7a5..88e0224 100644
--- a/test/design.createIndex.test.js
+++ b/test/design.createIndex.test.js
@@ -67,8 +67,8 @@ test('should handle 404 - POST /db/_index - db.index', async () => {
 
 test('should detect missing index - db.createIndex', async () => {
   const db = nano.db.use('db')
-  await expect(db.createIndex()).rejects.toThrow('Invalid index definition')
-  await expect(db.createIndex('myindex')).rejects.toThrow('Invalid index definition')
+  await expect(db.createIndex()).rejects.toThrow('Invalid parameters')
+  await expect(db.createIndex('myindex')).rejects.toThrow('Invalid parameters')
 })
 
 test('should detect missing index (callback) - db.createIndex', async () => {
diff --git a/test/design.find.test.js b/test/design.find.test.js
index 39bf9d3..b4aaba4 100644
--- a/test/design.find.test.js
+++ b/test/design.find.test.js
@@ -68,8 +68,8 @@ test('should handle 404 - POST /db/_find - db.find', async () => {
 
 test('should detect missing query - db.find', async () => {
   const db = nano.db.use('db')
-  await expect(db.find()).rejects.toThrow('Invalid query')
-  await expect(db.find('susan')).rejects.toThrow('Invalid query')
+  await expect(db.find()).rejects.toThrow('Invalid parameters')
+  await expect(db.find('susan')).rejects.toThrow('Invalid parameters')
 })
 
 test('should detect missing query (callback) - db.find', async () => {
diff --git a/test/design.search.test.js b/test/design.search.test.js
index 7be860c..8a5c37c 100644
--- a/test/design.search.test.js
+++ b/test/design.search.test.js
@@ -55,10 +55,10 @@ test('should be able to handle 404 - db.search', async () => {
 
 test('should detect missing parameters - db.search', async () => {
   const db = nano.db.use('db')
-  await expect(db.search()).rejects.toThrow('Invalid view')
-  await expect(db.search('susan')).rejects.toThrow('Invalid view')
-  await expect(db.search('susan', '')).rejects.toThrow('Invalid view')
-  await expect(db.search('', 'susan')).rejects.toThrow('Invalid view')
+  await expect(db.search()).rejects.toThrow('Invalid parameters')
+  await expect(db.search('susan')).rejects.toThrow('Invalid parameters')
+  await expect(db.search('susan', '')).rejects.toThrow('Invalid parameters')
+  await expect(db.search('', 'susan')).rejects.toThrow('Invalid parameters')
 })
 
 test('should detect missing parameters (callback) - db.search', async () => {
diff --git a/test/design.show.test.js b/test/design.show.test.js
index 258f1bb..4fc6278 100644
--- a/test/design.show.test.js
+++ b/test/design.show.test.js
@@ -49,10 +49,10 @@ test('should be able to handle 404 - db.show', async () => {
 
 test('should detect missing parameters - db.show', async () => {
   const db = nano.db.use('db')
-  await expect(db.show()).rejects.toThrow('Invalid show')
-  await expect(db.show('ddoc')).rejects.toThrow('Invalid show')
-  await expect(db.show('ddoc', 'showname')).rejects.toThrow('Invalid show')
-  await expect(db.show('', 'showname', 'docid')).rejects.toThrow('Invalid show')
+  await expect(db.show()).rejects.toThrow('Invalid parameters')
+  await expect(db.show('ddoc')).rejects.toThrow('Invalid parameters')
+  await expect(db.show('ddoc', 'showname')).rejects.toThrow('Invalid parameters')
+  await expect(db.show('', 'showname', 'docid')).rejects.toThrow('Invalid parameters')
 })
 
 test('should detect missing parameters (callback) - db.show', async () => {
diff --git a/test/design.view.test.js b/test/design.view.test.js
index 767b4f9..b53074d 100644
--- a/test/design.view.test.js
+++ b/test/design.view.test.js
@@ -147,10 +147,10 @@ test('should be able to handle 404 - db.view', async () => {
 
 test('should detect missing parameters - db.view', async () => {
   const db = nano.db.use('db')
-  await expect(db.view()).rejects.toThrow('Invalid view')
-  await expect(db.view('susan')).rejects.toThrow('Invalid view')
-  await expect(db.view('susan', '')).rejects.toThrow('Invalid view')
-  await expect(db.view('', 'susan')).rejects.toThrow('Invalid view')
+  await expect(db.view()).rejects.toThrow('Invalid parameters')
+  await expect(db.view('susan')).rejects.toThrow('Invalid parameters')
+  await expect(db.view('susan', '')).rejects.toThrow('Invalid parameters')
+  await expect(db.view('', 'susan')).rejects.toThrow('Invalid parameters')
 })
 
 test('should detect missing parameters (callback) - db.view', async () => {
diff --git a/test/document.copy.test.js b/test/document.copy.test.js
index 29d2d6a..9904313 100644
--- a/test/document.copy.test.js
+++ b/test/document.copy.test.js
@@ -31,12 +31,12 @@ test('should be able to copy a document - db.copy', async () => {
 
 test('should detect missing source doc id - db.copy', async () => {
   const db = nano.db.use('db')
-  await expect(db.copy(undefined, 'rabbbit2')).rejects.toThrow('Invalid doc id')
+  await expect(db.copy(undefined, 'rabbbit2')).rejects.toThrow('Invalid parameters')
 })
 
 test('should detect missing target doc id - db.copy', async () => {
   const db = nano.db.use('db')
-  await expect(db.copy('rabbit1')).rejects.toThrow('Invalid doc id')
+  await expect(db.copy('rabbit1')).rejects.toThrow('Invalid parameters')
 })
 
 test('should be able to copy a document in overwrite mode - db.copy', async () => {
@@ -74,3 +74,21 @@ test('should be able to copy a document in overwrite mode missing target - db.co
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
 })
+
+test('should detect invalid parameters - db.copy', async () => {
+  const db = nano.db.use('db')
+  await expect(db.copy()).rejects.toThrowError('Invalid parameters')
+  await expect(db.copy('')).rejects.toThrowError('Invalid parameters')
+  await expect(db.copy('', 'rabbit2')).rejects.toThrowError('Invalid parameters')
+  await expect(db.copy('rabbit1', '')).rejects.toThrowError('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.copy', async () => {
+  return new Promise((resolve, reject) => {
+    const db = nano.db.use('db')
+    db.copy(undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/document.destroy.test.js b/test/document.destroy.test.js
index 2177992..8c50f12 100644
--- a/test/document.destroy.test.js
+++ b/test/document.destroy.test.js
@@ -45,7 +45,17 @@ test('should be able to handle 409 conflicts - DELETE /db/id - db.destroy', asyn
   expect(scope.isDone()).toBe(true)
 })
 
-test('should detect missing doc id - db.destroy', async () => {
+test('should detect missing parameters - db.destroy', async () => {
   const db = nano.db.use('db')
-  await expect(db.destroy(undefined, '1-123')).rejects.toThrow('Invalid doc id')
+  await expect(db.destroy(undefined, '1-123')).rejects.toThrow('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.destroy', async () => {
+  return new Promise((resolve, reject) => {
+    const db = nano.db.use('db')
+    db.destroy(undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })
diff --git a/test/document.fetch.test.js b/test/document.fetch.test.js
index 55281fc..c2056f9 100644
--- a/test/document.fetch.test.js
+++ b/test/document.fetch.test.js
@@ -150,11 +150,21 @@ test('should be able to handle 404 - POST /db/_all_docs - db.fetch', async () =>
   expect(scope.isDone()).toBe(true)
 })
 
-test('should detect missing keys - db.fetch', async () => {
+test('should detect invalid parameters - db.fetch', async () => {
   const db = nano.db.use('db')
-  await expect(db.fetch()).rejects.toThrow('Invalid keys')
-  await expect(db.fetch({})).rejects.toThrow('Invalid keys')
-  await expect(db.fetch({ keys: {} })).rejects.toThrow('Invalid keys')
-  await expect(db.fetch({ keys: '123' })).rejects.toThrow('Invalid keys')
-  await expect(db.fetch({ keys: [] })).rejects.toThrow('Invalid keys')
+  await expect(db.fetch()).rejects.toThrow('Invalid parameters')
+  await expect(db.fetch({})).rejects.toThrow('Invalid parameters')
+  await expect(db.fetch({ keys: {} })).rejects.toThrow('Invalid parameters')
+  await expect(db.fetch({ keys: '123' })).rejects.toThrow('Invalid parameters')
+  await expect(db.fetch({ keys: [] })).rejects.toThrow('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.fetch', async () => {
+  return new Promise((resolve, reject) => {
+    const db = nano.db.use('db')
+    db.fetch(undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })
diff --git a/test/document.fetchRevs.test.js b/test/document.fetchRevs.test.js
index 80eda1c..4cf610d 100644
--- a/test/document.fetchRevs.test.js
+++ b/test/document.fetchRevs.test.js
@@ -15,7 +15,7 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
-test('should be able to fetch a list of document revisions - POST /db/_all_docs - db.fetch', async () => {
+test('should be able to fetch a list of document revisions - POST /db/_all_docs - db.fetchRevs', async () => {
   // mocks
   const keys = ['1000501', '1000543', '100077']
   const response = {
@@ -56,7 +56,7 @@ test('should be able to fetch a list of document revisions - POST /db/_all_docs
   expect(scope.isDone()).toBe(true)
 })
 
-test('should be able to fetch a list of document revisions  with opts - GET /db/_all_docs - db.fetch', async () => {
+test('should be able to fetch a list of document revisions  with opts - GET /db/_all_docs - db.fetchRevs', async () => {
   // mocks
   const keys = ['1000501', '1000543', '100077']
   const response = {
@@ -97,7 +97,7 @@ test('should be able to fetch a list of document revisions  with opts - GET /db/
   expect(scope.isDone()).toBe(true)
 })
 
-test('should be able to handle 404 - POST /db/_all_docs - db.fetch', async () => {
+test('should be able to handle 404 - POST /db/_all_docs - db.fetchRevs', async () => {
   // mocks
   const keys = ['1000501', '1000543', '100077']
   const response = {
@@ -114,11 +114,21 @@ test('should be able to handle 404 - POST /db/_all_docs - db.fetch', async () =>
   expect(scope.isDone()).toBe(true)
 })
 
-test('should detect missing keys - db.fetch', async () => {
+test('should detect missing parameters - db.fetchRevs', async () => {
   const db = nano.db.use('db')
-  await expect(db.fetchRevs()).rejects.toThrow('Invalid keys')
-  await expect(db.fetchRevs({})).rejects.toThrow('Invalid keys')
-  await expect(db.fetchRevs({ keys: {} })).rejects.toThrow('Invalid keys')
-  await expect(db.fetchRevs({ keys: '123' })).rejects.toThrow('Invalid keys')
-  await expect(db.fetchRevs({ keys: [] })).rejects.toThrow('Invalid keys')
+  await expect(db.fetchRevs()).rejects.toThrow('Invalid parameters')
+  await expect(db.fetchRevs({})).rejects.toThrow('Invalid parameters')
+  await expect(db.fetchRevs({ keys: {} })).rejects.toThrow('Invalid parameters')
+  await expect(db.fetchRevs({ keys: '123' })).rejects.toThrow('Invalid parameters')
+  await expect(db.fetchRevs({ keys: [] })).rejects.toThrow('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.fetchRevs', async () => {
+  return new Promise((resolve, reject) => {
+    const db = nano.db.use('db')
+    db.fetchRevs(undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })
diff --git a/test/document.get.test.js b/test/document.get.test.js
index a2cfcca..001fd77 100644
--- a/test/document.get.test.js
+++ b/test/document.get.test.js
@@ -61,5 +61,15 @@ test('should be able to handle 404 - GET /db/id - db.get', async () => {
 
 test('should detect missing doc id - db.get', async () => {
   const db = nano.db.use('db')
-  await expect(db.get()).rejects.toThrow('Invalid doc id')
+  await expect(db.get()).rejects.toThrow('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.get', async () => {
+  return new Promise((resolve, reject) => {
+    const db = nano.db.use('db')
+    db.get(undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })
diff --git a/test/document.head.test.js b/test/document.head.test.js
index dc2cb99..094b41a 100644
--- a/test/document.head.test.js
+++ b/test/document.head.test.js
@@ -60,7 +60,17 @@ test('should be able to head a missing document - HEAD /db/id - db.head', async
   expect(scope.isDone()).toBe(true)
 })
 
-test('should detect missing doc id - db.head', async () => {
+test('should detect missing parameters - db.head', async () => {
   const db = nano.db.use('db')
-  await expect(db.head()).rejects.toThrow('Invalid doc id')
+  await expect(db.head()).rejects.toThrow('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.head', async () => {
+  return new Promise((resolve, reject) => {
+    const db = nano.db.use('db')
+    db.head(undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
 })


[couchdb-nano] 06/15: document tests complete

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit 286db832c8c0ad96b74ac08e940e7abf26a8ed37
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Thu Feb 6 15:48:41 2020 +0000

    document tests complete
---
 lib/nano.js                        |  56 ++++++++--
 test/database.listAsStream.test.js |   2 +-
 test/document.bulk.test.js         |  52 ++++++++++
 test/document.copy.test.js         |  76 ++++++++++++++
 test/document.destroy.test.js      |  51 ++++++++++
 test/document.fetch.test.js        | 160 +++++++++++++++++++++++++++++
 test/document.fetchRevs.test.js    | 124 ++++++++++++++++++++++
 test/document.get.test.js          |  65 ++++++++++++
 test/document.head.test.js         |  66 ++++++++++++
 test/document.insert.test.js       | 128 +++++++++++++++++++++++
 test/document.list.test.js         | 104 +++++++++++++++++++
 test/document.listAsStream.test.js | 108 ++++++++++++++++++++
 test/nano.request.test.js          | 204 ++++++++++++++++++++++++++++++++++---
 13 files changed, 1174 insertions(+), 22 deletions(-)

diff --git a/lib/nano.js b/lib/nano.js
index 6e6e535..7b63bc3 100644
--- a/lib/nano.js
+++ b/lib/nano.js
@@ -519,11 +519,11 @@ module.exports = exports = function dbScope (cfg) {
     // http://docs.couchdb.org/en/latest/api/document/common.html#delete--db-docid
     function destroyDoc (docName, rev, callback) {
       if (!docName) {
-        const msg = 'Invalid doc id'
+        const e = new Error('Invalid doc id')
         if (callback) {
-          callback(msg, null)
+          return callback(e, null)
         } else {
-          return Promise.reject(msg)
+          return Promise.reject(e)
         }
       } else {
         return relax({
@@ -540,7 +540,12 @@ module.exports = exports = function dbScope (cfg) {
       const { opts, callback } = getCallback(qs0, callback0)
 
       if (!docName) {
-        if (callback) { callback(new Error('Invalid doc id'), null) }
+        const e = new Error('Invalid doc id')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
       } else {
         return relax({ db: dbName, doc: docName, qs: opts }, callback)
       }
@@ -548,6 +553,14 @@ module.exports = exports = function dbScope (cfg) {
 
     // http://docs.couchdb.org/en/latest/api/document/common.html#head--db-docid
     function headDoc (docName, callback) {
+      if (!docName) {
+        const e = new Error('Invalid doc id')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
       if (callback) {
         relax({
           db: dbName,
@@ -579,6 +592,15 @@ module.exports = exports = function dbScope (cfg) {
     function copyDoc (docSrc, docDest, opts0, callback0) {
       const { opts, callback } = getCallback(opts0, callback0)
 
+      if (!docSrc || !docDest) {
+        const e = new Error('Invalid doc id')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
+
       const qs = {
         db: dbName,
         doc: docSrc,
@@ -593,7 +615,7 @@ module.exports = exports = function dbScope (cfg) {
               qs.headers.Destination += '?rev=' +
                 h.etag.substring(1, h.etag.length - 1)
             }
-            relax(qs, callback)
+            return relax(qs, callback)
           },
           function (e) {
             if (e && e.statusCode !== 404) {
@@ -603,7 +625,7 @@ module.exports = exports = function dbScope (cfg) {
                 return Promise.reject(e)
               }
             } else {
-              relax(qs, callback)
+              return relax(qs, callback)
             }
           }
         )
@@ -631,6 +653,17 @@ module.exports = exports = function dbScope (cfg) {
       const { opts, callback } = getCallback(qs0, callback0)
       opts.include_docs = true
 
+      if (!docNames || typeof docNames !== 'object' ||
+          !docNames.keys || !Array.isArray(docNames.keys) ||
+          docNames.keys.length === 0) {
+        const e = new Error('Invalid keys')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
+
       return relax({
         db: dbName,
         path: '_all_docs',
@@ -642,6 +675,17 @@ module.exports = exports = function dbScope (cfg) {
 
     function fetchRevs (docNames, qs0, callback0) {
       const { opts, callback } = getCallback(qs0, callback0)
+
+      if (!docNames || typeof docNames !== 'object' ||
+      !docNames.keys || !Array.isArray(docNames.keys) ||
+      docNames.keys.length === 0) {
+        const e = new Error('Invalid keys')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
       return relax({
         db: dbName,
         path: '_all_docs',
diff --git a/test/database.listAsStream.test.js b/test/database.listAsStream.test.js
index 6568e26..25b6ed2 100644
--- a/test/database.listAsStream.test.js
+++ b/test/database.listAsStream.test.js
@@ -23,7 +23,7 @@ test('should get a streamed list of databases - GET /_all_dbs - nano.db.listAsSt
     .reply(200, response)
 
   return new Promise((resolve, reject) => {
-    // test GET /db/_all_dbs
+    // test GET /_all_dbs
     const s = nano.db.listAsStream()
     expect(typeof s).toBe('object')
     let buffer = ''
diff --git a/test/document.bulk.test.js b/test/document.bulk.test.js
new file mode 100644
index 0000000..672df9d
--- /dev/null
+++ b/test/document.bulk.test.js
@@ -0,0 +1,52 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to insert documents in bulk - POST /db/_bulk_docs - db.bulk', async () => {
+  // mocks
+  const docs = [{ a: 1, b: 2 }, { a: 2, b: 3 }, { a: 3, b: 4 }]
+  const response = [
+    { ok: true, id: 'x', rev: '1-123' },
+    { ok: true, id: 'y', rev: '1-456' },
+    { ok: true, id: 'z', rev: '1-789' }
+  ]
+  const scope = nock(COUCH_URL)
+    .post('/db/_bulk_docs', { docs: docs })
+    .reply(200, response)
+
+  // test POST /db/_bulk_docs
+  const db = nano.db.use('db')
+  const p = await db.bulk({ docs: docs })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle missing database - POST /db/_bulk_docs - db.bulk', async () => {
+  // mocks
+  const docs = [{ a: 1, b: 2 }, { a: 2, b: 3 }, { a: 3, b: 4 }]
+  const response = {
+    error: 'not_found',
+    reason: 'Database does not exist.'
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_bulk_docs', { docs: docs })
+    .reply(404, response)
+
+  // test POST /db/_bulk_docs
+  const db = nano.db.use('db')
+  await expect(db.bulk({ docs: docs })).rejects.toThrow('Database does not exist.')
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/document.copy.test.js b/test/document.copy.test.js
new file mode 100644
index 0000000..29d2d6a
--- /dev/null
+++ b/test/document.copy.test.js
@@ -0,0 +1,76 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to copy a document - db.copy', async () => {
+  // mocks
+  const response = { ok: true, id: 'rabbit2', rev: '1-123' }
+  const scope = nock(COUCH_URL, { reqheaders: { destination: 'rabbit2' } })
+    .intercept('/db/rabbit1', 'COPY')
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.copy('rabbit1', 'rabbit2')
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing source doc id - db.copy', async () => {
+  const db = nano.db.use('db')
+  await expect(db.copy(undefined, 'rabbbit2')).rejects.toThrow('Invalid doc id')
+})
+
+test('should detect missing target doc id - db.copy', async () => {
+  const db = nano.db.use('db')
+  await expect(db.copy('rabbit1')).rejects.toThrow('Invalid doc id')
+})
+
+test('should be able to copy a document in overwrite mode - db.copy', async () => {
+  // mocks
+  const response = { ok: true, id: 'rabbit2', rev: '1-123' }
+  const scope = nock(COUCH_URL)
+    .head('/db/rabbit2')
+    .reply(200, '', { ETag: '1-123' })
+    .intercept('/db/rabbit1', 'COPY')
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.copy('rabbit1', 'rabbit2', { overwrite: true })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to copy a document in overwrite mode missing target - db.copy', async () => {
+  // mocks
+  const response = { ok: true, id: 'rabbit2', rev: '1-123' }
+  const errResponse = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL)
+    .head('/db/rabbit2')
+    .reply(404, errResponse)
+    .intercept('/db/rabbit1', 'COPY')
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.copy('rabbit1', 'rabbit2', { overwrite: true })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/document.destroy.test.js b/test/document.destroy.test.js
new file mode 100644
index 0000000..2177992
--- /dev/null
+++ b/test/document.destroy.test.js
@@ -0,0 +1,51 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to destroy a document - DELETE /db/id - db.destroy', async () => {
+  // mocks
+  const response = { ok: true, id: 'id', rev: '2-456' }
+  const scope = nock(COUCH_URL)
+    .delete('/db/id?rev=1-123')
+    .reply(200, response)
+
+  // test DELETE /db/id
+  const db = nano.db.use('db')
+  const p = await db.destroy('id', '1-123')
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 409 conflicts - DELETE /db/id - db.destroy', async () => {
+  // mocks
+  const response = {
+    error: 'conflict',
+    reason: 'Document update conflict.'
+  }
+  const scope = nock(COUCH_URL)
+    .delete('/db/id?rev=1-123')
+    .reply(409, response)
+
+  // test DELETE /db/id
+  const db = nano.db.use('db')
+  await expect(db.destroy('id', '1-123')).rejects.toThrow('Document update conflict.')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing doc id - db.destroy', async () => {
+  const db = nano.db.use('db')
+  await expect(db.destroy(undefined, '1-123')).rejects.toThrow('Invalid doc id')
+})
diff --git a/test/document.fetch.test.js b/test/document.fetch.test.js
new file mode 100644
index 0000000..55281fc
--- /dev/null
+++ b/test/document.fetch.test.js
@@ -0,0 +1,160 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to fetch a list of documents - POST /db/_all_docs - db.fetch', async () => {
+  // mocks
+  const keys = ['1000501', '1000543', '100077']
+  const response = {
+    total_rows: 23516,
+    offset: 0,
+    rows: [
+      {
+        id: '1000501',
+        key: '1000501',
+        value: {
+          rev: '2-46dcf6bf2f8d428504f5290e591aa182'
+        },
+        doc: {
+          _id: '1000501',
+          _rev: '2-46dcf6bf2f8d428504f5290e591aa182',
+          a: 1,
+          b: 2
+        }
+      },
+      {
+        id: '1000543',
+        key: '1000543',
+        value: {
+          rev: '1-3256046064953e2f0fdb376211fe78ab'
+        },
+        doc: {
+          _id: '1000543',
+          _rev: '2-3256046064953e2f0fdb376211fe78ab',
+          a: 3,
+          b: 4
+        }
+      },
+      {
+        id: '100077',
+        key: '100077',
+        value: {
+          rev: '1-101bff1251d4bd75beb6d3c232d05a5c'
+        },
+        doc: {
+          _id: '100077',
+          _rev: '2-101bff1251d4bd75beb6d3c232d05a5c',
+          a: 5,
+          b: 6
+        }
+      }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_all_docs?include_docs=true', { keys: keys })
+    .reply(200, response)
+
+  // test POST /db/_all_docs
+  const db = nano.db.use('db')
+  const p = await db.fetch({ keys: keys })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to fetch a list of documents with opts - GET /db/_all_docs - db.fetch', async () => {
+  // mocks
+  const keys = ['1000501', '1000543', '100077']
+  const response = {
+    total_rows: 23516,
+    offset: 0,
+    rows: [
+      {
+        id: '1000501',
+        key: '1000501',
+        value: {
+          rev: '2-46dcf6bf2f8d428504f5290e591aa182'
+        },
+        doc: {
+          _id: '1000501',
+          _rev: '2-46dcf6bf2f8d428504f5290e591aa182',
+          a: 1,
+          b: 2
+        }
+      },
+      {
+        id: '1000543',
+        key: '1000543',
+        value: {
+          rev: '1-3256046064953e2f0fdb376211fe78ab'
+        },
+        doc: {
+          _id: '1000543',
+          _rev: '2-3256046064953e2f0fdb376211fe78ab',
+          a: 3,
+          b: 4
+        }
+      },
+      {
+        id: '100077',
+        key: '100077',
+        value: {
+          rev: '1-101bff1251d4bd75beb6d3c232d05a5c'
+        },
+        doc: {
+          _id: '100077',
+          _rev: '2-101bff1251d4bd75beb6d3c232d05a5c',
+          a: 5,
+          b: 6
+        }
+      }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_all_docs?include_docs=true&descending=true', { keys: keys })
+    .reply(200, response)
+
+  // test POST /db/_all_docs
+  const db = nano.db.use('db')
+  const p = await db.fetch({ keys: keys }, { descending: true })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 404 - POST /db/_all_docs - db.fetch', async () => {
+  // mocks
+  const keys = ['1000501', '1000543', '100077']
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_all_docs?include_docs=true', { keys: keys })
+    .reply(404, response)
+
+  // test POST /db/_all_docs
+  const db = nano.db.use('db')
+  await expect(db.fetch({ keys: keys })).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing keys - db.fetch', async () => {
+  const db = nano.db.use('db')
+  await expect(db.fetch()).rejects.toThrow('Invalid keys')
+  await expect(db.fetch({})).rejects.toThrow('Invalid keys')
+  await expect(db.fetch({ keys: {} })).rejects.toThrow('Invalid keys')
+  await expect(db.fetch({ keys: '123' })).rejects.toThrow('Invalid keys')
+  await expect(db.fetch({ keys: [] })).rejects.toThrow('Invalid keys')
+})
diff --git a/test/document.fetchRevs.test.js b/test/document.fetchRevs.test.js
new file mode 100644
index 0000000..80eda1c
--- /dev/null
+++ b/test/document.fetchRevs.test.js
@@ -0,0 +1,124 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to fetch a list of document revisions - POST /db/_all_docs - db.fetch', async () => {
+  // mocks
+  const keys = ['1000501', '1000543', '100077']
+  const response = {
+    total_rows: 23516,
+    offset: 0,
+    rows: [
+      {
+        id: '1000501',
+        key: '1000501',
+        value: {
+          rev: '2-46dcf6bf2f8d428504f5290e591aa182'
+        }
+      },
+      {
+        id: '1000543',
+        key: '1000543',
+        value: {
+          rev: '1-3256046064953e2f0fdb376211fe78ab'
+        }
+      },
+      {
+        id: '100077',
+        key: '100077',
+        value: {
+          rev: '1-101bff1251d4bd75beb6d3c232d05a5c'
+        }
+      }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_all_docs', { keys: keys })
+    .reply(200, response)
+
+  // test POST /db/_all_docs
+  const db = nano.db.use('db')
+  const p = await db.fetchRevs({ keys: keys })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to fetch a list of document revisions  with opts - GET /db/_all_docs - db.fetch', async () => {
+  // mocks
+  const keys = ['1000501', '1000543', '100077']
+  const response = {
+    total_rows: 23516,
+    offset: 0,
+    rows: [
+      {
+        id: '1000501',
+        key: '1000501',
+        value: {
+          rev: '2-46dcf6bf2f8d428504f5290e591aa182'
+        }
+      },
+      {
+        id: '1000543',
+        key: '1000543',
+        value: {
+          rev: '1-3256046064953e2f0fdb376211fe78ab'
+        }
+      },
+      {
+        id: '100077',
+        key: '100077',
+        value: {
+          rev: '1-101bff1251d4bd75beb6d3c232d05a5c'
+        }
+      }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_all_docs?descending=true', { keys: keys })
+    .reply(200, response)
+
+  // test POST /db/_all_docs
+  const db = nano.db.use('db')
+  const p = await db.fetchRevs({ keys: keys }, { descending: true })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 404 - POST /db/_all_docs - db.fetch', async () => {
+  // mocks
+  const keys = ['1000501', '1000543', '100077']
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_all_docs', { keys: keys })
+    .reply(404, response)
+
+  // test POST /db/_all_docs
+  const db = nano.db.use('db')
+  await expect(db.fetchRevs({ keys: keys })).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing keys - db.fetch', async () => {
+  const db = nano.db.use('db')
+  await expect(db.fetchRevs()).rejects.toThrow('Invalid keys')
+  await expect(db.fetchRevs({})).rejects.toThrow('Invalid keys')
+  await expect(db.fetchRevs({ keys: {} })).rejects.toThrow('Invalid keys')
+  await expect(db.fetchRevs({ keys: '123' })).rejects.toThrow('Invalid keys')
+  await expect(db.fetchRevs({ keys: [] })).rejects.toThrow('Invalid keys')
+})
diff --git a/test/document.get.test.js b/test/document.get.test.js
new file mode 100644
index 0000000..a2cfcca
--- /dev/null
+++ b/test/document.get.test.js
@@ -0,0 +1,65 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to get a document - GET /db/id - db.get', async () => {
+  // mocks
+  const response = { _id: 'id', rev: '1-123', a: 1, b: 'two', c: true }
+  const scope = nock(COUCH_URL)
+    .get('/db/id')
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.get('id')
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to get a document with options - GET /db/id?conflicts=true - db.get', async () => {
+  // mocks
+  const response = { _id: 'id', rev: '1-123', a: 1, b: 'two', c: true }
+  const scope = nock(COUCH_URL)
+    .get('/db/id?conflicts=true')
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.get('id', { conflicts: true })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 404 - GET /db/id - db.get', async () => {
+  // mocks
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/id')
+    .reply(404, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  await expect(db.get('id')).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing doc id - db.get', async () => {
+  const db = nano.db.use('db')
+  await expect(db.get()).rejects.toThrow('Invalid doc id')
+})
diff --git a/test/document.head.test.js b/test/document.head.test.js
new file mode 100644
index 0000000..dc2cb99
--- /dev/null
+++ b/test/document.head.test.js
@@ -0,0 +1,66 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to head a document - HEAD /db/id - db.head', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .head('/db/id')
+    .reply(200, '', { ETag: '1-123' })
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.head('id')
+  // headers get lowercased
+  expect(p.etag).toBe('1-123')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to head a document with callback - HEAD /db/id - db.head', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .head('/db/id')
+    .reply(200, '', { ETag: '1-123' })
+
+  // test GET /db
+  return new Promise((resolve, reject) => {
+    const db = nano.db.use('db')
+    db.head('id', (err, data, headers) => {
+      // headers get lowercased
+      expect(err).toBeNull()
+      expect(headers.etag).toBe('1-123')
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
+
+test('should be able to head a missing document - HEAD /db/id - db.head', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .head('/db/id')
+    .reply(404, '')
+
+  // test GET /db
+  const db = nano.db.use('db')
+  await expect(db.head('id')).rejects.toThrow('couch returned 404')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing doc id - db.head', async () => {
+  const db = nano.db.use('db')
+  await expect(db.head()).rejects.toThrow('Invalid doc id')
+})
diff --git a/test/document.insert.test.js b/test/document.insert.test.js
new file mode 100644
index 0000000..812775b
--- /dev/null
+++ b/test/document.insert.test.js
@@ -0,0 +1,128 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to insert document - POST /db - db.insert', async () => {
+  // mocks
+  const doc = { a: 1, b: 2 }
+  const response = { ok: true, id: '8s8g8h8h9', rev: '1-123' }
+  const scope = nock(COUCH_URL)
+    .post('/db', doc)
+    .reply(200, response)
+
+  // test POST /db
+  const db = nano.db.use('db')
+  const p = await db.insert(doc)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to insert document with opts - POST /db?batch=ok - db.insert', async () => {
+  // mocks
+  const doc = { a: 1, b: 2 }
+  const response = { ok: true, id: '8s8g8h8h9', rev: '1-123' }
+  const scope = nock(COUCH_URL)
+    .post('/db?batch=ok', doc)
+    .reply(200, response)
+
+  // test POST /db
+  const db = nano.db.use('db')
+  const p = await db.insert(doc, { batch: 'ok' })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to insert document with known id - PUT /db/id - db.insert', async () => {
+  // mocks
+  const doc = { a: 1, b: 2 }
+  const response = { ok: true, id: 'myid', rev: '1-123' }
+
+  const scope = nock(COUCH_URL)
+    .put('/db/myid', doc)
+    .reply(200, response)
+
+  // test PUT /db
+  const db = nano.db.use('db')
+  const p = await db.insert(doc, 'myid')
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to insert document with id in object - POST /db - db.insert', async () => {
+  // mocks
+  const doc = { _id: 'myid', a: 1, b: 2 }
+  const response = { ok: true, id: 'myid', rev: '1-123' }
+
+  const scope = nock(COUCH_URL)
+    .post('/db', doc)
+    .reply(200, response)
+
+  // test POST /db
+  const db = nano.db.use('db')
+  const p = await db.insert(doc)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to update document with id/rev in object - POST /db - db.insert', async () => {
+  // mocks
+  const doc = { _id: 'myid', _rev: '1-123', a: 2, b: 2 }
+  const response = { ok: true, id: 'myid', rev: '2-456' }
+
+  const scope = nock(COUCH_URL)
+    .post('/db', doc)
+    .reply(200, response)
+
+  // test POST /db
+  const db = nano.db.use('db')
+  const p = await db.insert(doc)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 409 conflicts - POST /db - db.insert', async () => {
+  // mocks
+  const doc = { _id: 'myid', _rev: '1-123', a: 2, b: 2 }
+  const response = {
+    error: 'conflict',
+    reason: 'Document update conflict.'
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db', doc)
+    .reply(409, response)
+
+  // test POST /db
+  const db = nano.db.use('db')
+  await expect(db.insert(doc)).rejects.toThrow('Document update conflict.')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle missing database - POST /db - db.insert', async () => {
+  // mocks
+  const doc = { a: 1, b: 2 }
+  const response = {
+    error: 'not_found',
+    reason: 'Database does not exist.'
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db', doc)
+    .reply(404, response)
+
+  // test POST /db
+  const db = nano.db.use('db')
+  await expect(db.insert(doc)).rejects.toThrow('Database does not exist.')
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/document.list.test.js b/test/document.list.test.js
new file mode 100644
index 0000000..3e0705f
--- /dev/null
+++ b/test/document.list.test.js
@@ -0,0 +1,104 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to get a list of documents - GET /db/_all_docs - db.list', async () => {
+  // mocks
+  const response = {
+    total_rows: 23516,
+    offset: 0,
+    rows: [
+      {
+        id: '1000501',
+        key: '1000501',
+        value: {
+          rev: '2-46dcf6bf2f8d428504f5290e591aa182'
+        }
+      },
+      {
+        id: '1000543',
+        key: '1000543',
+        value: {
+          rev: '1-3256046064953e2f0fdb376211fe78ab'
+        }
+      },
+      {
+        id: '100077',
+        key: '100077',
+        value: {
+          rev: '1-101bff1251d4bd75beb6d3c232d05a5c'
+        }
+      }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_all_docs')
+    .reply(200, response)
+
+  // test GET /db/_all_docs
+  const db = nano.db.use('db')
+  const p = await db.list()
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to get a list of documents with opts - GET /db/_all_docs - db.list', async () => {
+  // mocks
+  const response = {
+    total_rows: 23516,
+    offset: 0,
+    rows: [
+      {
+        id: '1000501',
+        key: '1000501',
+        value: {
+          rev: '2-46dcf6bf2f8d428504f5290e591aa182'
+        },
+        doc: {
+          _id: '1000501',
+          _rev: '2-46dcf6bf2f8d428504f5290e591aa182',
+          a: 1,
+          b: 2
+        }
+      }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_all_docs?include_docs=true&limit=1')
+    .reply(200, response)
+
+  // test GET /db/_all_docs
+  const db = nano.db.use('db')
+  const p = await db.list({ include_docs: true, limit: 1 })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 404 - GET /db/_all_docs - db.list', async () => {
+  // mocks
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_all_docs')
+    .reply(404, response)
+
+  // test GET /db/_all_docs
+  const db = nano.db.use('db')
+  await expect(db.list()).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/document.listAsStream.test.js b/test/document.listAsStream.test.js
new file mode 100644
index 0000000..45cdf49
--- /dev/null
+++ b/test/document.listAsStream.test.js
@@ -0,0 +1,108 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should get a streamed list of documents - GET /db/_all_docs - db.listAsStream', async () => {
+  // mocks
+  const response = {
+    total_rows: 23516,
+    offset: 0,
+    rows: [
+      {
+        id: '1000501',
+        key: '1000501',
+        value: {
+          rev: '2-46dcf6bf2f8d428504f5290e591aa182'
+        }
+      },
+      {
+        id: '1000543',
+        key: '1000543',
+        value: {
+          rev: '1-3256046064953e2f0fdb376211fe78ab'
+        }
+      },
+      {
+        id: '100077',
+        key: '100077',
+        value: {
+          rev: '1-101bff1251d4bd75beb6d3c232d05a5c'
+        }
+      }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_all_docs')
+    .reply(200, response)
+
+  return new Promise((resolve, reject) => {
+    // test GET /db/_all_docs
+    const db = nano.db.use('db')
+    const s = db.listAsStream()
+    expect(typeof s).toBe('object')
+    let buffer = ''
+    s.on('data', (chunk) => {
+      buffer += chunk.toString()
+    })
+    s.on('end', () => {
+      expect(buffer).toBe(JSON.stringify(response))
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
+
+test('should get a streamed list of documents with opts- GET /db/_all_docs - db.listAsStream', async () => {
+  // mocks
+  const response = {
+    total_rows: 23516,
+    offset: 0,
+    rows: [
+      {
+        id: '1000501',
+        key: '1000501',
+        value: {
+          rev: '2-46dcf6bf2f8d428504f5290e591aa182'
+        },
+        doc: {
+          _id: '1000501',
+          _rev: '2-46dcf6bf2f8d428504f5290e591aa182',
+          a: 1,
+          b: 2
+        }
+      }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_all_docs?limit=1&include_docs=true')
+    .reply(200, response)
+
+  return new Promise((resolve, reject) => {
+    // test GET /db/_all_docs
+    const db = nano.db.use('db')
+    const s = db.listAsStream({ limit: 1, include_docs: true })
+    expect(typeof s).toBe('object')
+    let buffer = ''
+    s.on('data', (chunk) => {
+      buffer += chunk.toString()
+    })
+    s.on('end', () => {
+      expect(buffer).toBe(JSON.stringify(response))
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
diff --git a/test/nano.request.test.js b/test/nano.request.test.js
index dc23da1..045071d 100644
--- a/test/nano.request.test.js
+++ b/test/nano.request.test.js
@@ -19,13 +19,13 @@ test('check request can do GET requests - nano.request', async () => {
   // mocks
   const response = { ok: true }
   const scope = nock(COUCH_URL)
-    .get('/mydb?a=1&b=2')
+    .get('/db?a=1&b=2')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db?a=1&b=2
   const req = {
     method: 'get',
-    db: 'mydb',
+    db: 'db',
     qs: { a: 1, b: 2 }
   }
   const p = await nano.request(req)
@@ -37,13 +37,13 @@ test('check request can do POST requests - nano.request', async () => {
   // mocks
   const response = { ok: true }
   const scope = nock(COUCH_URL)
-    .post('/mydb', { _id: '1', a: true })
+    .post('/db', { _id: '1', a: true })
     .reply(200, response)
 
-  // test GET /db
+  // test POST /db
   const req = {
     method: 'post',
-    db: 'mydb',
+    db: 'db',
     body: { _id: '1', a: true }
   }
   const p = await nano.request(req)
@@ -55,13 +55,13 @@ test('check request can do PUT requests - nano.request', async () => {
   // mocks
   const response = { ok: true }
   const scope = nock(COUCH_URL)
-    .put('/mydb/1', { _id: '1', a: true })
+    .put('/db/1', { _id: '1', a: true })
     .reply(200, response)
 
-  // test GET /db
+  // test PUT /db
   const req = {
     method: 'put',
-    db: 'mydb',
+    db: 'db',
     path: '1',
     body: { _id: '1', a: true }
   }
@@ -74,14 +74,14 @@ test('check request can do DELETE requests - nano.request', async () => {
   // mocks
   const response = { ok: true }
   const scope = nock(COUCH_URL)
-    .delete('/mydb/mydoc')
+    .delete('/db/mydoc')
     .query({ rev: '1-123' })
     .reply(200, response)
 
-  // test GET /db
+  // test DELETE /db
   const req = {
     method: 'delete',
-    db: 'mydb',
+    db: 'db',
     path: 'mydoc',
     qs: { rev: '1-123' }
 
@@ -95,16 +95,190 @@ test('check request can do HEAD requests - nano.request', async () => {
   // mocks
   const response = ''
   const scope = nock(COUCH_URL)
-    .head('/mydb/mydoc')
+    .head('/db/mydoc')
     .reply(200, '')
 
-  // test GET /db
+  // test HEAD /db/mydoc
   const req = {
     method: 'head',
-    db: 'mydb',
+    db: 'db',
     path: 'mydoc'
   }
   const p = await nano.request(req)
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
 })
+
+test('check request can do GET requests with callback - nano.request', async () => {
+  // mocks
+  const response = { ok: true }
+  const scope = nock(COUCH_URL)
+    .get('/db?a=1&b=2')
+    .reply(200, response)
+
+  // test GET /db?a=1&b=2
+  const req = {
+    method: 'get',
+    db: 'db',
+    qs: { a: 1, b: 2 }
+  }
+  return new Promise((resolve, reject) => {
+    nano.request(req, (err, data) => {
+      expect(err).toBe(null)
+      expect(data).toStrictEqual(response)
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
+
+test('check request can do failed GET requests with callback - nano.request', async () => {
+  // mocks
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/a')
+    .reply(404, response)
+
+  // test GET /db/a
+  const req = {
+    method: 'get',
+    db: 'db',
+    path: 'a'
+  }
+  return new Promise((resolve, reject) => {
+    nano.request(req, (err, data) => {
+      expect(err).not.toBe(null)
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
+
+test('check request formats keys properly - nano.request', async () => {
+  // mocks
+  const response = { ok: true }
+  const arr = ['a', 'b', 'c']
+  const scope = nock(COUCH_URL)
+    .get('/db/_all_docs')
+    .query({ keys: JSON.stringify(arr) })
+    .reply(200, response)
+
+  // test GET /db/_all_docs?keys=[]
+  const req = {
+    method: 'get',
+    db: 'db',
+    path: '_all_docs',
+    qs: { keys: arr }
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request formats startkey properly - nano.request', async () => {
+  // mocks
+  const response = { ok: true }
+  const val = 'x'
+  const scope = nock(COUCH_URL)
+    .get('/db/_all_docs')
+    .query({ startkey: JSON.stringify(val) })
+    .reply(200, response)
+
+  // test GET /db/_all_docs?startkey=
+  const req = {
+    method: 'get',
+    db: 'db',
+    path: '_all_docs',
+    qs: { startkey: val }
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request formats start_key properly - nano.request', async () => {
+  // mocks
+  const response = { ok: true }
+  const val = 'x'
+  const scope = nock(COUCH_URL)
+    .get('/db/_all_docs')
+    .query({ start_key: JSON.stringify(val) })
+    .reply(200, response)
+
+  // test GET /db/_all_docs?start_key=
+  const req = {
+    method: 'get',
+    db: 'db',
+    path: '_all_docs',
+    qs: { start_key: val }
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request formats endkey properly - nano.request', async () => {
+  // mocks
+  const response = { ok: true }
+  const val = 'x'
+  const scope = nock(COUCH_URL)
+    .get('/db/_all_docs')
+    .query({ endkey: JSON.stringify(val) })
+    .reply(200, response)
+
+  // test GET /db/_all_docs?endkey=
+  const req = {
+    method: 'get',
+    db: 'db',
+    path: '_all_docs',
+    qs: { endkey: val }
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request formats end_key properly - nano.request', async () => {
+  // mocks
+  const response = { ok: true }
+  const val = 'x'
+  const scope = nock(COUCH_URL)
+    .get('/db/_all_docs')
+    .query({ end_key: JSON.stringify(val) })
+    .reply(200, response)
+
+  // test GET /db/_all_docs?end_key=
+  const req = {
+    method: 'get',
+    db: 'db',
+    path: '_all_docs',
+    qs: { end_key: val }
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request formats key properly - nano.request', async () => {
+  // mocks
+  const response = { ok: true }
+  const val = 'x'
+  const scope = nock(COUCH_URL)
+    .get('/db/_all_docs')
+    .query({ key: JSON.stringify(val) })
+    .reply(200, response)
+
+  // test GET /db/_all_docs?key=
+  const req = {
+    method: 'get',
+    db: 'db',
+    path: '_all_docs',
+    qs: { key: val }
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})


[couchdb-nano] 12/15: 100% coverage

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit 35ede5e80c9f13034617502b89cfc94b1fa22de1
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Mon Feb 10 10:44:06 2020 +0000

    100% coverage
---
 lib/logger.js                                      |   2 -
 lib/nano.js                                        |   1 +
 test/attachment.destroy.test.js                    |   4 +
 test/attachment.get.test.js                        |   5 +-
 test/attachment.getAsStream.test.js                |   5 +-
 test/attachment.insert.test.js                     |   5 +-
 test/attachment.insertAsStream.test.js             |   5 +-
 test/database.changes.test.js                      |  17 ++
 test/database.changesAsStream.test.js              |   4 +
 test/database.compact.test.js                      |  30 ++++
 test/database.create.test.js                       |   4 +
 test/database.destroy.test.js                      |   4 +
 test/database.follow.test.js                       |  26 +++
 test/database.get.test.js                          |   4 +
 test/database.list.test.js                         |   4 +
 test/database.listAsStream.test.js                 |   4 +
 test/database.replicate.test.js                    |  17 ++
 test/database.replication.disable.test.js          |  18 ++
 test/database.replication.enable.test.js           |  31 ++++
 test/database.replication.query.test.js            |  17 ++
 test/design.atomic.test.js                         |  14 ++
 test/design.createIndex.test.js                    |   4 +
 test/design.find.test.js                           |   4 +
 test/design.findAsStream.test.js                   |   4 +
 test/design.search.test.js                         |   4 +
 test/design.searchAsStream.test.js                 |   4 +
 test/design.show.test.js                           |   4 +
 test/design.view.test.js                           |   4 +
 test/design.viewAsStream.test.js                   |   4 +
 ...no.auth.test.js => design.viewWithList.test.js} |  19 +-
 test/document.bulk.test.js                         |   4 +
 test/document.copy.test.js                         |  50 ++++++
 test/document.destroy.test.js                      |   4 +
 test/document.fetch.test.js                        |   4 +
 test/document.fetchRevs.test.js                    |   4 +
 test/document.get.test.js                          |   4 +
 test/document.head.test.js                         |   4 +
 test/document.insert.test.js                       |   4 +
 test/document.list.test.js                         |   4 +
 test/document.listAsStream.test.js                 |   4 +
 test/multipart.get.test.js                         |   5 +-
 test/multipart.insert.test.js                      |   5 +-
 test/nano.auth.test.js                             |   6 +-
 test/nano.config.test.js                           |  39 ++++
 test/{nano.session.test.js => nano.logger.test.js} |  28 ++-
 test/nano.request.test.js                          | 200 ++++++++++++++++++++-
 test/nano.session.test.js                          |   4 +
 test/nano.timeout.test.js                          |  64 +++++++
 test/nano.updates.test.js                          |   4 +
 test/nano.uuids.test.js                            |  26 +++
 50 files changed, 711 insertions(+), 28 deletions(-)

diff --git a/lib/logger.js b/lib/logger.js
index 9f73271..87aa782 100644
--- a/lib/logger.js
+++ b/lib/logger.js
@@ -10,8 +10,6 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-'use strict'
-
 const debug = require('debug')('nano/logger')
 
 module.exports = function logging (cfg) {
diff --git a/lib/nano.js b/lib/nano.js
index 0ca315f..c1bcc23 100644
--- a/lib/nano.js
+++ b/lib/nano.js
@@ -469,6 +469,7 @@ module.exports = exports = function dbScope (cfg) {
   function uuids (count, callback) {
     if (typeof count === 'function') {
       callback = count
+      count = 1
     }
     count = count || 1
     return relax({ method: 'GET', path: '_uuids', qs: { count: count } }, callback)
diff --git a/test/attachment.destroy.test.js b/test/attachment.destroy.test.js
index d7b6450..0a225ff 100644
--- a/test/attachment.destroy.test.js
+++ b/test/attachment.destroy.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to destroy a document - DELETE /db/id/attname - db.attachment.destroy', async () => {
   // mocks
   const response = { ok: true, id: 'id', rev: '2-456' }
diff --git a/test/attachment.get.test.js b/test/attachment.get.test.js
index 61285d5..53638b1 100644
--- a/test/attachment.get.test.js
+++ b/test/attachment.get.test.js
@@ -14,9 +14,12 @@ const Nano = require('..')
 const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
-
 const image = Buffer.from('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', 'base64')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to get an attachment - GET /db/id/attname - db.attachment.get', async () => {
   // mocks
   const scope = nock(COUCH_URL)
diff --git a/test/attachment.getAsStream.test.js b/test/attachment.getAsStream.test.js
index c5ad8eb..4598417 100644
--- a/test/attachment.getAsStream.test.js
+++ b/test/attachment.getAsStream.test.js
@@ -14,9 +14,12 @@ const Nano = require('..')
 const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
-
 const image = Buffer.from('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', 'base64')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to get an attachment as a stream - GET /db/id/attname - db.attachment.get', async () => {
   // mocks
   const scope = nock(COUCH_URL)
diff --git a/test/attachment.insert.test.js b/test/attachment.insert.test.js
index 4f0809f..78ccad9 100644
--- a/test/attachment.insert.test.js
+++ b/test/attachment.insert.test.js
@@ -14,9 +14,12 @@ const Nano = require('..')
 const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
-
 const image = Buffer.from('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', 'base64')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to insert document attachment - PUT /db/docname/attachment - db.attachment.insert', async () => {
   // mocks
   const response = { ok: true, id: 'docname', rev: '2-456' }
diff --git a/test/attachment.insertAsStream.test.js b/test/attachment.insertAsStream.test.js
index b805028..cc6a620 100644
--- a/test/attachment.insertAsStream.test.js
+++ b/test/attachment.insertAsStream.test.js
@@ -15,7 +15,6 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 const fs = require('fs')
-
 const image = Buffer.from(''.concat(
   'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAsV',
   'BMVEUAAAD////////////////////////5ur3rEBn////////////////wDBL/',
@@ -27,6 +26,10 @@ const image = Buffer.from(''.concat(
   'vaND1c8OG4vrdOqD8YwgpDYDxRgkSm5rwu0nQVBJuMg++pLXZyr5jnc1BaH4GT',
   'LvEliY253nA3pVhQqdPt0f/erJkMGMB8xucAAAAASUVORK5CYII='), 'base64')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to insert document attachment as stream - PUT /db/docname/attachment - db.attachment.insertAsStream', async () => {
   // mocks
   const response = { ok: true, id: 'docname', rev: '2-456' }
diff --git a/test/database.changes.test.js b/test/database.changes.test.js
index d176bef..e4a7216 100644
--- a/test/database.changes.test.js
+++ b/test/database.changes.test.js
@@ -34,6 +34,10 @@ const errResponse = {
   reason: 'Database does not exist.'
 }
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to fetch the changes - GET /db/_changes - nano.db.changes', async () => {
   // mocks
   const scope = nock(COUCH_URL)
@@ -84,3 +88,16 @@ test('should detect missing parameters (callback) - nano.db.changes', async () =
     })
   })
 })
+
+test('should be able to fetch the changes from db.changes - GET /db/_changes - db.changes', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/_changes')
+    .reply(200, response)
+
+  // test GET /db/_changes
+  const db = nano.db.use('db')
+  const p = await db.changes()
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/database.changesAsStream.test.js b/test/database.changesAsStream.test.js
index adedbe8..adaf9f4 100644
--- a/test/database.changesAsStream.test.js
+++ b/test/database.changesAsStream.test.js
@@ -30,6 +30,10 @@ const response = {
   pending: 0
 }
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should get a streamed list of changes - GET /_changes - nano.db.changesAsStream', async () => {
   // mocks
   const scope = nock(COUCH_URL)
diff --git a/test/database.compact.test.js b/test/database.compact.test.js
index 7fb3006..420a5ac 100644
--- a/test/database.compact.test.js
+++ b/test/database.compact.test.js
@@ -16,6 +16,10 @@ const nano = Nano(COUCH_URL)
 const nock = require('nock')
 const response = { ok: true }
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to send compaction request - POST /db/_compact - nano.db.compact', async () => {
   // mocks
   const scope = nock(COUCH_URL)
@@ -53,3 +57,29 @@ test('should detect missing parameters (callback) - nano.db.compact', async () =
     })
   })
 })
+
+test('should be able to send compaction request from db.compact - POST /db/_compact - db.compact', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .post('/db/_compact')
+    .reply(200, response)
+
+  // test POST /db/_compact
+  const db = nano.db.use('db')
+  const p = await db.compact()
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to send compaction request with design doc from db.view.compact - POST /db/_compact - db.view.compact', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .post('/db/_compact/ddoc')
+    .reply(200, response)
+
+  // test POST /db/_compact/ddoc
+  const db = nano.db.use('db')
+  const p = await db.view.compact('ddoc')
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/database.create.test.js b/test/database.create.test.js
index ae461df..099d415 100644
--- a/test/database.create.test.js
+++ b/test/database.create.test.js
@@ -16,6 +16,10 @@ const nano = Nano(COUCH_URL)
 const nock = require('nock')
 const response = { ok: true }
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should create a database - PUT /db - nano.db.create', async () => {
   // mocks
   const scope = nock(COUCH_URL)
diff --git a/test/database.destroy.test.js b/test/database.destroy.test.js
index 659de5b..8174c7a 100644
--- a/test/database.destroy.test.js
+++ b/test/database.destroy.test.js
@@ -16,6 +16,10 @@ const nano = Nano(COUCH_URL)
 const nock = require('nock')
 const response = { ok: true }
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should destroy a database - DELETE /db - nano.db.destroy', async () => {
   // mocks
   const scope = nock(COUCH_URL)
diff --git a/test/database.follow.test.js b/test/database.follow.test.js
index 870a7bf..7218a89 100644
--- a/test/database.follow.test.js
+++ b/test/database.follow.test.js
@@ -13,6 +13,11 @@
 const Nano = require('..')
 const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+afterEach(() => {
+  nock.cleanAll()
+})
 
 test('should be able to follow changes feed - nano.db.follow', () => {
   const db = nano.db.use('db')
@@ -20,3 +25,24 @@ test('should be able to follow changes feed - nano.db.follow', () => {
   expect(feed.constructor.name).toBe('Feed')
   // no need to test the changes feed follower - it has its own tests
 })
+
+test('should be able to follow changes feed (callback) - nano.db.follow', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db')
+    .reply(404, {
+      error: 'not_found',
+      reason: 'Database does not exist.'
+    })
+
+  return new Promise((resolve, reject) => {
+    const db = nano.db.use('db')
+    const feed = db.follow({ since: 'now' }, (err, data) => {
+      expect(err).not.toBeNull()
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+    expect(feed.constructor.name).toBe('Feed')
+  })
+  // no need to test the changes feed follower - it has its own tests
+})
diff --git a/test/database.get.test.js b/test/database.get.test.js
index ae9e421..454940d 100644
--- a/test/database.get.test.js
+++ b/test/database.get.test.js
@@ -41,6 +41,10 @@ const response = {
   instance_start_time: '0'
 }
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to fetch the database info - GET /db - nano.db.get', async () => {
   // mocks
   const scope = nock(COUCH_URL)
diff --git a/test/database.list.test.js b/test/database.list.test.js
index f83dc74..e07c4ea 100644
--- a/test/database.list.test.js
+++ b/test/database.list.test.js
@@ -16,6 +16,10 @@ const nano = Nano(COUCH_URL)
 const nock = require('nock')
 const response = ['rita', 'sue', 'bob']
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be to get list of databases - GET /_all_dbs - nano.db.list', async () => {
   // mocks
   const scope = nock(COUCH_URL)
diff --git a/test/database.listAsStream.test.js b/test/database.listAsStream.test.js
index 25b6ed2..f887dd6 100644
--- a/test/database.listAsStream.test.js
+++ b/test/database.listAsStream.test.js
@@ -16,6 +16,10 @@ const nano = Nano(COUCH_URL)
 const nock = require('nock')
 const response = ['rita', 'sue', 'bob']
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should get a streamed list of databases - GET /_all_dbs - nano.db.listAsStream', async () => {
   // mocks
   const scope = nock(COUCH_URL)
diff --git a/test/database.replicate.test.js b/test/database.replicate.test.js
index 19290d7..a133cf8 100644
--- a/test/database.replicate.test.js
+++ b/test/database.replicate.test.js
@@ -22,6 +22,10 @@ const response = {
   source_last_seq: 28
 }
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to send replication request with local database names- POST /_replicate - nano.db.replicate', async () => {
   // mocks
   const scope = nock(COUCH_URL)
@@ -77,3 +81,16 @@ test('should detect missing parameters (callback) - nano.db.replicate', async ()
     })
   })
 })
+
+test('should be replicate from db.replicate - POST /_replicate - db.replicate', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .post('/_replicate', { source: COUCH_URL + '/source', target: COUCH_URL + '/target' })
+    .reply(200, response)
+
+  // test POST /_replicate
+  const db = nano.db.use('source')
+  const p = await db.replicate('target')
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/database.replication.disable.test.js b/test/database.replication.disable.test.js
index 51fff73..da76cfc 100644
--- a/test/database.replication.disable.test.js
+++ b/test/database.replication.disable.test.js
@@ -20,6 +20,10 @@ const errResponse = {
   reason: 'missing'
 }
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to delete a replication - DELETE /_replicator - nano.db.replication.disable', async () => {
   // mocks
   const scope = nock(COUCH_URL)
@@ -59,3 +63,17 @@ test('should detect missing parameters (callback) - nano.db.replication.disable'
     })
   })
 })
+
+test('should be able to delete a replication from db.replication.disable - DELETE /_replicator - db.replication.disable', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .delete('/_replicator/rep1')
+    .query({ rev: '1-456' })
+    .reply(200, response)
+
+  // test DELETE /_replicator/id
+  const db = nano.db.use('db')
+  const p = await db.replication.disable('rep1', '1-456')
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/database.replication.enable.test.js b/test/database.replication.enable.test.js
index bb74f9a..7fda367 100644
--- a/test/database.replication.enable.test.js
+++ b/test/database.replication.enable.test.js
@@ -16,6 +16,10 @@ const nano = Nano(COUCH_URL)
 const nock = require('nock')
 const response = { ok: true, id: 'abc', rev: '1-123' }
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to send replication request with local database names - POST /_replicator - nano.db.replication.enable', async () => {
   // mocks
   const scope = nock(COUCH_URL)
@@ -42,6 +46,20 @@ test('should be able to send replication request with URLs - POST /_replicator -
   expect(scope.isDone()).toBe(true)
 })
 
+test('should be able to send replication request with objects - POST /_replicator - nano.db.replication.enable', async () => {
+  // mocks
+  const source = { config: { url: 'http://mydomain1.com', db: 'source' } }
+  const target = { config: { url: 'https://mydomain2.com', db: 'target' } }
+  const scope = nock(COUCH_URL)
+    .post('/_replicator', { source: 'http://mydomain1.com/source', target: 'https://mydomain2.com/target' })
+    .reply(200, response)
+
+  // test POST /_replicator
+  const p = await nano.db.replication.enable(source, target)
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
 test('should be able to supply additional parameters - POST /_replicator - nano.db.replication.enable', async () => {
   // mocks
   const source = 'http://mydomain1.com/source'
@@ -72,3 +90,16 @@ test('should detect missing parameters (callback) - nano.db.replication.enable',
     })
   })
 })
+
+test('should be able to send replication request db.replication.enable - POST /_replicator - db.replication.enable', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .post('/_replicator', { source: COUCH_URL + '/source', target: COUCH_URL + '/target' })
+    .reply(200, response)
+
+  // test POST /_replicator
+  const db = nano.db.use('source')
+  const p = await db.replication.enable('target')
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/database.replication.query.test.js b/test/database.replication.query.test.js
index deff494..368511a 100644
--- a/test/database.replication.query.test.js
+++ b/test/database.replication.query.test.js
@@ -40,6 +40,10 @@ const errResponse = {
   reason: 'missing'
 }
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to query a replication - GET /_replicator/id - nano.db.replication.query', async () => {
   // mocks
   const scope = nock(COUCH_URL)
@@ -90,3 +94,16 @@ test('should detect missing parameters (callback) - nano.db.replication.query',
     })
   })
 })
+
+test('should be able to query a replication from db.replication.quey - GET /_replicator/id - db.replication.query', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/_replicator/rep1')
+    .reply(200, response)
+
+  // test GET /_replicator/id
+  const db = nano.db.use('db')
+  const p = await db.replication.query('rep1')
+  expect(p).toEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/design.atomic.test.js b/test/design.atomic.test.js
index b0904aa..0382943 100644
--- a/test/design.atomic.test.js
+++ b/test/design.atomic.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to use an update function - PUT /db/_design/ddoc/_update/updatename/docid - db.atomic', async () => {
   const updateFunction = function (doc, req) {
     if (doc) {
@@ -92,3 +96,13 @@ test('should detect missing parameters (callback) - db.update', async () => {
     })
   })
 })
+
+test('should detect missing parameters (callback no body) - db.update', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.atomic('', '', '', (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/design.createIndex.test.js b/test/design.createIndex.test.js
index 88e0224..bd7bdcc 100644
--- a/test/design.createIndex.test.js
+++ b/test/design.createIndex.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to create an index - POST /db/_index - db.index', async () => {
   // mocks
   const indexDef = {
diff --git a/test/design.find.test.js b/test/design.find.test.js
index b4aaba4..b0990f3 100644
--- a/test/design.find.test.js
+++ b/test/design.find.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to query an index - POST /db/_find - db.find', async () => {
   // mocks
   const query = {
diff --git a/test/design.findAsStream.test.js b/test/design.findAsStream.test.js
index b330779..cb7f298 100644
--- a/test/design.findAsStream.test.js
+++ b/test/design.findAsStream.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to query an index as a stream- POST /db/_find - db.findAsStream', async () => {
   // mocks
   const query = {
diff --git a/test/design.search.test.js b/test/design.search.test.js
index 8a5c37c..e7e8e42 100644
--- a/test/design.search.test.js
+++ b/test/design.search.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to access a search index - POST /db/_design/ddoc/_search/searchname - db.search', async () => {
   // mocks
   const response = {
diff --git a/test/design.searchAsStream.test.js b/test/design.searchAsStream.test.js
index d86f35d..565d604 100644
--- a/test/design.searchAsStream.test.js
+++ b/test/design.searchAsStream.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to access a search index as a stream - POST /db/_design/ddoc/_search/searchname - db.searchAsStream', async () => {
   // mocks
   const response = {
diff --git a/test/design.show.test.js b/test/design.show.test.js
index 4fc6278..1097e89 100644
--- a/test/design.show.test.js
+++ b/test/design.show.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to use a show function - GET /db/_design/ddoc/_show/showname/docid - db.show', async () => {
   const showFunction = function (doc, req) {
     return 'Hello, world!'
diff --git a/test/design.view.test.js b/test/design.view.test.js
index b53074d..7a62626 100644
--- a/test/design.view.test.js
+++ b/test/design.view.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to access a MapReduce view - GET /db/_design/ddoc/_view/viewname - db.view', async () => {
   // mocks
   const response = {
diff --git a/test/design.viewAsStream.test.js b/test/design.viewAsStream.test.js
index e332897..2ec4b0a 100644
--- a/test/design.viewAsStream.test.js
+++ b/test/design.viewAsStream.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to access a MapReduce view as a stream - GET /db/_design/ddoc/_view/viewname - db.viewAsStream', async () => {
   // mocks
   const response = {
diff --git a/test/nano.auth.test.js b/test/design.viewWithList.test.js
similarity index 64%
copy from test/nano.auth.test.js
copy to test/design.viewWithList.test.js
index f952887..92bb7f6 100644
--- a/test/nano.auth.test.js
+++ b/test/design.viewWithList.test.js
@@ -15,17 +15,20 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
-test('should be able to authenticate - POST /_session - nano.auth', async () => {
+afterEach(() => {
+  nock.cleanAll()
+})
+
+test('should be able to access a MapReduce view with a list - GET /db/_design/ddoc/_list/listname/viewname - db.viewWithList', async () => {
   // mocks
-  const username = 'u'
-  const password = 'p'
-  const response = { ok: true, name: 'admin', roles: ['_admin', 'admin'] }
+  const response = '1,2,3\n4,5,6\n7,8,9\n'
   const scope = nock(COUCH_URL)
-    .post('/_session', 'name=u&password=p', { 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' })
-    .reply(200, response)
+    .get('/db/_design/ddoc/_list/listname/viewname')
+    .reply(200, response, { 'Content-type': 'text/csv' })
 
-  // test GET /_uuids
-  const p = await nano.auth(username, password)
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.viewWithList('ddoc', 'viewname', 'listname')
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
 })
diff --git a/test/document.bulk.test.js b/test/document.bulk.test.js
index 672df9d..a3cd304 100644
--- a/test/document.bulk.test.js
+++ b/test/document.bulk.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to insert documents in bulk - POST /db/_bulk_docs - db.bulk', async () => {
   // mocks
   const docs = [{ a: 1, b: 2 }, { a: 2, b: 3 }, { a: 3, b: 4 }]
diff --git a/test/document.copy.test.js b/test/document.copy.test.js
index 9904313..e5eb7d7 100644
--- a/test/document.copy.test.js
+++ b/test/document.copy.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to copy a document - db.copy', async () => {
   // mocks
   const response = { ok: true, id: 'rabbit2', rev: '1-123' }
@@ -55,6 +59,52 @@ test('should be able to copy a document in overwrite mode - db.copy', async () =
   expect(scope.isDone()).toBe(true)
 })
 
+test('should be able to handle an error  in overwrite mode # 1 - db.copy', async () => {
+  // mocks
+  const response = 'Internal server error'
+  const scope = nock(COUCH_URL)
+    .head('/db/rabbit2')
+    .reply(200, '', { ETag: '1-123' })
+    .intercept('/db/rabbit1', 'COPY')
+    .reply(500, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  await expect(db.copy('rabbit1', 'rabbit2', { overwrite: true })).rejects.toThrow(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle an error  in overwrite mode # 2 - db.copy', async () => {
+  // mocks
+  const response = 'Internal server error'
+  const scope = nock(COUCH_URL)
+    .head('/db/rabbit2')
+    .reply(500, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  await expect(db.copy('rabbit1', 'rabbit2', { overwrite: true })).rejects.toThrow(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle an error  in overwrite mode # 3 - db.copy', async () => {
+  // mocks
+  const response = 'Internal server error'
+  const scope = nock(COUCH_URL)
+    .head('/db/rabbit2')
+    .reply(500, response)
+
+  // test GET /db
+  return new Promise((resolve, reject) => {
+    const db = nano.db.use('db')
+    db.copy('rabbit1', 'rabbit2', { overwrite: true }, (err, data) => {
+      expect(err).not.toBeNull()
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
+
 test('should be able to copy a document in overwrite mode missing target - db.copy', async () => {
   // mocks
   const response = { ok: true, id: 'rabbit2', rev: '1-123' }
diff --git a/test/document.destroy.test.js b/test/document.destroy.test.js
index 8c50f12..2958d27 100644
--- a/test/document.destroy.test.js
+++ b/test/document.destroy.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to destroy a document - DELETE /db/id - db.destroy', async () => {
   // mocks
   const response = { ok: true, id: 'id', rev: '2-456' }
diff --git a/test/document.fetch.test.js b/test/document.fetch.test.js
index c2056f9..bde243b 100644
--- a/test/document.fetch.test.js
+++ b/test/document.fetch.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to fetch a list of documents - POST /db/_all_docs - db.fetch', async () => {
   // mocks
   const keys = ['1000501', '1000543', '100077']
diff --git a/test/document.fetchRevs.test.js b/test/document.fetchRevs.test.js
index 4cf610d..aa6f3fa 100644
--- a/test/document.fetchRevs.test.js
+++ b/test/document.fetchRevs.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to fetch a list of document revisions - POST /db/_all_docs - db.fetchRevs', async () => {
   // mocks
   const keys = ['1000501', '1000543', '100077']
diff --git a/test/document.get.test.js b/test/document.get.test.js
index 001fd77..109b7cb 100644
--- a/test/document.get.test.js
+++ b/test/document.get.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to get a document - GET /db/id - db.get', async () => {
   // mocks
   const response = { _id: 'id', rev: '1-123', a: 1, b: 'two', c: true }
diff --git a/test/document.head.test.js b/test/document.head.test.js
index 094b41a..0dfd9f1 100644
--- a/test/document.head.test.js
+++ b/test/document.head.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to head a document - HEAD /db/id - db.head', async () => {
   // mocks
   const scope = nock(COUCH_URL)
diff --git a/test/document.insert.test.js b/test/document.insert.test.js
index 812775b..60f1696 100644
--- a/test/document.insert.test.js
+++ b/test/document.insert.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to insert document - POST /db - db.insert', async () => {
   // mocks
   const doc = { a: 1, b: 2 }
diff --git a/test/document.list.test.js b/test/document.list.test.js
index 3e0705f..53fc245 100644
--- a/test/document.list.test.js
+++ b/test/document.list.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to get a list of documents - GET /db/_all_docs - db.list', async () => {
   // mocks
   const response = {
diff --git a/test/document.listAsStream.test.js b/test/document.listAsStream.test.js
index 45cdf49..c4a6c03 100644
--- a/test/document.listAsStream.test.js
+++ b/test/document.listAsStream.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should get a streamed list of documents - GET /db/_all_docs - db.listAsStream', async () => {
   // mocks
   const response = {
diff --git a/test/multipart.get.test.js b/test/multipart.get.test.js
index 6383367..2db92eb 100644
--- a/test/multipart.get.test.js
+++ b/test/multipart.get.test.js
@@ -14,7 +14,6 @@ const Nano = require('..')
 const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
-
 const multipartResponse = ''.concat(
   '--e89b3e29388aef23453450d10e5aaed0',
   'Content-Type: application/json',
@@ -33,6 +32,10 @@ const multipartResponse = ''.concat(
   '',
   '--e89b3e29388aef23453450d10e5aaed0--')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to fetch a document with attachments - multipart GET /db - db.multipart.get', async () => {
   // mocks
   const scope = nock(COUCH_URL, { reqheaders: { accept: 'multipart/related' } })
diff --git a/test/multipart.insert.test.js b/test/multipart.insert.test.js
index 2982bc5..43f46b1 100644
--- a/test/multipart.insert.test.js
+++ b/test/multipart.insert.test.js
@@ -14,7 +14,6 @@ const Nano = require('..')
 const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
-
 const image1 = Buffer.from(''.concat(
   'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAsV',
   'BMVEUAAAD////////////////////////5ur3rEBn////////////////wDBL/',
@@ -47,6 +46,10 @@ const doc = {
   }
 }
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to insert a document with attachments #1 - multipart POST /db - db.multipart.insert', async () => {
   // mocks
   const response = { ok: true, id: '8s8g8h8h9', rev: '1-123' }
diff --git a/test/nano.auth.test.js b/test/nano.auth.test.js
index f952887..fe6af9b 100644
--- a/test/nano.auth.test.js
+++ b/test/nano.auth.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to authenticate - POST /_session - nano.auth', async () => {
   // mocks
   const username = 'u'
@@ -22,7 +26,7 @@ test('should be able to authenticate - POST /_session - nano.auth', async () =>
   const response = { ok: true, name: 'admin', roles: ['_admin', 'admin'] }
   const scope = nock(COUCH_URL)
     .post('/_session', 'name=u&password=p', { 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' })
-    .reply(200, response)
+    .reply(200, response, { 'Set-Cookie': 'AuthSession=YWRtaW46NUU0MTFBMDE6stHsxYnlDy4mYxwZEcnXHn4fm5w; Version=1; Expires=Mon, 10-Feb-2050 09:03:21 GMT; Max-Age=600; Path=/; HttpOnly' })
 
   // test GET /_uuids
   const p = await nano.auth(username, password)
diff --git a/test/nano.config.test.js b/test/nano.config.test.js
index 72de445..16c02b5 100644
--- a/test/nano.config.test.js
+++ b/test/nano.config.test.js
@@ -11,6 +11,7 @@
 // the License.
 
 const Nano = require('..')
+const assert = require('assert')
 
 test('should be able to supply HTTP url - nano.config', () => {
   const HTTP_URL = 'http://localhost:5984'
@@ -61,3 +62,41 @@ test('should be able to supply logging function - nano.config', () => {
   expect(nano.config.url).toBe(HTTPS_URL)
   expect(typeof nano.config.log).toBe('function')
 })
+
+test('should be able to handle missing URL - nano.config', () => {
+  try {
+    Nano()
+  } catch (e) {
+    expect(e instanceof assert.AssertionError)
+    expect(e.message).toBe('You must specify the endpoint url when invoking this module')
+  }
+})
+
+test('should be able to handle invalid URL #1 - nano.config', () => {
+  const INVALID_URL = 'badurl.com'
+  try {
+    Nano(INVALID_URL)
+  } catch (e) {
+    expect(e instanceof assert.AssertionError)
+    expect(e.message).toBe('url is not valid')
+  }
+})
+
+test('should be able to handle invalid URL #2 - nano.config', () => {
+  const INVALID_URL = 'badurl.com'
+  try {
+    Nano({ url: INVALID_URL })
+  } catch (e) {
+    expect(e instanceof assert.AssertionError)
+    expect(e.message).toBe('url is not valid')
+  }
+})
+
+test('exercise the parseUrl feature for proxies etc - nano.config', () => {
+  const HTTP_URL = 'http://localhost:5984/prefix'
+  const nano = Nano({
+    url: HTTP_URL,
+    parseUrl: false
+  })
+  expect(nano.config.url).toBe(HTTP_URL)
+})
diff --git a/test/nano.session.test.js b/test/nano.logger.test.js
similarity index 62%
copy from test/nano.session.test.js
copy to test/nano.logger.test.js
index ca2eb97..a6ae009 100644
--- a/test/nano.session.test.js
+++ b/test/nano.logger.test.js
@@ -10,20 +10,34 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
+const nock = require('nock')
 const Nano = require('..')
 const COUCH_URL = 'http://localhost:5984'
-const nano = Nano(COUCH_URL)
-const nock = require('nock')
 
-test('should be able to check your session - GET /_session - nano.auth', async () => {
+afterEach(() => {
+  nock.cleanAll()
+})
+
+test('should be able to log output with user-defined function', async () => {
+  // setup Nano with custom logger
+  const logs = []
+  const nano = Nano({
+    url: COUCH_URL,
+    log: (data) => {
+      logs.push(data)
+    }
+  })
+
   // mocks
-  const response = { ok: true, userCtx: { name: null, roles: [] }, info: { authentication_db: '_users', authentication_handlers: ['cookie', 'default'] } }
+  const response = { _id: 'id', rev: '1-123', a: 1, b: 'two', c: true }
   const scope = nock(COUCH_URL)
-    .get('/_session')
+    .get('/db/id')
     .reply(200, response)
 
-  // test GET /_uuids
-  const p = await nano.session()
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.get('id')
   expect(p).toStrictEqual(response)
+  expect(logs.length).toBe(2)
   expect(scope.isDone()).toBe(true)
 })
diff --git a/test/nano.request.test.js b/test/nano.request.test.js
index 045071d..40b0e86 100644
--- a/test/nano.request.test.js
+++ b/test/nano.request.test.js
@@ -11,10 +11,14 @@
 // the License.
 
 const Nano = require('..')
-const COUCH_URL = 'http://localhost:5984'
-const nano = Nano(COUCH_URL)
+const COUCH_URL = 'http://localhost:59804'
+const nano = Nano({ url: COUCH_URL, cookie: true })
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('check request can do GET requests - nano.request', async () => {
   // mocks
   const response = { ok: true }
@@ -36,15 +40,16 @@ test('check request can do GET requests - nano.request', async () => {
 test('check request can do POST requests - nano.request', async () => {
   // mocks
   const response = { ok: true }
+  const doc = { _id: '_design/myddoc', a: true }
   const scope = nock(COUCH_URL)
-    .post('/db', { _id: '1', a: true })
+    .post('/db', doc)
     .reply(200, response)
 
   // test POST /db
   const req = {
     method: 'post',
     db: 'db',
-    body: { _id: '1', a: true }
+    body: doc
   }
   const p = await nano.request(req)
   expect(p).toStrictEqual(response)
@@ -282,3 +287,190 @@ test('check request formats key properly - nano.request', async () => {
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
 })
+
+test('check request can do 500s - nano.request', async () => {
+  // mocks
+  const errorMessage = 'Internal server error'
+  const scope = nock(COUCH_URL)
+    .get('/db?a=1&b=2')
+    .reply(500, errorMessage)
+
+  // test GET /db?a=1&b=2
+  const req = {
+    method: 'get',
+    db: 'db',
+    qs: { a: 1, b: 2 }
+  }
+  await expect(nano.request(req)).rejects.toThrow(errorMessage)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request can do 500s with callback - nano.request', async () => {
+  // mocks
+  const errorMessage = 'Internal server error'
+  const scope = nock(COUCH_URL)
+    .get('/db?a=1&b=2')
+    .reply(500, errorMessage)
+
+  // test GET /db?a=1&b=2
+  const req = {
+    method: 'get',
+    db: 'db',
+    qs: { a: 1, b: 2 }
+  }
+
+  return new Promise((resolve, reject) => {
+    nano.request(req, (err, data) => {
+      expect(err).not.toBe(null)
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
+
+test('check request handle empty parameter list - nano.request', async () => {
+  // mocks
+  const response = {
+    couchdb: 'Welcome',
+    version: '2.3.1',
+    git_sha: 'c298091a4',
+    uuid: '865f5b0c258c5749012ce7807b4b0622',
+    features: [
+      'pluggable-storage-engines',
+      'scheduler'
+    ],
+    vendor: {
+      name: 'The Apache Software Foundation'
+    }
+  }
+  const scope = nock(COUCH_URL)
+    .get('/')
+    .reply(200, response)
+
+  // test GET /
+  const p = await nano.request()
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request handle empty parameter list (callback) - nano.request', async () => {
+  // mocks
+  const response = {
+    couchdb: 'Welcome',
+    version: '2.3.1',
+    git_sha: 'c298091a4',
+    uuid: '865f5b0c258c5749012ce7807b4b0622',
+    features: [
+      'pluggable-storage-engines',
+      'scheduler'
+    ],
+    vendor: {
+      name: 'The Apache Software Foundation'
+    }
+  }
+  const scope = nock(COUCH_URL)
+    .get('/')
+    .reply(200, response)
+
+  // test GET /
+  return new Promise((resolve, reject) => {
+    nano.request((err, data) => {
+      expect(err).toBeNull()
+      expect(data).toStrictEqual(response)
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
+
+test('check request handles single string parameter - nano.request', async () => {
+  // mocks
+  const response = {
+    db_name: 'db',
+    purge_seq: '0-8KhNZEiqhyjKAgBm5Rxs',
+    update_seq: '23523-gUFPHo-6PQIAJ_EdrA',
+    sizes: {
+      file: 18215344,
+      external: 5099714,
+      active: 6727596
+    }
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db')
+    .reply(200, response)
+
+  // test GET /
+  const p = await nano.request('db')
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request handles cookies - nano.request', async () => {
+  // mocks
+  const username = 'u'
+  const password = 'p'
+  const response = { ok: true, name: 'admin', roles: ['_admin', 'admin'] }
+  const scope = nock(COUCH_URL)
+    .post('/_session', 'name=u&password=p', { 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' })
+    .reply(200, response, { 'Set-Cookie': 'AuthSession=YWRtaW46NUU0MTFBMDE6stHsxYnlDy4mYxwZEcnXHn4fm5w; Version=1; Expires=Mon, 10-Feb-2050 09:03:21 GMT; Max-Age=600; Path=/; HttpOnly' })
+
+  // test GET /_uuids
+  const req = {
+    method: 'post',
+    path: '_session',
+    form: {
+      name: username,
+      password: password
+    },
+    jar: true
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request can do GET a doc - nano.request', async () => {
+  // mocks
+  const response = { _id: 'docname/design', _rev: '1-123', ok: true }
+  const scope = nock(COUCH_URL)
+    .get('/db/_design/docname?a=1&b=2')
+    .reply(200, response)
+
+  // test GET /db?a=1&b=2
+  const req = {
+    method: 'get',
+    db: 'db',
+    doc: '_design/docname',
+    qs: { a: 1, b: 2 }
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('check request doesn\'t mangle bodies containing functions - nano.request', async () => {
+  // mocks
+  const emit = () => { }
+  const doc = {
+    a: 1,
+    views: {
+      bytime: {
+        map: function () { emit(doc.ts, true) }
+      }
+    }
+  }
+  const response = { id: 'jfjfjf', rev: '1-123', ok: true }
+  const scope = nock(COUCH_URL)
+    .post('/db', { a: 1, views: { bytime: { map: 'function () {\n          emit(doc.ts, true);\n        }' } } })
+    .reply(200, response)
+
+  // test GET /db?a=1&b=2
+  const req = {
+    method: 'post',
+    db: 'db',
+    body: doc
+  }
+  const p = await nano.request(req)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
diff --git a/test/nano.session.test.js b/test/nano.session.test.js
index ca2eb97..2c0179a 100644
--- a/test/nano.session.test.js
+++ b/test/nano.session.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to check your session - GET /_session - nano.auth', async () => {
   // mocks
   const response = { ok: true, userCtx: { name: null, roles: [] }, info: { authentication_db: '_users', authentication_handlers: ['cookie', 'default'] } }
diff --git a/test/nano.timeout.test.js b/test/nano.timeout.test.js
new file mode 100644
index 0000000..2e7d2b8
--- /dev/null
+++ b/test/nano.timeout.test.js
@@ -0,0 +1,64 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:59804'
+const nano = Nano({
+  url: COUCH_URL,
+  requestDefaults: {
+    timeout: 500
+  }
+})
+const nock = require('nock')
+
+afterEach(() => {
+  nock.cleanAll()
+})
+
+test('check requests timeout - nano.request', async () => {
+  // mocks
+  const response = { ok: true }
+  nock(COUCH_URL)
+    .get('/db?a=1&b=2')
+    .delay(1000)
+    .reply(200, response)
+
+  // test GET /db?a=1&b=2
+  const req = {
+    method: 'get',
+    db: 'db',
+    qs: { a: 1, b: 2 }
+  }
+  await expect(nano.request(req)).rejects.toThrow('error happened in your connection')
+})
+
+test('check request timeout (callback) - nano.request', async () => {
+  // mocks
+  const response = { ok: true }
+  nock(COUCH_URL)
+    .get('/db?a=1&b=2')
+    .delay(1000)
+    .reply(200, response)
+
+  // test GET /db?a=1&b=2
+  const req = {
+    method: 'get',
+    db: 'db',
+    qs: { a: 1, b: 2 }
+  }
+  return new Promise((resolve, reject) => {
+    nano.request(req, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/nano.updates.test.js b/test/nano.updates.test.js
index 127041e..23c9245 100644
--- a/test/nano.updates.test.js
+++ b/test/nano.updates.test.js
@@ -39,6 +39,10 @@ const errResponse = {
   reason: 'Database does not exist.'
 }
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to fetch db updates - GET /_db_updates - nano.updates', async () => {
   // mocks
   const scope = nock(COUCH_URL)
diff --git a/test/nano.uuids.test.js b/test/nano.uuids.test.js
index ea004f1..315aed9 100644
--- a/test/nano.uuids.test.js
+++ b/test/nano.uuids.test.js
@@ -15,6 +15,10 @@ const COUCH_URL = 'http://localhost:5984'
 const nano = Nano(COUCH_URL)
 const nock = require('nock')
 
+afterEach(() => {
+  nock.cleanAll()
+})
+
 test('should be able to fetch uuids - GET /_uuids - nano.uuids', async () => {
   // mocks
   const response = {
@@ -50,3 +54,25 @@ test('should be able to fetch more uuids - GET /_uuids?count=3 - nano.uuids', as
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
 })
+
+test('should be able to fetch uuids callback - GET /_uuids - nano.uuids', async () => {
+  // mocks
+  const response = {
+    uuids: [
+      'c42ddf1272c7d05b2dc45b696200145f'
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/_uuids?count=1')
+    .reply(200, response)
+
+  // test GET /_uuids
+  return new Promise((resolve, reject) => {
+    nano.uuids((err, data) => {
+      expect(err).toBe(null)
+      expect(data).toStrictEqual(response)
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})


[couchdb-nano] 14/15: tidy up

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit a7ba7590da2af81e8dddabe543dc7e205f85d60f
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Wed Feb 12 09:05:24 2020 +0000

    tidy up
---
 test/attachment.destroy.test.js           |  10 +--
 test/attachment.getAsStream.test.js       |   2 +-
 test/database.compact.test.js             |   4 +-
 test/database.get.test.js                 |   2 +-
 test/database.list.test.js                |   2 +-
 test/database.replicate.test.js           |   2 +-
 test/database.replication.disable.test.js |   6 +-
 test/design.atomic.test.js                |   6 +-
 test/design.createIndex.test.js           |   4 +-
 test/design.search.test.js                |   4 +-
 test/design.show.test.js                  |   4 +-
 test/design.view.test.js                  |  10 +--
 test/design.viewWithList.test.js          |   2 +-
 test/document.copy.test.js                |   4 +-
 test/document.fetch.test.js               |   2 +-
 test/document.fetchRevs.test.js           |   2 +-
 test/document.get.test.js                 |   8 +--
 test/document.head.test.js                |   6 +-
 test/multipart.get.test.js                |   6 +-
 test/multipart.insert.test.js             |  10 +--
 test/nano.auth.test.js                    |   2 +-
 test/nano.logger.test.js                  |   2 +-
 test/nano.request.test.js                 |   2 +-
 test/nano.session.test.js                 |   2 +-
 test/nano.updates.test.js                 |   6 +-
 test/notnocked.test.js                    | 111 ++++++++++++++++++++++++++++++
 test/partition.find.test.js               |   4 +-
 test/partition.findAsStream.test.js       |   2 +-
 test/partition.info.test.js               |   6 +-
 test/partition.list.test.js               |   8 +--
 test/partition.listAsStream.test.js       |   4 +-
 test/partition.search.test.js             |   6 +-
 test/partition.searchAsStream.test.js     |   2 +-
 test/partition.view.test.js               |   6 +-
 test/partition.viewAsStream.test.js       |   4 +-
 35 files changed, 187 insertions(+), 76 deletions(-)

diff --git a/test/attachment.destroy.test.js b/test/attachment.destroy.test.js
index 0a225ff..64d244f 100644
--- a/test/attachment.destroy.test.js
+++ b/test/attachment.destroy.test.js
@@ -19,21 +19,21 @@ afterEach(() => {
   nock.cleanAll()
 })
 
-test('should be able to destroy a document - DELETE /db/id/attname - db.attachment.destroy', async () => {
+test('should be able to destroy an attachment - DELETE /db/id/attname - db.attachment.destroy', async () => {
   // mocks
   const response = { ok: true, id: 'id', rev: '2-456' }
   const scope = nock(COUCH_URL)
     .delete('/db/id/logo.jpg?rev=1-123')
     .reply(200, response)
 
-  // test DELETE /db/id
+  // test DELETE DELETE /db/id/attname
   const db = nano.db.use('db')
   const p = await db.attachment.destroy('id', 'logo.jpg', { rev: '1-123' })
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
 })
 
-test('should be able to handle 409 conflicts - DELETE /db/id - db.attachment.destroy', async () => {
+test('should be able to handle 409 conflicts - DELETE /db/id/attname- db.attachment.destroy', async () => {
   // mocks
   const response = {
     error: 'conflict',
@@ -43,7 +43,7 @@ test('should be able to handle 409 conflicts - DELETE /db/id - db.attachment.des
     .delete('/db/id/logo.jpg?rev=1-123')
     .reply(409, response)
 
-  // test DELETE /db/id
+  // test DELETE /db/id/attname
   const db = nano.db.use('db')
   await expect(db.attachment.destroy('id', 'logo.jpg', { rev: '1-123' })).rejects.toThrow('Document update conflict.')
   expect(scope.isDone()).toBe(true)
@@ -57,7 +57,7 @@ test('should detect missing doc id - db.attachment.destroy', async () => {
   await expect(db.attachment.destroy('', 'logo.jpg')).rejects.toThrow('Invalid parameters')
 })
 
-test('should detect missing parameters (callback) - db.attachment.get', async () => {
+test('should detect missing parameters (callback) - db.attachment.destroy', async () => {
   const db = nano.db.use('db')
   return new Promise((resolve, reject) => {
     db.attachment.destroy(undefined, undefined, undefined, (err, data) => {
diff --git a/test/attachment.getAsStream.test.js b/test/attachment.getAsStream.test.js
index 4598417..f184655 100644
--- a/test/attachment.getAsStream.test.js
+++ b/test/attachment.getAsStream.test.js
@@ -20,7 +20,7 @@ afterEach(() => {
   nock.cleanAll()
 })
 
-test('should be able to get an attachment as a stream - GET /db/id/attname - db.attachment.get', async () => {
+test('should be able to get an attachment as a stream - GET /db/id/attname - db.attachment.getAsStream', async () => {
   // mocks
   const scope = nock(COUCH_URL)
     .get('/db/id/transparent.gif')
diff --git a/test/database.compact.test.js b/test/database.compact.test.js
index 420a5ac..c046af9 100644
--- a/test/database.compact.test.js
+++ b/test/database.compact.test.js
@@ -32,7 +32,7 @@ test('should be able to send compaction request - POST /db/_compact - nano.db.co
   expect(scope.isDone()).toBe(true)
 })
 
-test('should be able to send compaction request with design doc - POST /db/_compact - nano.db.compact', async () => {
+test('should be able to send compaction request with design doc - POST /db/_compact/ddoc - nano.db.compact', async () => {
   // mocks
   const scope = nock(COUCH_URL)
     .post('/db/_compact/ddoc')
@@ -71,7 +71,7 @@ test('should be able to send compaction request from db.compact - POST /db/_comp
   expect(scope.isDone()).toBe(true)
 })
 
-test('should be able to send compaction request with design doc from db.view.compact - POST /db/_compact - db.view.compact', async () => {
+test('should be able to send compaction request with design doc from db.view.compact - POST /db/_compact/ddoc - db.view.compact', async () => {
   // mocks
   const scope = nock(COUCH_URL)
     .post('/db/_compact/ddoc')
diff --git a/test/database.get.test.js b/test/database.get.test.js
index 454940d..6cbf478 100644
--- a/test/database.get.test.js
+++ b/test/database.get.test.js
@@ -74,7 +74,7 @@ test('should be able to fetch the database info - GET /db - db.info', async () =
   expect(scope.isDone()).toBe(true)
 })
 
-test('should handle missing database - PUT /db - nano.db.create', async () => {
+test('should handle missing database - GET /db - nano.db.get', async () => {
   // mocks
   const scope = nock(COUCH_URL)
     .get('/db')
diff --git a/test/database.list.test.js b/test/database.list.test.js
index e07c4ea..abe6e10 100644
--- a/test/database.list.test.js
+++ b/test/database.list.test.js
@@ -26,7 +26,7 @@ test('should be to get list of databases - GET /_all_dbs - nano.db.list', async
     .get('/_all_dbs')
     .reply(200, response)
 
-  // test GET /db/_all_dbs
+  // test GET /_all_dbs
   const p = await nano.db.list()
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
diff --git a/test/database.replicate.test.js b/test/database.replicate.test.js
index a133cf8..2120d86 100644
--- a/test/database.replicate.test.js
+++ b/test/database.replicate.test.js
@@ -26,7 +26,7 @@ afterEach(() => {
   nock.cleanAll()
 })
 
-test('should be able to send replication request with local database names- POST /_replicate - nano.db.replicate', async () => {
+test('should be able to send replication request with local database names - POST /_replicate - nano.db.replicate', async () => {
   // mocks
   const scope = nock(COUCH_URL)
     .post('/_replicate', { source: COUCH_URL + '/source', target: COUCH_URL + '/target' })
diff --git a/test/database.replication.disable.test.js b/test/database.replication.disable.test.js
index da76cfc..dcef360 100644
--- a/test/database.replication.disable.test.js
+++ b/test/database.replication.disable.test.js
@@ -24,7 +24,7 @@ afterEach(() => {
   nock.cleanAll()
 })
 
-test('should be able to delete a replication - DELETE /_replicator - nano.db.replication.disable', async () => {
+test('should be able to delete a replication - DELETE /_replicator/id - nano.db.replication.disable', async () => {
   // mocks
   const scope = nock(COUCH_URL)
     .delete('/_replicator/rep1')
@@ -37,7 +37,7 @@ test('should be able to delete a replication - DELETE /_replicator - nano.db.rep
   expect(scope.isDone()).toBe(true)
 })
 
-test('should be able to handle a 404 - DELETE /_replicator - nano.db.replication.disable', async () => {
+test('should be able to handle a 404 - DELETE /_replicator/id - nano.db.replication.disable', async () => {
   // mocks
   const scope = nock(COUCH_URL)
     .delete('/_replicator/rep1')
@@ -64,7 +64,7 @@ test('should detect missing parameters (callback) - nano.db.replication.disable'
   })
 })
 
-test('should be able to delete a replication from db.replication.disable - DELETE /_replicator - db.replication.disable', async () => {
+test('should be able to delete a replication from db.replication.disable - DELETE /_replicator/id - db.replication.disable', async () => {
   // mocks
   const scope = nock(COUCH_URL)
     .delete('/_replicator/rep1')
diff --git a/test/design.atomic.test.js b/test/design.atomic.test.js
index 0382943..5c659a5 100644
--- a/test/design.atomic.test.js
+++ b/test/design.atomic.test.js
@@ -33,7 +33,7 @@ test('should be able to use an update function - PUT /db/_design/ddoc/_update/up
     .put('/db/_design/ddoc/_update/updatename/docid')
     .reply(200, response)
 
-  // test POST /db/_find
+  // test PUT /db/_design/ddoc/_update/updatename/docid
   const db = nano.db.use('db')
   const p = await db.atomic('ddoc', 'updatename', 'docid')
   expect(p).toStrictEqual(response)
@@ -55,7 +55,7 @@ test('should be able to use an update function with body - PUT /db/_design/ddoc/
     .put('/db/_design/ddoc/_update/updatename/docid', body)
     .reply(200, response)
 
-  // test POST /db/_find
+  // test PUT /db/_design/ddoc/_update/updatename/docid
   const db = nano.db.use('db')
   const p = await db.atomic('ddoc', 'updatename', 'docid', body)
   expect(p).toStrictEqual(response)
@@ -73,7 +73,7 @@ test('should be able to handle 404 - db.atomic', async () => {
     .put('/db/_design/ddoc/_update/updatename/docid', body)
     .reply(404, response)
 
-  // test GET /db
+  // test PUT /db/_design/ddoc/_update/updatename/docid
   const db = nano.db.use('db')
   await expect(db.atomic('ddoc', 'updatename', 'docid', body)).rejects.toThrow('missing')
   expect(scope.isDone()).toBe(true)
diff --git a/test/design.createIndex.test.js b/test/design.createIndex.test.js
index bd7bdcc..fbb1f53 100644
--- a/test/design.createIndex.test.js
+++ b/test/design.createIndex.test.js
@@ -19,7 +19,7 @@ afterEach(() => {
   nock.cleanAll()
 })
 
-test('should be able to create an index - POST /db/_index - db.index', async () => {
+test('should be able to create an index - POST /db/_index - db.createIndex', async () => {
   // mocks
   const indexDef = {
     index: {
@@ -45,7 +45,7 @@ test('should be able to create an index - POST /db/_index - db.index', async ()
   expect(scope.isDone()).toBe(true)
 })
 
-test('should handle 404 - POST /db/_index - db.index', async () => {
+test('should handle 404 - POST /db/_index - db.createIndex', async () => {
   // mocks
   const indexDef = {
     index: {
diff --git a/test/design.search.test.js b/test/design.search.test.js
index e7e8e42..5c9181f 100644
--- a/test/design.search.test.js
+++ b/test/design.search.test.js
@@ -33,7 +33,7 @@ test('should be able to access a search index - POST /db/_design/ddoc/_search/se
     .post('/db/_design/ddoc/_search/searchname', params)
     .reply(200, response)
 
-  // test GET /db
+  // test POST /db/_design/ddoc/_search/searchnameGET /db
   const db = nano.db.use('db')
   const p = await db.search('ddoc', 'searchname', params)
   expect(p).toStrictEqual(response)
@@ -51,7 +51,7 @@ test('should be able to handle 404 - db.search', async () => {
     .post('/db/_design/ddoc/_search/searchname', params)
     .reply(404, response)
 
-  // test GET /db
+  // test POST /db/_design/ddoc/_search/searchname
   const db = nano.db.use('db')
   await expect(db.search('ddoc', 'searchname', params)).rejects.toThrow('missing')
   expect(scope.isDone()).toBe(true)
diff --git a/test/design.show.test.js b/test/design.show.test.js
index 1097e89..e761f06 100644
--- a/test/design.show.test.js
+++ b/test/design.show.test.js
@@ -28,7 +28,7 @@ test('should be able to use a show function - GET /db/_design/ddoc/_show/shownam
     .get('/db/_design/ddoc/_show/showname/docid')
     .reply(200, showFunction(), { 'Content-type': 'text/plain' })
 
-  // test POST /db/_find
+  // test GET /db/_design/ddoc/_show/showname/docid
   const db = nano.db.use('db')
   const p = await db.show('ddoc', 'showname', 'docid')
   expect(p).toStrictEqual(showFunction())
@@ -45,7 +45,7 @@ test('should be able to handle 404 - db.show', async () => {
     .get('/db/_design/ddoc/_show/showname/docid')
     .reply(404, response)
 
-  // test GET /db
+  // test GET /db/_design/ddoc/_show/showname/docid
   const db = nano.db.use('db')
   await expect(db.show('ddoc', 'showname', 'docid')).rejects.toThrow('missing')
   expect(scope.isDone()).toBe(true)
diff --git a/test/design.view.test.js b/test/design.view.test.js
index 7a62626..e450946 100644
--- a/test/design.view.test.js
+++ b/test/design.view.test.js
@@ -30,7 +30,7 @@ test('should be able to access a MapReduce view - GET /db/_design/ddoc/_view/vie
     .get('/db/_design/ddoc/_view/viewname')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db/_design/ddoc/_view/viewname
   const db = nano.db.use('db')
   const p = await db.view('ddoc', 'viewname')
   expect(p).toStrictEqual(response)
@@ -61,7 +61,7 @@ test('should be able to access a MapReduce view with opts - GET /db/_design/ddoc
     .get('/db/_design/ddoc/_view/viewname?group=true&startkey="BA"&endkey="BQ"')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db/_design/ddoc/_view/viewname
   const db = nano.db.use('db')
   const p = await db.view('ddoc', 'viewname', { group: true, startkey: 'BA', endkey: 'BQ' })
   expect(p).toStrictEqual(response)
@@ -81,7 +81,7 @@ test('should be able to access a MapReduce view with keys - POST /db/_design/ddo
     .post('/db/_design/ddoc/_view/viewname', { keys: keys })
     .reply(200, response)
 
-  // test GET /db
+  // test POST /db/_design/ddoc/_view/viewname
   const db = nano.db.use('db')
   const p = await db.view('ddoc', 'viewname', { keys: keys })
   expect(p).toStrictEqual(response)
@@ -126,7 +126,7 @@ test('should be able to access a MapReduce view with queries - POST /db/_design/
     .post('/db/_design/ddoc/_view/viewname', { queries: opts.queries })
     .reply(200, response)
 
-  // test GET /db
+  // test POST /db/_design/ddoc/_view/viewname
   const db = nano.db.use('db')
   const p = await db.view('ddoc', 'viewname', opts)
   expect(p).toStrictEqual(response)
@@ -143,7 +143,7 @@ test('should be able to handle 404 - db.view', async () => {
     .get('/db/_design/ddoc/_view/viewname?group=true&startkey="BA"&endkey="BQ"')
     .reply(404, response)
 
-  // test GET /db
+  // test GET /db/_design/ddoc/_view/viewname
   const db = nano.db.use('db')
   await expect(db.view('ddoc', 'viewname', { group: true, startkey: 'BA', endkey: 'BQ' })).rejects.toThrow('missing')
   expect(scope.isDone()).toBe(true)
diff --git a/test/design.viewWithList.test.js b/test/design.viewWithList.test.js
index 92bb7f6..53c4a92 100644
--- a/test/design.viewWithList.test.js
+++ b/test/design.viewWithList.test.js
@@ -26,7 +26,7 @@ test('should be able to access a MapReduce view with a list - GET /db/_design/dd
     .get('/db/_design/ddoc/_list/listname/viewname')
     .reply(200, response, { 'Content-type': 'text/csv' })
 
-  // test GET /db
+  // test GET /db/_design/ddoc/_list/listname/viewname
   const db = nano.db.use('db')
   const p = await db.viewWithList('ddoc', 'viewname', 'listname')
   expect(p).toStrictEqual(response)
diff --git a/test/document.copy.test.js b/test/document.copy.test.js
index e5eb7d7..c9f74d4 100644
--- a/test/document.copy.test.js
+++ b/test/document.copy.test.js
@@ -26,7 +26,7 @@ test('should be able to copy a document - db.copy', async () => {
     .intercept('/db/rabbit1', 'COPY')
     .reply(200, response)
 
-  // test GET /db
+  // test COPY /db/id
   const db = nano.db.use('db')
   const p = await db.copy('rabbit1', 'rabbit2')
   expect(p).toStrictEqual(response)
@@ -52,7 +52,7 @@ test('should be able to copy a document in overwrite mode - db.copy', async () =
     .intercept('/db/rabbit1', 'COPY')
     .reply(200, response)
 
-  // test GET /db
+  // test HEAD /db/id2 + COPY /db/id1
   const db = nano.db.use('db')
   const p = await db.copy('rabbit1', 'rabbit2', { overwrite: true })
   expect(p).toStrictEqual(response)
diff --git a/test/document.fetch.test.js b/test/document.fetch.test.js
index bde243b..7ba3f0c 100644
--- a/test/document.fetch.test.js
+++ b/test/document.fetch.test.js
@@ -78,7 +78,7 @@ test('should be able to fetch a list of documents - POST /db/_all_docs - db.fetc
   expect(scope.isDone()).toBe(true)
 })
 
-test('should be able to fetch a list of documents with opts - GET /db/_all_docs - db.fetch', async () => {
+test('should be able to fetch a list of documents with opts - POST /db/_all_docs - db.fetch', async () => {
   // mocks
   const keys = ['1000501', '1000543', '100077']
   const response = {
diff --git a/test/document.fetchRevs.test.js b/test/document.fetchRevs.test.js
index aa6f3fa..9b87d25 100644
--- a/test/document.fetchRevs.test.js
+++ b/test/document.fetchRevs.test.js
@@ -60,7 +60,7 @@ test('should be able to fetch a list of document revisions - POST /db/_all_docs
   expect(scope.isDone()).toBe(true)
 })
 
-test('should be able to fetch a list of document revisions  with opts - GET /db/_all_docs - db.fetchRevs', async () => {
+test('should be able to fetch a list of document revisions  with opts - POST /db/_all_docs - db.fetchRevs', async () => {
   // mocks
   const keys = ['1000501', '1000543', '100077']
   const response = {
diff --git a/test/document.get.test.js b/test/document.get.test.js
index 4b45b5a..ea0ba64 100644
--- a/test/document.get.test.js
+++ b/test/document.get.test.js
@@ -26,7 +26,7 @@ test('should be able to get a document - GET /db/id - db.get', async () => {
     .get('/db/id')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db/id
   const db = nano.db.use('db')
   const p = await db.get('id')
   expect(p).toStrictEqual(response)
@@ -40,7 +40,7 @@ test('should be able to get a document from a partition - GET /db/pkey:id - db.g
     .get('/db/partkey%3Aid')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db/pkey:id
   const db = nano.db.use('db')
   const p = await db.get('partkey:id')
   expect(p).toStrictEqual(response)
@@ -54,7 +54,7 @@ test('should be able to get a document with options - GET /db/id?conflicts=true
     .get('/db/id?conflicts=true')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db/id?x=y
   const db = nano.db.use('db')
   const p = await db.get('id', { conflicts: true })
   expect(p).toStrictEqual(response)
@@ -71,7 +71,7 @@ test('should be able to handle 404 - GET /db/id - db.get', async () => {
     .get('/db/id')
     .reply(404, response)
 
-  // test GET /db
+  // test GET /db/id
   const db = nano.db.use('db')
   await expect(db.get('id')).rejects.toThrow('missing')
   expect(scope.isDone()).toBe(true)
diff --git a/test/document.head.test.js b/test/document.head.test.js
index 0dfd9f1..6555941 100644
--- a/test/document.head.test.js
+++ b/test/document.head.test.js
@@ -25,7 +25,7 @@ test('should be able to head a document - HEAD /db/id - db.head', async () => {
     .head('/db/id')
     .reply(200, '', { ETag: '1-123' })
 
-  // test GET /db
+  // test HEAD /db
   const db = nano.db.use('db')
   const p = await db.head('id')
   // headers get lowercased
@@ -39,7 +39,7 @@ test('should be able to head a document with callback - HEAD /db/id - db.head',
     .head('/db/id')
     .reply(200, '', { ETag: '1-123' })
 
-  // test GET /db
+  // test HEAD /db
   return new Promise((resolve, reject) => {
     const db = nano.db.use('db')
     db.head('id', (err, data, headers) => {
@@ -58,7 +58,7 @@ test('should be able to head a missing document - HEAD /db/id - db.head', async
     .head('/db/id')
     .reply(404, '')
 
-  // test GET /db
+  // test HEAD /db
   const db = nano.db.use('db')
   await expect(db.head('id')).rejects.toThrow('couch returned 404')
   expect(scope.isDone()).toBe(true)
diff --git a/test/multipart.get.test.js b/test/multipart.get.test.js
index 2db92eb..03b76e3 100644
--- a/test/multipart.get.test.js
+++ b/test/multipart.get.test.js
@@ -42,7 +42,7 @@ test('should be able to fetch a document with attachments - multipart GET /db -
     .get('/db/docid?attachments=true')
     .reply(200, multipartResponse, { 'content-type': 'multipart/related; boundary="e89b3e29388aef23453450d10e5aaed0"' })
 
-  // test POST /db
+  // test GET /db/id?attachments=true
   const db = nano.db.use('db')
   const p = await db.multipart.get('docid')
   expect(p.toString()).toStrictEqual(multipartResponse)
@@ -55,14 +55,14 @@ test('should be able to fetch a document with attachments with opts - multipart
     .get('/db/docid?attachments=true&conflicts=true')
     .reply(200, multipartResponse, { 'content-type': 'multipart/related; boundary="e89b3e29388aef23453450d10e5aaed0"' })
 
-  // test POST /db
+  // test GET /db/id?attachments=true&x=y
   const db = nano.db.use('db')
   const p = await db.multipart.get('docid', { conflicts: true })
   expect(p.toString()).toStrictEqual(multipartResponse)
   expect(scope.isDone()).toBe(true)
 })
 
-test('should be able to handle 404 - db.search', async () => {
+test('should be able to handle 404 - db.multipart.get', async () => {
   // mocks
   const response = {
     error: 'not_found',
diff --git a/test/multipart.insert.test.js b/test/multipart.insert.test.js
index 43f46b1..157a076 100644
--- a/test/multipart.insert.test.js
+++ b/test/multipart.insert.test.js
@@ -50,27 +50,27 @@ afterEach(() => {
   nock.cleanAll()
 })
 
-test('should be able to insert a document with attachments #1 - multipart POST /db - db.multipart.insert', async () => {
+test('should be able to insert a document with attachments #1 - multipart PUT /db/id - db.multipart.insert', async () => {
   // mocks
   const response = { ok: true, id: '8s8g8h8h9', rev: '1-123' }
   const scope = nock(COUCH_URL, { reqheaders: { 'content-type': h => h.includes('multipart/related') } })
     .put('/db/docid')
     .reply(200, response)
 
-  // test POST /db
+  // test PUT /db/id
   const db = nano.db.use('db')
   const p = await db.multipart.insert(doc, images, 'docid')
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
 })
 
-test('should be able to insert a document with attachments #2 - multipart POST /db - db.multipart.insert', async () => {
+test('should be able to insert a document with attachments #2 - multipart PUT /db/id - db.multipart.insert', async () => {
   const response = { ok: true, id: '8s8g8h8h9', rev: '1-123' }
   const scope = nock(COUCH_URL, { reqheaders: { 'content-type': h => h.includes('multipart/related') } })
     .put('/db/docid')
     .reply(200, response)
 
-  // test POST /db
+  // test PUT /db/id
   const db = nano.db.use('db')
   const p = await db.multipart.insert(doc, images, { docName: 'docid' })
   expect(p).toStrictEqual(response)
@@ -87,7 +87,7 @@ test('should be able to handle 404 - db.multipart.insert', async () => {
     .put('/db/docid')
     .reply(404, response)
 
-  // test GET /db
+  // test PUT /db/id
   const db = nano.db.use('db')
   await expect(db.multipart.insert(doc, images, { docName: 'docid' })).rejects.toThrow('missing')
   expect(scope.isDone()).toBe(true)
diff --git a/test/nano.auth.test.js b/test/nano.auth.test.js
index fe6af9b..571b206 100644
--- a/test/nano.auth.test.js
+++ b/test/nano.auth.test.js
@@ -28,7 +28,7 @@ test('should be able to authenticate - POST /_session - nano.auth', async () =>
     .post('/_session', 'name=u&password=p', { 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' })
     .reply(200, response, { 'Set-Cookie': 'AuthSession=YWRtaW46NUU0MTFBMDE6stHsxYnlDy4mYxwZEcnXHn4fm5w; Version=1; Expires=Mon, 10-Feb-2050 09:03:21 GMT; Max-Age=600; Path=/; HttpOnly' })
 
-  // test GET /_uuids
+  // test POST /_session
   const p = await nano.auth(username, password)
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
diff --git a/test/nano.logger.test.js b/test/nano.logger.test.js
index a6ae009..0c212e5 100644
--- a/test/nano.logger.test.js
+++ b/test/nano.logger.test.js
@@ -34,7 +34,7 @@ test('should be able to log output with user-defined function', async () => {
     .get('/db/id')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db/id
   const db = nano.db.use('db')
   const p = await db.get('id')
   expect(p).toStrictEqual(response)
diff --git a/test/nano.request.test.js b/test/nano.request.test.js
index 40b0e86..f0e7496 100644
--- a/test/nano.request.test.js
+++ b/test/nano.request.test.js
@@ -464,7 +464,7 @@ test('check request doesn\'t mangle bodies containing functions - nano.request',
     .post('/db', { a: 1, views: { bytime: { map: 'function () {\n          emit(doc.ts, true);\n        }' } } })
     .reply(200, response)
 
-  // test GET /db?a=1&b=2
+  // test POST /db
   const req = {
     method: 'post',
     db: 'db',
diff --git a/test/nano.session.test.js b/test/nano.session.test.js
index 2c0179a..7c3d1ee 100644
--- a/test/nano.session.test.js
+++ b/test/nano.session.test.js
@@ -26,7 +26,7 @@ test('should be able to check your session - GET /_session - nano.auth', async (
     .get('/_session')
     .reply(200, response)
 
-  // test GET /_uuids
+  // test GET /_session
   const p = await nano.session()
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
diff --git a/test/nano.updates.test.js b/test/nano.updates.test.js
index 23c9245..eca355b 100644
--- a/test/nano.updates.test.js
+++ b/test/nano.updates.test.js
@@ -49,7 +49,7 @@ test('should be able to fetch db updates - GET /_db_updates - nano.updates', asy
     .get('/_db_updates')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /_db_updates
   const p = await nano.updates()
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
@@ -61,7 +61,7 @@ test('should be able to fetch db updates with options - GET /_db_updates - nano.
     .get('/_db_updates?timeout=10000')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /_db_updates
   const p = await nano.updates({ timeout: 10000 })
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
@@ -73,7 +73,7 @@ test('should handle 404 - GET /_db_updates - nano.updates', async () => {
     .get('/_db_updates')
     .reply(404, errResponse)
 
-  // test GET /db
+  // test GET /_db_updates
   await expect(nano.db.updates()).rejects.toThrow('Database does not exist.')
   expect(scope.isDone()).toBe(true)
 })
diff --git a/test/notnocked.test.js b/test/notnocked.test.js
new file mode 100644
index 0000000..9350963
--- /dev/null
+++ b/test/notnocked.test.js
@@ -0,0 +1,111 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const dbName = 'notnocked' + new Date().getTime()
+let db
+const emit = (k, v) => {
+  console.log(k, v)
+}
+
+test('should be able to create a database string', () => {
+  expect(typeof dbName).toBe('string')
+})
+
+// this section only runs if the TRAVIS environment variable is set.
+// It is set when running tests in TravisCI, where a CouchDB/Docker container
+// should be running. These non-mocked tests are not exhaustive, but serve
+// to demonstrate that the library does actually work with real CouchDB.
+if (process.env.TRAVIS) {
+  test('should be able to create a database - nano.db.create', async () => {
+    await nano.db.create(dbName)
+    db = nano.db.use(dbName, { n: 1 })
+  })
+
+  test('should be able to populate a database - nano.db.bulk', async () => {
+    const docs = [
+      { _id: 'crookshanks', name: 'Crookshanks', description: 'Hermione Granger\'s pet cat', year: 2004 },
+      { _id: 'felix', name: 'Felix', description: 'Cat from the silent film era', year: 1929 },
+      { _id: 'garfield', name: 'Garfield', description: 'Large orange cartoon cat', year: 1978 },
+      { _id: 'cheshirecat', name: 'Cheshire Cat', description: 'From Alice in Wonderland', year: 1865 },
+      { _id: 'snowbell', name: 'Snowbell', description: 'From Stuart Little', year: 1945 },
+      { _id: 'catinthehat', name: 'The Cat in the Hat', description: 'Tall cat with red and white striped hat and bow tie', year: 1957 },
+      { _id: 'dummy', name: 'to be deleted' }
+    ]
+    await db.bulk({ docs: docs })
+  })
+
+  test('should be able to get database info - nano.db.bulk', async () => {
+    const info = await db.info(dbName)
+    expect(info.doc_count).toBe(7)
+  })
+
+  test('should be able to delete a document', async () => {
+    const doc = await db.get('dummy')
+    await db.destroy('dummy', doc._rev)
+    const info = await db.info(dbName)
+    expect(info.doc_count).toBe(6)
+    expect(info.doc_del_count).toBe(1)
+  })
+
+  test('should be able to update a document', async () => {
+    const doc = await db.get('catinthehat')
+    doc.newfield = true
+    await db.insert(doc)
+    const info = await db.info(dbName)
+    expect(info.doc_count).toBe(6)
+  })
+
+  test('should be able to list documents in a database', async () => {
+    const data = await db.list({ limit: 1, descending: true })
+    expect(data.rows.length).toBe(1)
+    expect(data.rows[0].id).toBe('snowbell')
+  })
+
+  test('should be able to create a view', async () => {
+    const f = function (doc) {
+      emit(doc.year, doc.name)
+    }
+    const doc = {
+      views: {
+        byYear: {
+          map: f.toString(),
+          reduce: '_count'
+        }
+      }
+    }
+    await db.insert(doc, '_design/views')
+  })
+
+  test('should be able to query a view', async () => {
+    const data = await db.view('views', 'byYear', { reduce: false })
+    const response = {
+      total_rows: 6,
+      offset: 0,
+      rows: [
+        { id: 'cheshirecat', key: 1865, value: 'Cheshire Cat' },
+        { id: 'felix', key: 1929, value: 'Felix' },
+        { id: 'snowbell', key: 1945, value: 'Snowbell' },
+        { id: 'catinthehat', key: 1957, value: 'The Cat in the Hat' },
+        { id: 'garfield', key: 1978, value: 'Garfield' },
+        { id: 'crookshanks', key: 2004, value: 'Crookshanks' }
+      ]
+    }
+    expect(response).toStrictEqual(data)
+  })
+
+  test('should be able to destroy a database - nano.db.destroy', async () => {
+    await nano.db.destroy(dbName)
+  })
+}
diff --git a/test/partition.find.test.js b/test/partition.find.test.js
index 325758a..806f947 100644
--- a/test/partition.find.test.js
+++ b/test/partition.find.test.js
@@ -42,7 +42,7 @@ test('should be able to query a partitioned index - POST /db/_partition/partitio
     .post('/db/_partition/partition/_find', query)
     .reply(200, response)
 
-  // test POST /db/_find
+  // test POST /db/_partition/partition/_find
   const db = nano.db.use('db')
   const p = await db.partitionedFind('partition', query)
   expect(p).toStrictEqual(response)
@@ -64,7 +64,7 @@ test('should handle 404 - POST /db/_partition/partition/_find - db.partitionedFi
     .post('/db/_partition/partition/_find', query)
     .reply(404, response)
 
-  // test POST /db/_find
+  // test POST /db/_partition/partition/_find
   const db = nano.db.use('db')
   await expect(db.partitionedFind('partition', query)).rejects.toThrow('missing')
   expect(scope.isDone()).toBe(true)
diff --git a/test/partition.findAsStream.test.js b/test/partition.findAsStream.test.js
index 340eadf..9e53c90 100644
--- a/test/partition.findAsStream.test.js
+++ b/test/partition.findAsStream.test.js
@@ -43,7 +43,7 @@ test('should get a queried streamed list of documents from a partition- POST /db
     .reply(200, response)
 
   return new Promise((resolve, reject) => {
-    // test GET /db/_all_docs
+    // test /db/_partition/partition/_find
     const db = nano.db.use('db')
     const s = db.partitionedFindAsStream('partition', query)
     expect(typeof s).toBe('object')
diff --git a/test/partition.info.test.js b/test/partition.info.test.js
index 52c6670..2d9e8f5 100644
--- a/test/partition.info.test.js
+++ b/test/partition.info.test.js
@@ -36,7 +36,7 @@ test('should be able to fetch partition info info - GET /db/_partition/partition
     .get('/db/_partition/partition')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db/_partition/partition
   const p = await db.partitionInfo('partition')
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
@@ -48,7 +48,7 @@ test('should be able to fetch partition info info (callback) - GET /db/_partitio
     .get('/db/_partition/partition')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db/_partition/partition
   return new Promise((resolve, reject) => {
     db.partitionInfo('partition', (err, data) => {
       expect(err).toBeNull()
@@ -68,7 +68,7 @@ test('should handle missing database - PUT /db - nano.db.create', async () => {
       reason: 'Database does not exist.'
     })
 
-  // test GET /db
+  // test GET /db/_partition/partition
   await expect(db.partitionInfo('partition')).rejects.toThrow('Database does not exist')
   expect(scope.isDone()).toBe(true)
 })
diff --git a/test/partition.list.test.js b/test/partition.list.test.js
index c1b0e04..2d1035a 100644
--- a/test/partition.list.test.js
+++ b/test/partition.list.test.js
@@ -67,7 +67,7 @@ test('should be list documents form a partition - GET /db/_partition/_all_docs -
     .get('/db/_partition/partition/_all_docs')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db/_partition/_all_docs
   const p = await db.partitionedList('partition')
   expect(p).toStrictEqual(response)
   expect(scope.isDone()).toBe(true)
@@ -98,7 +98,7 @@ test('should be list documents form a partition with opts - GET /db/_partition/_
     .get('/db/_partition/partition/_all_docs?limit=1&include_docs=true')
     .reply(200, optsResponse)
 
-  // test GET /db
+  // test GET /db/_partition/_all_docs
   const p = await db.partitionedList('partition', { limit: 1, include_docs: true })
   expect(p).toStrictEqual(optsResponse)
   expect(scope.isDone()).toBe(true)
@@ -110,7 +110,7 @@ test('should be able to list partition docs (callback) - GET /db/_partition/_all
     .get('/db/_partition/partition/_all_docs')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db/_partition/_all_docs
   return new Promise((resolve, reject) => {
     db.partitionedList('partition', (err, data) => {
       expect(err).toBeNull()
@@ -130,7 +130,7 @@ test('should handle missing database - GET /db/_partition/_all_docs - db.partiti
       reason: 'Database does not exist.'
     })
 
-  // test GET /db
+  // test GET /db/_partition/_all_docs
   await expect(db.partitionedList('partition')).rejects.toThrow('Database does not exist')
   expect(scope.isDone()).toBe(true)
 })
diff --git a/test/partition.listAsStream.test.js b/test/partition.listAsStream.test.js
index f360cb2..b45c5be 100644
--- a/test/partition.listAsStream.test.js
+++ b/test/partition.listAsStream.test.js
@@ -53,7 +53,7 @@ test('should get a streamed list of documents from a partition- GET /db/_partiti
     .reply(200, response)
 
   return new Promise((resolve, reject) => {
-    // test GET /db/_all_docs
+    // test GET /db/_partition/_all_docs
     const db = nano.db.use('db')
     const s = db.partitionedListAsStream('partition')
     expect(typeof s).toBe('object')
@@ -95,7 +95,7 @@ test('should get a streamed list of documents from a partition with opts- GET /d
     .reply(200, response)
 
   return new Promise((resolve, reject) => {
-    // test GET /db/_all_docs
+    // test GET /db/_partition/_all_docs
     const db = nano.db.use('db')
     const s = db.partitionedListAsStream('partition', { limit: 1, include_docs: true })
     expect(typeof s).toBe('object')
diff --git a/test/partition.search.test.js b/test/partition.search.test.js
index 9f470fb..a54ed36 100644
--- a/test/partition.search.test.js
+++ b/test/partition.search.test.js
@@ -19,7 +19,7 @@ afterEach(() => {
   nock.cleanAll()
 })
 
-test('should be able to access a partitioned search index - POST /db/_partition/partition/_design/ddoc/_search/searchname - db.partitionedSearch', async () => {
+test('should be able to access a partitioned search index - GET /db/_partition/partition/_design/ddoc/_search/searchname - db.partitionedSearch', async () => {
   // mocks
   const response = {
     total_rows: 100000,
@@ -33,7 +33,7 @@ test('should be able to access a partitioned search index - POST /db/_partition/
     .get('/db/_partition/partition/_design/ddoc/_search/searchname?q=*:*')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db/_partition/partition/_design/ddoc/_search/searchname
   const db = nano.db.use('db')
   const p = await db.partitionedSearch('partition', 'ddoc', 'searchname', params)
   expect(p).toStrictEqual(response)
@@ -51,7 +51,7 @@ test('should be able to handle 404 - db.partitionedSearch', async () => {
     .get('/db/_partition/partition/_design/ddoc/_search/searchname?q=*:*')
     .reply(404, response)
 
-  // test GET /db
+  // test GET /db/_partition/partition/_design/ddoc/_search/searchname
   const db = nano.db.use('db')
   await expect(db.partitionedSearch('partition', 'ddoc', 'searchname', params)).rejects.toThrow('missing')
   expect(scope.isDone()).toBe(true)
diff --git a/test/partition.searchAsStream.test.js b/test/partition.searchAsStream.test.js
index 73faabd..ec90bc0 100644
--- a/test/partition.searchAsStream.test.js
+++ b/test/partition.searchAsStream.test.js
@@ -34,7 +34,7 @@ test('should get a searched streamed list of documents from a partition- GET /db
     .reply(200, response)
 
   return new Promise((resolve, reject) => {
-    // test GET /db/_all_docs
+    // test GET /db/_partition/partition/_design/ddoc/_search/searchname
     const db = nano.db.use('db')
     const s = db.partitionedSearchAsStream('partition', 'ddoc', 'searchname', params)
     expect(typeof s).toBe('object')
diff --git a/test/partition.view.test.js b/test/partition.view.test.js
index 7338fcb..4b532fd 100644
--- a/test/partition.view.test.js
+++ b/test/partition.view.test.js
@@ -30,7 +30,7 @@ test('should be able to access a partitioned view index - GET /db/_partition/par
     .get('/db/_partition/partition/_design/ddoc/_view/viewname')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db/_partition/partition/_design/ddoc/_view/viewname
   const db = nano.db.use('db')
   const p = await db.partitionedView('partition', 'ddoc', 'viewname')
   expect(p).toStrictEqual(response)
@@ -54,7 +54,7 @@ test('should be able to access a partitioned view index with opts - GET /db/_par
     .get('/db/_partition/partition/_design/ddoc/_view/viewname?reduce=false&startkey=%22a%22&endkey=%22b%22&limit=1')
     .reply(200, response)
 
-  // test GET /db
+  // test GET /db/_partition/partition/_design/ddoc/_view/viewname
   const db = nano.db.use('db')
   const p = await db.partitionedView('partition', 'ddoc', 'viewname', params)
   expect(p).toStrictEqual(response)
@@ -71,7 +71,7 @@ test('should be able to handle 404 - db.partitionedView', async () => {
     .get('/db/_partition/partition/_design/ddoc/_view/viewname')
     .reply(404, response)
 
-  // test GET /db
+  // test GET /db/_partition/partition/_design/ddoc/_view/viewname
   const db = nano.db.use('db')
   await expect(db.partitionedView('partition', 'ddoc', 'viewname')).rejects.toThrow('missing')
   expect(scope.isDone()).toBe(true)
diff --git a/test/partition.viewAsStream.test.js b/test/partition.viewAsStream.test.js
index 24a899f..97663db 100644
--- a/test/partition.viewAsStream.test.js
+++ b/test/partition.viewAsStream.test.js
@@ -19,7 +19,7 @@ afterEach(() => {
   nock.cleanAll()
 })
 
-test('should get a streamed list of documents from a view from  partition- GET /db/_partition/partition/_design/ddoc/_view/viewname - db.partitionedViewAsStream', async () => {
+test('should get a streamed list of documents from a view from  partition - GET /db/_partition/partition/_design/ddoc/_view/viewname - db.partitionedViewAsStream', async () => {
   // mocks
   const response = {
     rows: [
@@ -37,7 +37,7 @@ test('should get a streamed list of documents from a view from  partition- GET /
     .reply(200, response)
 
   return new Promise((resolve, reject) => {
-    // test GET /db/_all_docs
+    // test GET /db/_partition/partition/_design/ddoc/_view/viewnameGET /db/_all_docs
     const db = nano.db.use('db')
     const s = db.partitionedViewAsStream('partition', 'ddoc', 'viewname', params)
     expect(typeof s).toBe('object')


[couchdb-nano] 09/15: attachment tests

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit c472a7edd7459d2706a278bd72a0d26127fd66ff
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Fri Feb 7 15:33:18 2020 +0000

    attachment tests
---
 lib/nano.js                            |  24 ++++++++++++
 test/attachment.destroy.test.js        |  64 ++++++++++++++++++++++++++++++++
 test/attachment.get.test.js            |  62 +++++++++++++++++++++++++++++++
 test/attachment.getAsStream.test.js    |  40 ++++++++++++++++++++
 test/attachment.insert.test.js         |  66 +++++++++++++++++++++++++++++++++
 test/attachment.insertAsStream.test.js |  53 ++++++++++++++++++++++++++
 test/logo.jpg                          | Bin 0 -> 401 bytes
 7 files changed, 309 insertions(+)

diff --git a/lib/nano.js b/lib/nano.js
index 3bbf7bc..d396acf 100644
--- a/lib/nano.js
+++ b/lib/nano.js
@@ -908,6 +908,14 @@ module.exports = exports = function dbScope (cfg) {
 
     function insertAtt (docName, attName, att, contentType, qs0, callback0) {
       const { opts, callback } = getCallback(qs0, callback0)
+      if (!docName || !attName || !att || !contentType) {
+        const e = new Error('Invalid parameters')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
       return relax({
         db: dbName,
         att: attName,
@@ -936,6 +944,14 @@ module.exports = exports = function dbScope (cfg) {
 
     function getAtt (docName, attName, qs0, callback0) {
       const { opts, callback } = getCallback(qs0, callback0)
+      if (!docName || !attName) {
+        const e = new Error('Invalid parameters')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
       return relax({
         db: dbName,
         att: attName,
@@ -959,6 +975,14 @@ module.exports = exports = function dbScope (cfg) {
     }
 
     function destroyAtt (docName, attName, qs, callback) {
+      if (!docName || !attName) {
+        const e = new Error('Invalid parameters')
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
       return relax({
         db: dbName,
         att: attName,
diff --git a/test/attachment.destroy.test.js b/test/attachment.destroy.test.js
new file mode 100644
index 0000000..d7b6450
--- /dev/null
+++ b/test/attachment.destroy.test.js
@@ -0,0 +1,64 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+test('should be able to destroy a document - DELETE /db/id/attname - db.attachment.destroy', async () => {
+  // mocks
+  const response = { ok: true, id: 'id', rev: '2-456' }
+  const scope = nock(COUCH_URL)
+    .delete('/db/id/logo.jpg?rev=1-123')
+    .reply(200, response)
+
+  // test DELETE /db/id
+  const db = nano.db.use('db')
+  const p = await db.attachment.destroy('id', 'logo.jpg', { rev: '1-123' })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 409 conflicts - DELETE /db/id - db.attachment.destroy', async () => {
+  // mocks
+  const response = {
+    error: 'conflict',
+    reason: 'Document update conflict.'
+  }
+  const scope = nock(COUCH_URL)
+    .delete('/db/id/logo.jpg?rev=1-123')
+    .reply(409, response)
+
+  // test DELETE /db/id
+  const db = nano.db.use('db')
+  await expect(db.attachment.destroy('id', 'logo.jpg', { rev: '1-123' })).rejects.toThrow('Document update conflict.')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing doc id - db.attachment.destroy', async () => {
+  const db = nano.db.use('db')
+  await expect(db.attachment.destroy()).rejects.toThrow('Invalid parameters')
+  await expect(db.attachment.destroy('id')).rejects.toThrow('Invalid parameters')
+  await expect(db.attachment.destroy('id', '')).rejects.toThrow('Invalid parameters')
+  await expect(db.attachment.destroy('', 'logo.jpg')).rejects.toThrow('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.attachment.get', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.attachment.destroy(undefined, undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/attachment.get.test.js b/test/attachment.get.test.js
new file mode 100644
index 0000000..61285d5
--- /dev/null
+++ b/test/attachment.get.test.js
@@ -0,0 +1,62 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+const image = Buffer.from('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', 'base64')
+
+test('should be able to get an attachment - GET /db/id/attname - db.attachment.get', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/id/transparent.gif')
+    .reply(200, image, { 'content-type': 'image/gif' })
+
+  // test GET /db/id/attname
+  const db = nano.db.use('db')
+  const p = await db.attachment.get('id', 'transparent.gif')
+  expect(p).toStrictEqual(image)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to get an attachment with opts - GET /db/id/attname - db.attachment.get', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/id/transparent.gif?r=1')
+    .reply(200, image, { 'content-type': 'image/gif' })
+
+  // test GET /db/id/attname
+  const db = nano.db.use('db')
+  const p = await db.attachment.get('id', 'transparent.gif', { r: 1 })
+  expect(p).toStrictEqual(image)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing parameters - db.attachment.get', async () => {
+  const db = nano.db.use('db')
+  await expect(db.attachment.get()).rejects.toThrow('Invalid parameters')
+  await expect(db.attachment.get('id')).rejects.toThrow('Invalid parameters')
+  await expect(db.attachment.get('id', '')).rejects.toThrow('Invalid parameters')
+  await expect(db.attachment.get('', 'transparent.gif')).rejects.toThrow('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.attachment.get', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.attachment.get(undefined, undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/attachment.getAsStream.test.js b/test/attachment.getAsStream.test.js
new file mode 100644
index 0000000..c5ad8eb
--- /dev/null
+++ b/test/attachment.getAsStream.test.js
@@ -0,0 +1,40 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+const image = Buffer.from('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', 'base64')
+
+test('should be able to get an attachment as a stream - GET /db/id/attname - db.attachment.get', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/id/transparent.gif')
+    .reply(200, image, { 'content-type': 'image/gif' })
+
+  // test GET /db/id/attname
+  return new Promise((resolve, reject) => {
+    const db = nano.db.use('db')
+    let response = Buffer.from('')
+    db.attachment.getAsStream('id', 'transparent.gif')
+      .on('data', (data) => {
+        response = Buffer.concat([response, data])
+      })
+      .on('end', () => {
+        expect(response).toStrictEqual(image)
+        expect(scope.isDone()).toBe(true)
+        resolve()
+      })
+  })
+})
diff --git a/test/attachment.insert.test.js b/test/attachment.insert.test.js
new file mode 100644
index 0000000..4f0809f
--- /dev/null
+++ b/test/attachment.insert.test.js
@@ -0,0 +1,66 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+const image = Buffer.from('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', 'base64')
+
+test('should be able to insert document attachment - PUT /db/docname/attachment - db.attachment.insert', async () => {
+  // mocks
+  const response = { ok: true, id: 'docname', rev: '2-456' }
+  const scope = nock(COUCH_URL, { reqheaders: { 'content-type': 'image/gif' } })
+    .put('/db/docname/transparent.gif?rev=1-150', image)
+    .reply(200, response)
+
+  // test PUT /db/docname/attachment
+  const db = nano.db.use('db')
+  const p = await db.attachment.insert('docname', 'transparent.gif', image, 'image/gif', { rev: '1-150' })
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 404 - db.attachment.insert', async () => {
+  // mocks
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL, { reqheaders: { 'content-type': 'image/gif' } })
+    .put('/db/docname/transparent.gif?rev=1-150', image)
+    .reply(404, response)
+
+  // test PUT /db/docname/attachment
+  const db = nano.db.use('db')
+  await expect(db.attachment.insert('docname', 'transparent.gif', image, 'image/gif', { rev: '1-150' })).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing parameters - db.attachment.insert', async () => {
+  const db = nano.db.use('db')
+  await expect(db.attachment.insert()).rejects.toThrow('Invalid parameters')
+  await expect(db.attachment.insert('docname')).rejects.toThrow('Invalid parameters')
+  await expect(db.attachment.insert('docname', 't.gif')).rejects.toThrow('Invalid parameters')
+  await expect(db.attachment.insert('docname', 't.gif', image)).rejects.toThrow('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.attachment.insert', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.attachment.insert(undefined, undefined, undefined, undefined, undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/attachment.insertAsStream.test.js b/test/attachment.insertAsStream.test.js
new file mode 100644
index 0000000..b805028
--- /dev/null
+++ b/test/attachment.insertAsStream.test.js
@@ -0,0 +1,53 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+const fs = require('fs')
+
+const image = Buffer.from(''.concat(
+  'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAsV',
+  'BMVEUAAAD////////////////////////5ur3rEBn////////////////wDBL/',
+  'AADuBAe9EB3IEBz/7+//X1/qBQn2AgP/f3/ilpzsDxfpChDtDhXeCA76AQH/v7',
+  '/84eLyWV/uc3bJPEf/Dw/uw8bRWmP1h4zxSlD6YGHuQ0f6g4XyQkXvCA36MDH6',
+  'wMH/z8/yAwX64ODeh47BHiv/Ly/20dLQLTj98PDXWmP/Pz//39/wGyJ7Iy9JAA',
+  'AADHRSTlMAbw8vf08/bz+Pv19jK/W3AAAAg0lEQVR4Xp3LRQ4DQRBD0QqTm4Y5',
+  'zMxw/4OleiJlHeUtv2X6RbNO1Uqj9g0RMCuQO0vBIg4vMFeOpCWIWmDOw82fZx',
+  'vaND1c8OG4vrdOqD8YwgpDYDxRgkSm5rwu0nQVBJuMg++pLXZyr5jnc1BaH4GT',
+  'LvEliY253nA3pVhQqdPt0f/erJkMGMB8xucAAAAASUVORK5CYII='), 'base64')
+
+test('should be able to insert document attachment as stream - PUT /db/docname/attachment - db.attachment.insertAsStream', async () => {
+  // mocks
+  const response = { ok: true, id: 'docname', rev: '2-456' }
+  const scope = nock(COUCH_URL, { reqheaders: { 'content-type': 'image/jpg' } })
+    .put('/db/docname/logo.jpg?rev=1-150', image)
+    .reply(200, response)
+
+  // test PUT /db/docname/attachment
+  return new Promise((resolve, reject) => {
+    const rs = fs.createReadStream('./test/logo.jpg')
+    const db = nano.db.use('db')
+    let reply = ''
+    const is = db.attachment.insertAsStream('docname', 'logo.jpg', null, 'image/jpg', { rev: '1-150' })
+      .on('data', (data) => {
+        reply += data.toString()
+      })
+      .on('end', () => {
+        expect(reply).toStrictEqual(JSON.stringify(response))
+        expect(scope.isDone()).toBe(true)
+        resolve()
+      })
+    rs.pipe(is)
+  })
+})
diff --git a/test/logo.jpg b/test/logo.jpg
new file mode 100644
index 0000000..91d6d97
Binary files /dev/null and b/test/logo.jpg differ


[couchdb-nano] 13/15: partitioned functions and tests

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit 62e318f0d4feffafc132f8d9ea4f226db4e0c744
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Tue Feb 11 10:36:23 2020 +0000

    partitioned functions and tests
---
 README.md                             | 206 ++++++++++++++++++++++++++++++++++
 lib/nano.d.ts                         |  54 +++++++++
 lib/nano.js                           | 129 ++++++++++++++++++++-
 test/document.get.test.js             |  14 +++
 test/partition.find.test.js           |  87 ++++++++++++++
 test/partition.findAsStream.test.js   |  60 ++++++++++
 test/partition.info.test.js           |  88 +++++++++++++++
 test/partition.list.test.js           | 150 +++++++++++++++++++++++++
 test/partition.listAsStream.test.js   | 112 ++++++++++++++++++
 test/partition.search.test.js         |  78 +++++++++++++
 test/partition.searchAsStream.test.js |  51 +++++++++
 test/partition.view.test.js           |  98 ++++++++++++++++
 test/partition.viewAsStream.test.js   |  54 +++++++++
 13 files changed, 1180 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index f98afa1..94a2118 100644
--- a/README.md
+++ b/README.md
@@ -64,6 +64,16 @@ See [Migration Guide for switching from Nano 6.x to 7.x](migration_6_to_7.md).
   - [db.fetch(docnames, [params], [callback])](#dbfetchdocnames-params-callback)
   - [db.fetchRevs(docnames, [params], [callback])](#dbfetchrevsdocnames-params-callback)
   - [db.createIndex(indexDef, [callback])](#dbcreateindexindexdef-callback)
+- [Partitioned database functions][#partition-functions]
+  - [db.partitionInfo(partitionKey, [callback])](#dbpartitioninfopartitionkey-callback))
+  - [db.partitionedList(partitionKey, [params], [callback])](#dbpartitionedlistpartitionkey-params-callback)
+  - [db.partitionedListAsStream(partitionKey, [params])](#dbpartitionedlistasstreampartitionkey-params)
+  - [db.partitionedFind(partitionKey, query, [callback])](#dbpartitionedfindpartitionkey-query-params)
+  - [db.partitionedFindAsStream(partitionKey, query)](#dbpartitionedfindasstreampartitionkey-query)
+  - [db.partitionedSearch(partitionKey, designName, searchName, params, [callback])](#dbpartitionedsearchpartitioney-designname-searchname-params-callback)
+  - [db.partitionedSearchAsStream(partitionKey, designName, searchName, params)](#dbpartitionedsearchasstreampartitionkey-designName-searchName-params)
+  - [db.partitionedView(partitionKey, designName, viewName, [params], [callback])](#dbpartitionediewpartitionkey-designname-viewname-params-callback)
+  - [db.partitionedViewAsStream(partitionKey, designName, viewName, [params])](#dbpartitionediewasstreampartitionkey-designname-viewname-params)
 - [Multipart functions](#multipart-functions)
   - [db.multipart.insert(doc, attachments, [params], [callback])](#dbmultipartinsertdoc-attachments-params-callback)
   - [db.multipart.get(docname, [params], [callback])](#dbmultipartgetdocname-params-callback)
@@ -702,6 +712,202 @@ alice.createIndex(indexDef).then((result) => {
 });
 ```
 
+## Partition Functions
+
+Functions related to [partitioned databses](https://docs.couchdb.org/en/latest/partitioned-dbs/index.html).
+
+Create a partitioned database by passing `{ partitioned: true }` to `db.create`:
+
+```js
+await nano.db.create('my-partitioned-db', { partitioned: true })
+```
+
+The database can be used as normal:
+
+```js
+const db = nano.db.use('my-partitioned-db')
+```
+
+but documents must have a two-part `_id` made up of `<partition key>:<document id>`. They are insert with `db.insert` as normal:
+
+```js
+const doc = { _id: 'canidae:dog', name: 'Dog', latin: 'Canis lupus familiaris' }
+await db.insert(doc)
+```
+
+Documents can be retrieved by their `_id` using `db.get`:
+
+```js
+const doc = db.get('canidae:dog')
+```
+
+Mango indexes can be created to operate on a per-partition index by supplying `partitioned: true` on creation:
+
+```js
+const i = {
+  ddoc: 'partitioned-query',
+  index: { fields: ['name'] },
+  name: 'name-index',
+  partitioned: true,
+  type: 'json'
+}
+ 
+// instruct CouchDB to create the index
+await db.index(i)
+```
+
+Search indexes can be created by writing a design document with `opts.partitioned = true`:
+
+```js
+// the search definition
+const func = function(doc) {
+  index('name', doc.name)
+  index('latin', doc.latin)
+}
+ 
+// the design document containing the search definition function
+const ddoc = {
+  _id: '_design/search-ddoc',
+  indexes: {
+    search-index: {
+      index: func.toString()
+    }
+  },
+  options: {
+    partitioned: true
+  }
+}
+ 
+await db.insert(ddoc)
+```
+
+MapReduce views can be created by writing a design document with `opts.partitioned = true`:
+
+```js
+const func = function(doc) {
+  emit(doc.family, doc.weight)
+}
+ 
+// Design Document
+const ddoc = {
+  _id: '_design/view-ddoc',
+  views: {
+    family-weight: {
+      map: func.toString(),
+      reduce: '_sum'
+    }
+  },
+  options: {
+    partitioned: true
+  }
+}
+ 
+// create design document
+await db.insert(ddoc)
+```
+
+### db.partitionInfo(partitionKey, [callback])
+
+Fetch the stats of a single partition:
+
+```js
+const stats = await alice.partitionInfo('canidae')
+```
+
+### db.partitionedList(partitionKey, [params], [callback])
+
+Fetch documents from a database partition:
+
+```js
+// fetch document id/revs from a partition
+const docs = await alice.partitionedList('canidae')
+
+// add document bodies but limit size of response
+const docs = await alice.partitionedList('canidae', { include_docs: true, limit: 5 })
+```
+
+### db.partitionedListAsStream(partitionKey, [params])
+
+Fetch documents from a partition as a stream:
+
+```js
+// fetch document id/revs from a partition
+nano.db.partitionedListAsStream('canidae').pipe(process.stdout)
+
+// add document bodies but limit size of response
+nano.db.partitionedListAsStream('canidae', { include_docs: true, limit: 5 }).pipe(process.stdout)
+```
+
+### db.partitionedFind(partitionKey, query, [params])
+
+Query documents from a partition by supplying a Mango selector:
+
+```js
+// find document whose name is 'wolf' in the 'canidae' partition
+await db.partitionedFind('canidae', { 'selector' : { 'name': 'Wolf' }})
+```
+
+### db.partitionedFindAsStream(partitionKey, query)
+
+Query documents from a partition by supplying a Mango selector as a stream:
+
+```js
+// find document whose name is 'wolf' in the 'canidae' partition
+db.partitionedFindAsStream('canidae', { 'selector' : { 'name': 'Wolf' }}).pipe(process.stdout)
+```
+
+### db.partitionedSearch(partitionKey, designName, searchName, params, [callback])
+
+Search documents from a partition by supplying a Lucene query:
+
+```js
+const params = {
+  q: 'name:\'Wolf\''
+}
+await db.partitionedSearch('canidae', 'search-ddoc', 'search-index', params)
+// { total_rows: ... , bookmark: ..., rows: [ ...] }
+```
+
+### db.partitionedSearchAsStream(partitionKey, designName, searchName, params)
+
+Search documents from a partition by supplying a Lucene query as a stream:
+
+```js
+const params = {
+  q: 'name:\'Wolf\''
+}
+db.partitionedSearchAsStream('canidae', 'search-ddoc', 'search-index', params).pipe(process.stdout)
+// { total_rows: ... , bookmark: ..., rows: [ ...] }
+```
+
+### db.partitionedView(partitionKey, designName, viewName, params, [callback])
+
+Fetch documents from a MapReduce view from a partition:
+
+```js
+const params = {
+  startkey: 'a',
+  endkey: 'b',
+  limit: 1
+}
+await db.partitionedView('canidae', 'view-ddoc', 'view-name', params)
+// { rows: [ { key: ... , value: [Object] } ] }
+```
+
+### db.partitionedViewAsStream(partitionKey, designName, viewName, params)
+
+Fetch documents from a MapReduce view from a partition as a stream:
+
+```js
+const params = {
+  startkey: 'a',
+  endkey: 'b',
+  limit: 1
+}
+db.partitionedView('canidae', 'view-ddoc', 'view-name', params).pipe(process.stdout)
+// { rows: [ { key: ... , value: [Object] } ] }
+```
+
 ## Multipart functions
 
 ### db.multipart.insert(doc, attachments, params, [callback])
diff --git a/lib/nano.d.ts b/lib/nano.d.ts
index ca5a29f..d91917c 100644
--- a/lib/nano.d.ts
+++ b/lib/nano.d.ts
@@ -302,6 +302,38 @@ declare namespace nano {
     // http://docs.couchdb.org/en/latest/api/database/find.html#db-find
     find(query: MangoQuery, callback?: Callback<MangoResponse<D>>): Promise <MangoResponse<D>>;
     server: ServerScope;
+    //https://docs.couchdb.org/en/latest/partitioned-dbs/index.html
+    partitionInfo(partitionKey: string, callback?: Callback<PartitionInfoResponse<D>>): Promise <PartitionInfoResponse>;
+    partitionedList(partitionKey: string, params?: DocumentListParams, callback?: Callback<DocumentListResponse<D>>): Promise<DocumentListResponse<D>>;
+    partitionedListAsStream(partitionKey: string, params?: DocumentListParams): Request;
+    partitionedFind(partitionKey: string, query: MangoQuery, callback?: Callback<MangoResponse<D>>): Promise <MangoResponse<D>>;
+    partitionedFindAsStream(partitionKey: string, query: MangoQuery): Request;
+    partitionedViewpartitionedSearch<V>(
+      partitionKey: string,
+      designname: string,
+      searchname: string,
+      params: DocumentSearchParams,
+      callback?: Callback<DocumentSearchResponse<V>>
+    ): Promise<DocumentSearchResponse<V>>;
+    partitionedSearchAsStream(
+      partitionKey: string,
+      designname: string,
+      searchname: string,
+      params: DocumentSearchParams
+    ): Request;
+    partitionedView<V>(
+      partitionKey: string,
+      designname: string,
+      viewname: string,
+      params: DocumentViewParams,
+      callback?: Callback<DocumentViewResponse<V,D>>
+    ): Promise<DocumentViewResponse<V,D>>;
+    partitionedViewAsStream<V>(
+      partitionKey: string,
+      designname: string,
+      viewname: string,
+      params: DocumentViewParams
+    ): Request;
   }
 
   interface AttachmentData {
@@ -1025,6 +1057,28 @@ declare namespace nano {
 
   }
 
+
+  // https://docs.couchdb.org/en/latest/partitioned-dbs/index.html
+  interface PartitionInfoResponse {
+    // Database name
+    db_name:  string;
+
+    // Partition sizes
+    sizes: {
+      active: integer;
+      external: integer;
+    }
+
+    // Partition name
+    partition: string;
+
+    // Document count
+    doc_count: number;
+
+    // Deleted document count
+    doc_del_count: number;
+  }
+
   // https://console.bluemix.net/docs/services/Cloudant/api/search.html#queries
   interface DocumentSearchParams {
     // A bookmark that was received from a previous search. Used for pagination.
diff --git a/lib/nano.js b/lib/nano.js
index c1bcc23..b4cc0d0 100644
--- a/lib/nano.js
+++ b/lib/nano.js
@@ -1076,6 +1076,124 @@ module.exports = exports = function dbScope (cfg) {
       }, callback)
     }
 
+    function partitionInfo (partitionKey, callback) {
+      if (!partitionKey) {
+        const e = INVALID_PARAMETERS_ERROR
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
+      return relax({
+        db: dbName,
+        path: '_partition/' + partitionKey
+      }, callback)
+    }
+
+    function partitionedList (partitionKey, qs0, callback0) {
+      const { opts, callback } = getCallback(qs0, callback0)
+      if (!partitionKey) {
+        const e = INVALID_PARAMETERS_ERROR
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
+      return relax({
+        db: dbName,
+        path: '_partition/' + partitionKey + '/_all_docs',
+        qs: opts
+      }, callback)
+    }
+
+    function partitionedListAsStream (partitionKey, qs) {
+      return relax({
+        db: dbName,
+        path: '_partition/' + partitionKey + '/_all_docs',
+        qs: qs,
+        stream: true
+      })
+    }
+
+    function partitionedFind (partition, query, callback) {
+      if (!partition || !query || typeof query !== 'object') {
+        const e = INVALID_PARAMETERS_ERROR
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
+      return relax({
+        db: dbName,
+        path: '_partition/' + partition + '/_find',
+        method: 'POST',
+        body: query
+      }, callback)
+    }
+
+    function partitionedFindAsStream (partition, query) {
+      return relax({
+        db: dbName,
+        path: '_partition/' + partition + '/_find',
+        method: 'POST',
+        body: query,
+        stream: true
+      })
+    }
+
+    function partitionedSearch (partition, ddoc, searchName, opts, callback) {
+      if (!partition || !ddoc || !searchName || !opts || typeof opts !== 'object') {
+        const e = INVALID_PARAMETERS_ERROR
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
+      return relax({
+        db: dbName,
+        path: '_partition/' + partition + '/_design/' + ddoc + '/_search/' + searchName,
+        qs: opts
+      }, callback)
+    }
+
+    function partitionedSearchAsStream (partition, ddoc, searchName, opts) {
+      return relax({
+        db: dbName,
+        path: '_partition/' + partition + '/_design/' + ddoc + '/_search/' + searchName,
+        qs: opts,
+        stream: true
+      })
+    }
+
+    function partitionedView (partition, ddoc, viewName, opts, callback) {
+      if (!partition || !ddoc || !viewName) {
+        const e = INVALID_PARAMETERS_ERROR
+        if (callback) {
+          return callback(e, null)
+        } else {
+          return Promise.reject(e)
+        }
+      }
+      return relax({
+        db: dbName,
+        path: '_partition/' + partition + '/_design/' + ddoc + '/_view/' + viewName,
+        qs: opts
+      }, callback)
+    }
+
+    function partitionedViewAsStream (partition, ddoc, viewName, opts) {
+      return relax({
+        db: dbName,
+        path: '_partition/' + partition + '/_design/' + ddoc + '/_view/' + viewName,
+        qs: opts,
+        stream: true
+      })
+    }
+
     // db level exports
     docScope = {
       info: function (cb) {
@@ -1143,7 +1261,16 @@ module.exports = exports = function dbScope (cfg) {
         query: function (id, opts, cb) {
           return queryReplication(id, opts, cb)
         }
-      }
+      },
+      partitionInfo: partitionInfo,
+      partitionedList: partitionedList,
+      partitionedListAsStream: partitionedListAsStream,
+      partitionedFind: partitionedFind,
+      partitionedFindAsStream: partitionedFindAsStream,
+      partitionedSearch: partitionedSearch,
+      partitionedSearchAsStream: partitionedSearchAsStream,
+      partitionedView: partitionedView,
+      partitionedViewAsStream: partitionedViewAsStream
     }
 
     docScope.view.compact = function (ddoc, cb) {
diff --git a/test/document.get.test.js b/test/document.get.test.js
index 109b7cb..4b45b5a 100644
--- a/test/document.get.test.js
+++ b/test/document.get.test.js
@@ -33,6 +33,20 @@ test('should be able to get a document - GET /db/id - db.get', async () => {
   expect(scope.isDone()).toBe(true)
 })
 
+test('should be able to get a document from a partition - GET /db/pkey:id - db.get', async () => {
+  // mocks
+  const response = { _id: 'partkey:id', rev: '1-123', a: 1, b: 'two', c: true }
+  const scope = nock(COUCH_URL)
+    .get('/db/partkey%3Aid')
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.get('partkey:id')
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
 test('should be able to get a document with options - GET /db/id?conflicts=true - db.get', async () => {
   // mocks
   const response = { _id: 'id', rev: '1-123', a: 1, b: 'two', c: true }
diff --git a/test/partition.find.test.js b/test/partition.find.test.js
new file mode 100644
index 0000000..325758a
--- /dev/null
+++ b/test/partition.find.test.js
@@ -0,0 +1,87 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+afterEach(() => {
+  nock.cleanAll()
+})
+
+test('should be able to query a partitioned index - POST /db/_partition/partition/_find - db.partitionedFind', async () => {
+  // mocks
+  const query = {
+    selector: {
+      $and: {
+        date: {
+          $gt: '2018'
+        },
+        name: 'Susan'
+      }
+    },
+    fields: ['name', 'date', 'orderid']
+  }
+  const response = {
+    docs: [
+      { name: 'Susan', date: '2019-01-02', orderid: '4411' },
+      { name: 'Susan', date: '2019-01-03', orderid: '8523' }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_partition/partition/_find', query)
+    .reply(200, response)
+
+  // test POST /db/_find
+  const db = nano.db.use('db')
+  const p = await db.partitionedFind('partition', query)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should handle 404 - POST /db/_partition/partition/_find - db.partitionedFind', async () => {
+  // mocks
+  const query = {
+    selector: {
+      name: 'Susan'
+    }
+  }
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_partition/partition/_find', query)
+    .reply(404, response)
+
+  // test POST /db/_find
+  const db = nano.db.use('db')
+  await expect(db.partitionedFind('partition', query)).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing query - db.partitionedFind', async () => {
+  const db = nano.db.use('db')
+  await expect(db.partitionedFind()).rejects.toThrow('Invalid parameters')
+  await expect(db.partitionedFind('partition', 'susan')).rejects.toThrow('Invalid parameters')
+})
+
+test('should detect missing query (callback) - db.partitionedFind', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.partitionedFind(undefined, '', (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/partition.findAsStream.test.js b/test/partition.findAsStream.test.js
new file mode 100644
index 0000000..340eadf
--- /dev/null
+++ b/test/partition.findAsStream.test.js
@@ -0,0 +1,60 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+afterEach(() => {
+  nock.cleanAll()
+})
+
+test('should get a queried streamed list of documents from a partition- POST /db/_partition/partition/_find - db.partitionedFindAsStream', async () => {
+  // mocks
+  const query = {
+    selector: {
+      $and: {
+        date: {
+          $gt: '2018'
+        },
+        name: 'Susan'
+      }
+    },
+    fields: ['name', 'date', 'orderid']
+  }
+  const response = {
+    docs: [
+      { name: 'Susan', date: '2019-01-02', orderid: '4411' },
+      { name: 'Susan', date: '2019-01-03', orderid: '8523' }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .post('/db/_partition/partition/_find')
+    .reply(200, response)
+
+  return new Promise((resolve, reject) => {
+    // test GET /db/_all_docs
+    const db = nano.db.use('db')
+    const s = db.partitionedFindAsStream('partition', query)
+    expect(typeof s).toBe('object')
+    let buffer = ''
+    s.on('data', (chunk) => {
+      buffer += chunk.toString()
+    })
+    s.on('end', () => {
+      expect(buffer).toBe(JSON.stringify(response))
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
diff --git a/test/partition.info.test.js b/test/partition.info.test.js
new file mode 100644
index 0000000..52c6670
--- /dev/null
+++ b/test/partition.info.test.js
@@ -0,0 +1,88 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const db = nano.db.use('db')
+const nock = require('nock')
+const response = {
+  db_name: 'db',
+  sizes: {
+    active: 12955,
+    external: 15009
+  },
+  partition: 'partition',
+  doc_count: 28,
+  doc_del_count: 0
+}
+
+afterEach(() => {
+  nock.cleanAll()
+})
+
+test('should be able to fetch partition info info - GET /db/_partition/partition - db.partitionInfo', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition')
+    .reply(200, response)
+
+  // test GET /db
+  const p = await db.partitionInfo('partition')
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to fetch partition info info (callback) - GET /db/_partition/partition - db.partitionInfo', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition')
+    .reply(200, response)
+
+  // test GET /db
+  return new Promise((resolve, reject) => {
+    db.partitionInfo('partition', (err, data) => {
+      expect(err).toBeNull()
+      expect(data).toStrictEqual(response)
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
+
+test('should handle missing database - PUT /db - nano.db.create', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition')
+    .reply(404, {
+      error: 'not_found',
+      reason: 'Database does not exist.'
+    })
+
+  // test GET /db
+  await expect(db.partitionInfo('partition')).rejects.toThrow('Database does not exist')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should not attempt info fetch with missing parameters - nano.db.get', async () => {
+  await expect(db.partitionInfo()).rejects.toThrowError('Invalid parameters')
+  await expect(db.partitionInfo('')).rejects.toThrowError('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - nano.db.get', async () => {
+  return new Promise((resolve, reject) => {
+    db.partitionInfo(undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/partition.list.test.js b/test/partition.list.test.js
new file mode 100644
index 0000000..c1b0e04
--- /dev/null
+++ b/test/partition.list.test.js
@@ -0,0 +1,150 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const db = nano.db.use('db')
+const nock = require('nock')
+const response = {
+  total_rows: 1215,
+  offset: 0,
+  rows: [
+    {
+      id: 'partition:00003it00tDmkP2Hdlkz1sMOyA12WmDj',
+      key: 'partition:00003it00tDmkP2Hdlkz1sMOyA12WmDj',
+      value: {
+        rev: '1-7feb3dec79cbff2506762ac7c8550c45'
+      }
+    },
+    {
+      id: 'partition:0000tvHi1qDnsy2Plek31OG9pw0cG8VG',
+      key: 'partition:0000tvHi1qDnsy2Plek31OG9pw0cG8VG',
+      value: {
+        rev: '1-d0c62e02a18c5b714ed94277c3852cf4'
+      }
+    },
+    {
+      id: 'partition:0000vEYK2zb89n1QMdnr1MQ5Ax0wMaUa',
+      key: 'partition:0000vEYK2zb89n1QMdnr1MQ5Ax0wMaUa',
+      value: {
+        rev: '1-42a99d13a33e46b1f37f4f937d167458'
+      }
+    },
+    {
+      id: 'partition:0003RAaK16cHJ03fOZYJ3zti9g22ppGr',
+      key: 'partition:0003RAaK16cHJ03fOZYJ3zti9g22ppGr',
+      value: {
+        rev: '1-11929970736f90c3955fda281847bf58'
+      }
+    },
+    {
+      id: 'partition:0008Cu6D1LcJm142gadC13KRDD1LNkYw',
+      key: 'partition:0008Cu6D1LcJm142gadC13KRDD1LNkYw',
+      value: {
+        rev: '1-325d1f25f719304b89c64862d2c27832'
+      }
+    }
+  ]
+}
+
+afterEach(() => {
+  nock.cleanAll()
+})
+
+test('should be list documents form a partition - GET /db/_partition/_all_docs - db.partitionedList', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition/_all_docs')
+    .reply(200, response)
+
+  // test GET /db
+  const p = await db.partitionedList('partition')
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be list documents form a partition with opts - GET /db/_partition/_all_docs - db.partitionedList', async () => {
+  // mocks
+  const optsResponse = {
+    total_rows: 1215,
+    offset: 0,
+    rows: [
+      {
+        id: 'partition:00003it00tDmkP2Hdlkz1sMOyA12WmDj',
+        key: 'partition:00003it00tDmkP2Hdlkz1sMOyA12WmDj',
+        value: {
+          rev: '1-7feb3dec79cbff2506762ac7c8550c45'
+        },
+        doc: {
+          _id: 'partition:00003it00tDmkP2Hdlkz1sMOyA12WmDj',
+          _rev: '1-7feb3dec79cbff2506762ac7c8550c45',
+          a: 1,
+          b: 2
+        }
+      }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition/_all_docs?limit=1&include_docs=true')
+    .reply(200, optsResponse)
+
+  // test GET /db
+  const p = await db.partitionedList('partition', { limit: 1, include_docs: true })
+  expect(p).toStrictEqual(optsResponse)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to list partition docs (callback) - GET /db/_partition/_all_docs - db.partitionedList', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition/_all_docs')
+    .reply(200, response)
+
+  // test GET /db
+  return new Promise((resolve, reject) => {
+    db.partitionedList('partition', (err, data) => {
+      expect(err).toBeNull()
+      expect(data).toStrictEqual(response)
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
+
+test('should handle missing database - GET /db/_partition/_all_docs - db.partitionedList', async () => {
+  // mocks
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition/_all_docs')
+    .reply(404, {
+      error: 'not_found',
+      reason: 'Database does not exist.'
+    })
+
+  // test GET /db
+  await expect(db.partitionedList('partition')).rejects.toThrow('Database does not exist')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should not attempt info fetch with missing parameters - db.partitionedList', async () => {
+  await expect(db.partitionedList()).rejects.toThrowError('Invalid parameters')
+  await expect(db.partitionedList('')).rejects.toThrowError('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.partitionedList', async () => {
+  return new Promise((resolve, reject) => {
+    db.partitionedList(undefined, (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/partition.listAsStream.test.js b/test/partition.listAsStream.test.js
new file mode 100644
index 0000000..f360cb2
--- /dev/null
+++ b/test/partition.listAsStream.test.js
@@ -0,0 +1,112 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+afterEach(() => {
+  nock.cleanAll()
+})
+
+test('should get a streamed list of documents from a partition- GET /db/_partition/partition/_all_docs - db.partitionedListAsStream', async () => {
+  // mocks
+  const response = {
+    total_rows: 23516,
+    offset: 0,
+    rows: [
+      {
+        id: 'partition:1000501',
+        key: 'partition:1000501',
+        value: {
+          rev: '2-46dcf6bf2f8d428504f5290e591aa182'
+        }
+      },
+      {
+        id: 'partition:1000543',
+        key: 'partition:1000543',
+        value: {
+          rev: '1-3256046064953e2f0fdb376211fe78ab'
+        }
+      },
+      {
+        id: 'partition:100077',
+        key: 'partition:100077',
+        value: {
+          rev: '1-101bff1251d4bd75beb6d3c232d05a5c'
+        }
+      }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition/_all_docs')
+    .reply(200, response)
+
+  return new Promise((resolve, reject) => {
+    // test GET /db/_all_docs
+    const db = nano.db.use('db')
+    const s = db.partitionedListAsStream('partition')
+    expect(typeof s).toBe('object')
+    let buffer = ''
+    s.on('data', (chunk) => {
+      buffer += chunk.toString()
+    })
+    s.on('end', () => {
+      expect(buffer).toBe(JSON.stringify(response))
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
+
+test('should get a streamed list of documents from a partition with opts- GET /db/_all_docs - db.partitionedListAsStream', async () => {
+  // mocks
+  const response = {
+    total_rows: 23516,
+    offset: 0,
+    rows: [
+      {
+        id: 'partition:1000501',
+        key: 'partition:1000501',
+        value: {
+          rev: '2-46dcf6bf2f8d428504f5290e591aa182'
+        },
+        doc: {
+          _id: 'partition:1000501',
+          _rev: '2-46dcf6bf2f8d428504f5290e591aa182',
+          a: 1,
+          b: 2
+        }
+      }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition/_all_docs?limit=1&include_docs=true')
+    .reply(200, response)
+
+  return new Promise((resolve, reject) => {
+    // test GET /db/_all_docs
+    const db = nano.db.use('db')
+    const s = db.partitionedListAsStream('partition', { limit: 1, include_docs: true })
+    expect(typeof s).toBe('object')
+    let buffer = ''
+    s.on('data', (chunk) => {
+      buffer += chunk.toString()
+    })
+    s.on('end', () => {
+      expect(buffer).toBe(JSON.stringify(response))
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
diff --git a/test/partition.search.test.js b/test/partition.search.test.js
new file mode 100644
index 0000000..9f470fb
--- /dev/null
+++ b/test/partition.search.test.js
@@ -0,0 +1,78 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+afterEach(() => {
+  nock.cleanAll()
+})
+
+test('should be able to access a partitioned search index - POST /db/_partition/partition/_design/ddoc/_search/searchname - db.partitionedSearch', async () => {
+  // mocks
+  const response = {
+    total_rows: 100000,
+    bookmark: 'g123',
+    rows: [
+      { a: 1, b: 2 }
+    ]
+  }
+  const params = { q: '*:*' }
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition/_design/ddoc/_search/searchname?q=*:*')
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.partitionedSearch('partition', 'ddoc', 'searchname', params)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 404 - db.partitionedSearch', async () => {
+  // mocks
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const params = { q: '*:*' }
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition/_design/ddoc/_search/searchname?q=*:*')
+    .reply(404, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  await expect(db.partitionedSearch('partition', 'ddoc', 'searchname', params)).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing parameters - db.partitionedSearch', async () => {
+  const db = nano.db.use('db')
+  await expect(db.partitionedSearch()).rejects.toThrow('Invalid parameters')
+  await expect(db.partitionedSearch('partition', 'susan')).rejects.toThrow('Invalid parameters')
+  await expect(db.partitionedSearch('partition', 'susan', '')).rejects.toThrow('Invalid parameters')
+  await expect(db.partitionedSearch('partition', '', 'susan')).rejects.toThrow('Invalid parameters')
+  await expect(db.partitionedSearch('partition', 'susan', '', undefined)).rejects.toThrow('Invalid parameters')
+  await expect(db.partitionedSearch('partition', '', 'susan')).rejects.toThrow('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.partitionedSearch', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.partitionedSearch('', '', '', '', (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/partition.searchAsStream.test.js b/test/partition.searchAsStream.test.js
new file mode 100644
index 0000000..73faabd
--- /dev/null
+++ b/test/partition.searchAsStream.test.js
@@ -0,0 +1,51 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+afterEach(() => {
+  nock.cleanAll()
+})
+
+test('should get a searched streamed list of documents from a partition- GET /db/_partition/partition/_design/ddoc/_search/searchname - db.partitionedSearchAsStream', async () => {
+  // mocks
+  const response = {
+    total_rows: 100000,
+    bookmark: 'g123',
+    rows: [
+      { a: 1, b: 2 }
+    ]
+  }
+  const params = { q: '*:*' }
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition/_design/ddoc/_search/searchname?q=*:*')
+    .reply(200, response)
+
+  return new Promise((resolve, reject) => {
+    // test GET /db/_all_docs
+    const db = nano.db.use('db')
+    const s = db.partitionedSearchAsStream('partition', 'ddoc', 'searchname', params)
+    expect(typeof s).toBe('object')
+    let buffer = ''
+    s.on('data', (chunk) => {
+      buffer += chunk.toString()
+    })
+    s.on('end', () => {
+      expect(buffer).toBe(JSON.stringify(response))
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})
diff --git a/test/partition.view.test.js b/test/partition.view.test.js
new file mode 100644
index 0000000..7338fcb
--- /dev/null
+++ b/test/partition.view.test.js
@@ -0,0 +1,98 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+afterEach(() => {
+  nock.cleanAll()
+})
+
+test('should be able to access a partitioned view index - GET /db/_partition/partition/_design/ddoc/_view/viewname - db.partitionedView', async () => {
+  // mocks
+  const response = {
+    rows: [
+      { key: null, value: 23515 }
+    ]
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition/_design/ddoc/_view/viewname')
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.partitionedView('partition', 'ddoc', 'viewname')
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to access a partitioned view index with opts - GET /db/_partition/partition/_design/ddoc/_view/viewname - db.partitionedView', async () => {
+  // mocks
+  const response = {
+    rows: [
+      { key: 'a', value: null }
+    ]
+  }
+  const params = {
+    reduce: false,
+    startkey: 'a',
+    endkey: 'b',
+    limit: 1
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition/_design/ddoc/_view/viewname?reduce=false&startkey=%22a%22&endkey=%22b%22&limit=1')
+    .reply(200, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  const p = await db.partitionedView('partition', 'ddoc', 'viewname', params)
+  expect(p).toStrictEqual(response)
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should be able to handle 404 - db.partitionedView', async () => {
+  // mocks
+  const response = {
+    error: 'not_found',
+    reason: 'missing'
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition/_design/ddoc/_view/viewname')
+    .reply(404, response)
+
+  // test GET /db
+  const db = nano.db.use('db')
+  await expect(db.partitionedView('partition', 'ddoc', 'viewname')).rejects.toThrow('missing')
+  expect(scope.isDone()).toBe(true)
+})
+
+test('should detect missing parameters - db.partitionedView', async () => {
+  const db = nano.db.use('db')
+  await expect(db.partitionedView()).rejects.toThrow('Invalid parameters')
+  await expect(db.partitionedView('partition', 'susan')).rejects.toThrow('Invalid parameters')
+  await expect(db.partitionedView('partition', 'susan', '')).rejects.toThrow('Invalid parameters')
+  await expect(db.partitionedView('partition', '', 'susan')).rejects.toThrow('Invalid parameters')
+  await expect(db.partitionedView('partition', 'susan', '', undefined)).rejects.toThrow('Invalid parameters')
+  await expect(db.partitionedView('partition', '', 'susan')).rejects.toThrow('Invalid parameters')
+})
+
+test('should detect missing parameters (callback) - db.partitionedView', async () => {
+  const db = nano.db.use('db')
+  return new Promise((resolve, reject) => {
+    db.partitionedView('', '', '', '', (err, data) => {
+      expect(err).not.toBeNull()
+      resolve()
+    })
+  })
+})
diff --git a/test/partition.viewAsStream.test.js b/test/partition.viewAsStream.test.js
new file mode 100644
index 0000000..24a899f
--- /dev/null
+++ b/test/partition.viewAsStream.test.js
@@ -0,0 +1,54 @@
+// Licensed under the Apache License, Version 2.0 (the 'License'); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+const Nano = require('..')
+const COUCH_URL = 'http://localhost:5984'
+const nano = Nano(COUCH_URL)
+const nock = require('nock')
+
+afterEach(() => {
+  nock.cleanAll()
+})
+
+test('should get a streamed list of documents from a view from  partition- GET /db/_partition/partition/_design/ddoc/_view/viewname - db.partitionedViewAsStream', async () => {
+  // mocks
+  const response = {
+    rows: [
+      { key: 'a', value: null }
+    ]
+  }
+  const params = {
+    reduce: false,
+    startkey: 'a',
+    endkey: 'b',
+    limit: 1
+  }
+  const scope = nock(COUCH_URL)
+    .get('/db/_partition/partition/_design/ddoc/_view/viewname?reduce=false&startkey=%22a%22&endkey=%22b%22&limit=1')
+    .reply(200, response)
+
+  return new Promise((resolve, reject) => {
+    // test GET /db/_all_docs
+    const db = nano.db.use('db')
+    const s = db.partitionedViewAsStream('partition', 'ddoc', 'viewname', params)
+    expect(typeof s).toBe('object')
+    let buffer = ''
+    s.on('data', (chunk) => {
+      buffer += chunk.toString()
+    })
+    s.on('end', () => {
+      expect(buffer).toBe(JSON.stringify(response))
+      expect(scope.isDone()).toBe(true)
+      resolve()
+    })
+  })
+})


[couchdb-nano] 15/15: standard styling of examples

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

glynnbird pushed a commit to branch jest
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git

commit 4d1122af8b24fa2bfa96dcb6a5647cd6f51c032e
Author: Glynn Bird <gl...@gmail.com>
AuthorDate: Wed Feb 12 11:18:54 2020 +0000

    standard styling of examples
---
 examples/lazy_creation_of_views.js           | 6 ++++--
 examples/lazy_db_creation_and_replication.js | 7 ++++---
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/examples/lazy_creation_of_views.js b/examples/lazy_creation_of_views.js
index 7e7fbe6..7bb08c0 100644
--- a/examples/lazy_creation_of_views.js
+++ b/examples/lazy_creation_of_views.js
@@ -13,8 +13,10 @@
 module.exports = function () {
   const nano = require('nano')('http://localhost:5984')
   const users = nano.use('users')
-  const VIEWS = { by_twitter_id:
-    { 'map': 'function(doc) { emit(doc.twitter.screen_name, doc); }' } }
+  const VIEWS = {
+    by_twitter_id:
+    { map: 'function(doc) { emit(doc.twitter.screen_name, doc); }' }
+  }
 
   /*****************************************************************************
  * user.get()
diff --git a/examples/lazy_db_creation_and_replication.js b/examples/lazy_db_creation_and_replication.js
index 7b7d5c2..46df559 100644
--- a/examples/lazy_db_creation_and_replication.js
+++ b/examples/lazy_db_creation_and_replication.js
@@ -12,8 +12,9 @@
 
 const nano = require('nano')
 const couch =
-    { 'master': 'http://localhost:5984/landing_m',
-      'replica': 'http://localhost:5984/landing_r'
+    {
+      master: 'http://localhost:5984/landing_m',
+      replica: 'http://localhost:5984/landing_r'
     }
 
 function insertWithRetry (db, email, retries, callback) {
@@ -47,7 +48,7 @@ function replicateWithRetry (masterUri, replicaUri, retries, callback) {
   retries = retries || 0
   var master = nano(couch.master)
   master.replicate(couch.replica, function (err, resp, head) {
-    if (err && err['error'] === 'db_not_found' && retries < 1) {
+    if (err && err.error === 'db_not_found' && retries < 1) {
       const replica = nano(couch.replica)
       const dbName = replica.config.db
       const server = nano(replica.config.url)