use clap::Parser;
use keyhog::args::ScanArgs;
use keyhog::testing::{CliTestApi, API};
#[test]
fn buffered_stdin_replay_uses_one_source_with_exact_lossy_decoding() {
let mut args =
ScanArgs::try_parse_from(["scan", "--stdin"]).expect("stdin scan arguments must parse");
let bytes = b"prefix=ok\xff\nsecret=AKIAQYLPM5HFIQR7XYA\n".to_vec();
API.set_buffered_stdin(&mut args, bytes);
let sources = API
.build_sources(&args, Vec::new(), None)
.expect("buffered stdin source must build");
assert_eq!(
sources.len(),
1,
"stdin replay must not add a filesystem source"
);
let chunks = sources[0]
.chunks()
.collect::<Result<Vec<_>, _>>()
.expect("buffered stdin must decode within the default limit");
assert_eq!(chunks.len(), 1, "stdin is one logical source chunk");
assert_eq!(chunks[0].metadata.source_type.as_ref(), "stdin");
assert_eq!(chunks[0].metadata.path, None);
assert_eq!(
chunks[0].data.as_ref(),
"prefix=ok\u{fffd}\nsecret=AKIAQYLPM5HFIQR7XYA\n",
"replay must match the normal lossy UTF-8 stdin decoder exactly"
);
}
#[test]
fn buffered_stdin_replay_emits_bounded_overlapping_windows() {
const WINDOW: usize = 1024 * 1024;
const OVERLAP: usize = 128 * 1024;
let mut args =
ScanArgs::try_parse_from(["scan", "--stdin"]).expect("stdin scan arguments must parse");
let mut bytes = vec![b'a'; WINDOW + 16];
bytes[100] = b'\n';
bytes[200] = b'\n';
bytes[WINDOW - 10] = b'\n';
API.set_buffered_stdin(&mut args, bytes.clone());
let sources = API
.build_sources(&args, Vec::new(), None)
.expect("buffered stdin source must build");
let chunks = sources[0]
.chunks()
.collect::<Result<Vec<_>, _>>()
.expect("bounded buffered stdin must decode");
assert_eq!(chunks.len(), 2);
assert_eq!(chunks[0].data.len(), WINDOW);
assert_eq!(chunks[0].metadata.base_offset, 0);
assert_eq!(chunks[0].metadata.base_line, 0);
assert_eq!(chunks[1].metadata.base_offset, WINDOW - OVERLAP);
assert_eq!(chunks[1].metadata.base_line, 2);
assert_eq!(
chunks[1].data.as_bytes(),
&bytes[WINDOW - OVERLAP..],
"the retry window must preserve the exact overlap and trailing bytes"
);
}