summaryrefslogtreecommitdiff
path: root/test/elixir/test/nouveau_test.exs
diff options
context:
space:
mode:
Diffstat (limited to 'test/elixir/test/nouveau_test.exs')
-rw-r--r--test/elixir/test/nouveau_test.exs242
1 files changed, 242 insertions, 0 deletions
diff --git a/test/elixir/test/nouveau_test.exs b/test/elixir/test/nouveau_test.exs
new file mode 100644
index 000000000..ee5d20542
--- /dev/null
+++ b/test/elixir/test/nouveau_test.exs
@@ -0,0 +1,242 @@
+defmodule NouveauTest do
+ use CouchTestCase
+
+ @moduletag :search
+
+ @moduledoc """
+ Test search
+ """
+
+ def create_search_docs(db_name) do
+ resp = Couch.post("/#{db_name}/_bulk_docs",
+ headers: ["Content-Type": "application/json"],
+ body: %{:docs => [
+ %{"_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]
+ end
+
+ def create_ddoc(db_name, opts \\ %{}) do
+ default_ddoc = %{
+ nouveau: %{
+ bar: %{
+ default_analyzer: "standard",
+ index: """
+ function (doc) {
+ index("string", "foo", doc.foo, {store: true});
+ index("double", "bar", doc.bar, {store: true});
+ }
+ """
+ }
+ }
+ }
+
+ ddoc = Enum.into(opts, default_ddoc)
+
+ 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 get_ids(resp) do
+ %{:body => %{"hits" => hits}} = resp
+ Enum.map(hits, fn hit -> hit["doc"]["_id"] end)
+ end
+
+ def get_bookmark(resp) do
+ %{:body => %{"bookmark" => bookmark}} = resp
+ bookmark
+ end
+
+ test "search analyze", context do
+ url = "/_nouveau_analyze"
+ resp = Couch.post(url,
+ headers: ["Content-Type": "application/json"],
+ body: %{analyzer: "standard", text: "hello there"})
+ assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+ assert resp.body == %{"tokens" => ["hello", "there"]}
+ end
+
+ @tag :with_db
+ test "search info", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ # query it so it builds
+ url = "/#{db_name}/_design/foo/_nouveau/bar"
+ resp = Couch.get(url, query: %{q: "*:*", include_docs: true})
+ assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+
+ url = "/#{db_name}/_design/foo/_nouveau_info/bar"
+ resp = Couch.get(url)
+ assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+ info = Map.get(resp.body, "search_index")
+ assert Map.get(info, "disk_size") > 0
+ assert Map.get(info, "num_docs") > 0
+ assert Map.get(info, "update_seq") > 0
+ end
+
+ @tag :with_db
+ test "search returns all items for GET", 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.get(url, query: %{q: "*:*", include_docs: true})
+ 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
+ test "search returns all items for POST", 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: "*:*", include_docs: true})
+ 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
+
+ @tag :with_db
+ test "ranges (open)", 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", max: 42},
+ %{label: "expensive", min: 42, min_inclusive: false}]},
+ 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