use crate::common::harness::EditorTestHarness;
use std::io::Write;
use tempfile::NamedTempFile;
fn create_stdin_temp_file(content: &str) -> NamedTempFile {
let mut file = NamedTempFile::new().unwrap();
file.write_all(content.as_bytes()).unwrap();
file.flush().unwrap();
file
}
#[test]
fn test_open_stdin_buffer() {
let mut harness = EditorTestHarness::new(80, 24).unwrap();
let content = "Hello from stdin!\nLine 2\nLine 3";
let temp_file = create_stdin_temp_file(content);
harness
.editor_mut()
.open_stdin_buffer(temp_file.path(), None)
.unwrap();
harness.assert_buffer_content(content);
harness.render().unwrap();
harness.assert_screen_contains("[stdin]");
}
#[test]
fn test_stdin_buffer_not_modified_initially() {
let mut harness = EditorTestHarness::new(80, 24).unwrap();
let content = "Some content from stdin";
let temp_file = create_stdin_temp_file(content);
harness
.editor_mut()
.open_stdin_buffer(temp_file.path(), None)
.unwrap();
harness.render().unwrap();
let screen = harness.screen_to_string();
assert!(screen.contains("[stdin]"), "Expected [stdin] in status bar");
}
#[test]
fn test_open_empty_stdin_buffer() {
let mut harness = EditorTestHarness::new(80, 24).unwrap();
let temp_file = create_stdin_temp_file("");
harness
.editor_mut()
.open_stdin_buffer(temp_file.path(), None)
.unwrap();
harness.assert_buffer_content("");
harness.render().unwrap();
harness.assert_screen_contains("[stdin]");
}
#[test]
fn test_stdin_replaces_empty_buffer() {
let mut harness = EditorTestHarness::new(80, 24).unwrap();
harness.assert_buffer_content("");
let content = "Stdin content";
let temp_file = create_stdin_temp_file(content);
harness
.editor_mut()
.open_stdin_buffer(temp_file.path(), None)
.unwrap();
harness.assert_buffer_content(content);
harness.render().unwrap();
harness.assert_screen_contains("[stdin]");
let screen = harness.screen_to_string();
assert!(
!screen.contains("[No Name]"),
"Empty buffer should have been replaced"
);
}
#[test]
fn test_stdin_multiline_content() {
let mut harness = EditorTestHarness::new(80, 24).unwrap();
let content = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5";
let temp_file = create_stdin_temp_file(content);
harness
.editor_mut()
.open_stdin_buffer(temp_file.path(), None)
.unwrap();
harness.assert_buffer_content(content);
harness.render().unwrap();
harness.assert_screen_contains("Line 1");
harness.assert_screen_contains("Line 2");
}
#[test]
fn test_stdin_special_characters() {
let mut harness = EditorTestHarness::new(80, 24).unwrap();
let content = "Tab:\there\nUnicode: 你好 🎉\nSpecial: <>&\"'";
let temp_file = create_stdin_temp_file(content);
harness
.editor_mut()
.open_stdin_buffer(temp_file.path(), None)
.unwrap();
harness.assert_buffer_content(content);
}
#[test]
fn test_stdin_streaming_progress() {
use std::fs::OpenOptions;
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
use std::thread;
use std::time::Duration;
let mut harness = EditorTestHarness::new(80, 24).unwrap();
let temp_file = NamedTempFile::new().unwrap();
let temp_path = temp_file.path().to_path_buf();
let stop_signal = Arc::new(AtomicBool::new(false));
let stop_signal_clone = stop_signal.clone();
let temp_path_clone = temp_path.clone();
let thread_handle = thread::spawn(move || -> anyhow::Result<()> {
let mut file = OpenOptions::new().append(true).open(&temp_path_clone)?;
let mut count = 0;
while !stop_signal_clone.load(Ordering::Relaxed) && count < 10 {
writeln!(file, "Line {}", count)?;
file.flush()?;
count += 1;
thread::sleep(Duration::from_millis(10));
}
Ok(())
});
harness
.editor_mut()
.open_stdin_buffer(&temp_path, Some(thread_handle))
.unwrap();
let initial_len = harness.editor().active_state().buffer.len();
for _ in 0..50 {
harness.editor_mut().poll_stdin_streaming();
thread::sleep(Duration::from_millis(5));
}
let after_poll_len = harness.editor().active_state().buffer.len();
assert!(
after_poll_len > initial_len,
"Buffer should have grown from {} to more, but got {}",
initial_len,
after_poll_len
);
stop_signal.store(true, Ordering::Relaxed);
for _ in 0..100 {
if !harness.editor().is_stdin_streaming() {
break;
}
harness.editor_mut().poll_stdin_streaming();
thread::sleep(Duration::from_millis(10));
}
assert!(
!harness.editor().is_stdin_streaming(),
"Streaming should be complete"
);
harness.render().unwrap();
harness.assert_screen_contains("[stdin]");
}
#[test]
fn test_stdin_large_file_lazy_loading() {
use crate::common::harness::HarnessOptions;
use fresh::config::Config;
let mut config = Config::default();
config.editor.large_file_threshold_bytes = 1024;
let mut harness =
EditorTestHarness::create(80, 24, HarnessOptions::new().with_config(config)).unwrap();
let content = "X".repeat(2048); let temp_file = create_stdin_temp_file(&content);
harness
.editor_mut()
.open_stdin_buffer(temp_file.path(), None)
.unwrap();
let state = harness.editor().active_state();
assert!(
state.buffer.is_large_file(),
"Large stdin should trigger lazy loading mode"
);
harness.render().unwrap();
harness.assert_screen_contains("[stdin]");
}