You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2023/04/18 13:40:33 UTC

[couchdb] 01/01: nouveau tests

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

rnewson pushed a commit to branch import-nouveau
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 4487f0702b332e23e859a62085cbb16374251bf2
Author: Robert Newson <rn...@apache.org>
AuthorDate: Tue Apr 18 13:33:56 2023 +0100

    nouveau tests
---
 test/elixir/test/config/nouveau.elixir |  10 +-
 test/elixir/test/nouveau_test.exs      | 176 +++++++++++++++++++++++++++------
 2 files changed, 153 insertions(+), 33 deletions(-)

diff --git a/test/elixir/test/config/nouveau.elixir b/test/elixir/test/config/nouveau.elixir
index 3dc1989e4..1f8bbe457 100644
--- a/test/elixir/test/config/nouveau.elixir
+++ b/test/elixir/test/config/nouveau.elixir
@@ -1,6 +1,14 @@
 %{
   "NouveauTest": [
     "search returns all items for GET",
-    "search returns all items for POST"
+    "search returns all items for POST",
+    "search returns all items (paginated)",
+    "search for foo:bar",
+    "sort by string field (asc)",
+    "sort by string field (desc)",
+    "sort by numeric field (asc)",
+    "sort by numeric field (desc)",
+    "counts",
+    "ranges"
   ]
 }
diff --git a/test/elixir/test/nouveau_test.exs b/test/elixir/test/nouveau_test.exs
index c81efb62f..e3f7919c2 100644
--- a/test/elixir/test/nouveau_test.exs
+++ b/test/elixir/test/nouveau_test.exs
@@ -11,49 +11,45 @@ defmodule NouveauTest do
     resp = Couch.post("/#{db_name}/_bulk_docs",
       headers: ["Content-Type": "application/json"],
       body: %{:docs => [
-                %{"item" => "apple",  "place" => "kitchen", "state" => "new"},
-                %{"item" => "banana", "place" => "kitchen", "state" => "new"},
-                %{"item" => "carrot", "place" => "kitchen", "state" => "old"},
-                %{"item" => "date",   "place" => "lobby",   "state" => "unknown"},
+                %{"_id" => "doc4", "foo" => "foo", "bar" => 42},
+                %{"_id" => "doc3", "foo" => "bar", "bar" => 12.0},
+                %{"_id" => "doc1", "foo" => "baz", "bar" => 0},
+                %{"_id" => "doc2", "foo" => "foobar", "bar" => 100},
       ]}
     )
-    assert resp.status_code in [201, 202]
+    assert resp.status_code in [201]
   end
 
   def create_ddoc(db_name, opts \\ %{}) do
     default_ddoc = %{
       nouveau: %{
-        fruits: %{
+        bar: %{
           default_analyzer: "standard",
-          index: "function (doc) {\n  index(\"item\", doc.item, {facet: true});\n  index(\"place\", doc.place, {facet: true});\n  index(\"state\", doc.state, {facet: true});\n}"
+          index: """
+            function (doc) {
+              index("string", "foo", doc.foo, {store: true, facet: true});
+              index("double", "bar", doc.bar, {store: true, facet: true});
+            }
+          """
         }
       }
     }
 
     ddoc = Enum.into(opts, default_ddoc)
 
-    resp = Couch.put("/#{db_name}/_design/inventory", body: ddoc)
-    assert resp.status_code in [201, 202]
+    resp = Couch.put("/#{db_name}/_design/foo", body: ddoc)
+    assert resp.status_code in [201]
     assert Map.has_key?(resp.body, "ok") == true
   end
 
-  def create_invalid_ddoc(db_name, opts \\ %{}) do
-    invalid_ddoc = %{
-      :indexes => [
-        %{"name" => "foo",  "ddoc" => "bar", "type" => "text"},
-      ]
-    }
-
-    ddoc = Enum.into(opts, invalid_ddoc)
-
-    resp = Couch.put("/#{db_name}/_design/search", body: ddoc)
-    assert resp.status_code in [201, 202]
-    assert Map.has_key?(resp.body, "ok") == true
+  def get_ids(resp) do
+    %{:body => %{"hits" => hits}} = resp
+    Enum.map(hits, fn hit -> hit["doc"]["_id"] end)
   end
 
-  def get_items (resp) do
-    %{:body => %{"rows" => rows}} = resp
-    Enum.map(rows, fn row -> row["doc"]["item"] end)
+  def get_bookmark(resp) do
+    %{:body => %{"bookmark" => bookmark}} = resp
+    bookmark
   end
 
   @tag :with_db
@@ -62,11 +58,12 @@ defmodule NouveauTest do
     create_search_docs(db_name)
     create_ddoc(db_name)
 
-    url = "/#{db_name}/_design/inventory/_nouveau/fruits"
+    url = "/#{db_name}/_design/foo/_nouveau/bar"
     resp = Couch.get(url, query: %{q: "*:*", include_docs: true})
-    assert resp.status_code == 200
-    ids = get_items(resp)
-    assert Enum.sort(ids) == Enum.sort(["apple", "banana", "carrot", "date"])
+    assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+    ids = get_ids(resp)
+    # nouveau sorts by _id as tie-breaker
+    assert ids == ["doc1", "doc2", "doc3", "doc4"]
   end
 
   @tag :with_db
@@ -75,11 +72,126 @@ defmodule NouveauTest do
     create_search_docs(db_name)
     create_ddoc(db_name)
 
-    url = "/#{db_name}/_design/inventory/_nouveau/fruits"
+    url = "/#{db_name}/_design/foo/_nouveau/bar"
     resp = Couch.post(url, body: %{q: "*:*", include_docs: true})
-    assert resp.status_code == 200
-    ids = get_items(resp)
-    assert Enum.sort(ids) == Enum.sort(["apple", "banana", "carrot", "date"])
+    assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+    ids = get_ids(resp)
+    assert ids == ["doc1", "doc2", "doc3", "doc4"]
+  end
+
+  @tag :with_db
+  test "search returns all items (paginated)", context do
+    db_name = context[:db_name]
+    create_search_docs(db_name)
+    create_ddoc(db_name)
+
+    url = "/#{db_name}/_design/foo/_nouveau/bar"
+
+    # page 1
+    resp = Couch.post(url, body: %{q: "*:*", limit: 2, include_docs: true})
+    assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+    ids = get_ids(resp)
+    assert ids == ["doc1", "doc2"]
+
+    # page 2
+    resp = Couch.post(url, body: %{q: "*:*", limit: 2, bookmark: get_bookmark(resp), include_docs: true})
+    assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+    ids = get_ids(resp)
+    assert ids == ["doc3", "doc4"]
+  end
+
+  @tag :with_db
+  test "search for foo:bar", context do
+    db_name = context[:db_name]
+    create_search_docs(db_name)
+    create_ddoc(db_name)
+
+    url = "/#{db_name}/_design/foo/_nouveau/bar"
+    resp = Couch.post(url, body: %{q: "foo:bar", include_docs: true})
+    assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+    ids = get_ids(resp)
+    assert ids == ["doc3"]
+  end
+
+  @tag :with_db
+  test "sort by string field (asc)", context do
+    db_name = context[:db_name]
+    create_search_docs(db_name)
+    create_ddoc(db_name)
+
+    url = "/#{db_name}/_design/foo/_nouveau/bar"
+    resp = Couch.post(url, body: %{q: "*:*", sort: "foo<string>", include_docs: true})
+    assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+    ids = get_ids(resp)
+    assert ids == ["doc3", "doc1", "doc4", "doc2"]
+  end
+
+  @tag :with_db
+  test "sort by string field (desc)", context do
+    db_name = context[:db_name]
+    create_search_docs(db_name)
+    create_ddoc(db_name)
+
+    url = "/#{db_name}/_design/foo/_nouveau/bar"
+    resp = Couch.post(url, body: %{q: "*:*", sort: "-foo<string>", include_docs: true})
+    assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+    ids = get_ids(resp)
+    assert ids == ["doc2", "doc4", "doc1", "doc3"]
+  end
+
+  @tag :with_db
+  test "sort by numeric field (asc)", context do
+    db_name = context[:db_name]
+    create_search_docs(db_name)
+    create_ddoc(db_name)
+
+    url = "/#{db_name}/_design/foo/_nouveau/bar"
+    resp = Couch.post(url, body: %{q: "*:*", sort: "bar<double>", include_docs: true})
+    assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+    ids = get_ids(resp)
+    assert ids == ["doc1", "doc3", "doc4", "doc2"]
+  end
+
+  @tag :with_db
+  test "sort by numeric field (desc)", context do
+    db_name = context[:db_name]
+    create_search_docs(db_name)
+    create_ddoc(db_name)
+
+    url = "/#{db_name}/_design/foo/_nouveau/bar"
+    resp = Couch.post(url, body: %{q: "*:*", sort: "-bar<double>", include_docs: true})
+    assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+    ids = get_ids(resp)
+    assert ids == ["doc2", "doc4", "doc3", "doc1"]
+  end
+
+  @tag :with_db
+  test "counts", context do
+    db_name = context[:db_name]
+    create_search_docs(db_name)
+    create_ddoc(db_name)
+
+    url = "/#{db_name}/_design/foo/_nouveau/bar"
+    resp = Couch.post(url, body: %{q: "*:*", counts: ["foo"], include_docs: true})
+    assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+    %{:body => %{"counts" => counts}} = resp
+    assert counts == %{"foo" => %{"bar" => 1, "baz" => 1, "foo" => 1, "foobar" => 1}}
+  end
+
+  @tag :with_db
+  test "ranges", context do
+    db_name = context[:db_name]
+    create_search_docs(db_name)
+    create_ddoc(db_name)
+
+    url = "/#{db_name}/_design/foo/_nouveau/bar"
+    resp = Couch.post(url, body: %{q: "*:*", ranges: %{bar: [
+      %{label: "cheap", min: 0, max: 42},
+      %{label: "expensive", min: 42, min_inclusive: false, max: 1000}]},
+      include_docs: true})
+    assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+    %{:body => %{"ranges" => ranges}} = resp
+    assert ranges == %{"bar" => %{"cheap" => 3, "expensive" => 1}}
   end
 
 end