返回 last30days-skill
test_rerank_fun.py
根目录 / tests / test_rerank_fun.py
1 """Tests for the fun judge heuristic fallback in rerank.py."""
2
3 import pytest
4
5 from lib import schema
6 from lib.rerank import _apply_single_fun_fallback, _extract_comment_text
7
8
9 def _make_candidate(
10 title: str = "Some Title",
11 snippet: str = "",
12 engagement: float | None = 0.0,
13 top_comments: list[dict] | None = None,
14 ) -> schema.Candidate:
15 """Build a minimal Candidate with optional source_items carrying top_comments."""
16 source_items = []
17 if top_comments is not None:
18 source_items.append(
19 schema.SourceItem(
20 item_id="si-1",
21 source="reddit",
22 title=title,
23 body="",
24 url="https://reddit.com/r/test/1",
25 metadata={"top_comments": top_comments},
26 )
27 )
28 return schema.Candidate(
29 candidate_id="c-1",
30 item_id="i-1",
31 source="reddit",
32 title=title,
33 url="https://reddit.com/r/test/1",
34 snippet=snippet,
35 subquery_labels=["q1"],
36 native_ranks={"reddit": 1},
37 local_relevance=0.5,
38 freshness=50,
39 engagement=engagement,
40 source_quality=0.5,
41 rrf_score=0.01,
42 source_items=source_items,
43 )
44
45
46 class TestFunFallbackCommentText:
47 """Heuristic fallback reads comment text, not just title+snippet."""
48
49 def test_comment_with_lmao_gets_marker_bonus(self):
50 """A candidate with 'lmao' in a top_comment should get the marker bonus."""
51 candidate = _make_candidate(
52 title="Boring press conference recap",
53 snippet="Coach talked about the game plan.",
54 top_comments=[{"body": "lmao this is gold"}],
55 )
56 _apply_single_fun_fallback(candidate)
57 # marker_bonus = 10, should be reflected in fun_score
58 assert candidate.fun_score is not None
59 assert candidate.fun_score >= 10.0
60 assert candidate.fun_explanation == "heuristic-fallback"
61
62 def test_short_punchy_comment_higher_shortness(self):
63 """A candidate with a short punchy comment should score higher shortness
64 bonus compared to one with a very long title and snippet."""
65 short_candidate = _make_candidate(
66 title="Hot dogs",
67 snippet="",
68 top_comments=[{"body": "bro what"}],
69 )
70 long_candidate = _make_candidate(
71 title="A very long and detailed analysis of the upcoming season with comprehensive breakdown of every roster move and coaching decision that happened over the past thirty days",
72 snippet="This extensive report covers all aspects of the team performance including advanced metrics and historical comparisons going back several decades.",
73 top_comments=[{"body": "bro what"}],
74 )
75 _apply_single_fun_fallback(short_candidate)
76 _apply_single_fun_fallback(long_candidate)
77 # Both get marker bonus from "bro", but short one gets higher shortness bonus
78 assert short_candidate.fun_score > long_candidate.fun_score
79
80 def test_no_comments_falls_back_to_title_snippet(self):
81 """A candidate with no source_items/comments still scores based on title+snippet."""
82 candidate = _make_candidate(
83 title="This is hilarious content",
84 snippet="Very funny stuff",
85 top_comments=None, # no source_items at all
86 )
87 _apply_single_fun_fallback(candidate)
88 assert candidate.fun_score is not None
89 assert candidate.fun_score >= 10.0 # marker bonus from "hilarious"
90 assert candidate.fun_explanation == "heuristic-fallback"
91
92 def test_empty_comment_bodies_no_crash(self):
93 """Candidates with empty comment bodies should not crash."""
94 candidate = _make_candidate(
95 title="Normal title",
96 snippet="Normal snippet",
97 top_comments=[
98 {"body": ""},
99 {"body": None},
100 {},
101 {"body": "actual comment"},
102 ],
103 )
104 _apply_single_fun_fallback(candidate)
105 assert candidate.fun_score is not None
106 assert candidate.fun_explanation == "heuristic-fallback"
107
108
109 class TestExtractCommentText:
110 """Verify _extract_comment_text handles edge cases."""
111
112 def test_extracts_from_top_comments(self):
113 candidate = _make_candidate(
114 top_comments=[{"body": "first comment"}, {"body": "second comment"}],
115 )
116 text = _extract_comment_text(candidate)
117 assert "first comment" in text
118 assert "second comment" in text
119
120 def test_empty_source_items(self):
121 candidate = _make_candidate(top_comments=None)
122 text = _extract_comment_text(candidate)
123 assert text == ""
124
124 lines PYTHON