diff --git a/tests/test_generate_popular_node_signatures.py b/tests/test_generate_popular_node_signatures.py index b27917a..25d76f8 100644 --- a/tests/test_generate_popular_node_signatures.py +++ b/tests/test_generate_popular_node_signatures.py @@ -5684,6 +5684,32 @@ class ManagerIngestionTests(unittest.TestCase): self.assertEqual(["second", "first", "third"], [entry["id"] for entry in ranked]) self.assertEqual([1, 2, 3], [entry["rank"] for entry in ranked]) + def test_rank_packs_prefers_higher_search_ranking_when_downloads_and_stars_tie(self): + packs = [ + { + "id": "low-search", + "title": "Low Search", + "repository": "https://github.com/example/low-search", + "downloads": 100, + "github_stars": 5, + "metrics": {"search_ranking": 1}, + "manager_order": 0, + }, + { + "id": "high-search", + "title": "High Search", + "repository": "https://github.com/example/high-search", + "downloads": 100, + "github_stars": 5, + "search_ranking": 10, + "manager_order": 1, + }, + ] + + ranked = rank_packs(packs) + + self.assertEqual(["high-search", "low-search"], [pack["id"] for pack in ranked]) + class RepoCacheTests(unittest.TestCase): def test_default_cache_dir_is_under_system_temp_dir(self): diff --git a/tools/generate_popular_node_signatures.py b/tools/generate_popular_node_signatures.py index 8c3b586..3788ac7 100644 --- a/tools/generate_popular_node_signatures.py +++ b/tools/generate_popular_node_signatures.py @@ -251,22 +251,22 @@ def _metric_max(metrics, names): return max(values, default=0) -def _metric_min_float(metrics, names): +def _metric_max_float(metrics, names): values = [] for name in names: value = _coerce_float(metrics.get(name)) if value is not None: values.append(value) - return min(values) if values else None + return max(values) if values else None -def _metric_min_float_from_sources(sources, names): +def _metric_max_float_from_sources(sources, names): values = [] for source in sources: - value = _metric_min_float(source, names) + value = _metric_max_float(source, names) if value is not None: values.append(value) - return min(values) if values else None + return max(values) if values else None def _pack_id_from_repository(repository): @@ -312,7 +312,7 @@ def _rank_sort_key(pack): metric_sources = (pack.get("metrics", {}), pack) downloads = max(_metric_max(source, ("downloads", "download_count")) for source in metric_sources) stars = max(_metric_max(source, ("stars", "github_stars", "stargazers_count")) for source in metric_sources) - search_ranking = _metric_min_float_from_sources( + search_ranking = _metric_max_float_from_sources( metric_sources, ("search_ranking", "search_rank", "search_order"), ) @@ -321,7 +321,7 @@ def _rank_sort_key(pack): -downloads, -stars, 1 if search_ranking is None else 0, - search_ranking if search_ranking is not None else 0.0, + -search_ranking if search_ranking is not None else 0.0, manager_order, str(pack.get("title", "")).lower(), str(pack.get("id", "")),