Merge pull request #302 from nidhi-singh02/fix/github-repo-canonicalization
fix: Canonicalize ambiguous GitHub repo resolution for product comparisons
This commit is contained in:
@@ -260,6 +260,51 @@ class CliV3Tests(unittest.TestCase):
|
||||
fake_progress.show_promo.assert_called_once_with("both", diag=diag)
|
||||
self.assertIn("# rendered", stdout.getvalue())
|
||||
|
||||
def test_main_canonicalizes_explicit_github_repo_flags(self):
|
||||
report = self.make_report()
|
||||
diag = {
|
||||
"available_sources": ["grounding"],
|
||||
"providers": {"google": True, "openai": False, "xai": False},
|
||||
"x_backend": None,
|
||||
"bird_installed": True,
|
||||
"bird_authenticated": False,
|
||||
"bird_username": None,
|
||||
"native_web_backend": "brave",
|
||||
}
|
||||
with mock.patch.object(cli.env, "get_config", return_value={}), \
|
||||
mock.patch.object(cli.pipeline, "diagnose", return_value=diag), \
|
||||
mock.patch.object(cli.pipeline, "run", return_value=report) as run_mock, \
|
||||
mock.patch.object(cli, "emit_output", return_value="# rendered"), \
|
||||
mock.patch.object(sys, "argv", [
|
||||
"last30days.py",
|
||||
"claude",
|
||||
"code",
|
||||
"vs",
|
||||
"codex",
|
||||
"--github-repo",
|
||||
"openai/codex,anthropics/claude-code-action",
|
||||
]):
|
||||
stdout = io.StringIO()
|
||||
stderr = io.StringIO()
|
||||
with redirect_stdout(stdout), redirect_stderr(stderr):
|
||||
rc = cli.main()
|
||||
self.assertEqual(0, rc)
|
||||
# In vs-mode main + competitors run in parallel via ThreadPoolExecutor,
|
||||
# so the order of pipeline.run invocations is non-deterministic. Find
|
||||
# the main runner's call by predicate on the canonicalized github_repos
|
||||
# rather than by index.
|
||||
expected_repos = ["openai/codex", "anthropics/claude-code"]
|
||||
main_call = next(
|
||||
(c for c in run_mock.call_args_list if c.kwargs.get("github_repos") == expected_repos),
|
||||
None,
|
||||
)
|
||||
self.assertIsNotNone(
|
||||
main_call,
|
||||
f"No pipeline.run call had github_repos={expected_repos}; "
|
||||
f"saw {[c.kwargs.get('github_repos') for c in run_mock.call_args_list]}",
|
||||
)
|
||||
self.assertIn("[GitHub] Canonicalized repos:", stderr.getvalue())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -109,6 +109,24 @@ class TestBuildContextSummary(unittest.TestCase):
|
||||
self.assertEqual(resolve._build_context_summary(items), "")
|
||||
|
||||
|
||||
class TestCanonicalizeGithubRepos(unittest.TestCase):
|
||||
def test_rewrites_integration_repo_to_canonical_product(self):
|
||||
repos = ["openai/codex", "anthropics/claude-code-action"]
|
||||
result = resolve.canonicalize_github_repos("claude code vs codex", repos, cap=None)
|
||||
self.assertEqual(result, ["openai/codex", "anthropics/claude-code"])
|
||||
|
||||
def test_preserves_action_repo_when_topic_intends_action(self):
|
||||
repos = ["anthropics/claude-code-action", "openai/codex"]
|
||||
result = resolve.canonicalize_github_repos("claude code action setup", repos, cap=None)
|
||||
self.assertIn("anthropics/claude-code-action", result)
|
||||
self.assertNotIn("anthropics/claude-code", result)
|
||||
|
||||
def test_dedupes_case_insensitive_after_canonicalization(self):
|
||||
repos = ["Anthropics/Claude-Code-Action", "anthropics/claude-code"]
|
||||
result = resolve.canonicalize_github_repos("claude code", repos, cap=None)
|
||||
self.assertEqual(result, ["Anthropics/Claude-Code"])
|
||||
|
||||
|
||||
class TestAutoResolve(unittest.TestCase):
|
||||
def test_no_backend_returns_empty(self):
|
||||
result = resolve.auto_resolve("test topic", {})
|
||||
|
||||
Reference in New Issue
Block a user