summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Branca <chewbranca@apache.org>2017-12-14 20:26:45 +0000
committerRussell Branca <chewbranca@apache.org>2017-12-14 20:26:45 +0000
commit9ddbbe54ee685f4f62d62ae78a8d0e9ec889497c (patch)
tree7b41435edc82f433985765c58eb4d1394e66ee20
parentf91b1812c7cad81d6df8c3c68bcb3dfe7b5f95d8 (diff)
downloadcouchdb-9ddbbe54ee685f4f62d62ae78a8d0e9ec889497c.tar.gz
WIP: Port most of rewrite.js suite
-rw-r--r--elixir_suite/test/reduce_test.exs10
-rw-r--r--elixir_suite/test/rewrite_test.exs339
-rw-r--r--elixir_suite/test/test_helper.exs20
3 files changed, 358 insertions, 11 deletions
diff --git a/elixir_suite/test/reduce_test.exs b/elixir_suite/test/reduce_test.exs
index 9a49bfa5b..5c56165ed 100644
--- a/elixir_suite/test/reduce_test.exs
+++ b/elixir_suite/test/reduce_test.exs
@@ -12,16 +12,6 @@ defmodule ReduceTest do
(n + 1) * n / 2
end
- def make_docs(id, count) do
- for i <- id..count do
- %{
- :_id => Integer.to_string(i),
- :integer => i,
- :string => Integer.to_string(i)
- }
- end
- end
-
@tag :with_db
test "Basic reduce functions", context do
db_name = context[:db_name]
diff --git a/elixir_suite/test/rewrite_test.exs b/elixir_suite/test/rewrite_test.exs
new file mode 100644
index 000000000..54ff80a64
--- /dev/null
+++ b/elixir_suite/test/rewrite_test.exs
@@ -0,0 +1,339 @@
+defmodule RewriteTest do
+ use CouchTestCase
+
+ @moduletag :js_engine
+
+ @moduledoc """
+ Test CouchDB rewrites
+ 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}"},
+ {"httpd", "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="
+ }
+ },
+ "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": "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"
+ },
+ "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\"]
+ }
+ 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\"]
+ }
+ return [null, \"Empty World\"];
+ }
+ 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);
+ }
+ })"
+ }
+ }
+}
+ """
+ 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 == 201
+ assert Couch.post("/#{db_name}/_bulk_docs", [body: %{:docs => docs2}, query: %{w: 3}]).status_code == 201
+
+ # 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 == 201
+ 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 == 201
+ 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"
+
+ # 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
+
+ # TODO: port _list function tests and everything below in rewrite.js
+ # This is currently broken because _list funcitons default to application/json
+ # response bodies and my attempts to change the content-type from within the
+ # _list function have not yet succeeded.
+ #
+ # Test GET with query params
+ # resp = Couch.get("/#{db_name}/_design/test/_rewrite/simpleForm/basicView", query: %{startkey: 3, endkey: 8})
+ # Logger.error("GOT RESP: #{inspect resp.body}")
+ # assert resp.status_code == 200
+ end
+ end)
+end
diff --git a/elixir_suite/test/test_helper.exs b/elixir_suite/test/test_helper.exs
index 1c61e4a86..cb01fc286 100644
--- a/elixir_suite/test/test_helper.exs
+++ b/elixir_suite/test/test_helper.exs
@@ -26,6 +26,10 @@ defmodule CouchTestCase do
Map.put(context, :db_name, random_db_name())
%{:with_db_name => db_name} when is_binary(db_name) ->
Map.put(context, :db_name, db_name)
+ %{:with_random_db => db_name} when is_binary(db_name) ->
+ context
+ |> Map.put(:db_name, random_db_name(db_name))
+ |> Map.put(:with_db, true)
%{:with_db => true} ->
Map.put(context, :db_name, random_db_name())
%{:with_db => db_name} when is_binary(db_name) ->
@@ -52,9 +56,13 @@ defmodule CouchTestCase do
end
def random_db_name do
+ random_db_name("random-test-db")
+ end
+
+ def random_db_name(prefix) do
time = :erlang.monotonic_time()
umi = :erlang.unique_integer([:monotonic])
- "random-test-db-#{time}-#{umi}"
+ "#{prefix}-#{time}-#{umi}"
end
def set_config({section, key, value}) do
@@ -112,6 +120,16 @@ defmodule CouchTestCase do
"bar": "baz"
}
end
+
+ def make_docs(id, count) do
+ for i <- id..count do
+ %{
+ :_id => Integer.to_string(i),
+ :integer => i,
+ :string => Integer.to_string(i)
+ }
+ end
+ end
end
end
end