diff options
author | Adam Kocoloski <adam@cloudant.com> | 2011-10-04 13:11:12 -0700 |
---|---|---|
committer | Adam Kocoloski <adam@cloudant.com> | 2011-10-04 13:11:12 -0700 |
commit | da7284ed2844926c7df0efef12ba30d8e2e6d039 (patch) | |
tree | 10fa2d5cf35bfae4d48fc632924cec98ee02a22a /rel/overlay/share | |
parent | b57aadd742e4f8cc925ba4f005ae658c43a7c5b4 (diff) | |
parent | 4e19639a64d3033e1cc7c22a0b7404d277643c78 (diff) |
Merge pull request #67 from cloudant/12645-merge_latest_1.1.x
Diffstat (limited to 'rel/overlay/share')
-rw-r--r-- | rel/overlay/share/www/script/couch_test_runner.js | 15 | ||||
-rw-r--r-- | rel/overlay/share/www/script/futon.browse.js | 3 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/all_docs.js | 7 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/basics.js | 19 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/changes.js | 26 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/design_docs.js | 39 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/etags_views.js | 8 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/jsonp.js | 2 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/recreate_doc.js | 65 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/show_documents.js | 26 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/update_documents.js | 38 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/view_collation_raw.js | 9 |
12 files changed, 253 insertions, 4 deletions
diff --git a/rel/overlay/share/www/script/couch_test_runner.js b/rel/overlay/share/www/script/couch_test_runner.js index 55a6533f..e14640b6 100644 --- a/rel/overlay/share/www/script/couch_test_runner.js +++ b/rel/overlay/share/www/script/couch_test_runner.js @@ -414,9 +414,22 @@ function waitForSuccess(fun, tag) { function waitForRestart() { var waiting = true; - while (waiting) { + // Wait for the server to go down but don't + // wait too long because we might miss the + // unavailable period. + var count = 25; + while (waiting && count > 0) { + count--; try { CouchDB.request("GET", "/"); + } catch(e) { + waiting = false; + } + } + // Wait for it to come back up + waiting = true; + while (waiting) { + try { CouchDB.request("GET", "/"); waiting = false; } catch(e) { diff --git a/rel/overlay/share/www/script/futon.browse.js b/rel/overlay/share/www/script/futon.browse.js index 0228b83e..5c10773a 100644 --- a/rel/overlay/share/www/script/futon.browse.js +++ b/rel/overlay/share/www/script/futon.browse.js @@ -1275,8 +1275,7 @@ return false; }).prependTo($("a", li)); } - }, - + } }); function encodeAttachment(name) { diff --git a/rel/overlay/share/www/script/test/all_docs.js b/rel/overlay/share/www/script/test/all_docs.js index 1d83aa95..1afe701d 100644 --- a/rel/overlay/share/www/script/test/all_docs.js +++ b/rel/overlay/share/www/script/test/all_docs.js @@ -41,6 +41,13 @@ couchTests.all_docs = function(debug) { var all = db.allDocs({startkey:"2"}); T(all.offset == 2); + // Confirm that queries may assume raw collation. + var raw = db.allDocs({ + startkey: "org.couchdb.user:", + endkey: "org.couchdb.user;" + }); + TEquals(0, raw.rows.length); + // check that the docs show up in the seq view in the order they were created var changes = db.changes(); var ids = ["0","3","1","2"]; diff --git a/rel/overlay/share/www/script/test/basics.js b/rel/overlay/share/www/script/test/basics.js index 30c27c11..5dcf9fa9 100644 --- a/rel/overlay/share/www/script/test/basics.js +++ b/rel/overlay/share/www/script/test/basics.js @@ -246,4 +246,23 @@ couchTests.basics = function(debug) { result = JSON.parse(xhr.responseText); TEquals("bad_request", result.error); TEquals("You tried to DELETE a database with a ?=rev parameter. Did you mean to DELETE a document instead?", result.reason); + + // On restart, a request for creating a database that already exists can + // not override the existing database file + db = new CouchDB("test_suite_foobar"); + db.deleteDb(); + xhr = CouchDB.request("PUT", "/" + db.name); + TEquals(201, xhr.status); + + TEquals(true, db.save({"_id": "doc1"}).ok); + TEquals(true, db.ensureFullCommit().ok); + + TEquals(1, db.info().doc_count); + + restartServer(); + + xhr = CouchDB.request("PUT", "/" + db.name); + TEquals(412, xhr.status); + + TEquals(1, db.info().doc_count); }; diff --git a/rel/overlay/share/www/script/test/changes.js b/rel/overlay/share/www/script/test/changes.js index ea22bfb3..284f1985 100644 --- a/rel/overlay/share/www/script/test/changes.js +++ b/rel/overlay/share/www/script/test/changes.js @@ -507,6 +507,32 @@ couchTests.changes = function(debug) { CouchDB.request("GET", "/" + db.name + "/_changes"); TEquals(0, CouchDB.requestStats('httpd', 'clients_requesting_changes').current); + // COUCHDB-1256 + T(db.deleteDb()); + T(db.createDb()); + + T(db.save({"_id":"foo", "a" : 123}).ok); + T(db.save({"_id":"bar", "a" : 456}).ok); + + options = { + headers: {"Content-Type": "application/json"}, + body: JSON.stringify({"_rev":"1-cc609831f0ca66e8cd3d4c1e0d98108a", "a":456}) + }; + req = CouchDB.request("PUT", "/" + db.name + "/foo?new_edits=false", options); + + req = CouchDB.request("GET", "/" + db.name + "/_changes?style=all_docs"); + resp = JSON.parse(req.responseText); + + TEquals(3, resp.last_seq); + TEquals(2, resp.results.length); + + req = CouchDB.request("GET", "/" + db.name + "/_changes?style=all_docs&since=2"); + resp = JSON.parse(req.responseText); + + TEquals(3, resp.last_seq); + TEquals(1, resp.results.length); + TEquals(2, resp.results[0].changes.length); + // cleanup db.deleteDb(); }; diff --git a/rel/overlay/share/www/script/test/design_docs.js b/rel/overlay/share/www/script/test/design_docs.js index 702f0441..dd38858a 100644 --- a/rel/overlay/share/www/script/test/design_docs.js +++ b/rel/overlay/share/www/script/test/design_docs.js @@ -421,6 +421,45 @@ couchTests.design_docs = function(debug) { run_on_modified_server(server_config, testFun); + // COUCHDB-1227 - if a design document is deleted, by adding a "_deleted" + // field with the boolean value true, its validate_doc_update functions + // should no longer have effect. + db.deleteDb(); + db.createDb(); + var ddoc = { + _id: "_design/test", + language: "javascript", + validate_doc_update: (function(newDoc, oldDoc, userCtx, secObj) { + if (newDoc.value % 2 == 0) { + throw({forbidden: "dont like even numbers"}); + } + return true; + }).toString() + }; + + TEquals(true, db.save(ddoc).ok); + try { + db.save({_id: "doc1", value: 4}); + T(false, "doc insertion should have failed"); + } catch (x) { + TEquals("forbidden", x.error); + } + + var doc = db.open("doc1"); + TEquals(null, doc); + ddoc._deleted = true; + TEquals(true, db.save(ddoc).ok); + + try { + TEquals(true, db.save({_id: "doc1", value: 4}).ok); + } catch (x) { + T(false, "doc insertion should have succeeded"); + } + + doc = db.open("doc1"); + TEquals(true, doc !== null, "doc was not persisted"); + TEquals(4, doc.value); + // cleanup db.deleteDb(); db2.deleteDb(); diff --git a/rel/overlay/share/www/script/test/etags_views.js b/rel/overlay/share/www/script/test/etags_views.js index 34116f71..f6a4e1a5 100644 --- a/rel/overlay/share/www/script/test/etags_views.js +++ b/rel/overlay/share/www/script/test/etags_views.js @@ -70,6 +70,14 @@ couchTests.etags_views = function(debug) { xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/basicView"); var etag1 = xhr.getResponseHeader("etag"); T(etag1 == etag); + + // verify ETag always changes for include_docs=true on update + xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/basicView?include_docs=true"); + var etag1 = xhr.getResponseHeader("etag"); + T(db.save({"_id":"doc2", "foo":"bar"}).ok); + xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/basicView?include_docs=true"); + var etag2 = xhr.getResponseHeader("etag"); + T(etag1 != etag2); // Verify that purges affect etags xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/fooView"); diff --git a/rel/overlay/share/www/script/test/jsonp.js b/rel/overlay/share/www/script/test/jsonp.js index 9aba7189..d1bca94a 100644 --- a/rel/overlay/share/www/script/test/jsonp.js +++ b/rel/overlay/share/www/script/test/jsonp.js @@ -48,6 +48,7 @@ couchTests.jsonp = function(debug) { // Test unchunked callbacks. var xhr = CouchDB.request("GET", "/test_suite_db/0?callback=jsonp_no_chunk"); + TEquals("text/javascript", xhr.getResponseHeader("Content-Type")); T(xhr.status == 200); jsonp_flag = 0; eval(xhr.responseText); @@ -70,6 +71,7 @@ couchTests.jsonp = function(debug) { var url = "/test_suite_db/_design/test/_view/all_docs?callback=jsonp_chunk"; xhr = CouchDB.request("GET", url); + TEquals("text/javascript", xhr.getResponseHeader("Content-Type")); T(xhr.status == 200); jsonp_flag = 0; eval(xhr.responseText); diff --git a/rel/overlay/share/www/script/test/recreate_doc.js b/rel/overlay/share/www/script/test/recreate_doc.js index 05843558..f9723793 100644 --- a/rel/overlay/share/www/script/test/recreate_doc.js +++ b/rel/overlay/share/www/script/test/recreate_doc.js @@ -77,4 +77,69 @@ couchTests.recreate_doc = function(debug) { } catch (e) { T(e.error == "conflict"); } + + db.deleteDb(); + db.createDb(); + + // Helper function to create a doc with multiple revisions + // that are compacted away to ?REV_MISSING. + + var createDoc = function(docid) { + var ret = [{_id: docid, count: 0}]; + T(db.save(ret[0]).ok); + for(var i = 0; i < 2; i++) { + ret[ret.length] = { + _id: docid, + _rev: ret[ret.length-1]._rev, + count: ret[ret.length-1].count+1 + }; + T(db.save(ret[ret.length-1]).ok); + } + db.compact(); + while(db.info().compact_running) {} + return ret; + } + + // Helper function to check that there are no duplicates + // in the changes feed and that it has proper update + // sequence ordering. + + var checkChanges = function() { + // Assert that there are no duplicates in _changes. + var req = CouchDB.request("GET", "/test_suite_db/_changes"); + var resp = JSON.parse(req.responseText); + var docids = {}; + var prev_seq = -1; + for(var i = 0; i < resp.results.length; i++) { + row = resp.results[i]; + T(row.seq > prev_seq, "Unordered _changes feed."); + T(docids[row.id] === undefined, "Duplicates in _changes feed."); + prev_seq = row.seq; + docids[row.id] = true; + } + }; + + // COUCHDB-1265 - Check that the changes feed remains proper + // after we try and break the update_seq tree. + + // This first case is the one originally reported and "fixed" + // in COUCHDB-1265. Reinserting an old revision into the + // revision tree causes duplicates in the update_seq tree. + + var revs = createDoc("a"); + T(db.save(revs[1], {new_edits: false}).ok); + T(db.save(revs[revs.length-1]).ok); + checkChanges(); + + // The original fix for COUCHDB-1265 is not entirely correct + // as it didn't consider the possibility that a compaction + // might run after the original tree screw up. + + revs = createDoc("b"); + T(db.save(revs[1], {new_edits: false}).ok); + db.compact(); + while(db.info().compact_running) {} + T(db.save(revs[revs.length-1]).ok); + checkChanges(); + }; diff --git a/rel/overlay/share/www/script/test/show_documents.js b/rel/overlay/share/www/script/test/show_documents.js index 55ed9698..cf73ed57 100644 --- a/rel/overlay/share/www/script/test/show_documents.js +++ b/rel/overlay/share/www/script/test/show_documents.js @@ -90,6 +90,24 @@ couchTests.show_documents = function(debug) { start({"X-Couch-Test-Header": "Yeah"}); send("Hey"); }), + "list-api-provides" : stringFun(function(doc, req) { + provides("text", function(){ + send("foo, "); + send("bar, "); + send("baz!"); + }) + }), + "list-api-provides-and-return" : stringFun(function(doc, req) { + provides("text", function(){ + send("4, "); + send("5, "); + send("6, "); + return "7!"; + }) + send("1, "); + send("2, "); + return "3, "; + }), "list-api-mix" : stringFun(function(doc, req) { start({"X-Couch-Test-Header": "Yeah"}); send("Hey "); @@ -395,6 +413,14 @@ couchTests.show_documents = function(debug) { T(xhr.responseText == "Hey"); TEquals("Yeah", xhr.getResponseHeader("X-Couch-Test-Header"), "header should be cool"); + // test list() compatible API with provides function + xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api-provides/foo?format=text"); + TEquals(xhr.responseText, "foo, bar, baz!", "should join chunks to response body"); + + // should keep next result order: chunks + return value + provided chunks + provided return value + xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api-provides-and-return/foo?format=text"); + TEquals(xhr.responseText, "1, 2, 3, 4, 5, 6, 7!", "should not break 1..7 range"); + xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api-mix/foo"); T(xhr.responseText == "Hey Dude"); TEquals("Yeah", xhr.getResponseHeader("X-Couch-Test-Header"), "header should be cool"); diff --git a/rel/overlay/share/www/script/test/update_documents.js b/rel/overlay/share/www/script/test/update_documents.js index 49d3b68a..59af4597 100644 --- a/rel/overlay/share/www/script/test/update_documents.js +++ b/rel/overlay/share/www/script/test/update_documents.js @@ -75,6 +75,17 @@ couchTests.update_documents = function(debug) { }), "get-uuid" : stringFun(function(doc, req) { return [null, req.uuid]; + }), + "code-n-bump" : stringFun(function(doc,req) { + if (!doc.counter) doc.counter = 0; + doc.counter += 1; + var message = "<h1>bumped it!</h1>"; + resp = {"code": 302, "body": message} + return [doc, resp]; + }), + "resp-code" : stringFun(function(doc,req) { + resp = {"code": 302} + return [null, resp]; }) } }; @@ -165,4 +176,31 @@ couchTests.update_documents = function(debug) { T(xhr.status == 200); T(xhr.responseText.length == 32); + // COUCHDB-1229 - allow slashes in doc ids for update handlers + // /db/_design/doc/_update/handler/doc/id + + var doc = { + _id:"with/slash", + counter:1 + }; + db.save(doc); + xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/bump-counter/with/slash"); + TEquals(201, xhr.status, "should return a 200 status"); + TEquals("<h1>bumped it!</h1>", xhr.responseText, "should report bumping"); + + var doc = db.open("with/slash"); + TEquals(2, doc.counter, "counter should be 2"); + + // COUCHDB-648 - the code in the JSON response should be honored + + xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/code-n-bump/"+docid, { + headers : {"X-Couch-Full-Commit":"true"} + }); + T(xhr.status == 302); + T(xhr.responseText == "<h1>bumped it!</h1>"); + doc = db.open(docid); + T(doc.counter == 3); + + xhr = CouchDB.request("POST", "/test_suite_db/_design/update/_update/resp-code/"); + T(xhr.status == 302); }; diff --git a/rel/overlay/share/www/script/test/view_collation_raw.js b/rel/overlay/share/www/script/test/view_collation_raw.js index 31624cdb..779f7eb8 100644 --- a/rel/overlay/share/www/script/test/view_collation_raw.js +++ b/rel/overlay/share/www/script/test/view_collation_raw.js @@ -76,12 +76,19 @@ couchTests.view_collation_raw = function(debug) { } } T(db.save(designDoc).ok); + + // Confirm that everything collates correctly. var rows = db.view("test/test").rows; for (i=0; i<values.length; i++) { T(equals(rows[i].key, values[i])); } - // everything has collated correctly. Now to check the descending output + // Confirm that couch allows raw semantics in key ranges. + rows = db.view("test/test", {startkey:"Z", endkey:"a"}).rows; + TEquals(1, rows.length); + TEquals("a", rows[0].key); + + // Check the descending output. rows = db.view("test/test", {descending: true}).rows; for (i=0; i<values.length; i++) { T(equals(rows[i].key, values[values.length - 1 -i])); |