The test framework has been set up with:
MockLsp: A mock implementation of the LSP client for testingEditorHarness: A test harness for creating editor instances- Basic test structure for movement commands
The editor's current architecture makes integration testing difficult because:
- Most editor methods are private
- The
executemethod that processes actions is private - Editor state (cursor position, mode, etc.) is not publicly accessible
- The main
runmethod starts an interactive terminal session
- Add public getter methods to Editor for testing:
#[cfg(test)] pub fn test_cursor_position(&self) -> (usize, usize) #[cfg(test)] pub fn test_mode(&self) -> Mode #[cfg(test)] pub fn test_execute_action(&mut self, action: Action) -> Result<()>
- Extract editor logic into a testable core that doesn't depend on terminal I/O
- Create a public API for editor operations
- Implement a command pattern that can be tested independently
- Full integration tests using terminal emulation
- Property-based testing for editor operations
- Fuzzing for robustness testing
- Basic movements: h, j, k, l
- Word movements: w, b, e, W, B, E
- Line movements: 0, ^, $, g_
- Paragraph movements: {, }
- File movements: gg, G, [n]G
- Screen movements: H, M, L, Ctrl-U, Ctrl-D, Ctrl-F, Ctrl-B
- Insert modes: i, a, I, A, o, O
- Delete operations: x, X, d{motion}, dd, D
- Change operations: c{motion}, cc, C, s, S
- Replace: r, R
- Undo/Redo: u, Ctrl-R
- Normal -> Insert
- Insert -> Normal
- Normal -> Visual (v, V, Ctrl-V)
- Visual -> Normal
- Normal -> Command (:)
- Command -> Normal
- Character selection
- Line selection
- Block selection
- Operations on selections (d, c, y, etc.)
- Forward search: /
- Backward search: ?
- Next/Previous: n, N
- Replace: :s/pattern/replacement/
- Save: :w
- Quit: :q
- Save and quit: :wq
- Force quit: :q!
- Open file: :e
- Buffer navigation
- Multiple cursors
- Macros
- Marks
- Registers
- Folding
- Start with the most basic operations (movement, mode changes)
- Add test helpers as needed
- Gradually increase test coverage
- Consider using snapshot testing for complex scenarios
- Add performance benchmarks for critical operations
#[test]
async fn test_basic_movement() {
let mut editor = TestEditor::new("Hello\nWorld");
// Start at (0, 0)
assert_eq!(editor.cursor(), (0, 0));
// Move right
editor.execute(Action::MoveRight).await;
assert_eq!(editor.cursor(), (1, 0));
// Move down
editor.execute(Action::MoveDown).await;
assert_eq!(editor.cursor(), (1, 1));
}- Propose API changes to make editor testable
- Implement basic test helpers
- Write tests for core functionality
- Set up CI to run tests
- Add code coverage reporting