use crate::common::harness::EditorTestHarness;
use tempfile::TempDir;
#[test]
fn test_basic_editing_workflow() {
let mut harness = EditorTestHarness::new(80, 24).unwrap();
harness.assert_buffer_content("");
harness.render().unwrap();
harness.assert_screen_contains("[No Name]");
}
#[test]
fn test_file_open_save_workflow() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.txt");
std::fs::write(&file_path, "Initial content").unwrap();
let mut harness = EditorTestHarness::new(80, 24).unwrap();
harness.open_file(&file_path).unwrap();
harness.render().unwrap();
harness.assert_screen_contains("test.txt");
harness.assert_buffer_content("Initial content");
}
#[test]
fn test_multi_buffer_workflow() {
let temp_dir = TempDir::new().unwrap();
let file1 = temp_dir.path().join("file1.txt");
let file2 = temp_dir.path().join("file2.txt");
std::fs::write(&file1, "File 1 content").unwrap();
std::fs::write(&file2, "File 2 content").unwrap();
let mut harness = EditorTestHarness::new(80, 24).unwrap();
harness.open_file(&file1).unwrap();
harness.assert_buffer_content("File 1 content");
harness.open_file(&file2).unwrap();
harness.assert_buffer_content("File 2 content");
harness.render().unwrap();
harness.assert_screen_contains("file1.txt");
harness.assert_screen_contains("file2.txt");
}
#[test]
fn test_buffer_switching() {
use crossterm::event::{KeyCode, KeyModifiers};
let temp_dir = TempDir::new().unwrap();
let file1 = temp_dir.path().join("alpha.txt");
let file2 = temp_dir.path().join("beta.txt");
std::fs::write(&file1, "Content of alpha").unwrap();
std::fs::write(&file2, "Content of beta").unwrap();
let mut harness = EditorTestHarness::new(80, 24).unwrap();
harness.open_file(&file1).unwrap();
harness.assert_buffer_content("Content of alpha");
harness.open_file(&file2).unwrap();
harness.assert_buffer_content("Content of beta");
harness.render().unwrap();
harness.assert_screen_contains("alpha.txt");
harness.assert_screen_contains("beta.txt");
harness
.send_key(KeyCode::PageUp, KeyModifiers::CONTROL)
.unwrap();
harness.render().unwrap();
harness.assert_buffer_content("Content of alpha");
harness
.send_key(KeyCode::PageDown, KeyModifiers::CONTROL)
.unwrap();
harness.render().unwrap();
harness.assert_buffer_content("Content of beta");
harness
.send_key(KeyCode::PageDown, KeyModifiers::CONTROL)
.unwrap();
harness.render().unwrap();
harness.assert_buffer_content("Content of alpha");
harness
.send_key(KeyCode::PageUp, KeyModifiers::CONTROL)
.unwrap();
harness.render().unwrap();
harness.assert_buffer_content("Content of beta");
}
#[test]
fn test_open_file_viewport_dimensions() {
use tempfile::TempDir;
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.txt");
std::fs::write(&file_path, "Line 1\nLine 2\nLine 3\n").unwrap();
let mut harness = EditorTestHarness::new(131, 31).unwrap();
harness.render().unwrap();
let expected_viewport_height = harness.viewport_height();
let initial_viewport_height = harness.editor().active_viewport().height as usize;
assert_eq!(
initial_viewport_height, expected_viewport_height,
"Initial viewport should be {expected_viewport_height} (31 - 3 for menu bar, tab bar, status bar)"
);
harness.open_file(&file_path).unwrap();
let viewport_height_after_open = harness.editor().active_viewport().height as usize;
assert_eq!(
viewport_height_after_open, expected_viewport_height,
"After opening file, viewport height should be {expected_viewport_height}, but got {viewport_height_after_open}. \\
This indicates the file was opened with hardcoded dimensions instead of actual terminal size."
);
harness.render().unwrap();
let visible_count = harness.editor().active_viewport().visible_line_count();
assert_eq!(
visible_count, expected_viewport_height,
"Visible range should be {expected_viewport_height} lines, but got {visible_count}"
);
}
#[test]
fn test_large_file_with_lsp() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("large_test.rs");
let mut content = String::new();
content.push_str("// Large Rust file for testing\n");
content.push_str("fn main() {\n");
for i in 0..25000 {
content.push_str(&format!(
" println!(\"Line number {i} of test content\");\n"
));
}
content.push_str("}\n");
std::fs::write(&file_path, &content).unwrap();
let file_size = std::fs::metadata(&file_path).unwrap().len();
assert!(
file_size > 1024 * 1024,
"Test file should be > 1MB (got {file_size} bytes)"
);
let mut harness = EditorTestHarness::new(80, 24).unwrap();
let result = harness.open_file(&file_path);
assert!(
result.is_ok(),
"Should be able to open large file without hanging"
);
harness.render().unwrap();
harness.assert_screen_contains("large_test.rs");
harness.assert_screen_contains("// Large Rust file");
}
#[test]
fn test_medium_file_with_lsp() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("medium_test.rs");
let mut content = String::new();
content.push_str("// Medium Rust file for testing\n");
content.push_str("fn main() {\n");
for i in 0..10000 {
content.push_str(&format!(" println!(\"Line {i}\");\n"));
}
content.push_str("}\n");
std::fs::write(&file_path, &content).unwrap();
let file_size = std::fs::metadata(&file_path).unwrap().len();
assert!(
file_size < 1024 * 1024,
"Test file should be < 1MB (got {file_size} bytes)"
);
let mut harness = EditorTestHarness::new(80, 24).unwrap();
let result = harness.open_file(&file_path);
assert!(
result.is_ok(),
"Should be able to open medium file with LSP"
);
harness.render().unwrap();
harness.assert_screen_contains("medium_test.rs");
harness.assert_screen_contains("// Medium Rust file");
}
#[test]
fn test_append_at_end_of_file() {
use crossterm::event::{KeyCode, KeyModifiers};
use tempfile::TempDir;
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.txt");
std::fs::write(&file_path, "Line 1\nLine 2\nLine 3").unwrap();
let mut harness = EditorTestHarness::new(80, 24).unwrap();
harness.enable_shadow_validation();
harness.open_file(&file_path).unwrap();
harness.render().unwrap();
harness
.send_key(KeyCode::End, KeyModifiers::CONTROL)
.unwrap();
harness.render().unwrap();
let cursor_pos = harness.cursor_position();
assert_eq!(cursor_pos, 20, "Cursor should be at end of Line 3");
harness
.send_key(KeyCode::Char('!'), KeyModifiers::NONE)
.unwrap();
harness.render().unwrap();
harness.assert_buffer_content("Line 1\nLine 2\nLine 3!");
let cursor_pos_after = harness.cursor_position();
assert_eq!(cursor_pos_after, 21, "Cursor should be after '!'");
harness
.send_key(KeyCode::Char('!'), KeyModifiers::NONE)
.unwrap();
harness.render().unwrap();
harness.assert_buffer_content("Line 1\nLine 2\nLine 3!!");
harness
.send_key(KeyCode::Enter, KeyModifiers::NONE)
.unwrap();
harness.render().unwrap();
harness.assert_buffer_content("Line 1\nLine 2\nLine 3!!\n");
harness
.send_key(KeyCode::Char('L'), KeyModifiers::NONE)
.unwrap();
harness
.send_key(KeyCode::Char('i'), KeyModifiers::NONE)
.unwrap();
harness
.send_key(KeyCode::Char('n'), KeyModifiers::NONE)
.unwrap();
harness
.send_key(KeyCode::Char('e'), KeyModifiers::NONE)
.unwrap();
harness
.send_key(KeyCode::Char(' '), KeyModifiers::NONE)
.unwrap();
harness
.send_key(KeyCode::Char('4'), KeyModifiers::NONE)
.unwrap();
harness.render().unwrap();
harness.assert_buffer_content("Line 1\nLine 2\nLine 3!!\nLine 4");
}