You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ju...@apache.org on 2020/07/23 06:27:52 UTC

[couchdb] branch master updated: Port view multi_key tests into elixir

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

juanjo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/couchdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 6944605  Port view multi_key tests into elixir
6944605 is described below

commit 694460508b714676c352972b0c2d7020c1990ae3
Author: Juanjo Rodriguez <ju...@apache.org>
AuthorDate: Wed Jul 22 13:36:05 2020 +0200

    Port view multi_key tests into elixir
---
 test/elixir/README.md                             |   6 +-
 test/elixir/test/view_multi_key_all_docs_test.exs | 191 +++++++++++++
 test/elixir/test/view_multi_key_design_test.exs   | 316 ++++++++++++++++++++++
 test/javascript/tests/view_multi_key_all_docs.js  |   1 +
 test/javascript/tests/view_multi_key_design.js    |   1 +
 test/javascript/tests/view_multi_key_temp.js      |   1 +
 6 files changed, 513 insertions(+), 3 deletions(-)

diff --git a/test/elixir/README.md b/test/elixir/README.md
index 566364a..38c85a5 100644
--- a/test/elixir/README.md
+++ b/test/elixir/README.md
@@ -104,9 +104,9 @@ X means done, - means partially
   - [ ] Port view_conflicts.js
   - [ ] Port view_errors.js
   - [ ] Port view_include_docs.js
-  - [ ] Port view_multi_key_all_docs.js
-  - [ ] Port view_multi_key_design.js
-  - [ ] Port view_multi_key_temp.js
+  - [X] Port view_multi_key_all_docs.js
+  - [X] Port view_multi_key_design.js
+  - [ ] ~~Port view_multi_key_temp.js~~
   - [X] Port view_offsets.js
   - [X] Port view_pagination.js
   - [X] Port view_sandboxing.js
diff --git a/test/elixir/test/view_multi_key_all_docs_test.exs b/test/elixir/test/view_multi_key_all_docs_test.exs
new file mode 100644
index 0000000..d9fa41e
--- /dev/null
+++ b/test/elixir/test/view_multi_key_all_docs_test.exs
@@ -0,0 +1,191 @@
+defmodule ViewMultiKeyAllDocsTest do
+  use CouchTestCase
+
+  @keys ["10", "15", "30", "37", "50"]
+
+  setup_all do
+    db_name = random_db_name()
+    {:ok, _} = create_db(db_name)
+    on_exit(fn -> delete_db(db_name) end)
+
+    bulk_save(db_name, make_docs(0..99))
+
+    {:ok, [db_name: db_name]}
+  end
+
+  test "keys in POST body", context do
+    db_name = context[:db_name]
+
+    resp = all_docs(db_name, nil, @keys)
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert length(rows) == length(@keys)
+
+    rows_id = Enum.map(rows, & &1["id"])
+    assert rows_id == @keys
+  end
+
+  test "keys in GET parameters", context do
+    db_name = context[:db_name]
+    resp = all_docs(db_name, keys: :jiffy.encode(@keys))
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert length(rows) == length(@keys)
+    rows_id = Enum.map(rows, & &1["id"])
+    assert rows_id == @keys
+  end
+
+  test "keys in POST body (limit)", context do
+    db_name = context[:db_name]
+
+    resp = all_docs(db_name, [limit: 1], @keys)
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert length(rows) == 1
+    assert Enum.at(rows, 0)["id"] == Enum.at(@keys, 0)
+  end
+
+  test "keys in GET parameters (limit)", context do
+    db_name = context[:db_name]
+    resp = all_docs(db_name, limit: 1, keys: :jiffy.encode(@keys))
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert length(rows) == 1
+    assert Enum.at(rows, 0)["id"] == Enum.at(@keys, 0)
+  end
+
+  test "keys in POST body (skip)", context do
+    db_name = context[:db_name]
+
+    resp = all_docs(db_name, [skip: 2], @keys)
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert length(rows) == 3
+
+    rows_id = Enum.map(rows, & &1["id"])
+    assert rows_id == Enum.drop(@keys, 2)
+  end
+
+  test "keys in GET parameters (skip)", context do
+    db_name = context[:db_name]
+    resp = all_docs(db_name, skip: 2, keys: :jiffy.encode(@keys))
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert length(rows) == 3
+    rows_id = Enum.map(rows, & &1["id"])
+    assert rows_id == Enum.drop(@keys, 2)
+  end
+
+  test "keys in POST body (descending)", context do
+    db_name = context[:db_name]
+
+    resp = all_docs(db_name, [descending: true], @keys)
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert length(rows) == length(@keys)
+
+    rows_id = Enum.map(rows, & &1["id"])
+    assert rows_id == Enum.reverse(@keys)
+  end
+
+  test "keys in GET parameters (descending)", context do
+    db_name = context[:db_name]
+    resp = all_docs(db_name, descending: true, keys: :jiffy.encode(@keys))
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert length(rows) == length(@keys)
+    rows_id = Enum.map(rows, & &1["id"])
+    assert rows_id == Enum.reverse(@keys)
+  end
+
+  test "keys in POST body (descending, skip, limit)", context do
+    db_name = context[:db_name]
+
+    resp = all_docs(db_name, [descending: "true", skip: 3, limit: 1], @keys)
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert length(rows) == 1
+
+    key =
+      @keys
+      |> Enum.reverse()
+      |> Enum.drop(3)
+      |> Enum.at(0)
+
+    assert Enum.at(rows, 0)["id"] == key
+  end
+
+  test "keys in GET parameters (descending, skip, limit)", context do
+    db_name = context[:db_name]
+
+    resp =
+      all_docs(db_name, descending: "true", skip: 3, limit: 1, keys: :jiffy.encode(@keys))
+
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert length(rows) == 1
+
+    key =
+      @keys
+      |> Enum.reverse()
+      |> Enum.drop(3)
+      |> Enum.at(0)
+
+    assert Enum.at(rows, 0)["id"] == key
+  end
+
+  test "POST - get invalid rows when the key doesn't exist", context do
+    db_name = context[:db_name]
+
+    resp = all_docs(db_name, nil, ["1211", "i_dont_exist", "0"])
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert length(rows) == 3
+    assert Enum.at(rows, 0)["error"] == "not_found"
+    assert not Map.has_key?(Enum.at(rows, 0), "id")
+    assert Enum.at(rows, 1)["error"] == "not_found"
+    assert not Map.has_key?(Enum.at(rows, 1), "id")
+    assert Enum.at(rows, 2)["id"] == Enum.at(rows, 2)["key"]
+    assert Enum.at(rows, 2)["key"] == "0"
+  end
+
+  test "GET - get invalid rows when the key doesn't exist", context do
+    db_name = context[:db_name]
+
+    resp = all_docs(db_name, keys: :jiffy.encode(["1211", "i_dont_exist", "0"]))
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert length(rows) == 3
+    assert Enum.at(rows, 0)["error"] == "not_found"
+    assert not Map.has_key?(Enum.at(rows, 0), "id")
+    assert Enum.at(rows, 1)["error"] == "not_found"
+    assert not Map.has_key?(Enum.at(rows, 1), "id")
+    assert Enum.at(rows, 2)["id"] == Enum.at(rows, 2)["key"]
+    assert Enum.at(rows, 2)["key"] == "0"
+  end
+
+  test "empty keys", context do
+    db_name = context[:db_name]
+
+    resp = all_docs(db_name, keys: :jiffy.encode([]))
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert Enum.empty?(rows)
+  end
+
+  defp all_docs(db_name, options, keys \\ nil) do
+    resp =
+      case keys do
+        nil ->
+          Couch.get("/#{db_name}/_all_docs", query: options)
+
+        _ ->
+          Couch.post("/#{db_name}/_all_docs",
+            query: options,
+            body: %{"keys" => keys}
+          )
+      end
+
+    resp
+  end
+end
diff --git a/test/elixir/test/view_multi_key_design_test.exs b/test/elixir/test/view_multi_key_design_test.exs
new file mode 100644
index 0000000..ab57e89
--- /dev/null
+++ b/test/elixir/test/view_multi_key_design_test.exs
@@ -0,0 +1,316 @@
+defmodule ViewMultiKeyDesignTest do
+  use CouchTestCase
+
+  @keys [10, 15, 30, 37, 50]
+
+  @ddoc %{
+    _id: "_design/test",
+    language: "javascript",
+    views: %{
+      all_docs: %{
+        map: "function(doc) { emit(doc.integer, doc.string) }"
+      },
+      multi_emit: %{
+        map: "function(doc) {for(var i = 0 ; i < 3 ; i++) { emit(i, doc.integer) ; } }"
+      },
+      summate: %{
+        map: "function (doc) {emit(doc.integer, doc.integer)};",
+        reduce: "function (keys, values) { return sum(values); };"
+      }
+    }
+  }
+
+  setup_all do
+    db_name = random_db_name()
+    {:ok, _} = create_db(db_name)
+    on_exit(fn -> delete_db(db_name) end)
+
+    bulk_save(db_name, make_docs(0..99))
+    {:ok, _} = create_doc(db_name, @ddoc)
+
+    {:ok, [db_name: db_name]}
+  end
+
+  test "that missing keys work too", context do
+    db_name = context[:db_name]
+    keys = [101, 30, 15, 37, 50]
+    resp = view(db_name, "test/summate", [group: true], keys)
+    rows = resp.body["rows"]
+    assert length(rows) == length(keys) - 1
+
+    assert Enum.all?(rows, &Enum.member?(keys, &1["key"]))
+    assert Enum.all?(rows, &(&1["key"] == &1["value"]))
+  end
+
+  test "keys in POST body", context do
+    db_name = context[:db_name]
+    resp = view(db_name, "test/all_docs", nil, @keys)
+    rows = resp.body["rows"]
+    assert length(rows) == length(@keys)
+    assert Enum.all?(rows, &Enum.member?(@keys, &1["key"]))
+    assert Enum.all?(rows, &(&1["key"] == String.to_integer(&1["value"])))
+  end
+
+  test "keys in GET parameters", context do
+    db_name = context[:db_name]
+    resp = view(db_name, "test/all_docs", keys: :jiffy.encode(@keys))
+    rows = resp.body["rows"]
+    assert length(rows) == length(@keys)
+    assert Enum.all?(rows, &Enum.member?(@keys, &1["key"]))
+    assert Enum.all?(rows, &(&1["key"] == String.to_integer(&1["value"])))
+  end
+
+  test "empty keys", context do
+    db_name = context[:db_name]
+
+    resp = view(db_name, "test/all_docs", keys: :jiffy.encode([]))
+    assert resp.status_code == 200
+    rows = resp.body["rows"]
+    assert Enum.empty?(rows)
+  end
+
+  test "keys in POST body (group)", context do
+    db_name = context[:db_name]
+    resp = view(db_name, "test/summate", [group: true], @keys)
+    rows = resp.body["rows"]
+    assert length(rows) == length(@keys)
+    assert Enum.all?(rows, &Enum.member?(@keys, &1["key"]))
+    assert Enum.all?(rows, &(&1["key"] == &1["value"]))
+  end
+
+  test "keys in GET body (group)", context do
+    db_name = context[:db_name]
+    resp = view(db_name, "test/summate", group: true, keys: :jiffy.encode(@keys))
+    rows = resp.body["rows"]
+    assert length(rows) == length(@keys)
+    assert Enum.all?(rows, &Enum.member?(@keys, &1["key"]))
+    assert Enum.all?(rows, &(&1["key"] == &1["value"]))
+  end
+
+  test "POST - invalid parameter combinations get rejected ", context do
+    db_name = context[:db_name]
+
+    badargs = [[startkey: 0], [endkey: 0], [key: 0], [group_level: 2]]
+
+    Enum.each(badargs, fn args ->
+      resp =
+        Couch.post("/#{db_name}/_design/test/_view/all_docs",
+          query: args,
+          body: %{"keys" => @keys}
+        )
+
+      assert resp.status_code == 400
+      assert resp.body["error"] == "query_parse_error"
+    end)
+
+    resp =
+      Couch.post("/#{db_name}/_design/test/_view/summate",
+        query: nil,
+        body: %{"keys" => @keys}
+      )
+
+    assert resp.status_code == 400
+    assert resp.body["error"] == "query_parse_error"
+  end
+
+  test "GET - invalid parameter combinations get rejected ", context do
+    db_name = context[:db_name]
+
+    badargs = [
+      [startkey: 0, keys: :jiffy.encode(@keys)],
+      [endkey: 0, keys: :jiffy.encode(@keys)],
+      [key: 0, keys: :jiffy.encode(@keys)],
+      [group_level: 2, keys: :jiffy.encode(@keys)]
+    ]
+
+    Enum.each(badargs, fn args ->
+      resp =
+        Couch.get("/#{db_name}/_design/test/_view/all_docs",
+          query: args
+        )
+
+      assert resp.status_code == 400
+      assert resp.body["error"] == "query_parse_error"
+    end)
+
+    resp =
+      Couch.get("/#{db_name}/_design/test/_view/summate",
+        query: [keys: :jiffy.encode(@keys)],
+        body: %{"keys" => @keys}
+      )
+
+    assert resp.status_code == 400
+    assert resp.body["error"] == "query_parse_error"
+  end
+
+  test "that a map & reduce containing func support keys when reduce=false", context do
+    db_name = context[:db_name]
+    resp = view(db_name, "test/summate", [reduce: false], @keys)
+    assert length(resp.body["rows"]) == 5
+
+    resp = view(db_name, "test/summate", reduce: false, keys: :jiffy.encode(@keys))
+    assert length(resp.body["rows"]) == 5
+  end
+
+  test "that limiting by startkey_docid and endkey_docid get applied", context do
+    db_name = context[:db_name]
+
+    exp_key = [0, 0, 0, 2, 2, 2]
+    exp_val = [21, 22, 23, 21, 22, 23]
+
+    resp =
+      view(db_name, "test/multi_emit", [startkey_docid: 21, endkey_docid: 23], [0, 2])
+
+    rows = resp.body["rows"]
+    rows_key = Enum.map(rows, & &1["key"])
+    assert rows_key == exp_key
+
+    rows_value = Enum.map(rows, & &1["value"])
+    assert rows_value == exp_val
+
+    resp =
+      view(db_name, "test/multi_emit",
+        startkey_docid: 21,
+        endkey_docid: 23,
+        keys: :jiffy.encode([0, 2])
+      )
+
+    rows = resp.body["rows"]
+    rows_key = Enum.map(rows, & &1["key"])
+    assert rows_key == exp_key
+
+    rows_value = Enum.map(rows, & &1["value"])
+    assert rows_value == exp_val
+  end
+
+  test "limit works", context do
+    db_name = context[:db_name]
+
+    resp = view(db_name, "test/all_docs", [limit: 1], @keys)
+    rows = resp.body["rows"]
+    assert length(rows) == 1
+    assert Enum.at(rows, 0)["key"] == 10
+
+    resp = view(db_name, "test/all_docs", limit: 1, keys: :jiffy.encode(@keys))
+    rows = resp.body["rows"]
+    assert length(rows) == 1
+    assert Enum.at(rows, 0)["key"] == 10
+  end
+
+  test "offset works", context do
+    db_name = context[:db_name]
+
+    resp = view(db_name, "test/multi_emit", [skip: 1], [0])
+    rows = resp.body["rows"]
+    assert length(rows) == 99
+
+    resp = view(db_name, "test/multi_emit", skip: 1, keys: :jiffy.encode([0]))
+    rows = resp.body["rows"]
+    assert length(rows) == 99
+  end
+
+  test "dir works", context do
+    db_name = context[:db_name]
+
+    resp = view(db_name, "test/multi_emit", [descending: true], [1])
+    rows = resp.body["rows"]
+    assert length(rows) == 100
+
+    resp = view(db_name, "test/multi_emit", descending: true, keys: :jiffy.encode([1]))
+    rows = resp.body["rows"]
+    assert length(rows) == 100
+  end
+
+  test "argument combinations", context do
+    db_name = context[:db_name]
+
+    resp = view(db_name, "test/multi_emit", [descending: true, skip: 3, limit: 2], [2])
+    rows = resp.body["rows"]
+    assert length(rows) == 2
+
+    resp =
+      view(db_name, "test/multi_emit",
+        descending: true,
+        skip: 3,
+        limit: 2,
+        keys: :jiffy.encode([2])
+      )
+
+    rows = resp.body["rows"]
+    assert length(rows) == 2
+
+    resp =
+      view(db_name, "test/multi_emit", [skip: 0, limit: 1, startkey_docid: "13"], [0])
+
+    rows = resp.body["rows"]
+    assert length(rows) == 1
+    assert Enum.at(rows, 0)["value"] == 13
+
+    resp =
+      view(db_name, "test/multi_emit", [skip: 2, limit: 3, startkey_docid: "13"], [0])
+
+    rows = resp.body["rows"]
+    assert length(rows) == 3
+
+    resp =
+      view(db_name, "test/multi_emit",
+        skip: 2,
+        limit: 3,
+        startkey_docid: "13",
+        keys: :jiffy.encode([0])
+      )
+
+    rows = resp.body["rows"]
+    assert length(rows) == 3
+
+    resp =
+      view(
+        db_name,
+        "test/multi_emit",
+        [skip: 1, limit: 5, startkey_docid: "25", endkey_docid: "27"],
+        [1]
+      )
+
+    rows = resp.body["rows"]
+    assert length(rows) == 2
+    assert Enum.at(rows, 0)["value"] == 26 or assert(Enum.at(rows, 0)["value"] == 27)
+
+    resp =
+      view(db_name, "test/multi_emit",
+        skip: 1,
+        limit: 5,
+        startkey_docid: "25",
+        endkey_docid: "27",
+        keys: :jiffy.encode([1])
+      )
+
+    rows = resp.body["rows"]
+    assert length(rows) == 2
+    assert Enum.at(rows, 0)["value"] == 26 or assert(Enum.at(rows, 0)["value"] == 27)
+
+    resp =
+      view(
+        db_name,
+        "test/multi_emit",
+        [skip: 1, limit: 5, startkey_docid: "28", endkey_docid: "26", descending: true],
+        [1]
+      )
+
+    rows = resp.body["rows"]
+    assert length(rows) == 2
+    assert Enum.at(rows, 0)["value"] == 26 or assert(Enum.at(rows, 0)["value"] == 27)
+
+    resp =
+      view(db_name, "test/multi_emit",
+        skip: 1,
+        limit: 5,
+        startkey_docid: "28",
+        endkey_docid: "26",
+        descending: true,
+        keys: :jiffy.encode([1])
+      )
+
+    rows = resp.body["rows"]
+    assert length(rows) == 2
+  end
+end
diff --git a/test/javascript/tests/view_multi_key_all_docs.js b/test/javascript/tests/view_multi_key_all_docs.js
index 6704a0f..8969c88 100644
--- a/test/javascript/tests/view_multi_key_all_docs.js
+++ b/test/javascript/tests/view_multi_key_all_docs.js
@@ -10,6 +10,7 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
+couchTests.elixir = true;
 couchTests.view_multi_key_all_docs = function(debug) {
   var db_name = get_random_db_name();
   var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
diff --git a/test/javascript/tests/view_multi_key_design.js b/test/javascript/tests/view_multi_key_design.js
index a50d1fb..20e52a2 100644
--- a/test/javascript/tests/view_multi_key_design.js
+++ b/test/javascript/tests/view_multi_key_design.js
@@ -10,6 +10,7 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
+couchTests.elixir = true;
 couchTests.view_multi_key_design = function(debug) {
   var db_name = get_random_db_name();
   var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
diff --git a/test/javascript/tests/view_multi_key_temp.js b/test/javascript/tests/view_multi_key_temp.js
index 25bec4b..2bed6e7 100644
--- a/test/javascript/tests/view_multi_key_temp.js
+++ b/test/javascript/tests/view_multi_key_temp.js
@@ -10,6 +10,7 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
+couchTests.skip = true;
 couchTests.view_multi_key_temp = function(debug) {
   var db_name = get_random_db_name();
   var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});