@@ -23,7 +23,7 @@ TEST(Search, make_search_empty) {
2323
2424TEST (Search, make_search_single_entry) {
2525 std::vector<sourcemeta::one::SearchEntry> entries{
26- {" /foo/bar" , " My Title" , " A description" }};
26+ {" /foo/bar" , " My Title" , " A description" , 80 }};
2727 const auto payload{sourcemeta::one::make_search (std::move (entries))};
2828 EXPECT_FALSE (payload.empty ());
2929
@@ -41,7 +41,7 @@ TEST(Search, search_empty_payload) {
4141
4242TEST (Search, search_no_match) {
4343 std::vector<sourcemeta::one::SearchEntry> entries{
44- {" /foo/bar" , " Title" , " Desc" }};
44+ {" /foo/bar" , " Title" , " Desc" , 80 }};
4545 const auto payload{sourcemeta::one::make_search (std::move (entries))};
4646 const auto result{
4747 sourcemeta::one::search (payload.data (), payload.size (), " zzzzz" )};
@@ -51,7 +51,7 @@ TEST(Search, search_no_match) {
5151
5252TEST (Search, search_match_in_path) {
5353 std::vector<sourcemeta::one::SearchEntry> entries{
54- {" /foo/bar" , " Title" , " Desc" }};
54+ {" /foo/bar" , " Title" , " Desc" , 80 }};
5555 const auto payload{sourcemeta::one::make_search (std::move (entries))};
5656 const auto result{
5757 sourcemeta::one::search (payload.data (), payload.size (), " foo" )};
@@ -61,7 +61,7 @@ TEST(Search, search_match_in_path) {
6161
6262TEST (Search, search_match_in_title) {
6363 std::vector<sourcemeta::one::SearchEntry> entries{
64- {" /foo/bar" , " Special Title" , " Desc" }};
64+ {" /foo/bar" , " Special Title" , " Desc" , 80 }};
6565 const auto payload{sourcemeta::one::make_search (std::move (entries))};
6666 const auto result{
6767 sourcemeta::one::search (payload.data (), payload.size (), " Special" )};
@@ -71,7 +71,7 @@ TEST(Search, search_match_in_title) {
7171
7272TEST (Search, search_match_in_description) {
7373 std::vector<sourcemeta::one::SearchEntry> entries{
74- {" /foo/bar" , " Title" , " Unique description here" }};
74+ {" /foo/bar" , " Title" , " Unique description here" , 80 }};
7575 const auto payload{sourcemeta::one::make_search (std::move (entries))};
7676 const auto result{
7777 sourcemeta::one::search (payload.data (), payload.size (), " Unique" )};
@@ -82,7 +82,7 @@ TEST(Search, search_match_in_description) {
8282
8383TEST (Search, search_case_insensitive) {
8484 std::vector<sourcemeta::one::SearchEntry> entries_lower{
85- {" /foo/bar" , " Hello World" , " desc" }};
85+ {" /foo/bar" , " Hello World" , " desc" , 80 }};
8686 const auto payload_lower{
8787 sourcemeta::one::make_search (std::move (entries_lower))};
8888 const auto result_lower{sourcemeta::one::search (
@@ -91,7 +91,7 @@ TEST(Search, search_case_insensitive) {
9191 EXPECT_SEARCH_RESULT (result_lower, 0 , " /foo/bar" , " Hello World" , " desc" );
9292
9393 std::vector<sourcemeta::one::SearchEntry> entries_upper{
94- {" /foo/bar" , " Hello World" , " desc" }};
94+ {" /foo/bar" , " Hello World" , " desc" , 80 }};
9595 const auto payload_upper{
9696 sourcemeta::one::make_search (std::move (entries_upper))};
9797 const auto result_upper{sourcemeta::one::search (
@@ -100,7 +100,7 @@ TEST(Search, search_case_insensitive) {
100100 EXPECT_SEARCH_RESULT (result_upper, 0 , " /foo/bar" , " Hello World" , " desc" );
101101
102102 std::vector<sourcemeta::one::SearchEntry> entries_mixed{
103- {" /foo/bar" , " Hello World" , " desc" }};
103+ {" /foo/bar" , " Hello World" , " desc" , 80 }};
104104 const auto payload_mixed{
105105 sourcemeta::one::make_search (std::move (entries_mixed))};
106106 const auto result_mixed{sourcemeta::one::search (
@@ -111,9 +111,9 @@ TEST(Search, search_case_insensitive) {
111111
112112TEST (Search, search_multiple_matches) {
113113 std::vector<sourcemeta::one::SearchEntry> entries{
114- {" /schemas/address" , " Address Schema" , " For addresses" },
115- {" /schemas/person" , " Person Schema" , " For people" },
116- {" /schemas/email" , " Email Schema" , " For emails" }};
114+ {" /schemas/address" , " Address Schema" , " For addresses" , 80 },
115+ {" /schemas/person" , " Person Schema" , " For people" , 80 },
116+ {" /schemas/email" , " Email Schema" , " For emails" , 80 }};
117117 const auto payload{sourcemeta::one::make_search (std::move (entries))};
118118 const auto result{
119119 sourcemeta::one::search (payload.data (), payload.size (), " schema" )};
@@ -128,14 +128,21 @@ TEST(Search, search_multiple_matches) {
128128
129129TEST (Search, search_limit_10) {
130130 std::vector<sourcemeta::one::SearchEntry> entries{
131- {" /schemas/test0" , " Test 0" , " " }, {" /schemas/test1" , " Test 1" , " " },
132- {" /schemas/test2" , " Test 2" , " " }, {" /schemas/test3" , " Test 3" , " " },
133- {" /schemas/test4" , " Test 4" , " " }, {" /schemas/test5" , " Test 5" , " " },
134- {" /schemas/test6" , " Test 6" , " " }, {" /schemas/test7" , " Test 7" , " " },
135- {" /schemas/test8" , " Test 8" , " " }, {" /schemas/test9" , " Test 9" , " " },
136- {" /schemas/test10" , " Test 10" , " " }, {" /schemas/test11" , " Test 11" , " " },
137- {" /schemas/test12" , " Test 12" , " " }, {" /schemas/test13" , " Test 13" , " " },
138- {" /schemas/test14" , " Test 14" , " " }};
131+ {" /schemas/test0" , " Test 0" , " " , 80 },
132+ {" /schemas/test1" , " Test 1" , " " , 80 },
133+ {" /schemas/test2" , " Test 2" , " " , 80 },
134+ {" /schemas/test3" , " Test 3" , " " , 80 },
135+ {" /schemas/test4" , " Test 4" , " " , 80 },
136+ {" /schemas/test5" , " Test 5" , " " , 80 },
137+ {" /schemas/test6" , " Test 6" , " " , 80 },
138+ {" /schemas/test7" , " Test 7" , " " , 80 },
139+ {" /schemas/test8" , " Test 8" , " " , 80 },
140+ {" /schemas/test9" , " Test 9" , " " , 80 },
141+ {" /schemas/test10" , " Test 10" , " " , 80 },
142+ {" /schemas/test11" , " Test 11" , " " , 80 },
143+ {" /schemas/test12" , " Test 12" , " " , 80 },
144+ {" /schemas/test13" , " Test 13" , " " , 80 },
145+ {" /schemas/test14" , " Test 14" , " " , 80 }};
139146
140147 const auto payload{sourcemeta::one::make_search (std::move (entries))};
141148 const auto result{
@@ -155,9 +162,9 @@ TEST(Search, search_limit_10) {
155162
156163TEST (Search, search_round_trip_data_fidelity) {
157164 std::vector<sourcemeta::one::SearchEntry> entries{
158- {" /a/b/c" , " My Title" , " My Description" },
159- {" /x/y/z" , " " , " Only description" },
160- {" /p/q" , " Only title" , " " }};
165+ {" /a/b/c" , " My Title" , " My Description" , 80 },
166+ {" /x/y/z" , " " , " Only description" , 80 },
167+ {" /p/q" , " Only title" , " " , 80 }};
161168 const auto payload{sourcemeta::one::make_search (std::move (entries))};
162169 const auto result{
163170 sourcemeta::one::search (payload.data (), payload.size (), " /" )};
@@ -168,7 +175,8 @@ TEST(Search, search_round_trip_data_fidelity) {
168175}
169176
170177TEST (Search, search_single_entry_match) {
171- std::vector<sourcemeta::one::SearchEntry> entries{{" /only" , " One" , " Entry" }};
178+ std::vector<sourcemeta::one::SearchEntry> entries{
179+ {" /only" , " One" , " Entry" , 80 }};
172180 const auto payload{sourcemeta::one::make_search (std::move (entries))};
173181 const auto result{
174182 sourcemeta::one::search (payload.data (), payload.size (), " One" )};
@@ -177,18 +185,147 @@ TEST(Search, search_single_entry_match) {
177185}
178186
179187TEST (Search, search_single_entry_no_match) {
180- std::vector<sourcemeta::one::SearchEntry> entries{{" /only" , " One" , " Entry" }};
188+ std::vector<sourcemeta::one::SearchEntry> entries{
189+ {" /only" , " One" , " Entry" , 80 }};
181190 const auto payload{sourcemeta::one::make_search (std::move (entries))};
182191 const auto result{
183192 sourcemeta::one::search (payload.data (), payload.size (), " nope" )};
184193 EXPECT_EQ (result.size (), 0 );
185194}
186195
187196TEST (Search, search_empty_title_and_description) {
188- std::vector<sourcemeta::one::SearchEntry> entries{{" /path/only" , " " , " " }};
197+ std::vector<sourcemeta::one::SearchEntry> entries{{" /path/only" , " " , " " , 80 }};
189198 const auto payload{sourcemeta::one::make_search (std::move (entries))};
190199 const auto result{
191200 sourcemeta::one::search (payload.data (), payload.size (), " path" )};
192201 EXPECT_EQ (result.size (), 1 );
193202 EXPECT_SEARCH_RESULT (result, 0 , " /path/only" , " " , " " );
194203}
204+
205+ TEST (Search, search_health_higher_scores_first) {
206+ std::vector<sourcemeta::one::SearchEntry> entries{
207+ {" /schemas/low" , " Low Health" , " Desc" , 20 },
208+ {" /schemas/high" , " High Health" , " Desc" , 100 },
209+ {" /schemas/mid" , " Mid Health" , " Desc" , 60 }};
210+ const auto payload{sourcemeta::one::make_search (std::move (entries))};
211+ const auto result{
212+ sourcemeta::one::search (payload.data (), payload.size (), " Health" )};
213+ EXPECT_EQ (result.size (), 3 );
214+ EXPECT_SEARCH_RESULT (result, 0 , " /schemas/high" , " High Health" , " Desc" );
215+ EXPECT_SEARCH_RESULT (result, 1 , " /schemas/mid" , " Mid Health" , " Desc" );
216+ EXPECT_SEARCH_RESULT (result, 2 , " /schemas/low" , " Low Health" , " Desc" );
217+ }
218+
219+ TEST (Search, search_health_100_before_50) {
220+ std::vector<sourcemeta::one::SearchEntry> entries{
221+ {" /schemas/beta" , " Beta" , " Desc" , 50 },
222+ {" /schemas/alpha" , " Alpha" , " Desc" , 100 }};
223+ const auto payload{sourcemeta::one::make_search (std::move (entries))};
224+ const auto result{
225+ sourcemeta::one::search (payload.data (), payload.size (), " schemas" )};
226+ EXPECT_EQ (result.size (), 2 );
227+ EXPECT_SEARCH_RESULT (result, 0 , " /schemas/alpha" , " Alpha" , " Desc" );
228+ EXPECT_SEARCH_RESULT (result, 1 , " /schemas/beta" , " Beta" , " Desc" );
229+ }
230+
231+ TEST (Search, search_health_0_ranks_last) {
232+ std::vector<sourcemeta::one::SearchEntry> entries{
233+ {" /schemas/zero" , " Zero" , " Desc" , 0 },
234+ {" /schemas/perfect" , " Perfect" , " Desc" , 100 },
235+ {" /schemas/okay" , " Okay" , " Desc" , 50 }};
236+ const auto payload{sourcemeta::one::make_search (std::move (entries))};
237+ const auto result{
238+ sourcemeta::one::search (payload.data (), payload.size (), " schemas" )};
239+ EXPECT_EQ (result.size (), 3 );
240+ EXPECT_SEARCH_RESULT (result, 0 , " /schemas/perfect" , " Perfect" , " Desc" );
241+ EXPECT_SEARCH_RESULT (result, 1 , " /schemas/okay" , " Okay" , " Desc" );
242+ EXPECT_SEARCH_RESULT (result, 2 , " /schemas/zero" , " Zero" , " Desc" );
243+ }
244+
245+ TEST (Search, search_health_same_score_sorts_by_path) {
246+ std::vector<sourcemeta::one::SearchEntry> entries{
247+ {" /schemas/zebra" , " Zebra" , " Desc" , 75 },
248+ {" /schemas/apple" , " Apple" , " Desc" , 75 },
249+ {" /schemas/mango" , " Mango" , " Desc" , 75 }};
250+ const auto payload{sourcemeta::one::make_search (std::move (entries))};
251+ const auto result{
252+ sourcemeta::one::search (payload.data (), payload.size (), " schemas" )};
253+ EXPECT_EQ (result.size (), 3 );
254+ EXPECT_SEARCH_RESULT (result, 0 , " /schemas/apple" , " Apple" , " Desc" );
255+ EXPECT_SEARCH_RESULT (result, 1 , " /schemas/mango" , " Mango" , " Desc" );
256+ EXPECT_SEARCH_RESULT (result, 2 , " /schemas/zebra" , " Zebra" , " Desc" );
257+ }
258+
259+ TEST (Search, search_metadata_score_beats_health) {
260+ std::vector<sourcemeta::one::SearchEntry> entries{
261+ {" /schemas/healthy" , " " , " " , 100 },
262+ {" /schemas/complete" , " Title" , " Description" , 30 }};
263+ const auto payload{sourcemeta::one::make_search (std::move (entries))};
264+ const auto result{
265+ sourcemeta::one::search (payload.data (), payload.size (), " schemas" )};
266+ EXPECT_EQ (result.size (), 2 );
267+ EXPECT_SEARCH_RESULT (result, 0 , " /schemas/complete" , " Title" , " Description" );
268+ EXPECT_SEARCH_RESULT (result, 1 , " /schemas/healthy" , " " , " " );
269+ }
270+
271+ TEST (Search, search_metadata_score_beats_health_title_only) {
272+ std::vector<sourcemeta::one::SearchEntry> entries{
273+ {" /schemas/no-meta" , " " , " " , 100 },
274+ {" /schemas/has-title" , " A Title" , " " , 10 }};
275+ const auto payload{sourcemeta::one::make_search (std::move (entries))};
276+ const auto result{
277+ sourcemeta::one::search (payload.data (), payload.size (), " schemas" )};
278+ EXPECT_EQ (result.size (), 2 );
279+ EXPECT_SEARCH_RESULT (result, 0 , " /schemas/has-title" , " A Title" , " " );
280+ EXPECT_SEARCH_RESULT (result, 1 , " /schemas/no-meta" , " " , " " );
281+ }
282+
283+ TEST (Search, search_health_tiebreaker_within_same_metadata) {
284+ std::vector<sourcemeta::one::SearchEntry> entries{
285+ {" /schemas/low-health" , " Title" , " " , 25 },
286+ {" /schemas/high-health" , " Title" , " " , 90 },
287+ {" /schemas/mid-health" , " Title" , " " , 50 }};
288+ const auto payload{sourcemeta::one::make_search (std::move (entries))};
289+ const auto result{
290+ sourcemeta::one::search (payload.data (), payload.size (), " schemas" )};
291+ EXPECT_EQ (result.size (), 3 );
292+ EXPECT_SEARCH_RESULT (result, 0 , " /schemas/high-health" , " Title" , " " );
293+ EXPECT_SEARCH_RESULT (result, 1 , " /schemas/mid-health" , " Title" , " " );
294+ EXPECT_SEARCH_RESULT (result, 2 , " /schemas/low-health" , " Title" , " " );
295+ }
296+
297+ TEST (Search, search_health_fine_grained_ordering) {
298+ std::vector<sourcemeta::one::SearchEntry> entries{
299+ {" /schemas/d" , " Title" , " Desc" , 70 },
300+ {" /schemas/a" , " Title" , " Desc" , 100 },
301+ {" /schemas/c" , " Title" , " Desc" , 85 },
302+ {" /schemas/e" , " Title" , " Desc" , 55 },
303+ {" /schemas/b" , " Title" , " Desc" , 95 }};
304+ const auto payload{sourcemeta::one::make_search (std::move (entries))};
305+ const auto result{
306+ sourcemeta::one::search (payload.data (), payload.size (), " schemas" )};
307+ EXPECT_EQ (result.size (), 5 );
308+ EXPECT_SEARCH_RESULT (result, 0 , " /schemas/a" , " Title" , " Desc" );
309+ EXPECT_SEARCH_RESULT (result, 1 , " /schemas/b" , " Title" , " Desc" );
310+ EXPECT_SEARCH_RESULT (result, 2 , " /schemas/c" , " Title" , " Desc" );
311+ EXPECT_SEARCH_RESULT (result, 3 , " /schemas/d" , " Title" , " Desc" );
312+ EXPECT_SEARCH_RESULT (result, 4 , " /schemas/e" , " Title" , " Desc" );
313+ }
314+
315+ TEST (Search, search_health_mixed_metadata_and_health) {
316+ std::vector<sourcemeta::one::SearchEntry> entries{
317+ {" /schemas/full-low" , " Title" , " Desc" , 30 },
318+ {" /schemas/title-high" , " Title" , " " , 95 },
319+ {" /schemas/full-high" , " Title" , " Desc" , 90 },
320+ {" /schemas/none-perfect" , " " , " " , 100 },
321+ {" /schemas/title-low" , " Title" , " " , 40 }};
322+ const auto payload{sourcemeta::one::make_search (std::move (entries))};
323+ const auto result{
324+ sourcemeta::one::search (payload.data (), payload.size (), " schemas" )};
325+ EXPECT_EQ (result.size (), 5 );
326+ EXPECT_SEARCH_RESULT (result, 0 , " /schemas/full-high" , " Title" , " Desc" );
327+ EXPECT_SEARCH_RESULT (result, 1 , " /schemas/full-low" , " Title" , " Desc" );
328+ EXPECT_SEARCH_RESULT (result, 2 , " /schemas/title-high" , " Title" , " " );
329+ EXPECT_SEARCH_RESULT (result, 3 , " /schemas/title-low" , " Title" , " " );
330+ EXPECT_SEARCH_RESULT (result, 4 , " /schemas/none-perfect" , " " , " " );
331+ }
0 commit comments