@@ -28,6 +28,61 @@ def test_init(self, temp_dir):
2828 assert analyzer .batch_size == 1000
2929 assert analyzer .exclude_paths == []
3030
31+ def test_ticket_detection_config_is_forwarded_to_extractor (self , temp_dir ):
32+ """Custom ticket_detection patterns must reach the analyzer's TicketExtractor.
33+
34+ Regression test: GitAnalyzer's in-memory ticket re-extraction (the
35+ "Analyzing commits for tickets" pass) used to silently fall back to the
36+ hard-coded default patterns because ticket_detection_config was never
37+ forwarded to build_ticket_extractor(). That caused user-supplied
38+ ``analysis.ticket_detection.patterns`` (e.g. an Azure DevOps ``AB#NNNN``
39+ regex) to be ignored during analyze, while GitDataFetcher honored them
40+ at fetch time -- producing inconsistent ticket-coverage numbers between
41+ a fresh fetch and a cached re-run.
42+ """
43+ from gitflow_analytics .config .schema import TicketDetectionConfig
44+
45+ cache = GitAnalysisCache (temp_dir / ".gitflow-cache" )
46+
47+ # Custom pattern that overrides the github default (#(\d+)) and matches
48+ # only a distinctive token that the default regex cannot match.
49+ custom_pattern = r"\bABCD-(\d+)\b"
50+ td_cfg = TicketDetectionConfig (
51+ patterns = {"github" : custom_pattern },
52+ exclude_patterns = [],
53+ )
54+
55+ analyzer = GitAnalyzer (cache , ticket_detection_config = td_cfg )
56+
57+ # The github pattern in the analyzer's extractor must be the custom one.
58+ github_patterns = [
59+ p .pattern for p in analyzer .ticket_extractor .compiled_patterns .get ("github" , [])
60+ ]
61+ assert github_patterns == [
62+ custom_pattern
63+ ], f"Expected custom github pattern to be forwarded, got: { github_patterns } "
64+
65+ # Behavior: the custom pattern matches its token, the old default does not.
66+ msg = "Implements ABCD-42 across the codebase"
67+ ticket_ids = [t ["id" ] for t in analyzer .ticket_extractor .extract_from_text (msg )]
68+ assert "42" in ticket_ids
69+
70+ # And the default github "#(\\d+)" no longer applies, so a bare "#99"
71+ # in the message is NOT picked up under the custom github pattern.
72+ msg2 = "See #99 for context"
73+ ticket_ids2 = [t ["id" ] for t in analyzer .ticket_extractor .extract_from_text (msg2 )]
74+ assert "99" not in ticket_ids2
75+
76+ def test_ticket_detection_config_default_is_backward_compatible (self , temp_dir ):
77+ """Without ticket_detection_config the analyzer behaves as before."""
78+ cache = GitAnalysisCache (temp_dir / ".gitflow-cache" )
79+ analyzer = GitAnalyzer (cache )
80+
81+ # The default github pattern (#(\\d+)) should still match.
82+ msg = "Closes #1234 final cleanup"
83+ ticket_ids = [t ["id" ] for t in analyzer .ticket_extractor .extract_from_text (msg )]
84+ assert "1234" in ticket_ids
85+
3186 @patch ("gitflow_analytics.core.analyzer.Repo" )
3287 def test_analyze_repository_basic (self , mock_repo_class , temp_dir ):
3388 """Test basic repository analysis functionality."""
0 commit comments