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

jiahuili430 pushed a commit to branch fix-elixir-tests
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit a771da106db27499e2e450e55ddf6d3b566d4928
Author: Jiahui Li <[email protected]>
AuthorDate: Wed Dec 10 14:31:57 2025 -0600

    Modify suite.elixir
---
 test/elixir/test/config/suite.elixir => t.json     | 291 ++++---
 t.py                                               |  25 +
 test/elixir/test/config/search.elixir              |   3 +-
 test/elixir/test/config/suite.elixir               |  24 +-
 .../{disk_monitor.exs => disk_monitor_test.exs}    |   0
 test/elixir/test/rewrite_js_test.exs               | 361 ++++----
 test/elixir/test/rewrite_test.exs                  | 937 +++++++++++----------
 7 files changed, 859 insertions(+), 782 deletions(-)

diff --git a/test/elixir/test/config/suite.elixir b/t.json
similarity index 83%
copy from test/elixir/test/config/suite.elixir
copy to t.json
index 65e983f1d..f6384dab4 100644
--- a/test/elixir/test/config/suite.elixir
+++ b/t.json
@@ -1,4 +1,4 @@
-%{
+{
   "AllDocsTest": [
     "All Docs tests",
     "GET with one key",
@@ -27,7 +27,8 @@
     "manages attachments in views successfully"
   ],
   "AttachmentsTest": [
-    "COUCHDB-809 - stubs should only require the 'stub' field",
+    "COUCHDB-497 - empty attachments",
+    "COUCHDB-809 - stubs should only require the ",
     "attachment via multipart/form-data",
     "delete attachment",
     "delete attachment request with a payload should not block following 
requests",
@@ -36,23 +37,52 @@
     "etags for attachments",
     "implicit doc creation allows creating docs with a reserved id. 
COUCHDB-565",
     "large attachments COUCHDB-366",
-    "md5 header for attachments",
     "reads attachment successfully",
     "saves attachment successfully",
     "saves binary",
-    "COUCHDB-497 - empty attachments",
     "update attachment"
   ],
   "AuthCacheTest": [
     "auth cache management"
   ],
   "AuthLockoutTest": [
-    "lockout after multiple failed authentications",
-    "lockout warning after multiple failed authentications"
+    "do not lockout after multiple failed authentications",
+    "lockout after multiple failed authentications"
+  ],
+  "BasicFindTest": [
+    "bad conflicts",
+    "bad fields",
+    "bad limit",
+    "bad r",
+    "bad selector",
+    "bad skip",
+    "bad sort",
+    "empty",
+    "empty subsel",
+    "empty subsel match",
+    "explain options",
+    "explain view args",
+    "fields",
+    "limit",
+    "missing not indexed",
+    "multi col idx",
+    "multi cond and",
+    "multi cond duplicate field",
+    "multi cond or",
+    "r",
+    "simple find",
+    "skip",
+    "sort",
+    "sort desc complex",
+    "sort desc complex error",
+    "sort exists true",
+    "sort with all docs",
+    "sort with primary sort not in selector",
+    "unsatisfiable range"
   ],
   "BasicsTest": [
-    "'+' in document name should encode to '+'",
-    "'+' in document name should encode to space",
+    "'+",
+    "'+",
     "A document read with etag works",
     "Can create several documents",
     "Check for invalid document members",
@@ -60,17 +90,17 @@
     "Created database has appropriate db info name",
     "Creating a new DB should return location header",
     "Creating a new DB with slashes should return Location header 
(COUCHDB-411)",
-    "DELETE'ing a non-existent doc should 404",
-    "Database name with '%2B' should encode to '+'",
-    "Database name with '+' should encode to '+'",
+    "DELETE",
+    "Database name with ",
+    "Database name with ",
     "Database should be in _all_dbs",
-    "Limit and skip should work in _all_dbs",
     "Default headers are returned for doc with open_revs=all",
     "Empty database should have zero docs",
+    "Limit and skip should work in _all_dbs",
     "Make sure you can do a seq=true option",
     "On restart, a request for creating an already existing db can not 
override",
     "POST doc response has a Location header",
-    "POST doc with an _id field isn't overwritten by uuid",
+    "POST doc with an _id field isn",
     "PUT doc has a Location header",
     "PUT error when body not an object",
     "PUT on existing DB should return 412 instead of 500",
@@ -79,7 +109,7 @@
     "Session contains adm context",
     "Simple map functions",
     "Welcome endpoint",
-    "_all_docs POST error when multi-get is not a {'key': [...]} structure",
+    "_all_docs POST error when multi-get is not a {",
     "_bulk_docs POST error when body not an object",
     "oops, the doc id got lost in code nirwana",
     "request ID can be specified at the client"
@@ -106,11 +136,11 @@
     "continuous filtered changes",
     "continuous filtered changes with doc ids",
     "eventsource changes",
-    "eventsource changes with limit under",
     "eventsource changes with limit exact",
     "eventsource changes with limit over",
-    "eventsource no junk in response",
+    "eventsource changes with limit under",
     "eventsource heartbeat",
+    "eventsource no junk in response",
     "live changes",
     "longpoll changes",
     "longpoll filtered changes"
@@ -141,21 +171,22 @@
   ],
   "ConfigTest": [
     "Atoms, binaries, and strings suffice as whitelist sections and keys.",
+    "Auto-reload config",
     "Blacklist is functional",
     "CouchDB respects configured protocols",
     "Keys not in the whitelist may not be modified",
     "Non-2-tuples in the whitelist are ignored",
     "Non-list whitelist values allow further modification of the whitelist",
     "Non-term whitelist values allow further modification of the whitelist",
+    "Only JSON strings are accepted",
     "PORT `BUGGED` ?raw tests from config.js",
     "Reload config",
-    "Auto-reload config",
     "Server-side password hashing, and raw updates disabling that",
     "Settings can be altered with undefined whitelist allowing any change",
-    "Standard config options are present",
-    "Only JSON strings are accepted"
+    "Standard config options are present"
   ],
   "CookieAuthTest": [
+    "basic+cookie auth interaction",
     "cookie auth"
   ],
   "CopyDocTest": [
@@ -203,15 +234,13 @@
     "design doc options - include_desing=true",
     "design doc options - local_seq=true"
   ],
-  "DiskMonitorTest": [
-    "block background view indexing",
-    "block interactive view indexing",
-    "block interactive database writes"
-  ],
   "DesignPathTest": [
     "design doc path",
     "design doc path with slash in db name"
   ],
+  "ElemMatchTests": [
+    "elem match non object"
+  ],
   "ErlangViewsTest": [
     "Erlang map function",
     "Erlang reduce function",
@@ -237,6 +266,9 @@
     "location header should include X-Forwarded-Host",
     "location header should include custom header"
   ],
+  "IgnoreDesignDocsForAllDocsIndexTests": [
+    "should not return design docs"
+  ],
   "InvalidDocIDsTest": [
     "_local-prefixed ids are illegal",
     "a PUT request with absent _id is forbidden",
@@ -257,6 +289,16 @@
     "jwt auth with required iss claim",
     "jwt auth without secret"
   ],
+  "JwtRolesClaimTest": [
+    "case: roles_claim_name (defined) / roles_claim_path (defined)",
+    "case: roles_claim_name (defined) / roles_claim_path (undefined)",
+    "case: roles_claim_name (undefined) / roles_claim_path (defined)",
+    "case: roles_claim_name (undefined) / roles_claim_path (undefined)",
+    "case: roles_claim_path with bad input"
+  ],
+  "LimitTests": [
+    "limit field"
+  ],
   "ListViewsTest": [
     "COUCHDB-1113",
     "HTTP header response set after getRow() called in _list function",
@@ -297,13 +339,48 @@
     "lots of docs with a regular view"
   ],
   "MethodOverrideTest": [
-    "Method Override is ignored when original Method isn't POST",
+    "Method Override is ignored when original Method isn",
     "method override DELETE",
     "method override PUT"
   ],
   "MultipleRowsTest": [
     "multiple rows"
   ],
+  "NouveauTest": [
+    "counts",
+    "delete",
+    "index not found",
+    "index same field with different field types",
+    "mango (partitioned)",
+    "mango search by number",
+    "mango search by string",
+    "mango search by text",
+    "mango sort by number",
+    "mango sort by string",
+    "meta",
+    "multiple values for stored field",
+    "purge",
+    "purge with conflicts",
+    "ranges",
+    "ranges (open)",
+    "search GET (partitioned)",
+    "search POST (partitioned)",
+    "search analyze",
+    "search for foo:bar",
+    "search for numeric ranges with locales",
+    "search info",
+    "search returns all items (paginated)",
+    "search returns all items for GET",
+    "search returns all items for POST",
+    "search returns all matches for hello by relevance",
+    "sort by numeric field (asc)",
+    "sort by numeric field (desc)",
+    "sort by string field (asc)",
+    "sort by string field (desc)",
+    "stale search",
+    "top_n",
+    "user-agent header is forbidden"
+  ],
   "PartitionAllDocsTest": [
     "all_docs with partitioned:true returns partitioned fields",
     "partition _all_docs with descending",
@@ -374,6 +451,21 @@
     "query using _id works for global and local query",
     "query with partitioned:true using index and $eq"
   ],
+  "PartitionSearchTest": [
+    "Cannot do global query with partition view",
+    "Cannot do partition query with global search ddoc",
+    "Only returns docs in partition not those in shard",
+    "Simple query returns partitioned search results",
+    "Works with bookmarks and limit",
+    "Works with limit using POST for on non-partitioned db",
+    "Works with limit using POST for partitioned db",
+    "normal search on non-partitioned dbs still work",
+    "normal search on non-partitioned dbs with limit",
+    "normal search on non-partitioned dbs with over limit",
+    "normal search on non-partitioned dbs without limit",
+    "rejects conflicting partition values",
+    "restricted parameters are not allowed in query or body"
+  ],
   "PartitionSizeLimitTest": [
     "compacting a full partition works",
     "decreasing partition size disables more writes",
@@ -394,7 +486,7 @@
   ],
   "PartitionSizeTest": [
     "adding docs increases partition sizes",
-    "attachments don't affect other partitions",
+    "attachments don",
     "deleting a doc affects partition sizes",
     "design docs do not affect partition sizes",
     "get all partition sizes",
@@ -403,7 +495,7 @@
     "partition activity not affect other partition sizes",
     "purging docs decreases partition size",
     "simple partition size",
-    "unknown partition return's zero",
+    "unknown partition return",
     "updating docs affects partition sizes"
   ],
   "PartitionViewUpdateTest": [
@@ -413,7 +505,7 @@
     "view updates properly remove old keys"
   ],
   "PasswordCacheTest": [
-    "password cache"
+    "password hash cache"
   ],
   "ProxyAuthTest": [
     "proxy auth with secret",
@@ -424,7 +516,7 @@
     "purge documents"
   ],
   "ReaderACLTest": [
-    "can't set non string reader names or roles",
+    "can",
     "members can query views",
     "restricted db can be read by authorized users",
     "unrestricted db can be read",
@@ -452,23 +544,23 @@
     "Reduce pagination"
   ],
   "ReplicationTest": [
-    "compressed attachment replication - remote-to-remote",
-    "continuous replication - remote-to-remote",
-    "create_target filter option - remote-to-remote",
+    "compressed attachment replication - #{name}",
+    "continuous replication - #{name}",
+    "create_target filter option - #{name}",
     "default headers returned for _scheduler/docs ",
     "default headers returned for _scheduler/jobs",
-    "filtered replications - remote-to-remote",
-    "non-admin or reader user on source - remote-to-remote",
-    "non-admin user on target - remote-to-remote",
-    "replicate with since_seq - remote-to-remote",
+    "filtered replications - #{name}",
+    "non-admin or reader user on source - #{name}",
+    "non-admin user on target - #{name}",
+    "replicate with since_seq - #{name}",
     "replicating attachment without conflict - COUCHDB-885",
-    "replication by doc ids - remote-to-remote",
+    "replication by doc ids - #{name}",
     "replication cancellation",
-    "replication restarts after filter change - COUCHDB-892 - 
remote-to-remote",
-    "simple remote-to-remote replication - remote-to-remote",
+    "replication restarts after filter change - COUCHDB-892 - #{name}",
+    "simple #{name} replication - #{name}",
     "source database not found with host",
     "unauthorized replication cancellation",
-    "validate_doc_update failure replications - remote-to-remote"
+    "validate_doc_update failure replications - #{name}"
   ],
   "ReshardAllDocsTest": [
     "all_docs after splitting all shards on node1",
@@ -493,26 +585,37 @@
     "multiple updates with same _rev raise conflict errors"
   ],
   "RewriteJSTest": [
-    "Test basic js rewrites on test_rewrite_suite_db",
-    "Test basic js rewrites on test_rewrite_suite_db%2Fwith_slashes",
-    "early response on test_rewrite_suite_db",
-    "early response on test_rewrite_suite_db%2Fwith_slashes",
-    "loop on test_rewrite_suite_db",
-    "loop on test_rewrite_suite_db%2Fwith_slashes",
-    "path relative to server on test_rewrite_suite_db",
-    "path relative to server on test_rewrite_suite_db%2Fwith_slashes",
-    "requests with body preserve the query string rewrite on 
test_rewrite_suite_db",
-    "requests with body preserve the query string rewrite on 
test_rewrite_suite_db%2Fwith_slashes"
+    "Test basic js rewrites on #{db_name}",
+    "early response on #{db_name}",
+    "loop on #{db_name}",
+    "path relative to server on #{db_name}",
+    "requests with body preserve the query string rewrite on #{db_name}"
   ],
   "RewriteTest": [
-    "Test basic rewrites on test_rewrite_suite_db",
-    "Test basic rewrites on test_rewrite_suite_db%2Fwith_slashes",
-    "loop detection on test_rewrite_suite_db",
-    "loop detection on test_rewrite_suite_db%2Fwith_slashes",
-    "path relative to server on test_rewrite_suite_db",
-    "path relative to server on test_rewrite_suite_db%2Fwith_slashes",
-    "serial execution is not spuriously counted as loop on 
test_rewrite_suite_db",
-    "serial execution is not spuriously counted as loop on 
test_rewrite_suite_db%2Fwith_slashes"
+    "Test basic rewrites on #{db_name}",
+    "loop detection on #{db_name}",
+    "path relative to server on #{db_name}",
+    "serial execution is not spuriously counted as loop on #{db_name}"
+  ],
+  "SearchTest": [
+    "clean up search index with invalid design document",
+    "drilldown multiple keys multiple values for POST",
+    "drilldown multiple keys single values for GET",
+    "drilldown multiple keys single values for POST",
+    "drilldown multiple query definitions for GET",
+    "drilldown multiple query definitions for POST",
+    "drilldown single key multiple values for GET",
+    "drilldown single key multiple values for POST",
+    "drilldown single key single value for GET",
+    "drilldown single key single value for POST",
+    "drilldown three keys single values for POST",
+    "facet counts, empty",
+    "facet counts, non-empty",
+    "facet ranges, empty",
+    "facet ranges, non-empty",
+    "search returns all items for GET",
+    "search returns all items for POST",
+    "timeouts do not expose internal state"
   ],
   "SecurityValidationTest": [
     "Author presence and user security",
@@ -526,7 +629,7 @@
     "try to set a wrong value for _security"
   ],
   "ShowDocumentsTest": [
-    "JS can't set etag",
+    "JS can",
     "accept header switching - different mime has different etag",
     "deleted docs",
     "id with slash",
@@ -625,8 +728,8 @@
     "no reduce support"
   ],
   "ViewMultiKeyAllDocsTest": [
-    "GET - get invalid rows when the key doesn't exist",
-    "POST - get invalid rows when the key doesn't exist",
+    "GET - get invalid rows when the key doesn",
+    "POST - get invalid rows when the key doesn",
     "empty keys",
     "keys in GET parameters",
     "keys in GET parameters (descending)",
@@ -643,7 +746,8 @@
     "GET - invalid parameter combinations get rejected ",
     "POST - invalid parameter combinations get rejected ",
     "argument combinations",
-    "dir works",
+    "dir ascending works",
+    "dir descending works",
     "empty keys",
     "keys in GET body (group)",
     "keys in GET parameters",
@@ -689,7 +793,7 @@
     "view query returns all docs for global query"
   ],
   "ViewSandboxingTest": [
-    "COUCHDB-925 - altering 'doc' variable in map function affects other map 
functions",
+    "COUCHDB-925 - altering ",
     "attempting to change the document has no effect",
     "runtime code evaluation can be prevented",
     "view cannot access the map_funs and map_results array",
@@ -729,66 +833,5 @@
     "Creating-Updating/Deleting doc with overriden quorum should return 
201-Created/200-OK",
     "Creating/Deleting DB should return 202-Acepted",
     "Creating/Updating/Deleting doc should return 202-Acepted"
-  ],
-  "BasicFindTest": [
-    "simple find",
-    "bad selector",
-    "bad limit",
-    "bad skip",
-    "bad sort",
-    "bad fields",
-    "bad r",
-    "bad conflicts",
-    "multi cond and",
-    "multi cond duplicate field",
-    "multi cond or",
-    "multi col idx",
-    "missing not indexed",
-    "limit",
-    "skip",
-    "sort",
-    "sort desc complex",
-    "sort with primary sort not in selector",
-    "sort exists true",
-    "sort desc complex error",
-    "fields",
-    "r",
-    "empty",
-    "empty subsel",
-    "empty subsel match",
-    "unsatisfiable range",
-    "explain view args",
-    "explain options",
-    "sort with all docs"
-  ],
-  "IgnoreDesignDocsForAllDocsIndexTests": [
-    "should not return design docs"
-  ],
-  "JSONIndexSelectionTest": [
-    "basic",
-    "with and",
-    "with nested and",
-    "with or",
-    "use most columns",
-    "no valid sort index",
-    "invalid use index",
-    "uses index when no range or equals",
-    "reject use index invalid fields",
-    "reject use index ddoc and name invalid fields",
-    "reject use index sort order",
-    "use index fallback if valid sort",
-    "prefer use index over optimal index",
-    "manual bad view idx01",
-    "explain sort reverse",
-    "use index with invalid name",
-    "use index without fallback succeeds for valid index",
-    "use index without fallback fails for invalid index with fallback 
available",
-    "use index without fallback succeeds for empty index",
-    "use index without fallback fails for empty index",
-    "use index without fallback fails for invalid index no fallback exists",
-    "index without fallback",
-    "no index without fallback",
-    "uses all docs when fields do not match selector",
-    "uses all docs when selector doesnt require fields to exist"
   ]
 }
diff --git a/t.py b/t.py
new file mode 100644
index 000000000..ad9adb947
--- /dev/null
+++ b/t.py
@@ -0,0 +1,25 @@
+import glob
+import json
+import os
+import re
+
+module_pattern = re.compile(r"defmodule\s+([A-Za-z0-9_.]+)\s+do")
+test_pattern = re.compile(r'test\s+["\'](.+?)["\']')
+result = {}
+
+files = glob.glob(os.path.join("test/elixir/test/**/*_test.exs"), 
recursive=True)
+
+for file_path in files:
+    with open(file_path, "r", encoding="utf-8") as f:
+        content = f.read()
+
+    module_match = module_pattern.search(content)
+    if not module_match:
+        continue
+    module_name = module_match.group(1)
+
+    tests = [m for m in test_pattern.findall(content)]
+    tests.sort()
+    result[module_name] = tests
+
+print(json.dumps(result, sort_keys=True))
diff --git a/test/elixir/test/config/search.elixir 
b/test/elixir/test/config/search.elixir
index 7d328c112..20e26682e 100644
--- a/test/elixir/test/config/search.elixir
+++ b/test/elixir/test/config/search.elixir
@@ -31,7 +31,8 @@
     "facet counts, non-empty",
     "facet counts, empty",
     "facet ranges, empty",
-    "facet ranges, non-empty"
+    "facet ranges, non-empty",
+    "timeouts do not expose internal state"
   ],
   "ElemMatchTests": [
     "elem match non object"
diff --git a/test/elixir/test/config/suite.elixir 
b/test/elixir/test/config/suite.elixir
index 65e983f1d..119640a49 100644
--- a/test/elixir/test/config/suite.elixir
+++ b/test/elixir/test/config/suite.elixir
@@ -36,7 +36,6 @@
     "etags for attachments",
     "implicit doc creation allows creating docs with a reserved id. 
COUCHDB-565",
     "large attachments COUCHDB-366",
-    "md5 header for attachments",
     "reads attachment successfully",
     "saves attachment successfully",
     "saves binary",
@@ -48,7 +47,7 @@
   ],
   "AuthLockoutTest": [
     "lockout after multiple failed authentications",
-    "lockout warning after multiple failed authentications"
+    "do not lockout after multiple failed authentications"
   ],
   "BasicsTest": [
     "'+' in document name should encode to '+'",
@@ -156,7 +155,8 @@
     "Only JSON strings are accepted"
   ],
   "CookieAuthTest": [
-    "cookie auth"
+    "cookie auth",
+    "basic+cookie auth interaction"
   ],
   "CopyDocTest": [
     "Copy doc tests"
@@ -257,6 +257,13 @@
     "jwt auth with required iss claim",
     "jwt auth without secret"
   ],
+  "JwtRolesClaimTest": [
+    "case: roles_claim_name (defined) / roles_claim_path (defined)",
+    "case: roles_claim_name (defined) / roles_claim_path (undefined)",
+    "case: roles_claim_name (undefined) / roles_claim_path (defined)",
+    "case: roles_claim_name (undefined) / roles_claim_path (undefined)",
+    "case: roles_claim_path with bad input"
+  ],
   "ListViewsTest": [
     "COUCHDB-1113",
     "HTTP header response set after getRow() called in _list function",
@@ -493,8 +500,8 @@
     "multiple updates with same _rev raise conflict errors"
   ],
   "RewriteJSTest": [
-    "Test basic js rewrites on test_rewrite_suite_db",
-    "Test basic js rewrites on test_rewrite_suite_db%2Fwith_slashes",
+    "basic js rewrites on test_rewrite_suite_db",
+    "basic js rewrites on test_rewrite_suite_db%2Fwith_slashes",
     "early response on test_rewrite_suite_db",
     "early response on test_rewrite_suite_db%2Fwith_slashes",
     "loop on test_rewrite_suite_db",
@@ -505,8 +512,8 @@
     "requests with body preserve the query string rewrite on 
test_rewrite_suite_db%2Fwith_slashes"
   ],
   "RewriteTest": [
-    "Test basic rewrites on test_rewrite_suite_db",
-    "Test basic rewrites on test_rewrite_suite_db%2Fwith_slashes",
+    "basic rewrites on test_rewrite_suite_db",
+    "basic rewrites on test_rewrite_suite_db%2Fwith_slashes",
     "loop detection on test_rewrite_suite_db",
     "loop detection on test_rewrite_suite_db%2Fwith_slashes",
     "path relative to server on test_rewrite_suite_db",
@@ -643,7 +650,8 @@
     "GET - invalid parameter combinations get rejected ",
     "POST - invalid parameter combinations get rejected ",
     "argument combinations",
-    "dir works",
+    "dir ascending works",
+    "dir descending works",
     "empty keys",
     "keys in GET body (group)",
     "keys in GET parameters",
diff --git a/test/elixir/test/disk_monitor.exs 
b/test/elixir/test/disk_monitor_test.exs
similarity index 100%
rename from test/elixir/test/disk_monitor.exs
rename to test/elixir/test/disk_monitor_test.exs
diff --git a/test/elixir/test/rewrite_js_test.exs 
b/test/elixir/test/rewrite_js_test.exs
index a3adb3e7d..d793e616a 100644
--- a/test/elixir/test/rewrite_js_test.exs
+++ b/test/elixir/test/rewrite_js_test.exs
@@ -209,203 +209,200 @@ defmodule RewriteJSTest do
     }
   }
 
-  Enum.each(
-    ["test_rewrite_suite_db", "test_rewrite_suite_db%2Fwith_slashes"],
-    fn db_name ->
-      @tag with_random_db: db_name
-      test "Test basic js rewrites on #{db_name}", context do
-        db_name = context[:db_name]
-
-        create_doc(db_name, @ddoc)
-
-        docs1 = make_docs(0..9)
-        bulk_save(db_name, docs1)
-
-        docs2 = [
-          %{"a" => 1, "b" => 1, "string" => "doc 1", "type" => "complex"},
-          %{"a" => 1, "b" => 2, "string" => "doc 2", "type" => "complex"},
-          %{"a" => "test", "b" => %{}, "string" => "doc 3", "type" => 
"complex"},
-          %{
-            "a" => "test",
-            "b" => ["test", "essai"],
-            "string" => "doc 4",
-            "type" => "complex"
-          },
-          %{"a" => %{"c" => 1}, "b" => "", "string" => "doc 5", "type" => 
"complex"}
-        ]
-
-        bulk_save(db_name, docs2)
-
-        # Test simple rewriting
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo")
-        assert resp.body == "This is a base64 encoded text"
-        assert resp.headers["Content-Type"] == "text/plain"
-
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo2")
-        assert resp.body == "This is a base64 encoded text"
-        assert resp.headers["Content-Type"] == "text/plain"
-
-        # Test POST, hello update world
-        resp =
-          Couch.post("/#{db_name}", body: %{"word" => "plankton", "name" => 
"Rusty"}).body
-
-        assert resp["ok"]
-        doc_id = resp["id"]
-        assert doc_id
-
-        resp = Couch.put("/#{db_name}/_design/test/_rewrite/hello/#{doc_id}")
-        assert resp.status_code in [201, 202]
-        assert resp.body == "hello doc"
-        assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/)
-
-        assert Couch.get("/#{db_name}/#{doc_id}").body["world"] == "hello"
-
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome?name=user")
-        assert resp.body == "Welcome user"
-
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome/user")
-        assert resp.body == "Welcome user"
-
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome2")
-        assert resp.body == "Welcome user"
-
-        resp = Couch.put("/#{db_name}/_design/test/_rewrite/welcome3/test")
-        assert resp.status_code in [201, 202]
-        assert resp.body == "New World"
-        assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/)
-
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome3/test")
-        assert resp.body == "Welcome test"
-
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome4/user")
-        assert resp.body == "Welcome user"
-
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome5/welcome3")
-        assert resp.body == "Welcome welcome3"
-
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/basicView")
-        assert resp.status_code == 200
-        assert resp.body["total_rows"] == 9
-
-        resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView")
-        assert resp.status_code == 200
-        assert String.match?(resp.body, ~r/FirstKey: [1, 2]/)
-
-        resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView2")
-        assert resp.status_code == 200
-        assert String.match?(resp.body, ~r/Value: doc 3/)
-
-        resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView3")
-        assert resp.status_code == 200
-        assert String.match?(resp.body, ~r/Value: doc 4/)
-
-        resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView4")
-        assert resp.status_code == 200
-        assert String.match?(resp.body, ~r/Value: doc 5/)
-
-        # COUCHDB-1612 - send body rewriting get to post
-        resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/sendBody1")
-        assert resp.status_code == 200
-        assert String.match?(resp.body, ~r/Value: doc 5 LineNo: 1/)
-
-        resp = 
Couch.get("/#{db_name}/_design/test/_rewrite/db/_design/test?meta=true")
-        assert resp.status_code == 200
-        assert resp.body["_id"] == "_design/test"
-        assert Map.has_key?(resp.body, "_revs_info")
-      end
-
-      @tag with_random_db: db_name
-      test "early response on #{db_name}", context do
-        db_name = context[:db_name]
-
-        ddoc = %{
-          _id: "_design/response",
-          rewrites: """
-           function(req){
-            status = parseInt(req.query.status);
-            return {code: status,
-                    body: JSON.stringify({"status": status}),
-                    headers: {'x-foo': 'bar', 'Content-Type': 
'application/json'}};
-          }
-          """
+  for db_name <- ["test_rewrite_suite_db", 
"test_rewrite_suite_db%2Fwith_slashes"] do
+    @tag with_random_db: db_name
+    test "basic js rewrites on #{db_name}", context do
+      db_name = context[:db_name]
+
+      create_doc(db_name, @ddoc)
+
+      docs1 = make_docs(0..9)
+      bulk_save(db_name, docs1)
+
+      docs2 = [
+        %{"a" => 1, "b" => 1, "string" => "doc 1", "type" => "complex"},
+        %{"a" => 1, "b" => 2, "string" => "doc 2", "type" => "complex"},
+        %{"a" => "test", "b" => %{}, "string" => "doc 3", "type" => "complex"},
+        %{
+          "a" => "test",
+          "b" => ["test", "essai"],
+          "string" => "doc 4",
+          "type" => "complex"
+        },
+        %{"a" => %{"c" => 1}, "b" => "", "string" => "doc 5", "type" => 
"complex"}
+      ]
+
+      bulk_save(db_name, docs2)
+
+      # Test simple rewriting
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo")
+      assert resp.body == "This is a base64 encoded text"
+      assert resp.headers["Content-Type"] == "text/plain"
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo2")
+      assert resp.body == "This is a base64 encoded text"
+      assert resp.headers["Content-Type"] == "text/plain"
+
+      # Test POST, hello update world
+      resp =
+        Couch.post("/#{db_name}", body: %{"word" => "plankton", "name" => 
"Rusty"}).body
+
+      assert resp["ok"]
+      doc_id = resp["id"]
+      assert doc_id
+
+      resp = Couch.put("/#{db_name}/_design/test/_rewrite/hello/#{doc_id}")
+      assert resp.status_code in [201, 202]
+      assert resp.body == "hello doc"
+      assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/)
+
+      assert Couch.get("/#{db_name}/#{doc_id}").body["world"] == "hello"
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome?name=user")
+      assert resp.body == "Welcome user"
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome/user")
+      assert resp.body == "Welcome user"
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome2")
+      assert resp.body == "Welcome user"
+
+      resp = Couch.put("/#{db_name}/_design/test/_rewrite/welcome3/test")
+      assert resp.status_code in [201, 202]
+      assert resp.body == "New World"
+      assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/)
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome3/test")
+      assert resp.body == "Welcome test"
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome4/user")
+      assert resp.body == "Welcome user"
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome5/welcome3")
+      assert resp.body == "Welcome welcome3"
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/basicView")
+      assert resp.status_code == 200
+      assert resp.body["total_rows"] == 9
+
+      resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView")
+      assert resp.status_code == 200
+      assert String.match?(resp.body, ~r/FirstKey: [1, 2]/)
+
+      resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView2")
+      assert resp.status_code == 200
+      assert String.match?(resp.body, ~r/Value: doc 3/)
+
+      resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView3")
+      assert resp.status_code == 200
+      assert String.match?(resp.body, ~r/Value: doc 4/)
+
+      resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView4")
+      assert resp.status_code == 200
+      assert String.match?(resp.body, ~r/Value: doc 5/)
+
+      # COUCHDB-1612 - send body rewriting get to post
+      resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/sendBody1")
+      assert resp.status_code == 200
+      assert String.match?(resp.body, ~r/Value: doc 5 LineNo: 1/)
+
+      resp = 
Couch.get("/#{db_name}/_design/test/_rewrite/db/_design/test?meta=true")
+      assert resp.status_code == 200
+      assert resp.body["_id"] == "_design/test"
+      assert Map.has_key?(resp.body, "_revs_info")
+    end
+
+    @tag with_random_db: db_name
+    test "early response on #{db_name}", context do
+      db_name = context[:db_name]
+
+      ddoc = %{
+        _id: "_design/response",
+        rewrites: """
+         function(req){
+          status = parseInt(req.query.status);
+          return {code: status,
+                  body: JSON.stringify({"status": status}),
+                  headers: {'x-foo': 'bar', 'Content-Type': 
'application/json'}};
         }
+        """
+      }
 
-        create_doc(db_name, ddoc)
+      create_doc(db_name, ddoc)
 
-        resp = Couch.get("/#{db_name}/_design/response/_rewrite?status=200")
-        assert resp.status_code == 200
-        assert resp.headers["x-foo"] == "bar"
-        assert resp.body["status"] == 200
+      resp = Couch.get("/#{db_name}/_design/response/_rewrite?status=200")
+      assert resp.status_code == 200
+      assert resp.headers["x-foo"] == "bar"
+      assert resp.body["status"] == 200
 
-        resp = Couch.get("/#{db_name}/_design/response/_rewrite?status=451")
-        assert resp.status_code == 451
-        assert resp.headers["Content-Type"] == "application/json"
+      resp = Couch.get("/#{db_name}/_design/response/_rewrite?status=451")
+      assert resp.status_code == 451
+      assert resp.headers["Content-Type"] == "application/json"
 
-        resp = Couch.get("/#{db_name}/_design/response/_rewrite?status=500")
-        assert resp.status_code == 500
-      end
+      resp = Couch.get("/#{db_name}/_design/response/_rewrite?status=500")
+      assert resp.status_code == 500
+    end
 
-      @tag with_random_db: db_name
-      test "path relative to server on #{db_name}", context do
-        db_name = context[:db_name]
+    @tag with_random_db: db_name
+    test "path relative to server on #{db_name}", context do
+      db_name = context[:db_name]
 
-        ddoc = %{
-          _id: "_design/relative",
-          rewrites: """
-           function(req){
-            return '../../../_uuids'
-          }
-          """
+      ddoc = %{
+        _id: "_design/relative",
+        rewrites: """
+         function(req){
+          return '../../../_uuids'
         }
+        """
+      }
 
-        create_doc(db_name, ddoc)
-        resp = Couch.get("/#{db_name}/_design/relative/_rewrite/uuids")
-        assert resp.status_code == 200
-        assert length(resp.body["uuids"]) == 1
-      end
-
-      @tag with_random_db: db_name
-      test "loop on #{db_name}", context do
-        db_name = context[:db_name]
-
-        ddoc_loop = %{
-          _id: "_design/loop",
-          rewrites: """
-          function(req) {
-            return '_rewrite/loop';
-          }
-          """
+      create_doc(db_name, ddoc)
+      resp = Couch.get("/#{db_name}/_design/relative/_rewrite/uuids")
+      assert resp.status_code == 200
+      assert length(resp.body["uuids"]) == 1
+    end
+
+    @tag with_random_db: db_name
+    test "loop on #{db_name}", context do
+      db_name = context[:db_name]
+
+      ddoc_loop = %{
+        _id: "_design/loop",
+        rewrites: """
+        function(req) {
+          return '_rewrite/loop';
         }
+        """
+      }
 
-        create_doc(db_name, ddoc_loop)
-        resp = Couch.get("/#{db_name}/_design/loop/_rewrite/loop")
-        assert resp.status_code == 400
-      end
+      create_doc(db_name, ddoc_loop)
+      resp = Couch.get("/#{db_name}/_design/loop/_rewrite/loop")
+      assert resp.status_code == 400
+    end
 
-      @tag with_random_db: db_name
-      test "requests with body preserve the query string rewrite on 
#{db_name}",
-           context do
-        db_name = context[:db_name]
+    @tag with_random_db: db_name
+    test "requests with body preserve the query string rewrite on #{db_name}",
+         context do
+      db_name = context[:db_name]
 
-        ddoc_qs = %{
-          _id: "_design/qs",
-          rewrites:
-            "function (r) { return {path: '../../_changes', query: {'filter': 
'_doc_ids'}};};"
-        }
+      ddoc_qs = %{
+        _id: "_design/qs",
+        rewrites:
+          "function (r) { return {path: '../../_changes', query: {'filter': 
'_doc_ids'}};};"
+      }
 
-        create_doc(db_name, ddoc_qs)
-        create_doc(db_name, %{_id: "qs1"})
-        create_doc(db_name, %{_id: "qs2"})
+      create_doc(db_name, ddoc_qs)
+      create_doc(db_name, %{_id: "qs1"})
+      create_doc(db_name, %{_id: "qs2"})
 
-        resp =
-          Couch.post("/#{db_name}/_design/qs/_rewrite",
-            body: %{doc_ids: ["qs2"]}
-          )
+      resp =
+        Couch.post("/#{db_name}/_design/qs/_rewrite",
+          body: %{doc_ids: ["qs2"]}
+        )
 
-        assert resp.status_code == 200
-        assert length(resp.body["results"]) == 1
-        assert Enum.at(resp.body["results"], 0)["id"] == "qs2"
-      end
+      assert resp.status_code == 200
+      assert length(resp.body["results"]) == 1
+      assert Enum.at(resp.body["results"], 0)["id"] == "qs2"
     end
-  )
+  end
 end
diff --git a/test/elixir/test/rewrite_test.exs 
b/test/elixir/test/rewrite_test.exs
index 34fe3b7f5..4a13803c6 100644
--- a/test/elixir/test/rewrite_test.exs
+++ b/test/elixir/test/rewrite_test.exs
@@ -8,519 +8,522 @@ defmodule RewriteTest do
   This is a port of the rewrite.js suite
   """
 
-  Enum.each(
-    ["test_rewrite_suite_db", "test_rewrite_suite_db%2Fwith_slashes"],
-    fn db_name ->
-      @tag with_random_db: db_name
-      @tag config: [
-             {"httpd", "authentication_handlers",
-              "{couch_httpd_auth, special_test_authentication_handler}"},
-             {"chttpd", "WWW-Authenticate", "X-Couch-Test-Auth"}
-           ]
-      test "Test basic rewrites on #{db_name}", context do
-        db_name = context[:db_name]
-
-        ddoc = ~S"""
-        {
-          "_id": "_design/test",
-          "language": "javascript",
-          "_attachments": {
-            "foo.txt": {
-              "content_type":"text/plain",
-              "data": "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
+  for db_name <- ["test_rewrite_suite_db", 
"test_rewrite_suite_db%2Fwith_slashes"] do
+    @tag with_random_db: db_name
+    @tag config: [
+           {"httpd", "authentication_handlers",
+            "{couch_httpd_auth, special_test_authentication_handler}"},
+           {"chttpd", "WWW-Authenticate", "X-Couch-Test-Auth"}
+         ]
+    test "basic rewrites on #{db_name}", context do
+      db_name = context[:db_name]
+
+      ddoc = ~S"""
+      {
+        "_id": "_design/test",
+        "language": "javascript",
+        "_attachments": {
+          "foo.txt": {
+            "content_type":"text/plain",
+            "data": "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
+          }
+        },
+        "rewrites": [
+          {
+            "from": "foo",
+            "to": "foo.txt"
+          },
+          {
+            "from": "foo2",
+            "to": "foo.txt",
+            "method": "GET"
+          },
+          {
+            "from": "hello/:id",
+            "to": "_update/hello/:id",
+            "method": "PUT"
+          },
+          {
+            "from": "/welcome",
+            "to": "_show/welcome"
+          },
+          {
+            "from": "/welcome/:name",
+            "to": "_show/welcome",
+            "query": {
+              "name": ":name"
             }
           },
-          "rewrites": [
-            {
-              "from": "foo",
-              "to": "foo.txt"
-            },
-            {
-              "from": "foo2",
-              "to": "foo.txt",
-              "method": "GET"
-            },
-            {
-              "from": "hello/:id",
-              "to": "_update/hello/:id",
-              "method": "PUT"
-            },
-            {
-              "from": "/welcome",
-              "to": "_show/welcome"
-            },
-            {
-              "from": "/welcome/:name",
-              "to": "_show/welcome",
-              "query": {
-                "name": ":name"
-              }
-            },
-            {
-              "from": "/welcome2",
-              "to": "_show/welcome",
-              "query": {
-                "name": "user"
-              }
-            },
-            {
-              "from": "/welcome3/:name",
-              "to": "_update/welcome2/:name",
-              "method": "PUT"
-            },
-            {
-              "from": "/welcome3/:name",
-              "to": "_show/welcome2/:name",
-              "method": "GET"
-            },
-            {
-              "from": "/welcome4/*",
-              "to" : "_show/welcome3",
-              "query": {
-                "name": "*"
-              }
-            },
-            {
-              "from": "/welcome5/*",
-              "to" : "_show/*",
-              "query": {
-                "name": "*"
-              }
-            },
-            {
-              "from": "basicView",
-              "to": "_view/basicView"
-            },
-            {
-              "from": "simpleForm/basicView",
-              "to": "_list/simpleForm/basicView"
-            },
-            {
-              "from": "simpleForm/basicViewFixed",
-              "to": "_list/simpleForm/basicView",
-              "query": {
-                "startkey": 3,
-                "endkey": 8
-              }
-            },
-            {
-              "from": "simpleForm/basicViewPath/:start/:end",
-              "to": "_list/simpleForm/basicView",
-              "query": {
-                "startkey": ":start",
-                "endkey": ":end"
-              },
-              "formats": {
-                "start": "int",
-                "end": "int"
-              }
-            },
-            {
-              "from": "simpleForm/complexView",
-              "to": "_list/simpleForm/complexView",
-              "query": {
-                "key": [1, 2]
-              }
-            },
-            {
-              "from": "simpleForm/complexView2",
-              "to": "_list/simpleForm/complexView",
-              "query": {
-                "key": ["test", {}]
-              }
-            },
-            {
-              "from": "simpleForm/complexView3",
-              "to": "_list/simpleForm/complexView",
-              "query": {
-                "key": ["test", ["test", "essai"]]
-              }
-            },
-            {
-              "from": "simpleForm/complexView4",
-              "to": "_list/simpleForm/complexView2",
-              "query": {
-                "key": {"c": 1}
-              }
+          {
+            "from": "/welcome2",
+            "to": "_show/welcome",
+            "query": {
+              "name": "user"
+            }
+          },
+          {
+            "from": "/welcome3/:name",
+            "to": "_update/welcome2/:name",
+            "method": "PUT"
+          },
+          {
+            "from": "/welcome3/:name",
+            "to": "_show/welcome2/:name",
+            "method": "GET"
+          },
+          {
+            "from": "/welcome4/*",
+            "to" : "_show/welcome3",
+            "query": {
+              "name": "*"
+            }
+          },
+          {
+            "from": "/welcome5/*",
+            "to" : "_show/*",
+            "query": {
+              "name": "*"
+            }
+          },
+          {
+            "from": "basicView",
+            "to": "_view/basicView"
+          },
+          {
+            "from": "simpleForm/basicView",
+            "to": "_list/simpleForm/basicView"
+          },
+          {
+            "from": "simpleForm/basicViewFixed",
+            "to": "_list/simpleForm/basicView",
+            "query": {
+              "startkey": 3,
+              "endkey": 8
+            }
+          },
+          {
+            "from": "simpleForm/basicViewPath/:start/:end",
+            "to": "_list/simpleForm/basicView",
+            "query": {
+              "startkey": ":start",
+              "endkey": ":end"
             },
-            {
-              "from": "simpleForm/complexView5/:a/:b",
-              "to": "_list/simpleForm/complexView3",
-              "query": {
-                "key": [":a", ":b"]
-              }
+            "formats": {
+              "start": "int",
+              "end": "int"
+            }
+          },
+          {
+            "from": "simpleForm/complexView",
+            "to": "_list/simpleForm/complexView",
+            "query": {
+              "key": [1, 2]
+            }
+          },
+          {
+            "from": "simpleForm/complexView2",
+            "to": "_list/simpleForm/complexView",
+            "query": {
+              "key": ["test", {}]
+            }
+          },
+          {
+            "from": "simpleForm/complexView3",
+            "to": "_list/simpleForm/complexView",
+            "query": {
+              "key": ["test", ["test", "essai"]]
+            }
+          },
+          {
+            "from": "simpleForm/complexView4",
+            "to": "_list/simpleForm/complexView2",
+            "query": {
+              "key": {"c": 1}
+            }
+          },
+          {
+            "from": "simpleForm/complexView5/:a/:b",
+            "to": "_list/simpleForm/complexView3",
+            "query": {
+              "key": [":a", ":b"]
+            }
+          },
+          {
+            "from": "simpleForm/complexView6",
+            "to": "_list/simpleForm/complexView3",
+            "query": {
+              "key": [":a", ":b"]
+            }
+          },
+          {
+            "from": "simpleForm/complexView7/:a/:b",
+            "to": "_view/complexView3",
+            "query": {
+              "key": [":a", ":b"],
+              "include_docs": ":doc"
             },
-            {
-              "from": "simpleForm/complexView6",
-              "to": "_list/simpleForm/complexView3",
-              "query": {
-                "key": [":a", ":b"]
+            "format": {
+              "doc": "bool"
+            }
+
+          },
+          {
+            "from": "/",
+            "to": "_view/basicView"
+          },
+          {
+            "from": "/db/*",
+            "to": "../../*"
+          }
+        ],
+        "lists": {
+          "simpleForm": "function(head, req) {
+            log(\"simpleForm\");
+            send(\"<ul>\");
+            var row, row_number = 0, prevKey, firstKey = null;
+            while (row = getRow()) {
+              row_number += 1;
+              if (!firstKey) firstKey = row.key;
+              prevKey = row.key;
+              send(\"\\n<li>Key: \"+row.key
+                   +\" Value: \"+row.value
+                   +\" LineNo: \"+row_number+\"</li>\");
+            }
+            return \"</ul><p>FirstKey: \"+ firstKey + \" LastKey: \"+ 
prevKey+\"</p>\";
+          }"
+        },
+        "shows": {
+          "welcome": "(function(doc,req) {
+            return \"Welcome \" + req.query[\"name\"];
+          })",
+          "welcome2": "(function(doc, req) {
+            return \"Welcome \" + doc.name;
+          })",
+          "welcome3": "(function(doc,req) {
+            return \"Welcome \" + req.query[\"name\"];
+          })"
+        },
+        "updates": {
+          "hello" : "(function(doc, req) {
+            if (!doc) {
+              if (req.id) {
+                return [{
+                  _id : req.id
+                }, \"New World\"]
               }
-            },
-            {
-              "from": "simpleForm/complexView7/:a/:b",
-              "to": "_view/complexView3",
-              "query": {
-                "key": [":a", ":b"],
-                "include_docs": ":doc"
-              },
-              "format": {
-                "doc": "bool"
+              return [null, \"Empty World\"];
+            }
+            doc.world = \"hello\";
+            doc.edited_by = req.userCtx;
+            return [doc, \"hello doc\"];
+          })",
+          "welcome2": "(function(doc, req) {
+            if (!doc) {
+              if (req.id) {
+                return [{
+                  _id: req.id,
+                  name: req.id
+                }, \"New World\"]
               }
-
-            },
-            {
-              "from": "/",
-              "to": "_view/basicView"
-            },
-            {
-              "from": "/db/*",
-              "to": "../../*"
+              return [null, \"Empty World\"];
             }
-          ],
-          "lists": {
-            "simpleForm": "function(head, req) {
-              log(\"simpleForm\");
-              send(\"<ul>\");
-              var row, row_number = 0, prevKey, firstKey = null;
-              while (row = getRow()) {
-                row_number += 1;
-                if (!firstKey) firstKey = row.key;
-                prevKey = row.key;
-                send(\"\\n<li>Key: \"+row.key
-                     +\" Value: \"+row.value
-                     +\" LineNo: \"+row_number+\"</li>\");
+            return [doc, \"hello doc\"];
+          })"
+        },
+        "views" : {
+          "basicView" : {
+            "map" : "(function(doc) {
+              if (doc.integer) {
+                emit(doc.integer, doc.string);
               }
-              return \"</ul><p>FirstKey: \"+ firstKey + \" LastKey: \"+ 
prevKey+\"</p>\";
-            }"
-          },
-          "shows": {
-            "welcome": "(function(doc,req) {
-              return \"Welcome \" + req.query[\"name\"];
-            })",
-            "welcome2": "(function(doc, req) {
-              return \"Welcome \" + doc.name;
-            })",
-            "welcome3": "(function(doc,req) {
-              return \"Welcome \" + req.query[\"name\"];
+
             })"
           },
-          "updates": {
-            "hello" : "(function(doc, req) {
-              if (!doc) {
-                if (req.id) {
-                  return [{
-                    _id : req.id
-                  }, \"New World\"]
-                }
-                return [null, \"Empty World\"];
+          "complexView": {
+            "map": "(function(doc) {
+              if (doc.type == \"complex\") {
+                emit([doc.a, doc.b], doc.string);
               }
-              doc.world = \"hello\";
-              doc.edited_by = req.userCtx;
-              return [doc, \"hello doc\"];
-            })",
-            "welcome2": "(function(doc, req) {
-              if (!doc) {
-                if (req.id) {
-                  return [{
-                    _id: req.id,
-                    name: req.id
-                  }, \"New World\"]
-                }
-                return [null, \"Empty World\"];
+            })"
+          },
+          "complexView2": {
+            "map": "(function(doc) {
+              if (doc.type == \"complex\") {
+                emit(doc.a, doc.string);
               }
-              return [doc, \"hello doc\"];
             })"
           },
-          "views" : {
-            "basicView" : {
-              "map" : "(function(doc) {
-                if (doc.integer) {
-                  emit(doc.integer, doc.string);
-                }
-
-              })"
-            },
-            "complexView": {
-              "map": "(function(doc) {
-                if (doc.type == \"complex\") {
-                  emit([doc.a, doc.b], doc.string);
-                }
-              })"
-            },
-            "complexView2": {
-              "map": "(function(doc) {
-                if (doc.type == \"complex\") {
-                  emit(doc.a, doc.string);
-                }
-              })"
-            },
-            "complexView3": {
-              "map": "(function(doc) {
-                if (doc.type == \"complex\") {
-                  emit(doc.b, doc.string);
-                }
-              })"
-            }
+          "complexView3": {
+            "map": "(function(doc) {
+              if (doc.type == \"complex\") {
+                emit(doc.b, doc.string);
+              }
+            })"
           }
         }
-        """
-
-        ddoc = String.replace(ddoc, ~r/[\r\n]+/, "")
-
-        docs1 = make_docs(0..9)
-
-        docs2 = [
-          %{"a" => 1, "b" => 1, "string" => "doc 1", "type" => "complex"},
-          %{"a" => 1, "b" => 2, "string" => "doc 2", "type" => "complex"},
-          %{"a" => "test", "b" => %{}, "string" => "doc 3", "type" => 
"complex"},
-          %{
-            "a" => "test",
-            "b" => ["test", "essai"],
-            "string" => "doc 4",
-            "type" => "complex"
-          },
-          %{"a" => %{"c" => 1}, "b" => "", "string" => "doc 5", "type" => 
"complex"}
-        ]
-
-        assert Couch.put("/#{db_name}/_design/test", body: ddoc).body["ok"]
-
-        assert Couch.post(
-                 "/#{db_name}/_bulk_docs",
-                 body: %{:docs => docs1},
-                 query: %{w: 3}
-               ).status_code in [201, 202]
-
-        assert Couch.post(
-                 "/#{db_name}/_bulk_docs",
-                 body: %{:docs => docs2},
-                 query: %{w: 3}
-               ).status_code in [201, 202]
-
-        # Test simple rewriting
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo")
-        assert resp.body == "This is a base64 encoded text"
-        assert resp.headers["Content-Type"] == "text/plain"
-
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo2")
-        assert resp.body == "This is a base64 encoded text"
-        assert resp.headers["Content-Type"] == "text/plain"
-
-        # Test POST, hello update world
-        resp =
-          Couch.post("/#{db_name}", body: %{"word" => "plankton", "name" => 
"Rusty"}).body
-
-        assert resp["ok"]
-        doc_id = resp["id"]
-        assert doc_id
-
-        resp = Couch.put("/#{db_name}/_design/test/_rewrite/hello/#{doc_id}")
-        assert resp.status_code in [201, 202]
-        assert resp.body == "hello doc"
-        assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/)
+      }
+      """
+
+      ddoc = String.replace(ddoc, ~r/[\r\n]+/, "")
+
+      docs1 = make_docs(0..9)
+
+      docs2 = [
+        %{"a" => 1, "b" => 1, "string" => "doc 1", "type" => "complex"},
+        %{"a" => 1, "b" => 2, "string" => "doc 2", "type" => "complex"},
+        %{"a" => "test", "b" => %{}, "string" => "doc 3", "type" => "complex"},
+        %{
+          "a" => "test",
+          "b" => ["test", "essai"],
+          "string" => "doc 4",
+          "type" => "complex"
+        },
+        %{"a" => %{"c" => 1}, "b" => "", "string" => "doc 5", "type" => 
"complex"}
+      ]
+
+      assert Couch.put("/#{db_name}/_design/test", body: ddoc).body["ok"]
+
+      assert Couch.post(
+               "/#{db_name}/_bulk_docs",
+               body: %{:docs => docs1},
+               query: %{w: 3}
+             ).status_code in [201, 202]
+
+      assert Couch.post(
+               "/#{db_name}/_bulk_docs",
+               body: %{:docs => docs2},
+               query: %{w: 3}
+             ).status_code in [201, 202]
+
+      # Test simple rewriting
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo")
+      assert resp.body == "This is a base64 encoded text"
+      assert resp.headers["Content-Type"] == "text/plain"
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo2")
+      assert resp.body == "This is a base64 encoded text"
+      assert resp.headers["Content-Type"] == "text/plain"
+
+      # Test POST, hello update world
+      resp =
+        Couch.post("/#{db_name}", body: %{"word" => "plankton", "name" => 
"Rusty"}).body
+
+      assert resp["ok"]
+      doc_id = resp["id"]
+      assert doc_id
+
+      resp = Couch.put("/#{db_name}/_design/test/_rewrite/hello/#{doc_id}")
+      assert resp.status_code in [201, 202]
+      assert resp.body == "hello doc"
+      assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/)
+
+      assert Couch.get("/#{db_name}/#{doc_id}").body["world"] == "hello"
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome?name=user")
+      assert resp.body == "Welcome user"
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome/user")
+      assert resp.body == "Welcome user"
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome2")
+      assert resp.body == "Welcome user"
+
+      resp = Couch.put("/#{db_name}/_design/test/_rewrite/welcome3/test")
+      assert resp.status_code in [201, 202]
+      assert resp.body == "New World"
+      assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/)
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome3/test")
+      assert resp.body == "Welcome test"
 
-        assert Couch.get("/#{db_name}/#{doc_id}").body["world"] == "hello"
+      # TODO: port the two "bugged" tests from rewrite.js
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite/basicView")
+      assert resp.status_code == 200
+      assert resp.body["total_rows"] == 9
+
+      resp = Couch.get("/#{db_name}/_design/test/_rewrite")
+      assert resp.status_code == 200
+      assert resp.body["total_rows"] == 9
+
+      resp =
+        Rawresp.get(
+          
"/#{db_name}/_design/test/_rewrite/simpleForm/basicView?startkey=3&endkey=8"
+        )
+
+      assert resp.status_code == 200
+      assert not String.match?(resp.body, ~r/Key: 1/)
+      assert String.match?(resp.body, ~r/FirstKey: 3/)
+      assert String.match?(resp.body, ~r/LastKey: 8/)
+
+      resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/basicViewFixed")
+      assert resp.status_code == 200
+      assert not String.match?(resp.body, ~r/Key: 1/)
+      assert String.match?(resp.body, ~r/FirstKey: 3/)
+      assert String.match?(resp.body, ~r/LastKey: 8/)
+
+      resp =
+        Rawresp.get(
+          
"/#{db_name}/_design/test/_rewrite/simpleForm/basicViewFixed?startkey=4"
+        )
+
+      assert resp.status_code == 200
+      assert not String.match?(resp.body, ~r/Key: 1/)
+      assert String.match?(resp.body, ~r/FirstKey: 3/)
+      assert String.match?(resp.body, ~r/LastKey: 8/)
+
+      resp =
+        
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/basicViewPath/3/8")
+
+      assert resp.status_code == 200
+      assert not String.match?(resp.body, ~r/Key: 1/)
+      assert String.match?(resp.body, ~r/FirstKey: 3/)
+      assert String.match?(resp.body, ~r/LastKey: 8/)
 
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome?name=user")
-        assert resp.body == "Welcome user"
+      resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView")
+      assert resp.status_code == 200
+      assert String.match?(resp.body, ~r/FirstKey: [1, 2]/)
 
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome/user")
-        assert resp.body == "Welcome user"
+      resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView2")
+      assert resp.status_code == 200
+      assert String.match?(resp.body, ~r/Value: doc 3/)
 
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome2")
-        assert resp.body == "Welcome user"
+      resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView3")
+      assert resp.status_code == 200
+      assert String.match?(resp.body, ~r/Value: doc 4/)
 
-        resp = Couch.put("/#{db_name}/_design/test/_rewrite/welcome3/test")
-        assert resp.status_code in [201, 202]
-        assert resp.body == "New World"
-        assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/)
+      resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView4")
+      assert resp.status_code == 200
+      assert String.match?(resp.body, ~r/Value: doc 5/)
 
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome3/test")
-        assert resp.body == "Welcome test"
+      resp =
+        Rawresp.get(
+          
"/#{db_name}/_design/test/_rewrite/simpleForm/complexView5/test/essai"
+        )
 
-        # TODO: port the two "bugged" tests from rewrite.js
-
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite/basicView")
-        assert resp.status_code == 200
-        assert resp.body["total_rows"] == 9
-
-        resp = Couch.get("/#{db_name}/_design/test/_rewrite")
-        assert resp.status_code == 200
-        assert resp.body["total_rows"] == 9
+      assert resp.status_code == 200
+      assert String.match?(resp.body, ~r/Value: doc 4/)
 
-        resp =
-          Rawresp.get(
-            
"/#{db_name}/_design/test/_rewrite/simpleForm/basicView?startkey=3&endkey=8"
-          )
+      resp =
+        Rawresp.get(
+          
"/#{db_name}/_design/test/_rewrite/simpleForm/complexView6?a=test&b=essai"
+        )
 
-        assert resp.status_code == 200
-        assert not String.match?(resp.body, ~r/Key: 1/)
-        assert String.match?(resp.body, ~r/FirstKey: 3/)
-        assert String.match?(resp.body, ~r/LastKey: 8/)
+      assert resp.status_code == 200
+      assert String.match?(resp.body, ~r/Value: doc 4/)
 
-        resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/basicViewFixed")
-        assert resp.status_code == 200
-        assert not String.match?(resp.body, ~r/Key: 1/)
-        assert String.match?(resp.body, ~r/FirstKey: 3/)
-        assert String.match?(resp.body, ~r/LastKey: 8/)
+      resp =
+        Rawresp.get(
+          
"/#{db_name}/_design/test/_rewrite/simpleForm/complexView7/test/essai?doc=true"
+        )
 
-        resp =
-          Rawresp.get(
-            
"/#{db_name}/_design/test/_rewrite/simpleForm/basicViewFixed?startkey=4"
-          )
+      assert resp.status_code == 200
 
-        assert resp.status_code == 200
-        assert not String.match?(resp.body, ~r/Key: 1/)
-        assert String.match?(resp.body, ~r/FirstKey: 3/)
-        assert String.match?(resp.body, ~r/LastKey: 8/)
+      result =
+        resp.body |> IO.iodata_to_binary() |> :jiffy.decode([:return_maps, 
:use_nil])
 
-        resp =
-          
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/basicViewPath/3/8")
+      first_row = Enum.at(result["rows"], 0)
+      assert Map.has_key?(first_row, "doc")
 
-        assert resp.status_code == 200
-        assert not String.match?(resp.body, ~r/Key: 1/)
-        assert String.match?(resp.body, ~r/FirstKey: 3/)
-        assert String.match?(resp.body, ~r/LastKey: 8/)
+      # COUCHDB-2031 - path normalization versus qs params
+      resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/db/_design/test?meta=true")
+      assert resp.status_code == 200
 
-        resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView")
-        assert resp.status_code == 200
-        assert String.match?(resp.body, ~r/FirstKey: [1, 2]/)
+      result =
+        resp.body |> IO.iodata_to_binary() |> :jiffy.decode([:return_maps, 
:use_nil])
 
-        resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView2")
-        assert resp.status_code == 200
-        assert String.match?(resp.body, ~r/Value: doc 3/)
+      assert result["_id"] == "_design/test"
+      assert Map.has_key?(result, "_revs_info")
 
-        resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView3")
-        assert resp.status_code == 200
-        assert String.match?(resp.body, ~r/Value: doc 4/)
+      ddoc2 = %{
+        _id: "_design/test2",
+        rewrites: [
+          %{
+            from: "uuids",
+            to: "../../../_uuids"
+          }
+        ]
+      }
 
-        resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView4")
-        assert resp.status_code == 200
-        assert String.match?(resp.body, ~r/Value: doc 5/)
+      create_doc(db_name, ddoc2)
+      resp = Couch.get("/#{db_name}/_design/test2/_rewrite/uuids")
+      assert resp.status_code == 500
+      assert resp.body["error"] == "insecure_rewrite_rule"
+    end
 
-        resp =
-          Rawresp.get(
-            
"/#{db_name}/_design/test/_rewrite/simpleForm/complexView5/test/essai"
-          )
+    @tag with_random_db: db_name
+    @tag config: [
+           {"chttpd", "secure_rewrites", "false"}
+         ]
+    test "path relative to server on #{db_name}", context do
+      db_name = context[:db_name]
 
-        assert resp.status_code == 200
-        assert String.match?(resp.body, ~r/Value: doc 4/)
+      ddoc = %{
+        _id: "_design/test2",
+        rewrites: [
+          %{
+            from: "uuids",
+            to: "../../../_uuids"
+          }
+        ]
+      }
 
-        resp =
-          Rawresp.get(
-            
"/#{db_name}/_design/test/_rewrite/simpleForm/complexView6?a=test&b=essai"
-          )
+      create_doc(db_name, ddoc)
 
-        assert resp.status_code == 200
-        assert String.match?(resp.body, ~r/Value: doc 4/)
+      resp = Couch.get("/#{db_name}/_design/test2/_rewrite/uuids")
+      assert resp.status_code == 200
+      assert length(resp.body["uuids"]) == 1
+    end
 
-        resp =
-          Rawresp.get(
-            
"/#{db_name}/_design/test/_rewrite/simpleForm/complexView7/test/essai?doc=true"
-          )
+    @tag with_random_db: db_name
+    @tag config: [
+           {"chttpd", "rewrite_limit", "2"}
+         ]
+    test "loop detection on #{db_name}", context do
+      db_name = context[:db_name]
 
-        assert resp.status_code == 200
-        result = resp.body |> IO.iodata_to_binary() |> 
:jiffy.decode([:return_maps, :use_nil])
-        first_row = Enum.at(result["rows"], 0)
-        assert Map.has_key?(first_row, "doc")
+      ddoc_loop = %{
+        _id: "_design/loop",
+        rewrites: [%{from: "loop", to: "_rewrite/loop"}]
+      }
 
-        # COUCHDB-2031 - path normalization versus qs params
-        resp = 
Rawresp.get("/#{db_name}/_design/test/_rewrite/db/_design/test?meta=true")
-        assert resp.status_code == 200
-        result = resp.body |> IO.iodata_to_binary() |> 
:jiffy.decode([:return_maps, :use_nil])
-        assert result["_id"] == "_design/test"
-        assert Map.has_key?(result, "_revs_info")
-
-        ddoc2 = %{
-          _id: "_design/test2",
-          rewrites: [
-            %{
-              from: "uuids",
-              to: "../../../_uuids"
-            }
-          ]
-        }
+      create_doc(db_name, ddoc_loop)
 
-        create_doc(db_name, ddoc2)
-        resp = Couch.get("/#{db_name}/_design/test2/_rewrite/uuids")
-        assert resp.status_code == 500
-        assert resp.body["error"] == "insecure_rewrite_rule"
-      end
+      resp = Couch.get("/#{db_name}/_design/loop/_rewrite/loop")
+      assert resp.status_code == 400
+    end
 
-      @tag with_random_db: db_name
-      @tag config: [
-             {"chttpd", "secure_rewrites", "false"}
-           ]
-      test "path relative to server on #{db_name}", context do
-        db_name = context[:db_name]
-
-        ddoc = %{
-          _id: "_design/test2",
-          rewrites: [
-            %{
-              from: "uuids",
-              to: "../../../_uuids"
-            }
-          ]
-        }
+    @tag with_random_db: db_name
+    @tag config: [
+           {"chttpd", "rewrite_limit", "2"},
+           {"chttpd", "secure_rewrites", "false"}
+         ]
+    test "serial execution is not spuriously counted as loop on #{db_name}", 
context do
+      db_name = context[:db_name]
+
+      ddoc = %{
+        _id: "_design/test",
+        language: "javascript",
+        _attachments: %{
+          "foo.txt": %{
+            content_type: "text/plain",
+            data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
+          }
+        },
+        rewrites: [
+          %{
+            from: "foo",
+            to: "foo.txt"
+          }
+        ]
+      }
 
-        create_doc(db_name, ddoc)
+      create_doc(db_name, ddoc)
 
-        resp = Couch.get("/#{db_name}/_design/test2/_rewrite/uuids")
+      for _i <- 0..4 do
+        resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo")
         assert resp.status_code == 200
-        assert length(resp.body["uuids"]) == 1
-      end
-
-      @tag with_random_db: db_name
-      @tag config: [
-             {"chttpd", "rewrite_limit", "2"}
-           ]
-      test "loop detection on #{db_name}", context do
-        db_name = context[:db_name]
-
-        ddoc_loop = %{
-          _id: "_design/loop",
-          rewrites: [%{from: "loop", to: "_rewrite/loop"}]
-        }
-
-        create_doc(db_name, ddoc_loop)
-
-        resp = Couch.get("/#{db_name}/_design/loop/_rewrite/loop")
-        assert resp.status_code == 400
-      end
-
-      @tag with_random_db: db_name
-      @tag config: [
-             {"chttpd", "rewrite_limit", "2"},
-             {"chttpd", "secure_rewrites", "false"}
-           ]
-      test "serial execution is not spuriously counted as loop on #{db_name}", 
context do
-        db_name = context[:db_name]
-
-        ddoc = %{
-          _id: "_design/test",
-          language: "javascript",
-          _attachments: %{
-            "foo.txt": %{
-              content_type: "text/plain",
-              data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
-            }
-          },
-          rewrites: [
-            %{
-              from: "foo",
-              to: "foo.txt"
-            }
-          ]
-        }
-
-        create_doc(db_name, ddoc)
-
-        for _i <- 0..4 do
-          resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo")
-          assert resp.status_code == 200
-        end
       end
     end
-  )
+  end
 end

Reply via email to