cranpose-foundation 0.1.112

Modifiers, nodes, and foundation elements for Cranpose
Documentation
use cranpose_foundation::text::{TextFieldBuffer, TextRange};

#[test]
fn a_fresh_buffer_has_no_selection_and_no_changes() {
    let buffer = TextFieldBuffer::new("hello");
    assert!(!buffer.has_selection(), "a new buffer selected something");
    assert!(
        !buffer.has_changes(),
        "a buffer nobody edited claimed to be dirty"
    );
    assert_eq!(buffer.selection(), TextRange::cursor(5));
}

#[test]
fn a_buffer_reports_changes_only_after_it_is_edited() {
    let mut buffer = TextFieldBuffer::new("hello");
    buffer.select_all();
    assert!(
        !buffer.has_changes(),
        "selecting is not editing and must not mark the buffer dirty"
    );

    buffer.insert("!");
    assert!(buffer.has_changes(), "an insert left the buffer clean");
}

#[test]
fn deleting_after_the_cursor_removes_the_following_character() {
    let mut buffer = TextFieldBuffer::with_selection("hello", TextRange::cursor(0));
    buffer.delete_after_cursor();
    assert_eq!(buffer.text(), "ello");
    assert_eq!(
        buffer.selection(),
        TextRange::cursor(0),
        "the cursor moved while deleting forward"
    );
}

#[test]
fn deleting_after_the_cursor_at_the_end_does_nothing() {
    let mut buffer = TextFieldBuffer::new("hello");
    buffer.delete_after_cursor();
    assert_eq!(buffer.text(), "hello");
    assert!(
        !buffer.has_changes(),
        "a delete that removed nothing marked the buffer dirty"
    );
}

#[test]
fn deleting_after_the_cursor_removes_a_whole_character_not_a_byte() {
    let mut buffer = TextFieldBuffer::with_selection("éa", TextRange::cursor(0));
    buffer.delete_after_cursor();
    assert_eq!(buffer.text(), "a");
}

#[test]
fn deleting_after_the_cursor_removes_the_selection_when_there_is_one() {
    let mut buffer = TextFieldBuffer::with_selection("hello", TextRange::new(1, 4));
    buffer.delete_after_cursor();
    assert_eq!(buffer.text(), "ho");
    assert!(!buffer.has_selection());
}

#[test]
fn extending_the_selection_left_grows_it_one_character_at_a_time() {
    let mut buffer = TextFieldBuffer::new("hello");
    buffer.extend_selection_left();
    assert_eq!(buffer.selection(), TextRange::new(5, 4));
    buffer.extend_selection_left();
    assert_eq!(buffer.selection(), TextRange::new(5, 3));
    assert_eq!(
        buffer.copy_selection().as_deref(),
        Some("lo"),
        "the extended selection did not cover the characters it grew over"
    );
}

#[test]
fn extending_the_selection_left_stops_at_the_start() {
    let mut buffer = TextFieldBuffer::with_selection("ab", TextRange::cursor(0));
    buffer.extend_selection_left();
    assert_eq!(buffer.selection(), TextRange::cursor(0));
}

#[test]
fn extending_left_and_then_right_returns_to_where_it_began() {
    let mut buffer = TextFieldBuffer::with_selection("hello", TextRange::cursor(2));
    buffer.extend_selection_left();
    assert!(buffer.has_selection());
    buffer.extend_selection_right();
    assert_eq!(
        buffer.selection(),
        TextRange::cursor(2),
        "shift-left then shift-right left a selection behind"
    );

    buffer.extend_selection_right();
    assert!(buffer.has_selection());
    buffer.extend_selection_left();
    assert_eq!(
        buffer.selection(),
        TextRange::cursor(2),
        "shift-right then shift-left left a selection behind"
    );
}

#[test]
fn extending_the_selection_right_grows_it_one_character_at_a_time() {
    let mut buffer = TextFieldBuffer::with_selection("hello", TextRange::cursor(0));
    buffer.extend_selection_right();
    assert_eq!(buffer.selection(), TextRange::new(0, 1));
    buffer.extend_selection_right();
    assert_eq!(buffer.selection(), TextRange::new(0, 2));
    assert_eq!(buffer.copy_selection().as_deref(), Some("he"));
}

#[test]
fn extending_the_selection_right_stops_at_the_end() {
    let mut buffer = TextFieldBuffer::new("ab");
    buffer.extend_selection_right();
    assert_eq!(buffer.selection(), TextRange::cursor(2));
}

#[test]
fn extending_the_selection_walks_whole_characters() {
    let mut buffer = TextFieldBuffer::with_selection("éa", TextRange::cursor(0));
    buffer.extend_selection_right();
    assert_eq!(
        buffer.copy_selection().as_deref(),
        Some("é"),
        "the selection stopped inside a multi-byte character"
    );
}