Port old JS Spec tests to Mocha
Changes that happened to jquery.couch.js which were not
reflected by the current failing JSpec Testsuite and
required changes to the testuite:
- jquery.couch returns the time for the request and not an
object with an url property
- jquery.couch does not show alerts any more
- success callbacks don't return a status any more
- db.copyDoc expects an docid as target in the first option object,
not a third parameter with an `Destination` property
COUCHDB-1566
diff --git a/README.md b/README.md
index 3403e2d..5fae08e 100644
--- a/README.md
+++ b/README.md
@@ -10,4 +10,11 @@
$ bower install
```
-Open `test/runner.html` in a browser to run the testsuite.
+Enable CORS:
+
+```
+curl -X PUT http://localhost:5984/_config/httpd/enable_cors -d '"true"'
+curl -X PUT http://localhost:5984/_config/cors/origins -d '"*"'
+```
+
+Restart CouchDB & open `test/runner.html` in a browser to run the testsuite.
diff --git a/test/runner.html b/test/runner.html
index 3512877..da5766e 100644
--- a/test/runner.html
+++ b/test/runner.html
@@ -32,6 +32,9 @@
</script>
<script src="../jquery.couch.js"></script>
<script src="test.js"></script>
+ <script src="test_spec_1.js"></script>
+ <script src="test_spec_2.js"></script>
+ <script src="test_spec_3.js"></script>
<script>
mocha.checkLeaks();
mocha.globals(['jQuery']);
diff --git a/test/test.js b/test/test.js
index a3cf33c..a74dfad 100644
--- a/test/test.js
+++ b/test/test.js
@@ -15,7 +15,7 @@
(function () {
var assert = chai.assert;
- describe('jquery.couch.js', function () {
+ describe('test.js', function () {
it('should be an object as a jquery function', function () {
assert.equal(typeof $.couch, 'object');
});
diff --git a/test/test_spec_1.js b/test/test_spec_1.js
new file mode 100644
index 0000000..5b7bb64
--- /dev/null
+++ b/test/test_spec_1.js
@@ -0,0 +1,258 @@
+// 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.
+
+// Specs for jquery_couch.js lines 163-209
+
+
+(function () {
+ 'use strict';
+
+ var assert = chai.assert;
+
+ function successCallback (resp) {
+ console.log('No error message here unexpectedly, successful response instead.');
+ throw('No error message here unexpectedly, successful response instead.');
+ }
+
+ function errorCallback (status, error, reason) {
+ console.log('Unexpected ' + status + ' error: ' + error + ' - ' + reason);
+ throw('Unexpected ' + status + ' error: ' + error + ' - ' + reason);
+ }
+
+ describe('test_spec_1.js', function () {
+ var db;
+
+ function dropCb (db, done) {
+ db.drop({
+ success: function () {
+ done();
+ },
+ error: function () {
+ done();
+ }
+ });
+ }
+
+ function createCb (db, done) {
+ db.create({
+ success: function () {
+ done();
+ },
+ error: function () {
+ done();
+ }
+ });
+ }
+
+ beforeEach(function () {
+ $.couch.urlPrefix = 'http://localhost:5984';
+ db = $.couch.db('spec_db');
+ });
+
+ describe('constructor', function () {
+ it('should set the name', function () {
+ assert.equal(db.name, 'spec_db');
+ });
+
+ it('should set the uri', function () {
+ assert.equal(db.uri, 'http://localhost:5984/spec_db/');
+ });
+ });
+
+ describe('triggering db functions', function () {
+ beforeEach(function (done) {
+ createCb(db, done);
+ });
+
+ afterEach(function (done) {
+ dropCb(db, done);
+ });
+
+ describe('compact', function () {
+ it('should return ok true', function (done) {
+ db.compact({
+ success: function (resp) {
+ assert.ok(resp.ok);
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('retuns a request time', function (done) {
+ db.compact({
+ success: function (resp, time) {
+ assert.equal(typeof time, 'number');
+ done();
+ },
+ error: errorCallback
+ });
+ });
+ });
+
+ describe('viewCleanup', function () {
+ it('should return ok true', function (done) {
+ db.viewCleanup({
+ success: function (resp) {
+ assert.ok(resp.ok);
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('retuns a request time', function (done) {
+ db.viewCleanup({
+ success: function (resp, time) {
+ assert.equal(typeof time, 'number');
+ done();
+ },
+ error: errorCallback
+ });
+ });
+ });
+
+ describe('compactView', function () {
+ beforeEach(function (done) {
+ createCb(db, done);
+ var designDoc = {
+ 'views' : {
+ 'people' : {
+ 'map' : 'function(doc) { emit(doc._id, doc); }'
+ }
+ },
+ '_id' : '_design/myview'
+ };
+ db.saveDoc(designDoc);
+ db.saveDoc({'Name' : 'Felix Gaeta', '_id' : '123'});
+ });
+
+ afterEach(function (done) {
+ dropCb(db, done);
+ });
+
+ it('should return ok true', function (done) {
+ db.compactView('/myview', {
+ success: function (resp) {
+ assert.ok(resp.ok);
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('retuns a request time', function (done) {
+ db.compactView('/myview', {
+ success: function (resp, time) {
+ assert.equal(typeof time, 'number');
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should return raise a 404 error when the design name doesnt exist', function (done) {
+ db.compactView('non_existing_design_name', {
+ error: function (status, error, reason) {
+ assert.equal(status, 404);
+ assert.equal(error, 'not_found');
+ assert.equal(reason, 'missing');
+ done();
+ },
+ success: function (resp) {
+ successCallback(resp);
+ }
+ });
+ });
+ });
+
+ describe('create', function () {
+ beforeEach(function (done) {
+ dropCb(db, done);
+ });
+
+ after(function (done) {
+ dropCb(db, done);
+ });
+
+ it('should return ok true', function (done) {
+ db.create({
+ success: function (resp) {
+ assert.ok(resp.ok);
+ done();
+ },
+ error: function (status, error, reason) {
+ errorCallback(status, error, reason);
+ done();
+ }
+ });
+ });
+
+ it('should result in a created db', function (done) {
+ db.create({
+ success: function () {
+ db.create({
+ error: function (status, error, reason) {
+ assert.equal(status, 412);
+ assert.equal(error, 'file_exists');
+ assert.equal(reason, 'The database could not be created, the file already exists.');
+ done();
+ },
+ success: function (resp) {
+ successCallback(resp);
+ }
+ });
+ }
+ });
+ });
+ });
+
+ describe('drop', function () {
+ beforeEach(function (done) {
+ createCb(db, done);
+ });
+
+ after(function (done) {
+ dropCb(db, done);
+ });
+
+ it('should return ok true', function (done) {
+ db.drop({
+ success: function (resp) {
+ assert.ok(resp.ok);
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should result in a deleted db', function (done) {
+ db.drop({
+ success: function () {
+ db.drop({
+ error: function (status, error, reason) {
+ assert.equal(status, 404);
+ assert.equal(error, 'not_found');
+ assert.equal(reason, 'missing');
+ done();
+ },
+ success: function (resp) {
+ successCallback(resp);
+ }
+ });
+ }
+ });
+ });
+ });
+ });
+ });
+})();
diff --git a/test/test_spec_2.js b/test/test_spec_2.js
new file mode 100644
index 0000000..d8d1f09
--- /dev/null
+++ b/test/test_spec_2.js
@@ -0,0 +1,478 @@
+// 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.
+
+// Specs for jquery_couch.js lines 210-299
+
+
+(function () {
+ 'use strict';
+
+ var assert = chai.assert;
+
+ function successCallback (resp) {
+ console.log('No error message here unexpectedly, successful response instead.');
+ throw('No error message here unexpectedly, successful response instead.');
+ }
+
+ function errorCallback (status, error, reason) {
+ console.log('Unexpected ' + status + ' error: ' + error + ' - ' + reason);
+ throw('Unexpected ' + status + ' error: ' + error + ' - ' + reason);
+ }
+
+ describe('test_spec_2.js', function () {
+ var db;
+
+ function dropCb (db, done) {
+ db.drop({
+ success: function () {
+ done();
+ },
+ error: function () {
+ done();
+ }
+ });
+ }
+
+ function createCb (db, done) {
+ db.create({
+ success: function () {
+ done();
+ },
+ error: function () {
+ done();
+ }
+ });
+ }
+
+ beforeEach(function (done) {
+ $.couch.urlPrefix = 'http://localhost:5984';
+ db = $.couch.db('spec_db');
+ createCb(db, done);
+ });
+
+ afterEach(function (done) {
+ dropCb(db, done);
+ });
+
+ describe('info', function () {
+ var res;
+ beforeEach(function (done) {
+ db.info({
+ success: function (resp) {
+ res = resp;
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should return the name of the database', function () {
+ assert.equal(res.db_name, 'spec_db');
+ });
+
+ it('should return the number of documents', function () {
+ assert.equal(res.doc_count, 0);
+ });
+
+ it('should return the start time of the db instance', function () {
+ assert.equal(typeof res.instance_start_time, 'string');
+ });
+ });
+
+ describe('allDocs', function () {
+ var res;
+
+ it('should return no docs when there arent any', function (done) {
+ db.allDocs({
+ success: function (resp) {
+ assert.equal(resp.total_rows, 0);
+ assert.deepEqual(resp.rows, []);
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ describe('with docs', function () {
+ beforeEach(function (done) {
+ db.saveDoc({'Name': 'Felix Gaeta', '_id': '123'}, {
+ success: function () {
+ db.saveDoc({'Name': 'Samuel T. Anders', '_id': '456'}, {
+ success: function () {
+ done();
+ }
+ });
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should return all docs', function (done) {
+ db.allDocs({
+ success: function (resp) {
+ assert.equal(resp.total_rows, 2);
+ assert.equal(resp.rows.length, 2);
+ assert.equal(resp.rows[0].id, '123');
+ assert.equal(resp.rows[0].key, '123');
+ assert.ok(resp.rows[0].value.rev.length > 30);
+ assert.equal(resp.rows[1].id, '456');
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should pass through the options', function (done) {
+ db.allDocs({
+ 'startkey': '123',
+ 'limit': '1',
+ success: function (resp) {
+ assert.equal(resp.rows.length, 1);
+ assert.equal(resp.rows[0].id, '123');
+ done();
+ },
+ error: errorCallback
+ });
+ });
+ });
+ });
+
+ describe('allDesignDocs', function () {
+ it('should return nothing when there arent any design docs', function (done) {
+ db.saveDoc({'Name': 'Felix Gaeta', '_id': '123'}, {
+ success: function () {
+ db.allDesignDocs({
+ success: function (resp) {
+ assert.deepEqual(resp.rows, []);
+ done();
+ },
+ error: errorCallback
+ });
+ }
+ });
+ });
+
+ it('should return all design docs', function (done) {
+ var designDoc = {
+ 'views' : {
+ 'people' : {
+ 'map' : 'function(doc) { emit(doc._id, doc); }'
+ }
+ },
+ '_id' : '_design/spec_db'
+ };
+ db.saveDoc(designDoc, {
+ success: cb
+ });
+
+ function cb () {
+ db.saveDoc({'Name': 'Felix Gaeta', '_id': '123'}, {
+ success: function () {
+ db.allDesignDocs({
+ success: function (resp) {
+ db.allDesignDocs({
+ success: function (resp) {
+ assert.equal(resp.total_rows, 2);
+ assert.equal(resp.rows.length, 1);
+ assert.equal(resp.rows[0].id, '_design/spec_db');
+ assert.equal(resp.rows[0].key, '_design/spec_db');
+ assert.ok(resp.rows[0].value.rev.length > 30);
+ done();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+ }
+ });
+ }
+ });
+ });
+
+ describe('allApps', function () {
+ it('should provide a custom function with appName, appPath and design' +
+ 'document when there is an attachment with index.html', function (done) {
+
+ var designDoc = {'_id' : '_design/with_attachments'};
+
+ designDoc._attachments = {
+ 'index.html' : {
+ 'content_type': 'text\/html',
+ // this is '<html><p>Hi, here is index!</p></html>', base64 encoded
+ 'data': 'PGh0bWw+PHA+SGksIGhlcmUgaXMgaW5kZXghPC9wPjwvaHRtbD4='
+ }
+ };
+ db.saveDoc(designDoc, {
+ success: function () {
+ db.allApps({
+ eachApp: function (appName, appPath, ddoc) {
+ assert.equal(appName, 'with_attachments');
+ assert.equal(appPath, '/spec_db/_design/with_attachments/index.html');
+ assert.equal(ddoc._id, '_design/with_attachments');
+ assert.equal(ddoc._attachments['index.html'].content_type, 'text/html');
+ assert.equal(ddoc._attachments['index.html'].length,
+ '<html><p>Hi, here is index!</p></html>'.length);
+ done();
+ },
+ error: errorCallback
+ });
+ }
+ });
+ });
+
+ it('should provide a custom function with appName, appPath' +
+ 'and design document when there is a couchapp with index file', function (done) {
+
+ var designDoc = {'_id' : '_design/with_index'};
+ designDoc.couchapp = {
+ 'index': 'cylon'
+ };
+ db.saveDoc(designDoc, {
+ success: function () {
+ db.allApps({
+ eachApp: function (appName, appPath, ddoc) {
+ assert.equal(appName, 'with_index');
+ assert.equal(appPath, '/spec_db/_design/with_index/cylon');
+ assert.equal(ddoc._id, '_design/with_index');
+ assert.equal(ddoc.couchapp.index, 'cylon');
+ done();
+ },
+ error: errorCallback
+ });
+ }
+ });
+ });
+ });
+
+ describe('openDoc', function () {
+ var doc = {'Name': 'Louanne Katraine', 'Callsign': 'Kat', '_id': '123'};
+ beforeEach(function (done) {
+ db.saveDoc(doc, {
+ success: function () {
+ done();
+ }
+ });
+ });
+
+ it('should open the document', function (done) {
+ db.openDoc('123', {
+ success: function (resp) {
+ assert.deepEqual(resp, doc);
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should raise a 404 error when there is no document with' +
+ 'the given ID', function (done) {
+ db.openDoc('non_existing', {
+ success: function (status, error, reason) {
+
+ },
+ error: function (status, error, reason) {
+ assert.equal(status, 404);
+ assert.equal(error, 'not_found');
+ assert.equal(reason, 'missing');
+ done();
+ }
+ });
+ });
+
+ it('should pass through the options', function (done) {
+ doc.name = 'Sasha';
+ db.saveDoc(doc, {
+ success: function () {
+ db.openDoc('123', {
+ revs: true,
+ success: function (resp) {
+ assert.equal(resp._revisions.start, 4);
+ assert.equal(resp._revisions.ids.length, 3);
+ done();
+ },
+ error: errorCallback
+ });
+ }
+ });
+ });
+ });
+
+ describe('saveDoc', function () {
+ var doc = {'Name': 'Kara Thrace', 'Callsign': 'Starbuck'};
+
+ it('should save the document and return ok: true', function (done) {
+ db.saveDoc(doc, {
+ success: function (resp) {
+ assert.ok(resp.ok);
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should return ID and revision of the document', function (done) {
+ db.saveDoc(doc, {
+ success: function (resp) {
+ assert.equal(typeof resp.id, 'string');
+ assert.equal(typeof resp.rev, 'string');
+ assert.ok(resp.rev.length > 30);
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should result in a saved document with generated ID', function (done) {
+ db.saveDoc(doc, {
+ success: function (resp) {
+ db.openDoc(resp.id, {
+ success: function (resp2) {
+ assert.equal(resp2.Name, 'Kara Thrace');
+ assert.equal(resp2.Callsign, 'Starbuck');
+ done();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should save the document with the specified ID', function (done) {
+ doc._id = '123';
+ db.saveDoc(doc, {
+ success: function (resp) {
+ assert.equal(resp.id, '123');
+ done();
+ },
+ error: errorCallback
+ });
+ });
+ });
+
+ describe('bulkSave', function () {
+ var doc = {'Name': 'Kara Thrace', 'Callsign': 'Starbuck'},
+ doc2 = {'Name': 'Karl C. Agathon', 'Callsign': 'Helo'},
+ doc3 = {'Name': 'Sharon Valerii', 'Callsign': 'Boomer'},
+ docs = [doc, doc2, doc3];
+
+ it('should save all documents', function (done) {
+ db.bulkSave({'docs': docs}, {
+ success: function (resp) {
+ db.allDocs({
+ success: function (resp) {
+ assert.equal(resp.total_rows, 3);
+ done();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should result in saved documents', function (done) {
+ doc3._id = '789';
+ db.bulkSave({'docs': docs}, {
+ success: function (resp) {
+ db.openDoc('789', {
+ success: function (resp) {
+ assert.equal(resp.Name, 'Sharon Valerii');
+ assert.equal(resp.Callsign, 'Boomer');
+ done();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should return ID and revision of the documents', function (done) {
+ db.bulkSave({'docs': docs}, {
+ success: function (resp) {
+ assert.equal(typeof resp[0].id, 'string');
+ assert.equal(typeof resp[1].id, 'string');
+ assert.equal(typeof resp[2].id, 'string');
+
+ assert.equal(typeof resp[0].rev, 'string');
+ assert.equal(typeof resp[1].rev, 'string');
+ assert.equal(typeof resp[2].rev, 'string');
+
+ assert.ok(resp[0].rev.length > 30);
+ assert.ok(resp[1].rev.length > 30);
+ assert.ok(resp[2].rev.length > 30);
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should return ID and revision of the documents', function (done) {
+ doc._id = '123';
+ doc2._id = '456';
+ docs = [doc, doc2, doc3];
+
+ db.bulkSave({'docs': docs}, {
+ success: function (resp) {
+ assert.equal(resp[0].id, '123');
+ assert.equal(resp[1].id, '456');
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should pass through the options', function (done) {
+ // a lengthy way to test that a conflict can't be created with the
+ // all_or_nothing option set to false, but can be when it's true.
+
+ var oldDoc = {'Name': 'Louanne Katraine', 'Callsign': 'Kat', '_id': '123'};
+ var newDoc = {'Name': 'Sasha', 'Callsign': 'Kat', '_id': '123'};
+ db.saveDoc(oldDoc, {
+ success: function (resp) {
+ oldDoc._rev = resp.rev;
+ db.bulkSave({'docs': [newDoc], 'all_or_nothing': false}, {
+ success: function (resp) {
+ assert.equal(resp[0].id, '123');
+ assert.equal(resp[0].error, 'conflict');
+ assert.equal(resp[0].reason, 'Document update conflict.');
+ next();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+
+ function next () {
+ db.bulkSave({'docs': [newDoc], 'all_or_nothing': true}, {
+ success: function (resp) {
+ assert.equal(resp[0].id, '123');
+ assert.notEqual(resp[0].rev, oldDoc._rev);
+ db.openDoc('123', {
+ 'conflicts': true,
+ success: function (resp) {
+ assert.equal(resp._conflicts[0], oldDoc._rev);
+ done();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+ }
+ });
+ });
+ });
+})();
diff --git a/test/test_spec_3.js b/test/test_spec_3.js
new file mode 100644
index 0000000..652a5c2
--- /dev/null
+++ b/test/test_spec_3.js
@@ -0,0 +1,626 @@
+// 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.
+
+// Specs for jquery_couch.js lines 300-411
+
+
+(function () {
+ 'use strict';
+
+ var assert = chai.assert;
+
+ function successCallback (resp) {
+ console.log('No error message here unexpectedly, successful response instead.');
+ throw('No error message here unexpectedly, successful response instead.');
+ }
+
+ function errorCallback (status, error, reason) {
+ console.log('Unexpected ' + status + ' error: ' + error + ' - ' + reason);
+ throw('Unexpected ' + status + ' error: ' + error + ' - ' + reason);
+ }
+
+ describe('test_spec_3.js', function () {
+ var db;
+
+ function dropCb (db, done) {
+ db.drop({
+ success: function () {
+ done();
+ },
+ error: function () {
+ done();
+ }
+ });
+ }
+
+ function createCb (db, done) {
+ db.create({
+ success: function () {
+ done();
+ },
+ error: function () {
+ done();
+ }
+ });
+ }
+
+ beforeEach(function (done) {
+ $.couch.urlPrefix = 'http://localhost:5984';
+ db = $.couch.db('spec_db');
+ createCb(db, done);
+ });
+
+ afterEach(function (done) {
+ dropCb(db, done);
+ });
+
+ describe('removeDoc', function () {
+ var doc = {'Name': 'Louanne Katraine', 'Callsign': 'Kat', '_id': '345'},
+ savedDoc;
+
+ beforeEach(function (done) {
+ db.saveDoc(doc, {
+ success: function (resp) {
+ savedDoc = resp;
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should result in a deleted document', function (done) {
+ db.removeDoc({_id : '345', _rev: savedDoc.rev}, {
+ success: function (resp) {
+ db.openDoc('345', {
+ error: function (status, error, reason) {
+ assert.equal(status, 404);
+ assert.equal(error, 'not_found');
+ assert.equal(reason, 'deleted');
+ done();
+ },
+ success: successCallback
+ });
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should return ok true, the ID and the revision of the deleted document', function (done) {
+ db.removeDoc({_id : '345', _rev: savedDoc.rev}, {
+ success: function (resp) {
+ assert.ok(resp.ok);
+ assert.equal(resp.id, '345');
+ assert.equal(typeof resp.rev, 'string');
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should record the revision in the deleted document', function (done) {
+ db.removeDoc({_id : '345', _rev: savedDoc.rev}, {
+ success: function (resp) {
+ db.openDoc('345', {
+ rev: resp.rev,
+ success: function (resp2) {
+ assert.equal(resp2._id, resp.id);
+ assert.equal(resp2._rev, resp.rev);
+ assert.ok(resp2._deleted);
+ done();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+ });
+ });
+
+ describe('bulkRemove', function () {
+ var doc, doc2, doc3, docs;
+
+ beforeEach(function (done) {
+ doc = {'Name': 'Kara Thrace', 'Callsign': 'Starbuck', '_id': '123'};
+ doc2 = {'Name': 'Karl C. Agathon', 'Callsign': 'Helo', '_id': '456'};
+ doc3 = {'Name': 'Sharon Valerii', 'Callsign': 'Boomer', '_id': '789'};
+ docs = [doc, doc2, doc3];
+
+ db.bulkSave({'docs': docs}, {
+ ensure_full_commit: true,
+ success: function (resp) {
+ for (var i = 0; i < docs.length; i++) {
+ docs[i]._rev = resp[i].rev;
+ }
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should remove all documents specified', function (done) {
+ db.bulkRemove({'docs': docs}, {
+ ensure_full_commit: true,
+ success: function () {
+ db.allDocs({
+ success: function (resp) {
+ assert.equal(resp.total_rows, 0);
+ done();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should not remove documents that should not have been deleted', function (done) {
+ db.bulkRemove({'docs': [doc3]}, {
+ success: function (resp) {
+ db.allDocs({
+ success: function (resp) {
+ assert.equal(resp.total_rows, 2);
+ done();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should result in deleted documents', function (done) {
+ db.bulkRemove({'docs': docs}, {
+ success: function (resp) {
+ db.openDoc('123', {
+ error: function (status, error, reason) {
+ assert.equal(status, 404);
+ assert.equal(error, 'not_found');
+ assert.equal(reason, 'deleted');
+ done();
+ },
+ success: successCallback
+ });
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should return the ID and the revision of the deleted documents', function (done) {
+ db.bulkRemove({'docs': docs}, {
+ success: function (resp) {
+ assert.equal(resp[0].id, '123');
+ assert.equal(resp[1].id, '456');
+ assert.equal(resp[2].id, '789');
+
+ assert.equal(typeof resp[0].rev, 'string');
+ assert.equal(typeof resp[1].rev, 'string');
+ assert.equal(typeof resp[2].rev, 'string');
+
+ assert.ok(resp[0].rev.length > 30);
+ assert.ok(resp[1].rev.length > 30);
+ assert.ok(resp[2].rev.length > 30);
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should record the revision in the deleted documents', function (done) {
+ db.bulkRemove({'docs': docs}, {
+ success: function (resp) {
+ db.openDoc('123', {
+ rev: resp[0].rev,
+ success: function (resp2) {
+ assert.equal(resp2._rev, resp[0].rev);
+ assert.equal(resp2._id, resp[0].id);
+ assert.ok(resp2._deleted);
+ done();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+ });
+ });
+
+ describe('copyDoc', function () {
+ var doc;
+ beforeEach(function (done) {
+ doc = {'Name': 'Sharon Agathon', 'Callsign': 'Athena', '_id': '123'};
+ db.saveDoc(doc, {
+ success: function () {
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should result in another document with same data and new id', function (done) {
+ db.copyDoc('123', {
+ docid: '456',
+ success: function (resp) {
+ assert.equal(resp.id, '456');
+ assert.ok(resp.rev.length > 30);
+ db.openDoc('456', {
+ success: function (resp) {
+ assert.equal(resp.Name, 'Sharon Agathon');
+ assert.equal(resp.Callsign, 'Athena');
+ done();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should throw an error when trying to overwrite a document' +
+ 'without providing a revision', function (done) {
+ var doc2 = {'Name': 'Louanne Katraine', 'Callsign': 'Kat', '_id': '456'};
+ db.saveDoc(doc2, {
+ success: function (resp) {
+ db.copyDoc('123', {
+ docid: '456',
+ error: function (status, error, reason) {
+ assert.equal(status, 409);
+ assert.equal(error, 'conflict');
+ assert.equal(reason, 'Document update conflict.');
+ done();
+ },
+ success: successCallback
+ });
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should overwrite a document with the correct revision', function (done) {
+ var doc2 = {'Name': 'Louanne Katraine', 'Callsign': 'Kat', '_id': '456'},
+ doc2Rev;
+
+ db.saveDoc(doc2, {
+ success: function (resp) {
+ doc2Rev = resp.rev;
+ next();
+ },
+ error: errorCallback
+ });
+
+ function next () {
+ db.copyDoc('123', {
+ docid: 456,
+ rev: doc2Rev,
+ success: function (resp) {
+ assert.equal(resp.id, '456');
+ assert.ok(resp.rev.length > 30);
+ db.openDoc('456', {
+ success: function (resp) {
+ assert.equal(resp.Name, 'Sharon Agathon');
+ assert.equal(resp.Callsign, 'Athena');
+ done();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+ }
+ });
+ });
+
+ describe('query', function () {
+ var docs, mapFunction, reduceFunction;
+ beforeEach(function (done) {
+ docs = [
+ {'Name': 'Cally Tyrol', 'job': 'deckhand', '_id': '789'},
+ {'Name': 'Felix Gaeta', 'job': 'officer', '_id': '123'},
+ {'Name': 'Samuel T. Anders', 'job': 'pilot', '_id': '456'},
+ ];
+ mapFunction = 'function (doc) { emit(doc._id, 1); }';
+ reduceFunction = 'function (key, values, rereduce) { return sum(values); }';
+
+ db.bulkSave({'docs': docs}, {
+ ensure_full_commit: true,
+ success: function (resp) {
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should apply the map function', function (done) {
+ db.query(mapFunction, null, null, {
+ success: function (resp) {
+ assert.equal(resp.rows.length, 3);
+
+ assert.equal(resp.rows[0].id, '123');
+ assert.equal(resp.rows[0].key, '123');
+ assert.equal(resp.rows[0].value, 1);
+
+ assert.equal(resp.rows[1].id, '456');
+ assert.equal(resp.rows[1].key, '456');
+ assert.equal(resp.rows[1].value, 1);
+
+ assert.equal(resp.rows[2].id, '789');
+ assert.equal(resp.rows[2].key, '789');
+ assert.equal(resp.rows[2].value, 1);
+
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should apply the reduct function', function (done) {
+ db.query(mapFunction, reduceFunction, null, {
+ success: function (resp) {
+ assert.equal(resp.rows.length, 1);
+ assert.equal(resp.rows[0].key, null);
+ assert.equal(resp.rows[0].value, 3);
+
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should pass through the options', function (done) {
+ db.query(mapFunction, null, null, {
+ startkey: '456',
+ success: function (resp) {
+ assert.equal(resp.rows.length, 2);
+
+ assert.equal(resp.rows[0].id, '456');
+ assert.equal(resp.rows[0].key, '456');
+ assert.equal(resp.rows[0].value, 1);
+
+ assert.equal(resp.rows[1].id, '789');
+ assert.equal(resp.rows[1].key, '789');
+ assert.equal(resp.rows[1].value, 1);
+
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should pass through the keys', function (done) {
+ db.query(mapFunction, null, null, {
+ keys: ['456', '123'],
+ success: function (resp) {
+ assert.equal(resp.rows.length, 2);
+
+ assert.equal(resp.rows[0].id, '456');
+ assert.equal(resp.rows[0].key, '456');
+ assert.equal(resp.rows[0].value, 1);
+
+ assert.equal(resp.rows[1].id, '123');
+ assert.equal(resp.rows[1].key, '123');
+ assert.equal(resp.rows[1].value, 1);
+
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should pass through the options and keys', function (done) {
+ db.query(mapFunction, null, null, {
+ keys: ['456'],
+ include_docs: true,
+ success: function (resp) {
+ assert.equal(resp.rows.length, 1);
+
+ assert.equal(resp.rows[0].id, '456');
+ assert.equal(resp.rows[0].key, '456');
+ assert.equal(resp.rows[0].value, 1);
+
+ assert.equal(resp.rows[0].doc.job, 'pilot');
+ assert.ok(resp.rows[0].doc._rev.length > 30);
+
+ done();
+ },
+ error: errorCallback
+ });
+ });
+ });
+ describe('view', function () {
+ var docs, view;
+ beforeEach(function (done) {
+ docs = [
+ {'Name': 'Cally Tyrol', 'job': 'deckhand', '_id': '789'},
+ {'Name': 'Felix Gaeta', 'job': 'officer', '_id': '123'},
+ {'Name': 'Samuel T. Anders', 'job': 'pilot', '_id': '456'}
+ ];
+ view = {
+ 'views': {
+ 'people': {
+ 'map': 'function (doc) { emit(doc._id, doc.Name); }'
+ }
+ },
+ '_id': '_design/spec_db'
+ };
+
+ db.bulkSave({'docs': docs}, {
+ success: function (resp) {
+ db.saveDoc(view, {
+ success: function () {
+ done();
+ },
+ error: errorCallback
+ });
+
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should apply the view', function (done) {
+ db.view('spec_db/people', {
+ success: function (resp) {
+ assert.equal(resp.rows.length, 3);
+
+ assert.equal(resp.rows[0].id, '123');
+ assert.equal(resp.rows[0].key, '123');
+ assert.equal(resp.rows[0].value, 'Felix Gaeta');
+
+ assert.equal(resp.rows[1].id, '456');
+ assert.equal(resp.rows[1].key, '456');
+ assert.equal(resp.rows[1].value, 'Samuel T. Anders');
+
+ assert.equal(resp.rows[2].id, '789');
+ assert.equal(resp.rows[2].key, '789');
+ assert.equal(resp.rows[2].value, 'Cally Tyrol');
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should pass through the options', function (done) {
+ db.view('spec_db/people', {
+ skip: 2,
+ success: function (resp) {
+ assert.equal(resp.rows.length, 1);
+ assert.equal(resp.rows[0].id, '789');
+ assert.equal(resp.rows[0].key, '789');
+ assert.equal(resp.rows[0].value, 'Cally Tyrol');
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should pass through the keys', function (done) {
+ db.view('spec_db/people', {
+ keys: ['456', '123'],
+ success: function (resp) {
+ assert.equal(resp.rows[0].id, '456');
+ assert.equal(resp.rows[0].key, '456');
+ assert.equal(resp.rows[0].value, 'Samuel T. Anders');
+ assert.equal(resp.rows[1].id, '123');
+ assert.equal(resp.rows[1].key, '123');
+ assert.equal(resp.rows[1].value, 'Felix Gaeta');
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should pass through the keys', function (done) {
+ db.view('spec_db/people', {
+ keys: ['456'],
+ include_docs: true,
+ success: function (resp) {
+ assert.equal(resp.rows.length, 1);
+
+ assert.equal(resp.rows[0].id, '456');
+ assert.equal(resp.rows[0].key, '456');
+ assert.equal(resp.rows[0].value, 'Samuel T. Anders');
+
+ assert.equal(resp.rows[0].doc.job, 'pilot');
+ assert.ok(resp.rows[0].doc._rev.length > 30);
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should throw a 404 when the view doesnt exist', function (done) {
+ db.view('spec_db/non_existing_view', {
+ keys: ['456'],
+ include_docs: true,
+ error: function (status, error, reason) {
+ assert.equal(status, 404);
+ assert.equal(error, 'not_found');
+ assert.equal(reason, 'missing_named_view');
+ done();
+ },
+ success: successCallback
+ });
+ });
+ });
+
+ describe('setDbProperty', function () {
+ it('should return ok true', function (done) {
+ db.setDbProperty('_revs_limit', 1500, {
+ success: function (resp) {
+ assert.ok(resp.ok);
+ done();
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should set a db property', function (done) {
+ db.setDbProperty('_revs_limit', 1500, {
+ success: function (resp) {
+ db.getDbProperty('_revs_limit', {
+ success: function (resp) {
+ assert.equal(resp, 1500);
+ next();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+
+ function next () {
+ db.setDbProperty('_revs_limit', 1200, {
+ success: function () {
+ db.getDbProperty('_revs_limit', {
+ success: function (resp) {
+ assert.equal(resp, 1200);
+ done();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+ }
+ });
+ });
+
+ describe('getDbProperty', function () {
+ it('should get a db property', function (done) {
+ db.setDbProperty('_revs_limit', 1337, {
+ success: function (resp) {
+ db.getDbProperty('_revs_limit', {
+ success: function (resp) {
+ assert.equal(resp, 1337);
+ done();
+ },
+ error: errorCallback
+ });
+ },
+ error: errorCallback
+ });
+ });
+
+ it('should throw a 404 when the property doesnt exist', function (done) {
+ db.getDbProperty('_doesnt_exist', {
+ success: successCallback,
+ error: function (status, error, reason) {
+ assert.equal(status, 404);
+ assert.equal(error, 'not_found');
+ assert.equal(reason, 'missing');
+ done();
+ }
+ });
+ });
+ });
+
+ });
+})();