static void test_calc_proximity_boost(TestBatchRunner *runner) { VArray *spans = VA_new(0); HeatMap *heat_map = HeatMap_new(spans, 133); Span *span1 = Span_new( 0, 10, 1.0f); Span *span2 = Span_new( 10, 10, 1.0f); Span *span3 = Span_new( 5, 4, 1.0f); Span *span4 = Span_new(100, 10, 1.0f); Span *span5 = Span_new(150, 10, 1.0f); float big_boost = HeatMap_Calc_Proximity_Boost(heat_map, span1, span2); float eq_big_boost = HeatMap_Calc_Proximity_Boost(heat_map, span1, span3); float smaller_boost = HeatMap_Calc_Proximity_Boost(heat_map, span1, span4); float zero_boost = HeatMap_Calc_Proximity_Boost(heat_map, span1, span5); TEST_TRUE(runner, big_boost == eq_big_boost, "overlapping and abutting produce the same proximity boost"); TEST_TRUE(runner, big_boost > smaller_boost, "closer is better"); TEST_TRUE(runner, zero_boost == 0.0, "distance outside of window yields no prox boost"); DECREF(span1); DECREF(span2); DECREF(span3); DECREF(span4); DECREF(span5); DECREF(heat_map); DECREF(spans); }
String* Highlighter_Create_Excerpt_IMP(Highlighter *self, HitDoc *hit_doc) { HighlighterIVARS *const ivars = Highlighter_IVARS(self); String *field_val = (String*)HitDoc_Extract(hit_doc, ivars->field); String *retval; if (!field_val || !Obj_Is_A((Obj*)field_val, STRING)) { retval = NULL; } else if (!Str_Get_Size(field_val)) { // Empty string yields empty string. retval = Str_new_from_trusted_utf8("", 0); } else { DocVector *doc_vec = Searcher_Fetch_Doc_Vec(ivars->searcher, HitDoc_Get_Doc_ID(hit_doc)); VArray *maybe_spans = Compiler_Highlight_Spans(ivars->compiler, ivars->searcher, doc_vec, ivars->field); VArray *score_spans = maybe_spans ? maybe_spans : VA_new(0); VA_Sort(score_spans, NULL, NULL); HeatMap *heat_map = HeatMap_new(score_spans, (ivars->excerpt_length * 2) / 3); int32_t top; String *raw_excerpt = Highlighter_Raw_Excerpt(self, field_val, &top, heat_map); String *highlighted = Highlighter_Highlight_Excerpt(self, score_spans, raw_excerpt, top); DECREF(raw_excerpt); DECREF(heat_map); DECREF(score_spans); DECREF(doc_vec); retval = highlighted; } DECREF(field_val); return retval; }
static void test_flatten_spans(TestBatchRunner *runner) { VArray *spans = VA_new(8); VArray *wanted = VA_new(8); HeatMap *heat_map = HeatMap_new(spans, 133); VArray *flattened, *boosts; VA_Push(spans, (Obj*)Span_new(10, 10, 1.0f)); VA_Push(spans, (Obj*)Span_new(16, 14, 2.0f)); flattened = HeatMap_Flatten_Spans(heat_map, spans); VA_Push(wanted, (Obj*)Span_new(10, 6, 1.0f)); VA_Push(wanted, (Obj*)Span_new(16, 4, 3.0f)); VA_Push(wanted, (Obj*)Span_new(20, 10, 2.0f)); TEST_TRUE(runner, VA_Equals(flattened, (Obj*)wanted), "flatten two overlapping spans"); VA_Clear(wanted); boosts = HeatMap_Generate_Proximity_Boosts(heat_map, spans); VA_Push(wanted, (Obj*)Span_new(10, 20, 3.0f)); TEST_TRUE(runner, VA_Equals(boosts, (Obj*)wanted), "prox boosts for overlap"); VA_Clear(wanted); VA_Clear(spans); DECREF(boosts); DECREF(flattened); VA_Push(spans, (Obj*)Span_new(10, 10, 1.0f)); VA_Push(spans, (Obj*)Span_new(16, 14, 2.0f)); VA_Push(spans, (Obj*)Span_new(50, 1, 1.0f)); flattened = HeatMap_Flatten_Spans(heat_map, spans); VA_Push(wanted, (Obj*)Span_new(10, 6, 1.0f)); VA_Push(wanted, (Obj*)Span_new(16, 4, 3.0f)); VA_Push(wanted, (Obj*)Span_new(20, 10, 2.0f)); VA_Push(wanted, (Obj*)Span_new(50, 1, 1.0f)); TEST_TRUE(runner, VA_Equals(flattened, (Obj*)wanted), "flatten two overlapping spans, leave hole, then third span"); VA_Clear(wanted); boosts = HeatMap_Generate_Proximity_Boosts(heat_map, spans); TEST_TRUE(runner, VA_Get_Size(boosts) == 2 + 1, "boosts generated for each unique pair, since all were in range"); VA_Clear(spans); DECREF(boosts); DECREF(flattened); VA_Push(spans, (Obj*)Span_new(10, 10, 1.0f)); VA_Push(spans, (Obj*)Span_new(14, 4, 4.0f)); VA_Push(spans, (Obj*)Span_new(16, 14, 2.0f)); flattened = HeatMap_Flatten_Spans(heat_map, spans); VA_Push(wanted, (Obj*)Span_new(10, 4, 1.0f)); VA_Push(wanted, (Obj*)Span_new(14, 2, 5.0f)); VA_Push(wanted, (Obj*)Span_new(16, 2, 7.0f)); VA_Push(wanted, (Obj*)Span_new(18, 2, 3.0f)); VA_Push(wanted, (Obj*)Span_new(20, 10, 2.0f)); TEST_TRUE(runner, VA_Equals(flattened, (Obj*)wanted), "flatten three overlapping spans"); VA_Clear(wanted); boosts = HeatMap_Generate_Proximity_Boosts(heat_map, spans); TEST_TRUE(runner, VA_Get_Size(boosts) == 2 + 1, "boosts generated for each unique pair, since all were in range"); VA_Clear(spans); DECREF(boosts); DECREF(flattened); VA_Push(spans, (Obj*)Span_new(10, 10, 1.0f)); VA_Push(spans, (Obj*)Span_new(16, 14, 4.0f)); VA_Push(spans, (Obj*)Span_new(16, 14, 2.0f)); VA_Push(spans, (Obj*)Span_new(30, 10, 10.0f)); flattened = HeatMap_Flatten_Spans(heat_map, spans); VA_Push(wanted, (Obj*)Span_new(10, 6, 1.0f)); VA_Push(wanted, (Obj*)Span_new(16, 4, 7.0f)); VA_Push(wanted, (Obj*)Span_new(20, 10, 6.0f)); VA_Push(wanted, (Obj*)Span_new(30, 10, 10.0f)); TEST_TRUE(runner, VA_Equals(flattened, (Obj*)wanted), "flatten 4 spans, middle two have identical range"); VA_Clear(wanted); boosts = HeatMap_Generate_Proximity_Boosts(heat_map, spans); TEST_TRUE(runner, VA_Get_Size(boosts) == 3 + 2 + 1, "boosts generated for each unique pair, since all were in range"); VA_Clear(spans); DECREF(boosts); DECREF(flattened); VA_Push(spans, (Obj*)Span_new( 10, 10, 1.0f)); VA_Push(spans, (Obj*)Span_new( 16, 4, 4.0f)); VA_Push(spans, (Obj*)Span_new( 16, 14, 2.0f)); VA_Push(spans, (Obj*)Span_new(230, 10, 10.0f)); flattened = HeatMap_Flatten_Spans(heat_map, spans); VA_Push(wanted, (Obj*)Span_new( 10, 6, 1.0f)); VA_Push(wanted, (Obj*)Span_new( 16, 4, 7.0f)); VA_Push(wanted, (Obj*)Span_new( 20, 10, 2.0f)); VA_Push(wanted, (Obj*)Span_new(230, 10, 10.0f)); TEST_TRUE(runner, VA_Equals(flattened, (Obj*)wanted), "flatten 4 spans, middle two have identical starts but different ends"); VA_Clear(wanted); boosts = HeatMap_Generate_Proximity_Boosts(heat_map, spans); TEST_TRUE(runner, VA_Get_Size(boosts) == 2 + 1, "boosts not generated for out of range span"); VA_Clear(spans); DECREF(boosts); DECREF(flattened); DECREF(heat_map); DECREF(wanted); DECREF(spans); }
static void test_Raw_Excerpt(TestBatchRunner *runner, Searcher *searcher, Obj *query) { String *content = (String*)SSTR_WRAP_UTF8("content", 7); Highlighter *highlighter = Highlighter_new(searcher, query, content, 6); int32_t top; String *raw_excerpt; String *field_val = (String *)SSTR_WRAP_UTF8("Ook. Urk. Ick. ", 18); Vector *spans = Vec_new(1); Vec_Push(spans, (Obj*)Span_new(0, 18, 1.0f)); HeatMap *heat_map = HeatMap_new(spans, 133); DECREF(spans); raw_excerpt = Highlighter_Raw_Excerpt(highlighter, field_val, &top, heat_map); TEST_TRUE(runner, Str_Equals_Utf8(raw_excerpt, "Ook.", 4), "Raw_Excerpt at top %s", Str_Get_Ptr8(raw_excerpt)); TEST_TRUE(runner, top == 0, "top is 0"); DECREF(raw_excerpt); DECREF(heat_map); spans = Vec_new(1); Vec_Push(spans, (Obj*)Span_new(6, 12, 1.0f)); heat_map = HeatMap_new(spans, 133); DECREF(spans); raw_excerpt = Highlighter_Raw_Excerpt(highlighter, field_val, &top, heat_map); TEST_TRUE(runner, Str_Equals_Utf8(raw_excerpt, "Urk.", 4), "Raw_Excerpt in middle, with 2 bounds"); TEST_TRUE(runner, top == 6, "top in the middle modified by Raw_Excerpt"); DECREF(raw_excerpt); DECREF(heat_map); field_val = (String *)SSTR_WRAP_UTF8("Ook urk ick i.", 14); spans = Vec_new(1); Vec_Push(spans, (Obj*)Span_new(12, 1, 1.0f)); heat_map = HeatMap_new(spans, 133); DECREF(spans); raw_excerpt = Highlighter_Raw_Excerpt(highlighter, field_val, &top, heat_map); TEST_TRUE(runner, Str_Equals_Utf8(raw_excerpt, ELLIPSIS " i.", 6), "Ellipsis at top"); TEST_TRUE(runner, top == 10, "top correct when leading ellipsis inserted"); DECREF(heat_map); DECREF(raw_excerpt); field_val = (String *)SSTR_WRAP_UTF8("Urk. Iz no good.", 17); spans = Vec_new(1); Vec_Push(spans, (Obj*)Span_new(6, 2, 1.0f)); heat_map = HeatMap_new(spans, 133); DECREF(spans); raw_excerpt = Highlighter_Raw_Excerpt(highlighter, field_val, &top, heat_map); TEST_TRUE(runner, Str_Equals_Utf8(raw_excerpt, "Iz no" ELLIPSIS, 8), "Ellipsis at end"); TEST_TRUE(runner, top == 6, "top trimmed"); DECREF(heat_map); DECREF(raw_excerpt); // Words longer than excerpt len field_val = (String *)SSTR_WRAP_UTF8("abc/def/ghi/jkl/mno", 19); spans = Vec_new(1); Vec_Push(spans, (Obj*)Span_new(0, 3, 1.0f)); heat_map = HeatMap_new(spans, 133); DECREF(spans); raw_excerpt = Highlighter_Raw_Excerpt(highlighter, field_val, &top, heat_map); TEST_TRUE(runner, Str_Equals_Utf8(raw_excerpt, "abc/d" ELLIPSIS, 8), "Long word at top"); DECREF(heat_map); DECREF(raw_excerpt); spans = Vec_new(1); Vec_Push(spans, (Obj*)Span_new(8, 3, 1.0f)); heat_map = HeatMap_new(spans, 133); DECREF(spans); raw_excerpt = Highlighter_Raw_Excerpt(highlighter, field_val, &top, heat_map); TEST_TRUE(runner, Str_Equals_Utf8(raw_excerpt, ELLIPSIS " f/g" ELLIPSIS, 10), "Long word in middle"); DECREF(heat_map); DECREF(raw_excerpt); DECREF(highlighter); }