Skip to content

Commit bfcab1e

Browse files
committed
test: add pattern repository resolution coverage
1 parent c7e51f3 commit bfcab1e

File tree

3 files changed

+96
-3
lines changed

3 files changed

+96
-3
lines changed

TODO.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ This roadmap is derived from deep research into Greptile's public docs, blog, MC
8282
46. [ ] Support document-backed context ingestion for design docs, RFCs, and runbooks.
8383
47. [ ] Add explicit "intent mismatch" review checks comparing PR changes to ticket acceptance criteria.
8484
48. [ ] Add review artifacts that show which external context sources influenced a finding.
85-
49. [ ] Add tests for pattern repository resolution across local paths, Git URLs, and broken sources.
85+
49. [x] Add tests for pattern repository resolution across local paths, Git URLs, and broken sources.
8686
50. [ ] Add analytics on which context sources actually improve acceptance and fix rates.
8787

8888
## 6. Review UX and Workflow Integration
@@ -174,4 +174,5 @@ This roadmap is derived from deep research into Greptile's public docs, blog, MC
174174
- [x] Add Analytics JSON/CSV exports covering review quality, lifecycle, and reinforcement metrics.
175175
- [x] Add learned-rules, attention-gap, and rejected-pattern analytics API endpoints for automation consumers.
176176
- [x] Add a PR re-review API that reuses stored review metadata and posting policy.
177+
- [x] Add pattern repository resolution coverage for repo-local directories, Git sources, and broken-source skips.
177178
- [ ] Commit and push each validated checkpoint before moving to the next epic.

src/review/context_helpers/pattern_repositories.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ pub use run::resolve_pattern_repositories;
1616

1717
#[cfg(test)]
1818
mod tests {
19+
use std::cell::RefCell;
20+
21+
use crate::config;
22+
1923
use super::git::{is_git_source, is_safe_git_url};
24+
use super::run::resolve_pattern_repositories_with;
2025

2126
#[test]
2227
fn test_is_git_source_https() {
@@ -81,4 +86,80 @@ mod tests {
8186
fn test_is_safe_git_url_rejects_http_without_git_suffix() {
8287
assert!(!is_safe_git_url("http://example.com/repo"));
8388
}
89+
90+
#[test]
91+
fn test_resolve_pattern_repositories_accepts_repo_relative_local_paths() {
92+
let tempdir = tempfile::tempdir().unwrap();
93+
let repo_root = tempdir.path();
94+
let local_repo = repo_root.join("patterns/local-rules");
95+
std::fs::create_dir_all(&local_repo).unwrap();
96+
97+
let mut config = config::Config::default();
98+
config.pattern_repositories = vec![config::PatternRepositoryConfig {
99+
source: "patterns/local-rules".to_string(),
100+
..Default::default()
101+
}];
102+
103+
let resolved = resolve_pattern_repositories_with(&config, repo_root, |_| None);
104+
105+
assert_eq!(resolved.len(), 1);
106+
assert_eq!(
107+
resolved.get("patterns/local-rules"),
108+
Some(&local_repo.canonicalize().unwrap())
109+
);
110+
}
111+
112+
#[test]
113+
fn test_resolve_pattern_repositories_accepts_git_sources_via_checkout_helper() {
114+
let tempdir = tempfile::tempdir().unwrap();
115+
let repo_root = tempdir.path();
116+
let checkout_path = repo_root.join("cloned-rules");
117+
std::fs::create_dir_all(&checkout_path).unwrap();
118+
119+
let mut config = config::Config::default();
120+
let source = "https://github.com/example/rules.git".to_string();
121+
config.pattern_repositories = vec![config::PatternRepositoryConfig {
122+
source: source.clone(),
123+
..Default::default()
124+
}];
125+
126+
let checkout_calls = RefCell::new(Vec::new());
127+
let resolved = resolve_pattern_repositories_with(&config, repo_root, |candidate| {
128+
checkout_calls.borrow_mut().push(candidate.to_string());
129+
Some(checkout_path.clone())
130+
});
131+
132+
assert_eq!(checkout_calls.into_inner(), vec![source.clone()]);
133+
assert_eq!(resolved.get(&source), Some(&checkout_path));
134+
}
135+
136+
#[test]
137+
fn test_resolve_pattern_repositories_skips_broken_sources() {
138+
let tempdir = tempfile::tempdir().unwrap();
139+
let repo_root = tempdir.path();
140+
141+
let mut config = config::Config::default();
142+
config.pattern_repositories = vec![
143+
config::PatternRepositoryConfig {
144+
source: "missing/local-rules".to_string(),
145+
..Default::default()
146+
},
147+
config::PatternRepositoryConfig {
148+
source: "https://github.com/example/broken.git".to_string(),
149+
..Default::default()
150+
},
151+
];
152+
153+
let checkout_calls = RefCell::new(Vec::new());
154+
let resolved = resolve_pattern_repositories_with(&config, repo_root, |candidate| {
155+
checkout_calls.borrow_mut().push(candidate.to_string());
156+
None
157+
});
158+
159+
assert!(resolved.is_empty());
160+
assert_eq!(
161+
checkout_calls.into_inner(),
162+
vec!["https://github.com/example/broken.git".to_string()]
163+
);
164+
}
84165
}

src/review/context_helpers/pattern_repositories/run.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::path::Path;
1+
use std::path::{Path, PathBuf};
22

33
use tracing::warn;
44

@@ -13,6 +13,17 @@ pub fn resolve_pattern_repositories(
1313
config: &config::Config,
1414
repo_root: &Path,
1515
) -> PatternRepositoryMap {
16+
resolve_pattern_repositories_with(config, repo_root, prepare_pattern_repository_checkout)
17+
}
18+
19+
pub(super) fn resolve_pattern_repositories_with<F>(
20+
config: &config::Config,
21+
repo_root: &Path,
22+
mut prepare_checkout: F,
23+
) -> PatternRepositoryMap
24+
where
25+
F: FnMut(&str) -> Option<PathBuf>,
26+
{
1627
let mut resolved = PatternRepositoryMap::new();
1728
if config.pattern_repositories.is_empty() {
1829
return resolved;
@@ -29,7 +40,7 @@ pub fn resolve_pattern_repositories(
2940
}
3041

3142
if is_git_source(&repo.source) {
32-
if let Some(path) = prepare_pattern_repository_checkout(&repo.source) {
43+
if let Some(path) = prepare_checkout(&repo.source) {
3344
resolved.insert(repo.source.clone(), path);
3445
continue;
3546
}

0 commit comments

Comments
 (0)