Return-Path: Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: (qmail 44895 invoked from network); 2 Jun 2010 17:47:13 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 2 Jun 2010 17:47:13 -0000 Received: (qmail 77983 invoked by uid 500); 2 Jun 2010 17:47:13 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 77932 invoked by uid 500); 2 Jun 2010 17:47:13 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 77923 invoked by uid 99); 2 Jun 2010 17:47:12 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 02 Jun 2010 17:47:12 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 02 Jun 2010 17:47:05 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 87C562388A3B; Wed, 2 Jun 2010 17:46:42 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r950690 [2/2] - in /couchdb/branches/0.11.x: ./ share/www/script/ share/www/script/jspec/ share/www/spec/ Date: Wed, 02 Jun 2010 17:46:42 -0000 To: commits@couchdb.apache.org From: jan@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100602174642.87C562388A3B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: couchdb/branches/0.11.x/share/www/spec/couch_js_instance_methods_1_spec.js URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/share/www/spec/couch_js_instance_methods_1_spec.js?rev=950690&view=auto ============================================================================== --- couchdb/branches/0.11.x/share/www/spec/couch_js_instance_methods_1_spec.js (added) +++ couchdb/branches/0.11.x/share/www/spec/couch_js_instance_methods_1_spec.js Wed Jun 2 17:46:41 2010 @@ -0,0 +1,299 @@ +// Specs for couch.js lines 1-130 + +describe 'CouchDB instance' + before_each + db = new CouchDB("spec_db", {"X-Couch-Full-Commit":"false"}); + end + + describe '.request' + before_each + db.createDb(); + end + + after_each + db.deleteDb(); + end + + it 'should return a XMLHttpRequest' + var req = db.request("GET", "/spec_db"); + req.should.include "readyState" + req.should.include "responseText" + req.should.include "statusText" + // in Safari a XMLHttpRequest is actually a XMLHttpRequestConstructor, + // otherwise we could just do: + // req.should.be_a XMLHttpRequest + end + + it 'should set the options the CouchDB instance has got as httpHeaders' + CouchDB.should.receive("request", "once").with_args("GET", "/spec_db", {headers: {"X-Couch-Full-Commit": "false"}}) + db.request("GET", "/spec_db"); + end + + it 'should pass through the options' + CouchDB.should.receive("request", "once").with_args("GET", "/spec_db", {"X-Couch-Persist": "true", headers: {"X-Couch-Full-Commit": "false"}}) + db.request("GET", "/spec_db", {"X-Couch-Persist":"true"}); + end + end + + describe '.createDb' + after_each + db.deleteDb(); + end + + it 'should create the db' + db.createDb(); + db.last_req.status.should.eql 201 + end + + it 'should return the ok true' + db.createDb().should.eql {"ok" : true} + end + + it 'should result in a created db' + db.createDb(); + try{ + db.createDb(); + } catch(e) { + e.error.should.eql "file_exists" + } + end + + it 'should have create a db with update sequence 0' + db.createDb(); + db.info().update_seq.should.eql 0 + end + end + + describe '.deleteDb' + before_each + db.createDb(); + end + + it 'should delete the db' + db.deleteDb(); + db.last_req.status.should.eql 200 + end + + it 'should return the responseText of the request' + db.deleteDb().should.eql {"ok" : true} + end + + it 'should result in a deleted db' + db.deleteDb(); + db.deleteDb(); + db.last_req.status.should.eql 404 + end + end + + describe 'document methods' + before_each + doc = {"Name" : "Kara Thrace", "Callsign" : "Starbuck"}; + db.createDb(); + end + + after_each + db.deleteDb(); + end + + describe '.save' + it 'should save the document' + db.save(doc); + db.last_req.status.should.eql 201 + end + + it 'should return ok true' + db.save(doc).ok.should.be_true + end + + it 'should return ID and revision of the document' + var response = db.save(doc); + response.id.should.be_a String + response.id.should.have_length 32 + response.rev.should.be_a String + response.rev.length.should.be_at_least 30 + end + + it 'should result in a saved document with generated ID' + var response = db.save(doc); + var saved_doc = db.open(response.id); + saved_doc.Name.should.eql "Kara Thrace" + saved_doc.Callsign.should.eql "Starbuck" + end + + it 'should save the document with the specified ID' + doc._id = "123"; + var response = db.save(doc); + response.id.should.eql "123" + end + + it 'should pass through the options' + doc._id = "123"; + CouchDB.should.receive("request", "once").with_args("PUT", "/spec_db/123?batch=ok") + db.save(doc, {"batch" : "ok"}); + end + end + + describe '.open' + before_each + doc._id = "123"; + db.save(doc); + end + + it 'should open the document' + db.open("123").should.eql doc + end + + it 'should return null when there is no document with the given ID' + db.open("non_existing").should.be_null + end + + it 'should pass through the options' + CouchDB.should.receive("request", "once").with_args("GET", "/spec_db/123?revs=true") + db.open("123", {"revs" : "true"}); + end + end + + describe '.deleteDoc' + before_each + doc._id = "123"; + saved_doc = db.save(doc); + delete_response = db.deleteDoc({_id : "123", _rev : saved_doc.rev}); + delete_last_req = db.last_req; + db.open("123"); + end + + it 'should send a successful request' + delete_last_req.status.should.eql 200 + end + + it 'should result in a deleted document' + db.open("123").should.be_null + end + + it 'should return ok true, the ID and the revision of the deleted document' + delete_response.ok.should.be_true + delete_response.id.should.eql "123" + delete_response.rev.should.be_a String + delete_response.rev.length.should.be_at_least 30 + end + + it 'should mark the document as deleted' + var responseText = db.request("GET", "/spec_db/123").responseText; + JSON.parse(responseText).should.eql {"error":"not_found","reason":"deleted"} + end + + it 'should record the revision in the deleted document' + var responseText = db.request("GET", "/spec_db/123?rev=" + delete_response.rev).responseText; + var deleted_doc = JSON.parse(responseText); + deleted_doc._rev.should.eql delete_response.rev + deleted_doc._id.should.eql delete_response.id + deleted_doc._deleted.should.be_true + end + end + + describe '.deleteDocAttachment' + before_each + doc._id = "123"; + doc._attachments = { + "friend.txt" : { + "content_type": "text\/plain", + // base64 encoded + "data": "TGVlIEFkYW1hIGlzIGEgZm9ybWVyIENvbG9uaWFsIEZsZWV0IFJlc2VydmUgb2ZmaWNlci4=" + } + }; + saved_doc = db.save(doc); + end + + it 'should be executed on a document with attachment' + db.open("123")._attachments.should.include "friend.txt" + db.open("123")._attachments["friend.txt"].stub.should.be_true + end + + describe 'after delete' + before_each + delete_response = db.deleteDocAttachment({_id : "123", _rev : saved_doc.rev}, "friend.txt"); + db.open("123"); + end + + it 'should send a successful request' + db.last_req.status.should.eql 200 + end + + it 'should leave the document untouched' + db.open("123").Callsign.should.eql "Starbuck" + end + + it 'should result in a deleted document attachment' + db.open("123").should.not.include "_attachments" + end + + it 'should record the revision in the document whose attachment has been deleted' + var responseText = db.request("GET", "/spec_db/123?rev=" + delete_response.rev).responseText; + var deleted_doc = JSON.parse(responseText); + deleted_doc._rev.should.eql delete_response.rev + deleted_doc._id.should.eql delete_response.id + end + + it 'should return ok true, the ID and the revision of the document whose attachment has been deleted' + delete_response.ok.should.be_true + delete_response.id.should.eql "123" + delete_response.should.have_property 'rev' + end + end + end + + describe '.bulkSave' + before_each + doc = {"Name" : "Kara Thrace", "Callsign" : "Starbuck"}; + doc2 = {"Name" : "Karl C. Agathon", "Callsign" : "Helo"}; + doc3 = {"Name" : "Sharon Valerii", "Callsign" : "Boomer"}; + docs = [doc, doc2, doc3]; + end + + it 'should save the documents' + db.bulkSave(docs); + db.last_req.status.should.eql 201 + end + + it 'should return ID and revision of the documents' + var response = db.bulkSave(docs); + response[0].id.should.be_a String + response[0].id.should.have_length 32 + response[0].rev.should.be_a String + response[0].rev.length.should.be_at_least 30 + response[1].id.should.be_a String + response[1].id.should.have_length 32 + response[1].rev.should.be_a String + response[1].rev.length.should.be_at_least 30 + response[2].id.should.be_a String + response[2].id.should.have_length 32 + response[2].rev.should.be_a String + response[2].rev.length.should.be_at_least 30 + end + + it 'should result in saved documents' + var response = db.bulkSave(docs); + db.open(response[0].id).Name.should.eql "Kara Thrace" + db.open(response[1].id).Name.should.eql "Karl C. Agathon" + db.open(response[2].id).Name.should.eql "Sharon Valerii" + end + + it 'should save the document with specified IDs' + doc._id = "123"; + doc2._id = "456"; + docs = [doc, doc2, doc3]; + var response = db.bulkSave(docs); + response[0].id.should.eql "123" + response[1].id.should.eql "456" + response[2].id.should.have_length 32 + end + + it 'should pass through the options' + doc._id = "123"; + docs = [doc]; + CouchDB.should.receive("request", "once").with_args("POST", "/spec_db/_bulk_docs", {body: '{"docs":[{"Name":"Kara Thrace","Callsign":"Starbuck","_id":"123"}],"batch":"ok"}'}) + db.bulkSave(docs, {"batch" : "ok"}); + end + end + end +end \ No newline at end of file Added: couchdb/branches/0.11.x/share/www/spec/couch_js_instance_methods_2_spec.js URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/share/www/spec/couch_js_instance_methods_2_spec.js?rev=950690&view=auto ============================================================================== --- couchdb/branches/0.11.x/share/www/spec/couch_js_instance_methods_2_spec.js (added) +++ couchdb/branches/0.11.x/share/www/spec/couch_js_instance_methods_2_spec.js Wed Jun 2 17:46:41 2010 @@ -0,0 +1,234 @@ +// Specs for couch.js lines 132-199 + +describe 'CouchDB instance' + before_each + db = new CouchDB("spec_db", {"X-Couch-Full-Commit":"false"}); + db.createDb(); + end + + after_each + db.deleteDb(); + end + + describe '.ensureFullCommit' + it 'should return ok true' + db.ensureFullCommit().ok.should.be_true + end + + it 'should return the instance start time' + db.ensureFullCommit().instance_start_time.should.have_length 16 + end + + it 'should post _ensure_full_commit to the db' + db.should.receive("request", "once").with_args("POST", "/spec_db/_ensure_full_commit") + db.ensureFullCommit(); + end + end + + describe '.query' + before_each + db.save({"Name" : "Cally Tyrol", "job" : "deckhand", "_id" : "789"}); + db.save({"Name" : "Felix Gaeta", "job" : "officer", "_id" : "123"}); + db.save({"Name" : "Samuel T. Anders", "job" : "pilot", "_id" : "456"}); + map_function = "function(doc) { emit(doc._id, 1); }"; + reduce_function = "function(key, values, rereduce) { return sum(values); }"; + end + + it 'should apply the map function' + var result = db.query(map_function); + + result.rows.should.have_length 3 + result.rows[0].id.should.eql "123" + result.rows[0].key.should.eql "123" + result.rows[0].value.should.eql 1 + result.rows[1].id.should.eql "456" + result.rows[1].key.should.eql "456" + result.rows[1].value.should.eql 1 + result.rows[2].id.should.eql "789" + result.rows[2].key.should.eql "789" + result.rows[2].value.should.eql 1 + end + + it 'should apply the reduce function' + var result = db.query(map_function, reduce_function); + + result.rows.should.have_length 1 + result.rows[0].key.should.be_null + result.rows[0].value.should_eql 3 + end + + it 'should pass through the options' + var result = db.query(map_function, null, {"startkey":"456"}); + + result.rows.should.have_length 2 + result.rows[0].id.should.eql "456" + result.rows[0].key.should.eql "456" + result.rows[0].value.should.eql 1 + result.rows[1].id.should.eql "789" + result.rows[1].key.should.eql "789" + result.rows[1].value.should.eql 1 + end + + it 'should pass through the keys' + var result = db.query(map_function, null, {}, ["456", "123"]); + + result.rows.should.have_length 2 + result.rows[0].id.should.eql "456" + result.rows[0].key.should.eql "456" + result.rows[0].value.should.eql 1 + result.rows[1].id.should.eql "123" + result.rows[1].key.should.eql "123" + result.rows[1].value.should.eql 1 + end + + it 'should pass through the options and the keys' + var result = db.query(map_function, null, {"include_docs":"true"}, ["456"]); + + result.rows.should.have_length 1 + result.rows[0].id.should.eql "456" + result.rows[0].key.should.eql "456" + result.rows[0].value.should.eql 1 + result.rows[0].doc["job"].should.eql "pilot" + result.rows[0].doc["_rev"].length.should.be_at_least 30 + end + + it 'should apply a view in erlang also' + // when this test fails, read this: http://wiki.apache.org/couchdb/EnableErlangViews + var erlang_map = 'fun({Doc}) -> ' + + 'ID = proplists:get_value(<<"_id">>, Doc, null), ' + + 'Emit(ID, 1) ' + + 'end.'; + var result = db.query(erlang_map, null, null, null, "erlang"); + + result.rows.should.have_length 3 + result.rows[0].id.should.eql "123" + result.rows[0].key.should.eql "123" + result.rows[0].value.should.eql 1 + result.rows[1].id.should.eql "456" + result.rows[1].key.should.eql "456" + result.rows[1].value.should.eql 1 + result.rows[2].id.should.eql "789" + result.rows[2].key.should.eql "789" + result.rows[2].value.should.eql 1 + end + end + + describe '.view' + before_each + db.save({"Name" : "Cally Tyrol", "job" : "deckhand", "_id" : "789"}); + db.save({"Name" : "Felix Gaeta", "job" : "officer", "_id" : "123"}); + db.save({"Name" : "Samuel T. Anders", "job" : "pilot", "_id" : "456"}); + view = { + "views" : { + "people" : { + "map" : "function(doc) { emit(doc._id, doc.Name); }" + } + }, + "_id" : "_design/spec_db" + }; + db.save(view); + end + + it 'should apply the view' + var result = db.view('spec_db/people'); + + result.rows.should.have_length 3 + result.rows[0].id.should.eql "123" + result.rows[0].key.should.eql "123" + result.rows[0].value.should.eql "Felix Gaeta" + result.rows[1].id.should.eql "456" + result.rows[1].key.should.eql "456" + result.rows[1].value.should.eql "Samuel T. Anders" + result.rows[2].id.should.eql "789" + result.rows[2].key.should.eql "789" + result.rows[2].value.should.eql "Cally Tyrol" + end + + it 'should pass through the options' + var result = db.view('spec_db/people', {"skip":"2"}); + + result.rows.should.have_length 1 + result.rows[0].id.should.eql "789" + result.rows[0].key.should.eql "789" + result.rows[0].value.should.eql "Cally Tyrol" + end + + it 'should pass through the keys' + var result = db.view('spec_db/people', {}, ["456", "123"]); + + result.rows.should.have_length 2 + result.rows[0].id.should.eql "456" + result.rows[0].key.should.eql "456" + result.rows[0].value.should.eql "Samuel T. Anders" + result.rows[1].id.should.eql "123" + result.rows[1].key.should.eql "123" + result.rows[1].value.should.eql "Felix Gaeta" + end + + it 'should pass through the options and the keys' + var result = db.view('spec_db/people', {"include_docs":"true"}, ["456"]); + + result.rows.should.have_length 1 + result.rows[0].id.should.eql "456" + result.rows[0].key.should.eql "456" + result.rows[0].value.should.eql "Samuel T. Anders" + result.rows[0].doc["job"].should.eql "pilot" + result.rows[0].doc["_rev"].length.should.be_at_least 30 + end + + it 'should return null when the view doesnt exist' + var result = db.view('spec_db/non_existing_view'); + + result.should.be_null + end + end + + describe '.info' + before_each + result = db.info(); + end + + it 'should return the name of the database' + result.db_name.should.eql "spec_db" + end + + it 'should return the number of documents' + result.doc_count.should.eql 0 + end + + it 'should return the start time of the db instance' + result.instance_start_time.should.have_length 16 + end + end + + describe '.designInfo' + before_each + designDoc = { + "views" : { + "people" : { + "map" : "function(doc) { emit(doc._id, doc); }" + } + }, + "_id" : "_design/spec_db" + }; + db.save(designDoc); + result = db.designInfo("_design/spec_db"); + end + + it 'should return the database name' + result.name.should.eql "spec_db" + end + + it 'should return a views language' + result.view_index.language.should.eql "javascript" + end + + it 'should return a views update sequence' + result.view_index.update_seq.should.eql 0 + end + + it 'should return a views signature' + result.view_index.signature.should.have_length 32 + end + end +end \ No newline at end of file Added: couchdb/branches/0.11.x/share/www/spec/couch_js_instance_methods_3_spec.js URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/share/www/spec/couch_js_instance_methods_3_spec.js?rev=950690&view=auto ============================================================================== --- couchdb/branches/0.11.x/share/www/spec/couch_js_instance_methods_3_spec.js (added) +++ couchdb/branches/0.11.x/share/www/spec/couch_js_instance_methods_3_spec.js Wed Jun 2 17:46:41 2010 @@ -0,0 +1,203 @@ +// Specs for couch.js lines 201-265 + +describe 'CouchDB instance' + before_each + db = new CouchDB("spec_db", {"X-Couch-Full-Commit":"false"}); + db.createDb(); + end + + after_each + db.deleteDb(); + end + + describe '.allDocs' + it 'should return no docs when there arent any' + db.allDocs().total_rows.should.eql 0 + db.allDocs().rows.should.eql [] + end + + describe 'with docs' + before_each + db.save({"Name" : "Felix Gaeta", "_id" : "123"}); + db.save({"Name" : "Samuel T. Anders", "_id" : "456"}); + end + + it 'should return all docs' + var result = db.allDocs(); + + result.total_rows.should.eql 2 + result.rows.should.have_length 2 + result.rows[0].id.should.eql "123" + result.rows[0].key.should.eql "123" + result.rows[0].value.rev.length.should.be_at_least 30 + result.rows[1].id.should.eql "456" + end + + it 'should pass through the options' + var result = db.allDocs({"startkey": "123", "limit": "1"}); + + result.rows.should.have_length 1 + result.rows[0].id.should.eql "123" + end + + it 'should pass through the keys' + var result = db.allDocs({}, ["456"]); + + result.rows.should.have_length 1 + result.rows[0].id.should.eql "456" + result.rows[0].key.should.eql "456" + result.rows[0].value.rev.length.should.be_at_least 30 + end + + it 'should pass through the options and the keys' + var result = db.allDocs({"include_docs":"true"}, ["456"]); + + result.rows.should.have_length 1 + result.rows[0].id.should.eql "456" + result.rows[0].key.should.eql "456" + result.rows[0].value.rev.length.should.be_at_least 30 + result.rows[0].doc["Name"].should.eql "Samuel T. Anders" + result.rows[0].doc["_rev"].length.should.be_at_least 30 + end + + end + end + + describe '.designDocs' + it 'should return nothing when there arent any design docs' + db.save({"Name" : "Felix Gaeta", "_id" : "123"}); + db.designDocs().rows.should.eql [] + end + + it 'should return all design docs' + var designDoc = { + "views" : { + "people" : { + "map" : "function(doc) { emit(doc._id, doc); }" + } + }, + "_id" : "_design/spec_db" + }; + db.save(designDoc); + db.save({"Name" : "Felix Gaeta", "_id" : "123"}); + + var result = db.designDocs(); + + result.total_rows.should.eql 2 + result.rows.should.have_length 1 + result.rows[0].id.should.eql "_design/spec_db" + result.rows[0].key.should.eql "_design/spec_db" + result.rows[0].value.rev.length.should.be_at_least 30 + end + end + + describe '.changes' + it 'should return no changes when there arent any' + db.changes().last_seq.should.eql 0 + db.changes().results.should.eql [] + end + + describe 'with changes' + before_each + db.save({"Name" : "Felix Gaeta", "_id" : "123"}); + db.save({"Name" : "Samuel T. Anders", "_id" : "456"}); + end + + it 'should return changes' + var result = db.changes(); + + result.last_seq.should.eql 2 + result.results[0].id.should.eql "123" + result.results[0].seq.should.eql 1 + result.results[0].changes[0].rev.length.should.be_at_least 30 + result.results[1].id.should.eql "456" + result.results[1].seq.should.eql 2 + result.results[1].changes[0].rev.length.should.be_at_least 30 + end + + it 'should pass through the options' + var result = db.changes({"since":"1"}); + + result.last_seq.should.eql 2 + result.results[0].id.should.eql "456" + end + end + end + + describe '.compact' + it 'should return ok true' + db.compact().ok.should.be_true + end + + it 'should post _compact to the db' + db.should.receive("request", "once").with_args("POST", "/spec_db/_compact") + db.compact(); + end + end + + describe '.viewCleanup' + it 'should return ok true' + db.viewCleanup().ok.should.be_true + end + + it 'should post _view_cleanup to the db' + db.should.receive("request", "once").with_args("POST", "/spec_db/_view_cleanup") + db.viewCleanup(); + end + end + + describe '.setDbProperty' + it 'should return ok true' + db.setDbProperty("_revs_limit", 1500).ok.should.be_true + end + + it 'should set a db property' + db.setDbProperty("_revs_limit", 1500); + db.getDbProperty("_revs_limit").should.eql 1500 + db.setDbProperty("_revs_limit", 1200); + db.getDbProperty("_revs_limit").should.eql 1200 + end + end + + describe '.getDbProperty' + it 'should get a db property' + db.setDbProperty("_revs_limit", 1200); + db.getDbProperty("_revs_limit").should.eql 1200 + end + + it 'should throw an error when the property doesnt exist' + function(){ db.getDbProperty("_doesnt_exist")}.should.throw_error + end + end + + describe '.setSecObj' + it 'should return ok true' + db.setSecObj({"readers":{"names":["laura"],"roles":["president"]}}).ok.should.be_true + end + + it 'should save a well formed object into the _security object ' + db.should.receive("request", "once").with_args("PUT", "/spec_db/_security", {body: '{"readers":{"names":["laura"],"roles":["president"]}}'}) + db.setSecObj({"readers": {"names" : ["laura"], "roles" : ["president"]}}) + end + + it 'should throw an error when the readers or admins object is malformed' + -{ db.setSecObj({"admins":["cylon"]}) }.should.throw_error + end + + it 'should save any other object into the _security object' + db.setSecObj({"something" : "anything"}) + db.getSecObj().should.eql {"something" : "anything"} + end + end + + describe '.getSecObj' + it 'should get the security object' + db.setSecObj({"admins" : {"names" : ["bill"], "roles" : ["admiral"]}}) + db.getSecObj().should.eql {"admins" : {"names": ["bill"], "roles": ["admiral"]}} + end + + it 'should return an empty object when there is no security object' + db.getSecObj().should.eql {} + end + end +end \ No newline at end of file Added: couchdb/branches/0.11.x/share/www/spec/custom_helpers.js URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/share/www/spec/custom_helpers.js?rev=950690&view=auto ============================================================================== --- couchdb/branches/0.11.x/share/www/spec/custom_helpers.js (added) +++ couchdb/branches/0.11.x/share/www/spec/custom_helpers.js Wed Jun 2 17:46:41 2010 @@ -0,0 +1,39 @@ +function stubAlert(){ + if(typeof(old_alert) == 'undefined'){ + old_alert = alert; + } + alert = function(msg){ + alert_msg = msg; + }; +} + +function destubAlert(){ + alert = old_alert; +} + +function errorCallback(status, error, reason){ + console.log("Unexpected " + status + " error: " + error + " - " + reason) + throw("Unexpected " + status + " error: " + error + " - " + reason); +} + +function successCallback(resp){ + console.log("No error message here unexpectedly, successful response instead.") + throw("No error message here unexpectedly, successful response instead."); +} + +function useTestUserDb(){ + users_db = new CouchDB("spec_users_db"); + var xhr = CouchDB.request("PUT", "/_config/couch_httpd_auth/authentication_db", { + body: JSON.stringify("spec_users_db") + }); + if(typeof(old_auth_db) == 'undefined'){ + old_auth_db = xhr.responseText.replace(/\n/,'').replace(/"/g,''); + } +} + +function useOldUserDb(){ + CouchDB.request("PUT", "/_config/couch_httpd_auth/authentication_db", { + body: JSON.stringify(old_auth_db) + }); + users_db.deleteDb(); +} \ No newline at end of file Added: couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_class_methods_spec.js URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_class_methods_spec.js?rev=950690&view=auto ============================================================================== --- couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_class_methods_spec.js (added) +++ couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_class_methods_spec.js Wed Jun 2 17:46:41 2010 @@ -0,0 +1,511 @@ +// Specs for jquery_couch.js lines 48-156 and 415-448 + +describe 'jQuery couchdb' + before + stubAlert(); + end + + after + destubAlert(); + end + + describe 'activeTasks' + before_each + db = $.couch.db("spec_db"); + db.create(); + end + + after_each + db.drop(); + end + + it 'should return an empty array when there are no active tasks' + $.couch.activeTasks({ + success: function(resp){ + resp.should.eql [] + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should return an active task' + // doing a bit of stuff here so compaction has something to do and takes a while + var battlestar, civillian; + db.saveDoc({"type":"Battlestar", "name":"Galactica"}, { + success: function(resp){ + db.openDoc(resp.id, { + success: function(resp2){ + battlestar = resp2; + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + battlestar.name = "Pegasus"; + db.saveDoc(battlestar); + + db.saveDoc({"type":"Civillian", "name":"Cloud 9"}, { + success: function(resp){ + db.openDoc(resp.id, { + success: function(resp2){ + civillian = resp2; + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + civillian.name = "Olympic Carrier"; + db.saveDoc(civillian); + db.removeDoc(civillian); + + db.compact({ + ajaxStart: function(resp){ + $.couch.activeTasks({ + success: function(resp2){ + resp2[0].type.should.eql "Database Compaction" + resp2[0].task.should.eql "spec_db" + resp2[0].should.have_prop "status" + resp2[0].should.include "pid" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + } + }); + end + end + + describe 'allDbs' + it 'should return an array that includes a created database' + temp_db = new CouchDB("temp_spec_db", {"X-Couch-Full-Commit":"false"}); + temp_db.createDb(); + $.couch.allDbs({ + success: function(resp){ + resp.should.include "temp_spec_db" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + temp_db.deleteDb(); + end + + it 'should return an array that does not include a database that does not exist' + $.couch.allDbs({ + success: function(resp){ + resp.should.not.include("not_existing_temp_spec_db"); + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + end + + describe 'config' + it 'should get the config settings' + $.couch.config({ + success: function(resp){ + resp.httpd.port.should.eql window.location.port + resp.stats.samples.should.match /\[.*\]/ + resp.native_query_servers.should.have_prop "erlang" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should get a specific config setting' + $.couch.config({ + success: function(resp){ + parseInt(resp.max_document_size).should.be_a Number + resp.delayed_commits.should.be_a String + resp.database_dir.should.be_a String + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }, "couchdb"); + end + + it 'should update a config setting' + $.couch.config({ + success: function(resp){ + resp.should.eql "" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }, "test", "colony", "Caprica"); + + $.couch.config({ + success: function(resp){ + resp.colony.should.eql "Caprica" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }, "test"); + + $.couch.config({}, "test", "colony", null); + end + + it 'should delete a config setting' + $.couch.config({}, "test", "colony", "Caprica"); + + $.couch.config({ + success: function(resp){ + resp.should.eql "Caprica" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }, "test", "colony", null); + + $.couch.config({ + success: function(resp){ + resp.should.eql {} + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }, "test"); + end + + it 'should alert with an error message prefix' + $.couch.config("asdf", "asdf", "asdf"); + alert_msg.should.match /An error occurred retrieving\/updating the server configuration/ + end + end + + describe 'session' + it 'should return information about the session' + $.couch.session({ + success: function(resp){ + resp.info.should.have_prop 'authentication_db' + resp.userCtx.should.include 'name' + resp.userCtx.roles.should.be_an Array + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + end + + describe 'userDb' + it 'should return the userDb' + var authentication_db; + $.couch.session({ + success: function(resp){ + authentication_db = resp.info.authentication_db; + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + + $.couch.userDb(function(resp){ + resp.name.should.eql authentication_db + }); + end + + it 'should return a db instance' + $.couch.userDb(function(resp){ + resp.should.respond_to 'allDocs' + resp.should.respond_to 'bulkSave' + }); + end + end + + describe 'user_db stuff' + before + useTestUserDb(); + end + + after + useOldUserDb(); + end + + describe 'signup' + it 'should return a saved user' + $.couch.signup( + {name: "Tom Zarek"}, "secretpass", { + success: function(resp){ + resp.id.should.eql "org.couchdb.user:Tom Zarek" + resp.rev.length.should.be_at_least 30 + resp.ok.should.be_true + users_db.deleteDoc({_id : resp.id, _rev : resp.rev}) + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should create a userDoc in the user db' + $.couch.signup( + {name: "Tom Zarek"}, "secretpass", { + success: function(resp){ + var user = users_db.open(resp.id); + user.name.should.eql "Tom Zarek" + user._id.should.eql "org.couchdb.user:Tom Zarek" + user.roles.should.eql [] + user.password_sha.length.should.be_at_least 30 + user.password_sha.should.be_a String + users_db.deleteDoc({_id : resp.id, _rev : resp.rev}) + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should create a userDoc with roles when specified' + $.couch.signup( + {name: "Tom Zarek", roles: ["vice_president", "activist"]}, "secretpass", { + success: function(resp){ + var user = users_db.open(resp.id); + user.roles.should.eql ["vice_president", "activist"] + users_db.deleteDoc({_id : resp.id, _rev : resp.rev}) + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + end + + describe 'login' + before_each + user = {}; + $.couch.signup({name: "Tom Zarek", roles: ["vice_president", "activist"]}, "secretpass", { + success: function(resp){ + user.id = resp.id; + user.rev = resp.rev; + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + after_each + users_db.deleteDoc({_id : user.id, _rev : user.rev}) + end + + it 'should return the logged in user' + $.couch.login({ + name: "Tom Zarek", + password: "secretpass", + success: function(resp){ + resp.name.should.eql "Tom Zarek" + resp.ok.should.be_true + resp.roles.should.eql ["vice_president", "activist"] + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should result in a session for the logged in user' + $.couch.login({ + name: "Tom Zarek", + password: "secretpass" + }); + $.couch.session({ + success: function(resp){ + resp.info.authentication_db.should.eql "spec_users_db" + resp.userCtx.name.should.eql "Tom Zarek" + resp.userCtx.roles.should.eql ["vice_president", "activist"] + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should return a 404 when password is wrong' + $.couch.login({ + name: "Tom Zarek", + password: "wrongpass", + error: function(status, error, reason){ + status.should.eql 401 + error.should.eql "unauthorized" + reason.should.eql "Name or password is incorrect." + }, + success: function(resp){successCallback(resp)} + }); + end + + it 'should return a 404 when the user doesnt exist in the users db' + $.couch.login({ + name: "Number Three", + password: "secretpass", + error: function(status, error, reason){ + status.should.eql 401 + error.should.eql "unauthorized" + reason.should.eql "Name or password is incorrect." + }, + success: function(resp){successCallback(resp)} + }); + end + + it 'should alert with an error message prefix' + $.couch.login("asdf"); + alert_msg.should.match /An error occurred logging in/ + end + end + + describe 'logout' + before_each + user = {}; + $.couch.signup({name: "Tom Zarek", roles: ["vice_president", "activist"]}, "secretpass", { + success: function(resp){ + user.id = resp.id; + user.rev = resp.rev; + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + $.couch.login({name: "Tom Zarek", password: "secretpass"}); + end + + after_each + users_db.deleteDoc({_id : user.id, _rev : user.rev}) + end + + it 'should return ok true' + $.couch.logout({ + success: function(resp){ + resp.ok.should.be_true + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should result in an empty session' + $.couch.logout(); + $.couch.session({ + success: function(resp){ + resp.userCtx.name.should.be_null + resp.userCtx.roles.should.not.include ["vice_president"] + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + end + end + + describe 'encodeDocId' + it 'should return the encoded docID when it is not a design document' + $.couch.encodeDocId("viper").should.eql(encodeURIComponent("viper")) + end + + it 'should encode only the name of the design document' + $.couch.encodeDocId("_design/raptor").should.eql("_design/" + encodeURIComponent("raptor")) + end + + it 'should also work when the name of the des' + $.couch.encodeDocId("_design/battlestar/_view/crew").should.eql("_design/" + encodeURIComponent("battlestar/_view/crew")) + end + end + + describe 'info' + it 'should return the CouchDB version' + $.couch.info({ + success: function(resp){ + resp.couchdb.should.eql "Welcome" + resp.version.should_match /^\d\d?\.\d\d?\.\d\d?.*/ + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + end + + describe 'replicate' + before_each + db = $.couch.db("spec_db"); + db.create(); + db2 = $.couch.db("spec_db_2"); + db2.create(); + host = window.location.protocol + "//" + window.location.host ; + end + + after_each + db.drop(); + db2.drop(); + end + + it 'should return no_changes true when there are no changes between the dbs' + $.couch.replicate(host + db.uri, host + db2.uri, { + success: function(resp){ + resp.ok.should.be_true + resp.no_changes.should.be_true + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should return the session ID' + db.saveDoc({'type':'battlestar', 'name':'galactica'}); + $.couch.replicate(host + db.uri, host + db2.uri, { + success: function(resp){ + resp.session_id.length.should.be_at_least 30 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should return source_last_seq' + db.saveDoc({'type':'battlestar', 'name':'galactica'}); + db.saveDoc({'type':'battlestar', 'name':'pegasus'}); + + $.couch.replicate(host + db.uri, host + db2.uri, { + success: function(resp){ + resp.source_last_seq.should.eql 2 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should return the replication history' + db.saveDoc({'type':'battlestar', 'name':'galactica'}); + db.saveDoc({'type':'battlestar', 'name':'pegasus'}); + + $.couch.replicate(host + db.uri, host + db2.uri, { + success: function(resp){ + resp.history[0].docs_written.should.eql 2 + resp.history[0].start_last_seq.should.eql 0 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should pass through replication options' + db.saveDoc({'type':'battlestar', 'name':'galactica'}); + db2.drop(); + $.couch.replicate(host + db.uri, host + db2.uri, { + error: function(status, error, reason){ + status.should.eql 500 + reason.should.match /db_not_found/ + }, + success: function(resp){successCallback(resp)} + }); + + $.couch.replicate(host + db.uri, host + db2.uri, { + success: function(resp){ + resp.ok.should.eql true + resp.history[0].docs_written.should.eql 1 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }, { + "create_target":true + }); + + db2.info({ + success: function(resp){ + resp.db_name.should.eql "spec_db_2" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should alert with an error message prefix' + $.couch.replicate("asdf"); + alert_msg.should.match /Replication failed/ + end + end + + describe 'newUUID' + it 'should return a new UUID' + var new_uuid = $.couch.newUUID(1); + new_uuid.should.be_a String + new_uuid.should.have_length 32 + end + + it 'should fill the uuidCache with the specified number minus 1' + // we can't reach the uuidCache from here, so we mock the next request + // to test that the next uuid is not coming from the request, but from the cache. + $.couch.newUUID(2); + mock_request().and_return({'uuids':['a_sample_uuid']}) + $.couch.newUUID(1).should.not.eql 'a_sample_uuid' + $.couch.newUUID(1).should.eql 'a_sample_uuid' + end + + it 'should alert with an error message prefix' + $.couch.newUUID("asdf"); + alert_msg.should.match /Failed to retrieve UUID batch/ + end + end +end \ No newline at end of file Added: couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_instance_methods_1_spec.js URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_instance_methods_1_spec.js?rev=950690&view=auto ============================================================================== --- couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_instance_methods_1_spec.js (added) +++ couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_instance_methods_1_spec.js Wed Jun 2 17:46:41 2010 @@ -0,0 +1,190 @@ +// Specs for jquery_couch.js lines 163-209 + +describe 'jQuery couchdb db' + before + stubAlert(); + end + + after + destubAlert(); + end + + before_each + db = $.couch.db('spec_db'); + end + + describe 'constructor' + it 'should set the name' + db.name.should.eql 'spec_db' + end + + it 'should set the uri' + db.uri.should.eql '/spec_db/' + end + end + + describe 'triggering db functions' + before_each + db.create(); + end + + after_each + db.drop(); + end + + describe 'compact' + it 'should return ok true' + db.compact({ + success: function(resp) { + resp.ok.should.be_true + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should trigger _compact' + db.compact({ + success: function(resp, obj) { + obj.url.should.eql "/spec_db/_compact" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + end + + describe 'viewCleanup' + it 'should return ok true' + db.viewCleanup({ + success: function(resp) { + resp.ok.should.be_true + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should trigger _view_cleanup' + db.viewCleanup({ + success: function(resp, obj) { + obj.url.should.eql "/spec_db/_view_cleanup" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + end + + describe 'compactView' + before_each + var designDoc = { + "views" : { + "people" : { + "map" : "function(doc) { emit(doc._id, doc); }" + } + }, + "_id" : "_design/myview" + }; + db.saveDoc(designDoc); + db.saveDoc({"Name" : "Felix Gaeta", "_id" : "123"}); + end + + it 'should return ok true' + db.compactView("myview", { + success: function(resp) { + resp.ok.should.be_true + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should trigger _compact_view with the groupname' + db.compactView("myview", { + success: function(resp, obj) { + obj.url.should.eql "/spec_db/_compact/myview" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should return raise a 404 error when the design name doesnt exist' + db.compactView("non_existing_design_name", { + error: function(status, error, reason){ + status.should.eql 404 + error.should.eql "not_found" + reason.should.eql "missing" + }, + success: function(resp){successCallback(resp)} + }); + end + + it 'should alert with an error message prefix' + db.compactView("asdf"); + alert_msg.should.match /The view could not be compacted/ + end + end + end + + describe 'create' + after_each + db.drop(); + end + + it 'should return ok true' + db.create({ + success: function(resp) { + resp.ok.should.be_true + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should result in a created db' + db.create(); + db.create({ + error: function(status, error, reason){ + status.should.eql 412 + error.should.eql "file_exists" + reason.should.eql "The database could not be created, the file already exists." + }, + success: function(resp){successCallback(resp)} + }); + end + + it 'should alert with an error message prefix' + db.create(); + db.create(); + alert_msg.should.match /The database could not be created/ + end + end + + describe 'drop' + before_each + db.create(); + end + + it 'should return ok true' + db.drop({ + success: function(resp) { + resp.ok.should.be_true + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should result in a deleted db' + db.drop(); + db.drop({ + error: function(status, error, reason){ + status.should.eql 404 + error.should.eql "not_found" + reason.should.eql "missing" + }, + success: function(resp){successCallback(resp)} + }); + end + + it 'should alert with an error message prefix' + db.drop(); + db.drop(); + alert_msg.should.match /The database could not be deleted/ + end + end +end \ No newline at end of file Added: couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_instance_methods_2_spec.js URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_instance_methods_2_spec.js?rev=950690&view=auto ============================================================================== --- couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_instance_methods_2_spec.js (added) +++ couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_instance_methods_2_spec.js Wed Jun 2 17:46:41 2010 @@ -0,0 +1,421 @@ +// Specs for jquery_couch.js lines 210-299 + +describe 'jQuery couchdb db' + before + stubAlert(); + end + + after + destubAlert(); + end + + before_each + db = $.couch.db('spec_db'); + db.create(); + end + + after_each + db.drop(); + end + + describe 'info' + before_each + result = {}; + db.info({ + success: function(resp) { result = resp; }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should return the name of the database' + result.db_name.should.eql "spec_db" + end + + it 'should return the number of documents' + result.doc_count.should.eql 0 + end + + it 'should return the start time of the db instance' + result.instance_start_time.should.have_length 16 + end + end + + describe 'allDocs' + it 'should return no docs when there arent any' + db.allDocs({ + success: function(resp) { + resp.total_rows.should.eql 0 + resp.rows.should.eql [] + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + describe 'with docs' + before_each + db.saveDoc({"Name" : "Felix Gaeta", "_id" : "123"}); + db.saveDoc({"Name" : "Samuel T. Anders", "_id" : "456"}); + end + + it 'should return all docs' + db.allDocs({ + success: function(resp) { + resp.total_rows.should.eql 2 + resp.rows.should.have_length 2 + resp.rows[0].id.should.eql "123" + resp.rows[0].key.should.eql "123" + resp.rows[0].value.rev.length.should.be_at_least 30 + resp.rows[1].id.should.eql "456" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should pass through the options' + db.allDocs({ + "startkey": "123", + "limit": "1", + success: function(resp) { + resp.rows.should.have_length 1 + resp.rows[0].id.should.eql "123" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + end + end + + describe 'allDesignDocs' + it 'should return nothing when there arent any design docs' + db.saveDoc({"Name" : "Felix Gaeta", "_id" : "123"}); + db.allDesignDocs({ + success: function(resp) { + resp.rows.should.eql [] + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should return all design docs' + var designDoc = { + "views" : { + "people" : { + "map" : "function(doc) { emit(doc._id, doc); }" + } + }, + "_id" : "_design/spec_db" + }; + db.saveDoc(designDoc); + db.saveDoc({"Name" : "Felix Gaeta", "_id" : "123"}); + + db.allDesignDocs({ + success: function(resp) { + resp.total_rows.should.eql 2 + resp.rows.should.have_length 1 + resp.rows[0].id.should.eql "_design/spec_db" + resp.rows[0].key.should.eql "_design/spec_db" + resp.rows[0].value.rev.length.should.be_at_least 30 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + end + + describe 'allApps' + it 'should provide a custom function with appName, appPath and design document when there is an attachment with index.html' + var designDoc = {"_id" : "_design/with_attachments"}; + + designDoc._attachments = { + "index.html" : { + "content_type": "text\/html", + // this is "

Hi, here is index!

", base64 encoded + "data": "PGh0bWw+PHA+SGksIGhlcmUgaXMgaW5kZXghPC9wPjwvaHRtbD4=" + } + }; + db.saveDoc(designDoc); + + db.allApps({ + eachApp: function(appName, appPath, ddoc) { + appName.should.eql "with_attachments" + appPath.should.eql "/spec_db/_design/with_attachments/index.html" + ddoc._id.should.eql "_design/with_attachments" + ddoc._attachments["index.html"].content_type.should.eql "text/html" + ddoc._attachments["index.html"].length.should.eql "

Hi, here is index!

".length + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should provide a custom function with appName, appPath and design document when there is a couchapp with index file' + var designDoc = {"_id" : "_design/with_index"}; + designDoc.couchapp = { + "index" : "cylon" + }; + db.saveDoc(designDoc); + + db.allApps({ + eachApp: function(appName, appPath, ddoc) { + appName.should.eql "with_index" + appPath.should.eql "/spec_db/_design/with_index/cylon" + ddoc._id.should.eql "_design/with_index" + ddoc.couchapp.index.should.eql "cylon" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should not call the eachApp function when there is neither index.html in _attachments nor a couchapp index file' + var designDoc = {"_id" : "_design/nothing"}; + db.saveDoc(designDoc); + + var eachApp_called = false; + db.allApps({ + eachApp: function(appName, appPath, ddoc) { + eachApp_called = true; + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + + eachApp_called.should.be_false + end + + it 'should alert with an error message prefix' + db.allApps(); + alert_msg.should.match /Please provide an eachApp function for allApps()/ + end + end + + describe 'openDoc' + before_each + doc = {"Name" : "Louanne Katraine", "Callsign" : "Kat", "_id" : "123"}; + db.saveDoc(doc); + end + + it 'should open the document' + db.openDoc("123", { + success: function(resp){ + resp.should.eql doc + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should raise a 404 error when there is no document with the given ID' + db.openDoc("non_existing", { + error: function(status, error, reason){ + status.should.eql 404 + error.should.eql "not_found" + reason.should.eql "missing" + }, + success: function(resp){successCallback(resp)} + }); + end + + it 'should pass through the options' + doc.Name = "Sasha"; + db.saveDoc(doc); + db.openDoc("123", { + revs: true, + success: function(resp){ + resp._revisions.start.should.eql 2 + resp._revisions.ids.should.have_length 2 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should alert with an error message prefix' + db.openDoc("asdf"); + alert_msg.should.match /The document could not be retrieved/ + end + end + + describe 'saveDoc' + before_each + doc = {"Name" : "Kara Thrace", "Callsign" : "Starbuck"}; + end + + it 'should save the document' + db.saveDoc(doc, { + success: function(resp, status){ + status.should.eql 201 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should return ok true' + db.saveDoc(doc, { + success: function(resp, status){ + resp.ok.should.be_true + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should return ID and revision of the document' + db.saveDoc(doc, { + success: function(resp, status){ + resp.id.should.be_a String + resp.id.should.have_length 32 + resp.rev.should.be_a String + resp.rev.length.should.be_at_least 30 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should result in a saved document with generated ID' + db.saveDoc(doc, { + success: function(resp, status){ + db.openDoc(resp.id, { + success: function(resp2){ + resp2.Name.should.eql "Kara Thrace" + resp2.Callsign.should.eql "Starbuck" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should save the document with the specified ID' + doc._id = "123"; + db.saveDoc(doc, { + success: function(resp, status){ + resp.id.should.eql "123" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should pass through the options' + db.saveDoc(doc, { + "batch" : "ok", + success: function(resp, status){ + // when using batch ok, couch sends a 202 status immediately + status.should.eql 202 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should alert with an error message prefix' + db.saveDoc("asdf"); + alert_msg.should.match /The document could not be saved/ + end + end + + describe 'bulkSave' + before_each + doc = {"Name" : "Kara Thrace", "Callsign" : "Starbuck"}; + doc2 = {"Name" : "Karl C. Agathon", "Callsign" : "Helo"}; + doc3 = {"Name" : "Sharon Valerii", "Callsign" : "Boomer"}; + docs = [doc, doc2, doc3]; + end + + it 'should save all documents' + db.bulkSave({"docs": docs}); + db.allDocs({ + success: function(resp) { + resp.total_rows.should.eql 3 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should result in saved documents' + doc3._id = "789"; + db.bulkSave({"docs": [doc3]}); + + db.openDoc("789", { + success: function(resp){ + resp.Name.should.eql "Sharon Valerii" + resp.Callsign.should.eql "Boomer" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should return ID and revision of the documents' + db.bulkSave({"docs": docs},{ + success: function(resp){ + resp[0].id.should.be_a String + resp[0].id.should.have_length 32 + resp[0].rev.should.be_a String + resp[0].rev.length.should.be_at_least 30 + resp[1].id.should.be_a String + resp[1].id.should.have_length 32 + resp[1].rev.should.be_a String + resp[1].rev.length.should.be_at_least 30 + resp[2].id.should.be_a String + resp[2].id.should.have_length 32 + resp[2].rev.should.be_a String + resp[2].rev.length.should.be_at_least 30 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should save the document with specified IDs' + doc._id = "123"; + doc2._id = "456"; + docs = [doc, doc2, doc3]; + + db.bulkSave({"docs": docs},{ + success: function(resp){ + resp[0].id.should.eql "123" + resp[1].id.should.eql "456" + resp[2].id.should.have_length 32 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should pass through the options' + // 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 old_doc = {"Name" : "Louanne Katraine", "Callsign" : "Kat", "_id" : "123"}; + db.saveDoc(old_doc, { + success: function(resp){ + old_doc._rev = resp.rev; + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + + var new_doc = {"Name" : "Sasha", "Callsign" : "Kat", "_id" : "123"}; + + db.bulkSave({"docs": [new_doc], "all_or_nothing": false}, { + success: function(resp){ + resp[0].id.should.eql "123" + resp[0].error.should.eql "conflict" + resp[0].reason.should.eql "Document update conflict." + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + + db.bulkSave({"docs": [new_doc], "all_or_nothing": true}, { + success: function(resp){ + resp[0].id.should.eql "123" + resp[0].rev.should.not.eql old_doc._rev + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + + db.openDoc("123", { + "conflicts": true, + success: function(resp){ + resp._conflicts[0].should.eql old_doc._rev + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should alert with an error message prefix' + db.bulkSave("asdf"); + alert_msg.should.match /The documents could not be saved/ + end + end +end \ No newline at end of file Added: couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_instance_methods_3_spec.js URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_instance_methods_3_spec.js?rev=950690&view=auto ============================================================================== --- couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_instance_methods_3_spec.js (added) +++ couchdb/branches/0.11.x/share/www/spec/jquery_couch_js_instance_methods_3_spec.js Wed Jun 2 17:46:41 2010 @@ -0,0 +1,528 @@ +// Specs for jquery_couch.js lines 300-411 + +describe 'jQuery couchdb db' + before + stubAlert(); + end + + after + destubAlert(); + end + + before_each + db = $.couch.db('spec_db'); + db.create(); + end + + after_each + db.drop(); + end + + describe 'removeDoc' + before_each + doc = {"Name" : "Louanne Katraine", "Callsign" : "Kat", "_id" : "345"}; + saved_doc = {}; + db.saveDoc(doc, { + success: function(resp){ + saved_doc = resp; + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should result in a deleted document' + db.removeDoc({_id : "345", _rev : saved_doc.rev}, { + success: function(resp){ + db.openDoc("345", { + error: function(status, error, reason){ + status.should.eql 404 + error.should.eql "not_found" + reason.should.eql "deleted" + }, + success: function(resp){successCallback(resp)} + }); + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should return ok true, the ID and the revision of the deleted document' + db.removeDoc({_id : "345", _rev : saved_doc.rev}, { + success: function(resp){ + resp.ok.should.be_true + resp.id.should.eql "345" + resp.rev.should.be_a String + resp.rev.length.should.be_at_least 30 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should record the revision in the deleted document' + db.removeDoc({_id : "345", _rev : saved_doc.rev}, { + success: function(resp){ + db.openDoc("345", { + rev: resp.rev, + success: function(resp2){ + resp2._rev.should.eql resp.rev + resp2._id.should.eql resp.id + resp2._deleted.should.be_true + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should alert with an error message prefix' + db.removeDoc({_id: "asdf"}); + alert_msg.should.match /The document could not be deleted/ + end + end + + describe 'bulkRemove' + before_each + 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}, { + success: function(resp){ + for (var i = 0; i < docs.length; i++) { + docs[i]._rev = resp[i].rev; + } + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should remove all documents specified' + db.bulkRemove({"docs": docs}); + db.allDocs({ + success: function(resp) { + resp.total_rows.should.eql 0 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should not remove documents that should not have been deleted' + db.bulkRemove({"docs": [doc3]}); + db.allDocs({ + success: function(resp) { + resp.total_rows.should.eql 2 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should result in deleted documents' + db.bulkRemove({"docs": docs}, { + success: function(resp){ + db.openDoc("123", { + error: function(status, error, reason){ + status.should.eql 404 + error.should.eql "not_found" + reason.should.eql "deleted" + }, + success: function(resp){successCallback(resp)} + }); + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should return the ID and the revision of the deleted documents' + db.bulkRemove({"docs": docs}, { + success: function(resp){ + resp[0].id.should.eql "123" + resp[0].rev.should.be_a String + resp[0].rev.length.should.be_at_least 30 + resp[1].id.should.eql "456" + resp[1].rev.should.be_a String + resp[1].rev.length.should.be_at_least 30 + resp[2].id.should.eql "789" + resp[2].rev.should.be_a String + resp[2].rev.length.should.be_at_least 30 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should record the revision in the deleted documents' + db.bulkRemove({"docs": docs}, { + success: function(resp){ + db.openDoc("123", { + rev: resp[0].rev, + success: function(resp2){ + resp2._rev.should.eql resp[0].rev + resp2._id.should.eql resp[0].id + resp2._deleted.should.be_true + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should alert with an error message prefix' + db.bulkRemove({docs: ["asdf"]}); + alert_msg.should.match /The documents could not be deleted/ + end + end + + describe 'copyDoc' + before_each + doc = {"Name" : "Sharon Agathon", "Callsign" : "Athena", "_id" : "123"}; + db.saveDoc(doc); + end + + it 'should result in another document with same data and new id' + db.copyDoc("123", { + success: function(resp){ + resp.id.should.eql "456" + resp.rev.length.should.be_at_least 30 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }, { + headers: {"Destination":"456"} + }); + + db.openDoc("456", { + success: function(resp){ + resp.Name.should.eql "Sharon Agathon" + resp.Callsign.should.eql "Athena" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should throw an error when trying to overwrite a document without providing a revision' + doc2 = {"Name" : "Louanne Katraine", "Callsign" : "Kat", "_id" : "456"}; + db.saveDoc(doc2); + + db.copyDoc("123", { + error: function(status, error, reason){ + status.should.eql 409 + error.should.eql "conflict" + reason.should.eql "Document update conflict." + }, + success: function(resp){successCallback(resp)} + }, { + headers: {"Destination":"456"} + }); + end + + it 'should overwrite a document with the correct revision' + doc2 = {"Name" : "Louanne Katraine", "Callsign" : "Kat", "_id" : "456"}; + var doc2_rev; + db.saveDoc(doc2, { + success: function(resp){ + doc2_rev = resp.rev; + } + }); + + db.copyDoc("123", { + success: function(resp){ + resp.id.should.eql "456" + resp.rev.length.should.be_at_least 30 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }, { + headers: {"Destination":"456?rev=" + doc2_rev} + }); + + db.openDoc("456", { + success: function(resp){ + resp.Name.should.eql "Sharon Agathon" + resp.Callsign.should.eql "Athena" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should alert with an error message prefix' + db.copyDoc("asdf", {}, {}); + alert_msg.should.match /The document could not be copied/ + end + end + + describe 'query' + before_each + db.saveDoc({"Name" : "Cally Tyrol", "job" : "deckhand", "_id" : "789"}); + db.saveDoc({"Name" : "Felix Gaeta", "job" : "officer", "_id" : "123"}); + db.saveDoc({"Name" : "Samuel T. Anders", "job" : "pilot", "_id" : "456"}); + map_function = "function(doc) { emit(doc._id, 1); }"; + reduce_function = "function(key, values, rereduce) { return sum(values); }"; + end + + it 'should apply the map function' + db.query(map_function, null, null, { + success: function(resp){ + resp.rows.should.have_length 3 + resp.rows[0].id.should.eql "123" + resp.rows[0].key.should.eql "123" + resp.rows[0].value.should.eql 1 + resp.rows[1].id.should.eql "456" + resp.rows[1].key.should.eql "456" + resp.rows[1].value.should.eql 1 + resp.rows[2].id.should.eql "789" + resp.rows[2].key.should.eql "789" + resp.rows[2].value.should.eql 1 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should apply the reduce function' + db.query(map_function, reduce_function, null, { + success: function(resp){ + resp.rows.should.have_length 1 + resp.rows[0].key.should.be_null + resp.rows[0].value.should_eql 3 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should pass through the options' + db.query(map_function, null, null, { + "startkey": "456", + success: function(resp){ + resp.rows.should.have_length 2 + resp.rows[0].id.should.eql "456" + resp.rows[0].key.should.eql "456" + resp.rows[0].value.should.eql 1 + resp.rows[1].id.should.eql "789" + resp.rows[1].key.should.eql "789" + resp.rows[1].value.should.eql 1 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should pass through the keys' + //shouldn't this better work? TODO: implement in jquery.couch.js + console.log("shouldn't this better work? TODO: implement in jquery.couch.js") + db.query(map_function, null, null, { + "keys": ["456", "123"], + success: function(resp){ + resp.rows.should.have_length 2 + resp.rows[0].id.should.eql "456" + resp.rows[0].key.should.eql "456" + resp.rows[0].value.should.eql 1 + resp.rows[1].id.should.eql "123" + resp.rows[1].key.should.eql "123" + resp.rows[1].value.should.eql 1 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should pass through the options and the keys' + //shouldn't this better work? TODO: implement in jquery.couch.js + console.log("shouldn't this better work? TODO: implement in jquery.couch.js") + db.query(map_function, null, null, { + "include_docs":"true", + "keys": ["456"], + success: function(resp){ + resp.rows.should.have_length 1 + resp.rows[0].id.should.eql "456" + resp.rows[0].key.should.eql "456" + resp.rows[0].value.should.eql 1 + resp.rows[0].doc["job"].should.eql "pilot" + resp.rows[0].doc["_rev"].length.should.be_at_least 30 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should apply a query in erlang also' + // when this test fails, read this: http://wiki.apache.org/couchdb/EnableErlangViews + var erlang_map = 'fun({Doc}) -> ' + + 'ID = proplists:get_value(<<"_id">>, Doc, null), ' + + 'Emit(ID, 1) ' + + 'end.'; + db.query(erlang_map, null, "erlang", { + success: function(resp){ + resp.rows.should.have_length 3 + resp.rows[0].id.should.eql "123" + resp.rows[0].key.should.eql "123" + resp.rows[0].value.should.eql 1 + resp.rows[1].id.should.eql "456" + resp.rows[1].key.should.eql "456" + resp.rows[1].value.should.eql 1 + resp.rows[2].id.should.eql "789" + resp.rows[2].key.should.eql "789" + resp.rows[2].value.should.eql 1 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should alert with an error message prefix' + db.query("asdf"); + alert_msg.should.match /An error occurred querying the database/ + end + end + + describe 'view' + before_each + db.saveDoc({"Name" : "Cally Tyrol", "job" : "deckhand", "_id" : "789"}); + db.saveDoc({"Name" : "Felix Gaeta", "job" : "officer", "_id" : "123"}); + db.saveDoc({"Name" : "Samuel T. Anders", "job" : "pilot", "_id" : "456"}); + view = { + "views" : { + "people" : { + "map" : "function(doc) { emit(doc._id, doc.Name); }" + } + }, + "_id" : "_design/spec_db" + }; + db.saveDoc(view); + end + + it 'should apply the view' + db.view('spec_db/people', { + success: function(resp){ + resp.rows.should.have_length 3 + resp.rows[0].id.should.eql "123" + resp.rows[0].key.should.eql "123" + resp.rows[0].value.should.eql "Felix Gaeta" + resp.rows[1].id.should.eql "456" + resp.rows[1].key.should.eql "456" + resp.rows[1].value.should.eql "Samuel T. Anders" + resp.rows[2].id.should.eql "789" + resp.rows[2].key.should.eql "789" + resp.rows[2].value.should.eql "Cally Tyrol" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should pass through the options' + db.view('spec_db/people', { + "skip":"2", + success: function(resp){ + resp.rows.should.have_length 1 + resp.rows[0].id.should.eql "789" + resp.rows[0].key.should.eql "789" + resp.rows[0].value.should.eql "Cally Tyrol" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should pass through the keys' + db.view('spec_db/people', { + "keys":["456", "123"], + success: function(resp){ + resp.rows.should.have_length 2 + resp.rows[0].id.should.eql "456" + resp.rows[0].key.should.eql "456" + resp.rows[0].value.should.eql "Samuel T. Anders" + resp.rows[1].id.should.eql "123" + resp.rows[1].key.should.eql "123" + resp.rows[1].value.should.eql "Felix Gaeta" + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should pass through the options and the keys' + db.view('spec_db/people', { + "include_docs":"true", + "keys":["456"], + success: function(resp){ + resp.rows.should.have_length 1 + resp.rows[0].id.should.eql "456" + resp.rows[0].key.should.eql "456" + resp.rows[0].value.should.eql "Samuel T. Anders" + resp.rows[0].doc["job"].should.eql "pilot" + resp.rows[0].doc["_rev"].length.should.be_at_least 30 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should throw a 404 when the view doesnt exist' + db.view('spec_db/non_existing_view', { + error: function(status, error, reason){ + status.should.eql 404 + error.should.eql "not_found" + reason.should.eql "missing_named_view" + }, + success: function(resp){successCallback(resp)} + }); + end + + it 'should alert with an error message prefix' + db.view("asdf"); + alert_msg.should.match /An error occurred accessing the view/ + end + end + + describe 'setDbProperty' + it 'should return ok true' + db.setDbProperty("_revs_limit", 1500, { + success: function(resp){ + resp.ok.should.be_true + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should set a db property' + db.setDbProperty("_revs_limit", 1500); + db.getDbProperty("_revs_limit", { + success: function(resp){ + resp.should.eql 1500 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + db.setDbProperty("_revs_limit", 1200); + db.getDbProperty("_revs_limit", { + success: function(resp){ + resp.should.eql 1200 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should alert with an error message prefix' + db.setDbProperty("asdf"); + alert_msg.should.match /The property could not be updated/ + end + end + + describe 'getDbProperty' + it 'should get a db property' + db.setDbProperty("_revs_limit", 1200); + db.getDbProperty("_revs_limit", { + success: function(resp){ + resp.should.eql 1200 + }, + error: function(status, error, reason){errorCallback(status, error, reason)} + }); + end + + it 'should throw a 404 when the property doesnt exist' + db.getDbProperty("_doesnt_exist", { + error: function(status, error, reason){ + status.should.eql 404 + error.should.eql "not_found" + reason.should.eql "missing" + }, + success: function(resp){successCallback(resp)} + }); + end + + it 'should alert with an error message prefix' + db.getDbProperty("asdf"); + alert_msg.should.match /The property could not be retrieved/ + end + end +end \ No newline at end of file Added: couchdb/branches/0.11.x/share/www/spec/run.html URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/share/www/spec/run.html?rev=950690&view=auto ============================================================================== --- couchdb/branches/0.11.x/share/www/spec/run.html (added) +++ couchdb/branches/0.11.x/share/www/spec/run.html Wed Jun 2 17:46:41 2010 @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + +

JSpec

+
+
+ +