tests: Faster index::search::mod IT tests

* Use shared index where possible.
* Call .succeeded/.failed when waiting for a task.
* Use newer format_args syntax
* Do not use fully qualified name for meili_snap:: functions. The
  functions are already imported in scope

Signed-off-by: Martin Tzvetanov Grigorov <mgrigorov@apache.org>
This commit is contained in:
Martin Tzvetanov Grigorov 2025-05-20 14:26:26 +03:00
parent 8047cfe438
commit 2fe5c78cb6
No known key found for this signature in database
GPG Key ID: 3194FD8C1AE300EF
2 changed files with 154 additions and 158 deletions

View File

@ -264,6 +264,25 @@ pub static SCORE_DOCUMENTS: Lazy<Value> = Lazy::new(|| {
]) ])
}); });
pub async fn shared_index_with_score_documents() -> &'static Index<'static, Shared> {
static INDEX: OnceCell<Index<'static, Shared>> = OnceCell::const_new();
INDEX.get_or_init(|| async {
let server = Server::new_shared();
let index = server._index("SCORE_DOCUMENTS").to_shared();
let documents = SCORE_DOCUMENTS.clone();
let (response, _code) = index._add_documents(documents, None).await;
index.wait_task(response.uid()).await.succeeded();
let (response, _code) = index
._update_settings(
json!({"filterableAttributes": ["id", "title"], "sortableAttributes": ["id", "title"]}),
)
.await;
index.wait_task(response.uid()).await.succeeded();
index
}).await
}
pub static NESTED_DOCUMENTS: Lazy<Value> = Lazy::new(|| { pub static NESTED_DOCUMENTS: Lazy<Value> = Lazy::new(|| {
json!([ json!([
{ {

View File

@ -1,4 +1,4 @@
// This modules contains all the test concerning search. Each particular feature of the search // This module contains all the test concerning search. Each particular feature of the search
// should be tested in its own module to isolate tests and keep the tests readable. // should be tested in its own module to isolate tests and keep the tests readable.
mod distinct; mod distinct;
@ -21,8 +21,9 @@ use meilisearch::Opt;
use tempfile::TempDir; use tempfile::TempDir;
use crate::common::{ use crate::common::{
default_settings, shared_index_with_documents, shared_index_with_nested_documents, Server, default_settings, shared_index_with_documents, shared_index_with_nested_documents,
Value, DOCUMENTS, FRUITS_DOCUMENTS, NESTED_DOCUMENTS, SCORE_DOCUMENTS, VECTOR_DOCUMENTS, shared_index_with_score_documents, Server, Value, DOCUMENTS, FRUITS_DOCUMENTS,
NESTED_DOCUMENTS, SCORE_DOCUMENTS, VECTOR_DOCUMENTS,
}; };
use crate::json; use crate::json;
@ -39,39 +40,33 @@ async fn test_settings_documents_indexing_swapping_and_search(
let index = server.index("test"); let index = server.index("test");
let (task, code) = index.add_documents(documents.clone(), None).await; let (task, code) = index.add_documents(documents.clone(), None).await;
assert_eq!(code, 202, "{}", task); assert_eq!(code, 202, "{task}");
let response = index.wait_task(task.uid()).await; index.wait_task(task.uid()).await.succeeded();
assert!(response.is_success(), "{:?}", response);
let (task, code) = index.update_settings(settings.clone()).await; let (task, code) = index.update_settings(settings.clone()).await;
assert_eq!(code, 202, "{}", task); assert_eq!(code, 202, "{task}");
let response = index.wait_task(task.uid()).await; index.wait_task(task.uid()).await.succeeded();
assert!(response.is_success(), "{:?}", response);
index.search(query.clone(), test.clone()).await; index.search(query.clone(), test.clone()).await;
let (task, code) = server.delete_index("test").await; let (task, code) = server.delete_index("test").await;
assert_eq!(code, 202, "{}", task); assert_eq!(code, 202, "{task}");
let response = server.wait_task(task.uid()).await; server.wait_task(task.uid()).await.succeeded();
assert!(response.is_success(), "{:?}", response);
eprintln!("Settings -> Documents -> test"); eprintln!("Settings -> Documents -> test");
let index = server.index("test"); let index = server.index("test");
let (task, code) = index.update_settings(settings.clone()).await; let (task, code) = index.update_settings(settings.clone()).await;
assert_eq!(code, 202, "{}", task); assert_eq!(code, 202, "{task}");
let response = index.wait_task(task.uid()).await; index.wait_task(task.uid()).await.succeeded();
assert!(response.is_success(), "{:?}", response);
let (task, code) = index.add_documents(documents.clone(), None).await; let (task, code) = index.add_documents(documents.clone(), None).await;
assert_eq!(code, 202, "{}", task); assert_eq!(code, 202, "{task}");
let response = index.wait_task(task.uid()).await; index.wait_task(task.uid()).await.succeeded();
assert!(response.is_success(), "{:?}", response);
index.search(query.clone(), test.clone()).await; index.search(query.clone(), test.clone()).await;
let (task, code) = server.delete_index("test").await; let (task, code) = server.delete_index("test").await;
assert_eq!(code, 202, "{}", task); assert_eq!(code, 202, "{task}");
let response = server.wait_task(task.uid()).await; server.wait_task(task.uid()).await.succeeded();
assert!(response.is_success(), "{:?}", response);
} }
#[actix_rt::test] #[actix_rt::test]
@ -79,7 +74,7 @@ async fn simple_placeholder_search() {
let index = shared_index_with_documents().await; let index = shared_index_with_documents().await;
index index
.search(json!({}), |response, code| { .search(json!({}), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 5); assert_eq!(response["hits"].as_array().unwrap().len(), 5);
}) })
.await; .await;
@ -87,7 +82,7 @@ async fn simple_placeholder_search() {
let index = shared_index_with_nested_documents().await; let index = shared_index_with_nested_documents().await;
index index
.search(json!({}), |response, code| { .search(json!({}), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 4); assert_eq!(response["hits"].as_array().unwrap().len(), 4);
}) })
.await; .await;
@ -98,7 +93,7 @@ async fn simple_search() {
let index = shared_index_with_documents().await; let index = shared_index_with_documents().await;
index index
.search(json!({"q": "glass"}), |response, code| { .search(json!({"q": "glass"}), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 1); assert_eq!(response["hits"].as_array().unwrap().len(), 1);
}) })
.await; .await;
@ -106,7 +101,7 @@ async fn simple_search() {
let index = shared_index_with_nested_documents().await; let index = shared_index_with_nested_documents().await;
index index
.search(json!({"q": "pésti"}), |response, code| { .search(json!({"q": "pésti"}), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 2); assert_eq!(response["hits"].as_array().unwrap().len(), 2);
}) })
.await; .await;
@ -141,7 +136,7 @@ async fn search_with_stop_word() {
let (_, code) = index let (_, code) = index
.update_settings(json!({"stopWords": ["the", "The", "a", "an", "to", "in", "of"]})) .update_settings(json!({"stopWords": ["the", "The", "a", "an", "to", "in", "of"]}))
.await; .await;
meili_snap::snapshot!(code, @"202 Accepted"); snapshot!(code, @"202 Accepted");
let documents = DOCUMENTS.clone(); let documents = DOCUMENTS.clone();
index.add_documents(documents, None).await; index.add_documents(documents, None).await;
@ -150,7 +145,7 @@ async fn search_with_stop_word() {
// prefix search // prefix search
index index
.search(json!({"q": "to the", "attributesToHighlight": ["title"], "attributesToRetrieve": ["title"] }), |response, code| { .search(json!({"q": "to the", "attributesToHighlight": ["title"], "attributesToRetrieve": ["title"] }), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
snapshot!(json_string!(response["hits"]), @"[]"); snapshot!(json_string!(response["hits"]), @"[]");
}) })
.await; .await;
@ -158,7 +153,7 @@ async fn search_with_stop_word() {
// non-prefix search // non-prefix search
index index
.search(json!({"q": "to the ", "attributesToHighlight": ["title"], "attributesToRetrieve": ["title"] }), |response, code| { .search(json!({"q": "to the ", "attributesToHighlight": ["title"], "attributesToRetrieve": ["title"] }), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
snapshot!(json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
@ -206,7 +201,7 @@ async fn search_with_typo_settings() {
let (_, code) = index let (_, code) = index
.update_settings(json!({"typoTolerance": { "disableOnAttributes": ["title", "id"]}})) .update_settings(json!({"typoTolerance": { "disableOnAttributes": ["title", "id"]}}))
.await; .await;
meili_snap::snapshot!(code, @"202 Accepted"); snapshot!(code, @"202 Accepted");
let documents = DOCUMENTS.clone(); let documents = DOCUMENTS.clone();
let (task, _status_code) = index.add_documents(documents, None).await; let (task, _status_code) = index.add_documents(documents, None).await;
@ -214,7 +209,7 @@ async fn search_with_typo_settings() {
index index
.search(json!({"q": "287947" }), |response, code| { .search(json!({"q": "287947" }), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
snapshot!(json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
@ -238,7 +233,7 @@ async fn phrase_search_with_stop_word() {
let index = server.index("test"); let index = server.index("test");
let (_, code) = index.update_settings(json!({"stopWords": ["the", "of"]})).await; let (_, code) = index.update_settings(json!({"stopWords": ["the", "of"]})).await;
meili_snap::snapshot!(code, @"202 Accepted"); snapshot!(code, @"202 Accepted");
let documents = DOCUMENTS.clone(); let documents = DOCUMENTS.clone();
let (task, _status_code) = index.add_documents(documents, None).await; let (task, _status_code) = index.add_documents(documents, None).await;
@ -246,7 +241,7 @@ async fn phrase_search_with_stop_word() {
index index
.search(json!({"q": "how \"to\" train \"the" }), |response, code| { .search(json!({"q": "how \"to\" train \"the" }), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 1); assert_eq!(response["hits"].as_array().unwrap().len(), 1);
}) })
.await; .await;
@ -257,7 +252,7 @@ async fn negative_phrase_search() {
let index = shared_index_with_documents().await; let index = shared_index_with_documents().await;
index index
.search(json!({"q": "-\"train your dragon\"" }), |response, code| { .search(json!({"q": "-\"train your dragon\"" }), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
let hits = response["hits"].as_array().unwrap(); let hits = response["hits"].as_array().unwrap();
assert_eq!(hits.len(), 4); assert_eq!(hits.len(), 4);
assert_eq!(hits[0]["id"], "287947"); assert_eq!(hits[0]["id"], "287947");
@ -273,7 +268,7 @@ async fn negative_word_search() {
let index = shared_index_with_documents().await; let index = shared_index_with_documents().await;
index index
.search(json!({"q": "-escape" }), |response, code| { .search(json!({"q": "-escape" }), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
let hits = response["hits"].as_array().unwrap(); let hits = response["hits"].as_array().unwrap();
assert_eq!(hits.len(), 4); assert_eq!(hits.len(), 4);
assert_eq!(hits[0]["id"], "287947"); assert_eq!(hits[0]["id"], "287947");
@ -286,7 +281,7 @@ async fn negative_word_search() {
// Everything that contains derivates of escape but not escape: nothing // Everything that contains derivates of escape but not escape: nothing
index index
.search(json!({"q": "-escape escape" }), |response, code| { .search(json!({"q": "-escape escape" }), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
let hits = response["hits"].as_array().unwrap(); let hits = response["hits"].as_array().unwrap();
assert_eq!(hits.len(), 0); assert_eq!(hits.len(), 0);
}) })
@ -298,7 +293,7 @@ async fn non_negative_search() {
let index = shared_index_with_documents().await; let index = shared_index_with_documents().await;
index index
.search(json!({"q": "- escape" }), |response, code| { .search(json!({"q": "- escape" }), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
let hits = response["hits"].as_array().unwrap(); let hits = response["hits"].as_array().unwrap();
assert_eq!(hits.len(), 1); assert_eq!(hits.len(), 1);
assert_eq!(hits[0]["id"], "522681"); assert_eq!(hits[0]["id"], "522681");
@ -307,7 +302,7 @@ async fn non_negative_search() {
index index
.search(json!({"q": "- \"train your dragon\"" }), |response, code| { .search(json!({"q": "- \"train your dragon\"" }), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
let hits = response["hits"].as_array().unwrap(); let hits = response["hits"].as_array().unwrap();
assert_eq!(hits.len(), 1); assert_eq!(hits.len(), 1);
assert_eq!(hits[0]["id"], "166428"); assert_eq!(hits[0]["id"], "166428");
@ -331,7 +326,7 @@ async fn negative_special_cases_search() {
// There is a synonym for escape -> glass but we don't want "escape", only the derivates: glass // There is a synonym for escape -> glass but we don't want "escape", only the derivates: glass
index index
.search(json!({"q": "-escape escape" }), |response, code| { .search(json!({"q": "-escape escape" }), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
let hits = response["hits"].as_array().unwrap(); let hits = response["hits"].as_array().unwrap();
assert_eq!(hits.len(), 1); assert_eq!(hits.len(), 1);
assert_eq!(hits[0]["id"], "450465"); assert_eq!(hits[0]["id"], "450465");
@ -356,7 +351,7 @@ async fn test_kanji_language_detection() {
index index
.search(json!({"q": "東京"}), |response, code| { .search(json!({"q": "東京"}), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 1); assert_eq!(response["hits"].as_array().unwrap().len(), 1);
}) })
.await; .await;
@ -382,7 +377,7 @@ async fn test_thai_language() {
index index
.search(json!({"q": "สบู"}), |response, code| { .search(json!({"q": "สบู"}), |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
}) })
.await; .await;
} }
@ -400,7 +395,7 @@ async fn search_multiple_params() {
"offset": 0, "offset": 0,
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 1); assert_eq!(response["hits"].as_array().unwrap().len(), 1);
}, },
) )
@ -417,7 +412,7 @@ async fn search_multiple_params() {
"offset": 0, "offset": 0,
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 2); assert_eq!(response["hits"].as_array().unwrap().len(), 2);
}, },
) )
@ -433,7 +428,7 @@ async fn search_with_sort_on_numbers() {
"sort": ["id:asc"] "sort": ["id:asc"]
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 5); assert_eq!(response["hits"].as_array().unwrap().len(), 5);
}, },
) )
@ -446,7 +441,7 @@ async fn search_with_sort_on_numbers() {
"sort": ["doggos.age:asc"] "sort": ["doggos.age:asc"]
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 4); assert_eq!(response["hits"].as_array().unwrap().len(), 4);
}, },
) )
@ -462,7 +457,7 @@ async fn search_with_sort_on_strings() {
"sort": ["title:desc"] "sort": ["title:desc"]
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 5); assert_eq!(response["hits"].as_array().unwrap().len(), 5);
}, },
) )
@ -475,7 +470,7 @@ async fn search_with_sort_on_strings() {
"sort": ["doggos.name:asc"] "sort": ["doggos.name:asc"]
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 4); assert_eq!(response["hits"].as_array().unwrap().len(), 4);
}, },
) )
@ -490,7 +485,7 @@ async fn search_with_multiple_sort() {
"sort": ["id:asc", "title:desc"] "sort": ["id:asc", "title:desc"]
})) }))
.await; .await;
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 5); assert_eq!(response["hits"].as_array().unwrap().len(), 5);
} }
@ -503,7 +498,7 @@ async fn search_facet_distribution() {
"facets": ["title"] "facets": ["title"]
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
let dist = response["facetDistribution"].as_object().unwrap(); let dist = response["facetDistribution"].as_object().unwrap();
assert_eq!(dist.len(), 1); assert_eq!(dist.len(), 1);
assert!(dist.get("title").is_some()); assert!(dist.get("title").is_some());
@ -521,7 +516,7 @@ async fn search_facet_distribution() {
"facets": ["father"] "facets": ["father"]
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
let dist = response["facetDistribution"].as_object().unwrap(); let dist = response["facetDistribution"].as_object().unwrap();
assert_eq!(dist.len(), 1); assert_eq!(dist.len(), 1);
assert_eq!( assert_eq!(
@ -544,9 +539,9 @@ async fn search_facet_distribution() {
"facets": ["doggos.name"] "facets": ["doggos.name"]
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
let dist = response["facetDistribution"].as_object().unwrap(); let dist = response["facetDistribution"].as_object().unwrap();
assert_eq!(dist.len(), 1, "{:?}", dist); assert_eq!(dist.len(), 1, "{dist:?}");
assert_eq!( assert_eq!(
dist["doggos.name"], dist["doggos.name"],
json!({ "bobby": 1, "buddy": 1, "gros bill": 1, "turbo": 1, "fast": 1}) json!({ "bobby": 1, "buddy": 1, "gros bill": 1, "turbo": 1, "fast": 1})
@ -561,9 +556,9 @@ async fn search_facet_distribution() {
"facets": ["doggos"] "facets": ["doggos"]
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
let dist = response["facetDistribution"].as_object().unwrap(); let dist = response["facetDistribution"].as_object().unwrap();
assert_eq!(dist.len(), 3, "{:?}", dist); assert_eq!(dist.len(), 3, "{dist:?}");
assert_eq!( assert_eq!(
dist["doggos.name"], dist["doggos.name"],
json!({ "bobby": 1, "buddy": 1, "gros bill": 1, "turbo": 1, "fast": 1}) json!({ "bobby": 1, "buddy": 1, "gros bill": 1, "turbo": 1, "fast": 1})
@ -579,7 +574,7 @@ async fn search_facet_distribution() {
"facets": ["doggos.name"] "facets": ["doggos.name"]
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
let dist = response["facetDistribution"].as_object().unwrap(); let dist = response["facetDistribution"].as_object().unwrap();
assert_eq!(dist.len(), 1); assert_eq!(dist.len(), 1);
assert_eq!( assert_eq!(
@ -604,7 +599,7 @@ async fn displayed_attributes() {
let (response, code) = let (response, code) =
index.search_post(json!({ "attributesToRetrieve": ["title", "id"] })).await; index.search_post(json!({ "attributesToRetrieve": ["title", "id"] })).await;
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert!(response["hits"][0].get("title").is_some()); assert!(response["hits"][0].get("title").is_some());
} }
@ -623,7 +618,7 @@ async fn placeholder_search_is_hard_limited() {
"limit": 1500, "limit": 1500,
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 1000); assert_eq!(response["hits"].as_array().unwrap().len(), 1000);
}, },
) )
@ -636,7 +631,7 @@ async fn placeholder_search_is_hard_limited() {
"limit": 400, "limit": 400,
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 200); assert_eq!(response["hits"].as_array().unwrap().len(), 200);
}, },
) )
@ -652,7 +647,7 @@ async fn placeholder_search_is_hard_limited() {
"limit": 1500, "limit": 1500,
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 1200); assert_eq!(response["hits"].as_array().unwrap().len(), 1200);
}, },
) )
@ -665,7 +660,7 @@ async fn placeholder_search_is_hard_limited() {
"limit": 400, "limit": 400,
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 200); assert_eq!(response["hits"].as_array().unwrap().len(), 200);
}, },
) )
@ -688,7 +683,7 @@ async fn search_is_hard_limited() {
"limit": 1500, "limit": 1500,
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 1000); assert_eq!(response["hits"].as_array().unwrap().len(), 1000);
}, },
) )
@ -702,7 +697,7 @@ async fn search_is_hard_limited() {
"limit": 400, "limit": 400,
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 200); assert_eq!(response["hits"].as_array().unwrap().len(), 200);
}, },
) )
@ -719,7 +714,7 @@ async fn search_is_hard_limited() {
"limit": 1500, "limit": 1500,
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 1200); assert_eq!(response["hits"].as_array().unwrap().len(), 1200);
}, },
) )
@ -733,7 +728,7 @@ async fn search_is_hard_limited() {
"limit": 400, "limit": 400,
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
assert_eq!(response["hits"].as_array().unwrap().len(), 200); assert_eq!(response["hits"].as_array().unwrap().len(), 200);
}, },
) )
@ -757,7 +752,7 @@ async fn faceting_max_values_per_facet() {
"facets": ["number"] "facets": ["number"]
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
let numbers = response["facetDistribution"]["number"].as_object().unwrap(); let numbers = response["facetDistribution"]["number"].as_object().unwrap();
assert_eq!(numbers.len(), 100); assert_eq!(numbers.len(), 100);
}, },
@ -774,7 +769,7 @@ async fn faceting_max_values_per_facet() {
"facets": ["number"] "facets": ["number"]
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
let numbers = &response["facetDistribution"]["number"].as_object().unwrap(); let numbers = &response["facetDistribution"]["number"].as_object().unwrap();
assert_eq!(numbers.len(), 10_000); assert_eq!(numbers.len(), 10_000);
}, },
@ -784,13 +779,7 @@ async fn faceting_max_values_per_facet() {
#[actix_rt::test] #[actix_rt::test]
async fn test_score_details() { async fn test_score_details() {
let server = Server::new().await; let index = shared_index_with_documents().await;
let index = server.index("test");
let documents = DOCUMENTS.clone();
let res = index.add_documents(json!(documents), None).await;
index.wait_task(res.0.uid()).await.succeeded();
index index
.search( .search(
@ -799,8 +788,8 @@ async fn test_score_details() {
"showRankingScoreDetails": true, "showRankingScoreDetails": true,
}), }),
|response, code| { |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"title": "How to Train Your Dragon: The Hidden World", "title": "How to Train Your Dragon: The Hidden World",
@ -850,13 +839,7 @@ async fn test_score_details() {
#[actix_rt::test] #[actix_rt::test]
async fn test_score() { async fn test_score() {
let server = Server::new().await; let index = shared_index_with_score_documents().await;
let index = server.index("test");
let documents = SCORE_DOCUMENTS.clone();
let res = index.add_documents(json!(documents), None).await;
index.wait_task(res.0.uid()).await.succeeded();
index index
.search( .search(
@ -865,8 +848,8 @@ async fn test_score() {
"showRankingScore": true, "showRankingScore": true,
}), }),
|response, code| { |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"title": "Batman the dark knight returns: Part 1", "title": "Batman the dark knight returns: Part 1",
@ -903,13 +886,7 @@ async fn test_score() {
#[actix_rt::test] #[actix_rt::test]
async fn test_score_threshold() { async fn test_score_threshold() {
let query = "Badman dark returns 1"; let query = "Badman dark returns 1";
let server = Server::new().await; let index = shared_index_with_score_documents().await;
let index = server.index("test");
let documents = SCORE_DOCUMENTS.clone();
let res = index.add_documents(json!(documents), None).await;
index.wait_task(res.0.uid()).await.succeeded();
index index
.search( .search(
@ -919,9 +896,9 @@ async fn test_score_threshold() {
"rankingScoreThreshold": 0.0 "rankingScoreThreshold": 0.0
}), }),
|response, code| { |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["estimatedTotalHits"]), @"5"); snapshot!(json_string!(response["estimatedTotalHits"]), @"5");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"title": "Batman the dark knight returns: Part 1", "title": "Batman the dark knight returns: Part 1",
@ -962,9 +939,9 @@ async fn test_score_threshold() {
"rankingScoreThreshold": 0.2 "rankingScoreThreshold": 0.2
}), }),
|response, code| { |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["estimatedTotalHits"]), @r###"3"###); snapshot!(json_string!(response["estimatedTotalHits"]), @r###"3"###);
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"title": "Batman the dark knight returns: Part 1", "title": "Batman the dark knight returns: Part 1",
@ -995,9 +972,9 @@ async fn test_score_threshold() {
"rankingScoreThreshold": 0.5 "rankingScoreThreshold": 0.5
}), }),
|response, code| { |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["estimatedTotalHits"]), @r###"2"###); snapshot!(json_string!(response["estimatedTotalHits"]), @r###"2"###);
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"title": "Batman the dark knight returns: Part 1", "title": "Batman the dark knight returns: Part 1",
@ -1023,9 +1000,9 @@ async fn test_score_threshold() {
"rankingScoreThreshold": 0.8 "rankingScoreThreshold": 0.8
}), }),
|response, code| { |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["estimatedTotalHits"]), @r###"1"###); snapshot!(json_string!(response["estimatedTotalHits"]), @r###"1"###);
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"title": "Batman the dark knight returns: Part 1", "title": "Batman the dark knight returns: Part 1",
@ -1046,10 +1023,10 @@ async fn test_score_threshold() {
"rankingScoreThreshold": 1.0 "rankingScoreThreshold": 1.0
}), }),
|response, code| { |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["estimatedTotalHits"]), @r###"0"###); snapshot!(json_string!(response["estimatedTotalHits"]), @r###"0"###);
// nobody is perfect // nobody is perfect
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @"[]"); snapshot!(json_string!(response["hits"]), @"[]");
}, },
) )
.await; .await;
@ -1075,8 +1052,8 @@ async fn test_degraded_score_details() {
"showRankingScoreDetails": true, "showRankingScoreDetails": true,
}), }),
|response, code| { |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###"
{ {
"hits": [ "hits": [
{ {
@ -1162,8 +1139,8 @@ async fn camelcased_words() {
index index
.search(json!({"q": "deLonghi"}), |response, code| { .search(json!({"q": "deLonghi"}), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"id": 0, "id": 0,
@ -1180,8 +1157,8 @@ async fn camelcased_words() {
index index
.search(json!({"q": "dellonghi"}), |response, code| { .search(json!({"q": "dellonghi"}), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"id": 0, "id": 0,
@ -1198,8 +1175,8 @@ async fn camelcased_words() {
index index
.search(json!({"q": "testa"}), |response, code| { .search(json!({"q": "testa"}), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"id": 2, "id": 2,
@ -1220,8 +1197,8 @@ async fn camelcased_words() {
index index
.search(json!({"q": "testab"}), |response, code| { .search(json!({"q": "testab"}), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"id": 2, "id": 2,
@ -1242,8 +1219,8 @@ async fn camelcased_words() {
index index
.search(json!({"q": "TestaB"}), |response, code| { .search(json!({"q": "TestaB"}), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"id": 2, "id": 2,
@ -1264,8 +1241,8 @@ async fn camelcased_words() {
index index
.search(json!({"q": "Testab"}), |response, code| { .search(json!({"q": "Testab"}), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"id": 2, "id": 2,
@ -1286,8 +1263,8 @@ async fn camelcased_words() {
index index
.search(json!({"q": "TestAb"}), |response, code| { .search(json!({"q": "TestAb"}), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"id": 2, "id": 2,
@ -1309,8 +1286,8 @@ async fn camelcased_words() {
// with Typos // with Typos
index index
.search(json!({"q": "dellonghi"}), |response, code| { .search(json!({"q": "dellonghi"}), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"id": 0, "id": 0,
@ -1327,8 +1304,8 @@ async fn camelcased_words() {
index index
.search(json!({"q": "TetsAB"}), |response, code| { .search(json!({"q": "TetsAB"}), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"id": 2, "id": 2,
@ -1349,8 +1326,8 @@ async fn camelcased_words() {
index index
.search(json!({"q": "TetsAB"}), |response, code| { .search(json!({"q": "TetsAB"}), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"id": 2, "id": 2,
@ -1377,8 +1354,8 @@ async fn simple_search_with_strange_synonyms() {
let (task, _status_code) = let (task, _status_code) =
index.update_settings(json!({ "synonyms": {"&": ["to"], "to": ["&"]} })).await; index.update_settings(json!({ "synonyms": {"&": ["to"], "to": ["&"]} })).await;
let r = index.wait_task(task.uid()).await; let r = index.wait_task(task.uid()).await.succeeded();
meili_snap::snapshot!(r["status"], @r###""succeeded""###); snapshot!(r["status"], @r###""succeeded""###);
let documents = DOCUMENTS.clone(); let documents = DOCUMENTS.clone();
let (task, _status_code) = index.add_documents(documents, None).await; let (task, _status_code) = index.add_documents(documents, None).await;
@ -1386,8 +1363,8 @@ async fn simple_search_with_strange_synonyms() {
index index
.search(json!({"q": "How to train"}), |response, code| { .search(json!({"q": "How to train"}), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"title": "How to Train Your Dragon: The Hidden World", "title": "How to Train Your Dragon: The Hidden World",
@ -1404,8 +1381,8 @@ async fn simple_search_with_strange_synonyms() {
index index
.search(json!({"q": "How & train"}), |response, code| { .search(json!({"q": "How & train"}), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"title": "How to Train Your Dragon: The Hidden World", "title": "How to Train Your Dragon: The Hidden World",
@ -1422,8 +1399,8 @@ async fn simple_search_with_strange_synonyms() {
index index
.search(json!({"q": "to"}), |response, code| { .search(json!({"q": "to"}), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"title": "How to Train Your Dragon: The Hidden World", "title": "How to Train Your Dragon: The Hidden World",
@ -1462,8 +1439,8 @@ async fn change_attributes_settings() {
"attributesToRetrieve": ["id", "doggos"] "attributesToRetrieve": ["id", "doggos"]
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"id": 852, "id": 852,
@ -1493,8 +1470,8 @@ async fn change_attributes_settings() {
"attributesToRetrieve": ["id", "doggos"] "attributesToRetrieve": ["id", "doggos"]
}), }),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
meili_snap::snapshot!(meili_snap::json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
"id": 852, "id": 852,
@ -1563,7 +1540,7 @@ async fn test_nested_fields() {
&settings, &settings,
&json!({"q": "document"}), &json!({"q": "document"}),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
snapshot!(json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
@ -1609,7 +1586,7 @@ async fn test_nested_fields() {
&settings, &settings,
&json!({"q": "zeroth"}), &json!({"q": "zeroth"}),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
snapshot!(json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
@ -1627,7 +1604,7 @@ async fn test_nested_fields() {
&settings, &settings,
&json!({"q": "first"}), &json!({"q": "first"}),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
snapshot!(json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
@ -1650,7 +1627,7 @@ async fn test_nested_fields() {
&settings, &settings,
&json!({"q": "field"}), &json!({"q": "field"}),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
snapshot!(json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
@ -1686,7 +1663,7 @@ async fn test_nested_fields() {
&settings, &settings,
&json!({"q": "array"}), &json!({"q": "array"}),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
// nested is not searchable // nested is not searchable
snapshot!(json_string!(response["hits"]), @"[]"); snapshot!(json_string!(response["hits"]), @"[]");
}, },
@ -1698,7 +1675,7 @@ async fn test_nested_fields() {
&settings, &settings,
&json!({"q": "lied"}), &json!({"q": "lied"}),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
// nested is not searchable // nested is not searchable
snapshot!(json_string!(response["hits"]), @"[]"); snapshot!(json_string!(response["hits"]), @"[]");
}, },
@ -1711,7 +1688,7 @@ async fn test_nested_fields() {
&settings, &settings,
&json!({"filter": "nested.object = field"}), &json!({"filter": "nested.object = field"}),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
snapshot!(json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
@ -1747,7 +1724,7 @@ async fn test_nested_fields() {
&settings, &settings,
&json!({"filter": "nested.machin = bidule"}), &json!({"filter": "nested.machin = bidule"}),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
snapshot!(json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
@ -1770,7 +1747,7 @@ async fn test_nested_fields() {
&settings, &settings,
&json!({"filter": "nested = array"}), &json!({"filter": "nested = array"}),
|response, code| { |response, code| {
assert_eq!(code, 400, "{}", response); assert_eq!(code, 400, "{response}");
snapshot!(json_string!(response), @r###" snapshot!(json_string!(response), @r###"
{ {
"message": "Index `test`: Attribute `nested` is not filterable. Available filterable attribute patterns are: `nested.machin`, `nested.object`, `title`.\n1:7 nested = array", "message": "Index `test`: Attribute `nested` is not filterable. Available filterable attribute patterns are: `nested.machin`, `nested.object`, `title`.\n1:7 nested = array",
@ -1789,7 +1766,7 @@ async fn test_nested_fields() {
&settings, &settings,
&json!({"filter": r#"nested = "I lied""#}), &json!({"filter": r#"nested = "I lied""#}),
|response, code| { |response, code| {
assert_eq!(code, 400, "{}", response); assert_eq!(code, 400, "{response}");
snapshot!(json_string!(response), @r###" snapshot!(json_string!(response), @r###"
{ {
"message": "Index `test`: Attribute `nested` is not filterable. Available filterable attribute patterns are: `nested.machin`, `nested.object`, `title`.\n1:7 nested = \"I lied\"", "message": "Index `test`: Attribute `nested` is not filterable. Available filterable attribute patterns are: `nested.machin`, `nested.object`, `title`.\n1:7 nested = \"I lied\"",
@ -1850,7 +1827,7 @@ async fn test_typo_settings() {
}), }),
&json!({"q": "document"}), &json!({"q": "document"}),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
snapshot!(json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
@ -1902,7 +1879,7 @@ async fn test_typo_settings() {
}), }),
&json!({"q": "docume"}), &json!({"q": "docume"}),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
snapshot!(json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
@ -1955,7 +1932,7 @@ async fn change_facet_casing() {
})) }))
.await; .await;
assert_eq!("202", code.as_str(), "{:?}", response); assert_eq!("202", code.as_str(), "{:?}", response);
index.wait_task(response.uid()).await; index.wait_task(response.uid()).await.succeeded();
let (response, _code) = index let (response, _code) = index
.add_documents( .add_documents(
@ -1968,7 +1945,7 @@ async fn change_facet_casing() {
None, None,
) )
.await; .await;
index.wait_task(response.uid()).await; index.wait_task(response.uid()).await.succeeded();
let (response, _code) = index let (response, _code) = index
.add_documents( .add_documents(
@ -1981,12 +1958,12 @@ async fn change_facet_casing() {
None, None,
) )
.await; .await;
index.wait_task(response.uid()).await; index.wait_task(response.uid()).await.succeeded();
index index
.search(json!({ "facets": ["dog"] }), |response, code| { .search(json!({ "facets": ["dog"] }), |response, code| {
meili_snap::snapshot!(code, @"200 OK"); snapshot!(code, @"200 OK");
meili_snap::snapshot!(meili_snap::json_string!(response["facetDistribution"]), @r###" snapshot!(json_string!(response["facetDistribution"]), @r###"
{ {
"dog": { "dog": {
"bouvier bernois": 1 "bouvier bernois": 1
@ -2045,7 +2022,7 @@ async fn test_exact_typos_terms() {
}), }),
&json!({"q": "12345"}), &json!({"q": "12345"}),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
snapshot!(json_string!(response["hits"]), @r###" snapshot!(json_string!(response["hits"]), @r###"
[ [
{ {
@ -2080,7 +2057,7 @@ async fn test_exact_typos_terms() {
}), }),
&json!({"q": "123457"}), &json!({"q": "123457"}),
|response, code| { |response, code| {
assert_eq!(code, 200, "{}", response); assert_eq!(code, 200, "{response}");
snapshot!(json_string!(response["hits"]), @r###"[]"###); snapshot!(json_string!(response["hits"]), @r###"[]"###);
}, },
) )