tests: centralize script path setup in conftest.py
Add a pytest-discovered tests/conftest.py for the last30days scripts path and remove duplicate per-file sys.path.insert boilerplate from tests. Normalize affected imports to rely on the shared scripts path and remove the now-unneeded E402 suppressions.
This commit is contained in:
+16
-22
@@ -5,11 +5,7 @@ tests exercise transitively but don't assert on directly. A regression in
|
||||
any of these functions would silently degrade output quality.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "skills" / "last30days" / "scripts"))
|
||||
|
||||
from lib import planner, rerank, render, signals, schema
|
||||
|
||||
@@ -34,11 +30,11 @@ def _candidate(source: str = "reddit", **kwargs) -> schema.Candidate:
|
||||
defaults.update(kwargs)
|
||||
return schema.Candidate(**defaults)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# rerank._fallback_tuple
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestFallbackTuple(unittest.TestCase):
|
||||
|
||||
def test_returns_score_and_explanation(self):
|
||||
@@ -58,11 +54,11 @@ class TestFallbackTuple(unittest.TestCase):
|
||||
low = _candidate(local_relevance=0.1, freshness=50, source_quality=0.7)
|
||||
self.assertGreater(rerank._fallback_tuple(high)[0], rerank._fallback_tuple(low)[0])
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# rerank._normalized_rrf
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestNormalizedRrf(unittest.TestCase):
|
||||
|
||||
def test_zero_input(self):
|
||||
@@ -77,11 +73,11 @@ class TestNormalizedRrf(unittest.TestCase):
|
||||
result = rerank._normalized_rrf(1.0)
|
||||
self.assertLessEqual(result, 100.0)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# render._assess_data_freshness
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestAssessDataFreshness(unittest.TestCase):
|
||||
|
||||
def _report(self, items_by_source: dict) -> schema.Report:
|
||||
@@ -120,11 +116,11 @@ class TestAssessDataFreshness(unittest.TestCase):
|
||||
result = render._assess_data_freshness(report)
|
||||
self.assertIsNone(result)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# render._format_date
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestFormatDate(unittest.TestCase):
|
||||
|
||||
def test_high_confidence_clean(self):
|
||||
@@ -138,11 +134,11 @@ class TestFormatDate(unittest.TestCase):
|
||||
def test_none_item(self):
|
||||
self.assertIn("unknown", render._format_date(None).lower())
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# render._format_actor
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestFormatActor(unittest.TestCase):
|
||||
|
||||
def test_reddit_subreddit(self):
|
||||
@@ -157,11 +153,11 @@ class TestFormatActor(unittest.TestCase):
|
||||
item = _item(source="youtube", author="Fireship")
|
||||
self.assertEqual(render._format_actor(item), "Fireship")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# render._format_engagement
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestFormatEngagement(unittest.TestCase):
|
||||
|
||||
def test_reddit_format(self):
|
||||
@@ -174,11 +170,11 @@ class TestFormatEngagement(unittest.TestCase):
|
||||
item = _item(engagement={})
|
||||
self.assertIsNone(render._format_engagement(item))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# render._format_corroboration
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestFormatCorroboration(unittest.TestCase):
|
||||
|
||||
def test_multi_source(self):
|
||||
@@ -191,11 +187,11 @@ class TestFormatCorroboration(unittest.TestCase):
|
||||
c = _candidate(sources=["reddit"])
|
||||
self.assertIsNone(render._format_corroboration(c))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# render._format_explanation
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestFormatExplanation(unittest.TestCase):
|
||||
|
||||
def test_hides_fallback_sentinel(self):
|
||||
@@ -206,11 +202,11 @@ class TestFormatExplanation(unittest.TestCase):
|
||||
c = _candidate(explanation="Directly compares frameworks")
|
||||
self.assertEqual(render._format_explanation(c), "Directly compares frameworks")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# render._fmt_pairs and _format_number
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestFmtPairs(unittest.TestCase):
|
||||
|
||||
def test_basic(self):
|
||||
@@ -231,11 +227,11 @@ class TestFormatNumber(unittest.TestCase):
|
||||
def test_small_integer(self):
|
||||
self.assertEqual(render._format_number(42), "42")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# render._truncate
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestTruncate(unittest.TestCase):
|
||||
|
||||
def test_short_text(self):
|
||||
@@ -246,11 +242,11 @@ class TestTruncate(unittest.TestCase):
|
||||
self.assertTrue(result.endswith("..."))
|
||||
self.assertEqual(len(result), 50)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# planner._normalize_subquery_weights
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestNormalizeSubqueryWeights(unittest.TestCase):
|
||||
|
||||
def test_sums_to_one(self):
|
||||
@@ -270,11 +266,11 @@ class TestNormalizeSubqueryWeights(unittest.TestCase):
|
||||
normed = planner._normalize_subquery_weights(sqs)
|
||||
self.assertAlmostEqual(normed[0].weight / normed[1].weight, 4.0)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# planner._normalize_weights
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestNormalizeWeights(unittest.TestCase):
|
||||
|
||||
def test_sums_to_one(self):
|
||||
@@ -285,11 +281,11 @@ class TestNormalizeWeights(unittest.TestCase):
|
||||
result = planner._normalize_weights({"a": 2.0, "b": -1.0})
|
||||
self.assertAlmostEqual(result["b"], 0.0)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# planner._trim_subqueries_for_depth
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestTrimSubqueriesForDepth(unittest.TestCase):
|
||||
|
||||
def _sq(self, label: str = "primary", sources: list[str] = None) -> schema.SubQuery:
|
||||
@@ -318,11 +314,11 @@ class TestTrimSubqueriesForDepth(unittest.TestCase):
|
||||
# Deep comparison should also use capability expansion, not trim
|
||||
self.assertGreaterEqual(len(result[0].sources), 4)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# signals.annotate_stream
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestAnnotateStream(unittest.TestCase):
|
||||
|
||||
def test_attaches_metadata(self):
|
||||
@@ -345,11 +341,11 @@ class TestAnnotateStream(unittest.TestCase):
|
||||
annotated = signals.annotate_stream(items, "test query", "balanced_recent")
|
||||
self.assertEqual(annotated[0].item_id, "high")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# signals.prune_low_relevance
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestPruneLowRelevance(unittest.TestCase):
|
||||
|
||||
def test_removes_low_relevance_items(self):
|
||||
@@ -369,11 +365,11 @@ class TestPruneLowRelevance(unittest.TestCase):
|
||||
result = signals.prune_low_relevance(items, minimum=0.1)
|
||||
self.assertEqual(len(result), 1) # fallback keeps all
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Bug fixes found by PR review agents
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestDaysAgoZeroFalsy(unittest.TestCase):
|
||||
"""render._assess_data_freshness must not treat days_ago=0 as falsy."""
|
||||
|
||||
@@ -455,7 +451,6 @@ class TestGenericEngagementFormatter(unittest.TestCase):
|
||||
# Should contain numeric values, not dict keys as numbers
|
||||
self.assertIn("500", result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -521,7 +516,6 @@ class TestDefaultDepthDoesNotCapSources(unittest.TestCase):
|
||||
self.assertLessEqual(len(plan.subqueries[0].sources), 3)
|
||||
|
||||
|
||||
|
||||
class TestRerankWeightBalance(unittest.TestCase):
|
||||
"""Reranker weight must dominate over RRF when candidates have divergent quality."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user