use std::fs;
use std::path::PathBuf;
use std::time::Duration;
use fff_search::file_picker::{FFFMode, FilePicker};
use fff_search::grep::{GrepMode, GrepSearchOptions, parse_grep_query};
use fff_search::{FilePickerOptions, SharedFilePicker, SharedFrecency};
const MARKER: &str = "__jai_runtime_init";
fn fixtures_dir() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/binaries")
}
fn plain_opts() -> GrepSearchOptions {
GrepSearchOptions {
max_file_size: 10 * 1024 * 1024,
max_matches_per_file: 200,
smart_case: true,
file_offset: 0,
page_limit: 200,
mode: GrepMode::PlainText,
time_budget_ms: 0,
before_context: 0,
after_context: 0,
classify_definitions: false,
trim_whitespace: false,
abort_signal: None,
}
}
#[test]
fn real_binary_fixtures_are_detected_and_excluded_from_grep() {
let fixtures = fixtures_dir();
let large = fixtures.join("codex_view"); let small = fixtures.join("codex_view.codex");
assert!(
large.exists() && small.exists(),
"missing binary fixtures in {}",
fixtures.display()
);
let large_bytes = fs::read(&large).unwrap();
let small_bytes = fs::read(&small).unwrap();
assert!(
contains_subslice(&large_bytes, MARKER.as_bytes()),
"fixture codex_view no longer contains the marker {MARKER:?}"
);
assert!(
contains_subslice(&small_bytes, MARKER.as_bytes()),
"fixture codex_view.codex no longer contains the marker {MARKER:?}"
);
assert!(
large_bytes.len() > 2 * 1024 * 1024,
"codex_view must exceed the 2 MB non-indexable threshold"
);
assert!(
small_bytes.len() < 2 * 1024 * 1024,
"codex_view.codex must stay under the 2 MB bigram cap"
);
let tmp = tempfile::TempDir::new().unwrap();
let base = tmp.path();
fs::copy(&large, base.join("codex_view")).unwrap();
fs::copy(&small, base.join("codex_view.codex")).unwrap();
fs::write(
base.join("marker.txt"),
format!("the only legitimate hit lives here: {MARKER}\n"),
)
.unwrap();
let shared_picker = SharedFilePicker::default();
let shared_frecency = SharedFrecency::default();
FilePicker::new_with_shared_state(
shared_picker.clone(),
shared_frecency.clone(),
FilePickerOptions {
base_path: base.to_string_lossy().to_string(),
enable_mmap_cache: false,
enable_content_indexing: true,
mode: FFFMode::Neovim,
watch: false,
..Default::default()
},
)
.expect("failed to create FilePicker");
shared_picker.wait_for_indexing_complete(Duration::from_secs(5));
let guard = shared_picker.read().unwrap();
let picker = guard.as_ref().unwrap();
for name in ["codex_view", "codex_view.codex"] {
let flagged = picker
.get_files()
.iter()
.any(|f| f.relative_path(picker).ends_with(name) && f.is_binary());
assert!(flagged, "{name} must be flagged is_binary");
}
let parsed = parse_grep_query(MARKER);
let result = picker.grep(&parsed, &plain_opts());
let matched: Vec<String> = result
.files
.iter()
.map(|f| f.relative_path(picker))
.collect();
assert_eq!(
result.files.len(),
1,
"exactly one file should match {MARKER:?}, got: {matched:?}"
);
assert!(
matched[0].ends_with("marker.txt"),
"the only match must be marker.txt, got {:?}",
matched[0]
);
}
fn contains_subslice(haystack: &[u8], needle: &[u8]) -> bool {
if needle.is_empty() || haystack.len() < needle.len() {
return false;
}
haystack
.windows(needle.len())
.any(|window| window == needle)
}