revue 2.71.1

A Vue-style TUI framework for Rust with CSS styling
Documentation
//! TextArea Unicode/CJK handling tests
//!
//! Tests for char-index-based cursor operations with multi-byte characters.
//! Verifies fixes from fix/textarea-unicode-width PR.

use revue::event::Key;
use revue::widget::textarea;

#[test]
fn test_textarea_insert_cjk_and_get_content() {
    let mut t = textarea().focused(true);
    t.insert_char('ν•œ');
    t.insert_char('κΈ€');
    assert_eq!(t.get_content(), "ν•œκΈ€");
}

#[test]
fn test_textarea_insert_emoji_cursor_position() {
    let mut t = textarea().focused(true);
    t.insert_char('πŸ˜€');
    t.insert_char('!');
    assert_eq!(t.get_content(), "πŸ˜€!");
    let (_, col) = t.cursor_position();
    assert_eq!(col, 2);
}

#[test]
fn test_textarea_backspace_cjk() {
    let mut t = textarea().focused(true);
    t.insert_char('κ°€');
    t.insert_char('λ‚˜');
    t.insert_char('λ‹€');
    assert_eq!(t.get_content(), "κ°€λ‚˜λ‹€");

    t.delete_char_before();
    assert_eq!(t.get_content(), "κ°€λ‚˜");

    t.delete_char_before();
    assert_eq!(t.get_content(), "κ°€");
}

#[test]
fn test_textarea_backspace_emoji() {
    let mut t = textarea().focused(true);
    t.insert_char('πŸŽ‰');
    t.insert_char('πŸ”₯');
    assert_eq!(t.get_content(), "πŸŽ‰πŸ”₯");

    t.delete_char_before();
    assert_eq!(t.get_content(), "πŸŽ‰");
}

#[test]
fn test_textarea_delete_at_cjk() {
    let mut t = textarea().focused(true).content("ν•œκΈ€ν…ŒμŠ€νŠΈ");
    t.set_cursor(0, 0);

    t.delete_char_at();
    assert_eq!(t.get_content(), "κΈ€ν…ŒμŠ€νŠΈ");

    t.delete_char_at();
    assert_eq!(t.get_content(), "ν…ŒμŠ€νŠΈ");
}

#[test]
fn test_textarea_insert_str_cjk_cursor() {
    let mut t = textarea().focused(true);
    t.insert_str("μ•ˆλ…•ν•˜μ„Έμš”");
    assert_eq!(t.get_content(), "μ•ˆλ…•ν•˜μ„Έμš”");
    let (_, col) = t.cursor_position();
    assert_eq!(col, 5); // 5 chars, not 15 bytes
}

#[test]
fn test_textarea_mixed_ascii_cjk() {
    let mut t = textarea().focused(true);
    t.insert_str("Hello");
    t.insert_char('δΈ–');
    t.insert_char('η•Œ');
    assert_eq!(t.get_content(), "HelloδΈ–η•Œ");
    let (_, col) = t.cursor_position();
    assert_eq!(col, 7);
}

#[test]
fn test_textarea_cursor_navigation_cjk() {
    let mut t = textarea().focused(true).content("κ°€λ‚˜λ‹€λΌ");
    t.set_cursor(0, 4);

    t.handle_key(&Key::Left);
    let (_, col) = t.cursor_position();
    assert_eq!(col, 3);

    t.handle_key(&Key::Home);
    let (_, col) = t.cursor_position();
    assert_eq!(col, 0);

    t.handle_key(&Key::End);
    let (_, col) = t.cursor_position();
    assert_eq!(col, 4);
}

#[test]
fn test_textarea_insert_in_middle_cjk() {
    let mut t = textarea().focused(true).content("κ°€λ‹€");
    t.set_cursor(0, 1);

    t.insert_char('λ‚˜');
    assert_eq!(t.get_content(), "κ°€λ‚˜λ‹€");
}

#[test]
fn test_textarea_newline_with_cjk() {
    let mut t = textarea().focused(true).content("μ•ˆλ…•ν•˜μ„Έμš”");
    t.set_cursor(0, 2);

    t.insert_char('\n');
    assert_eq!(t.get_content(), "μ•ˆλ…•\nν•˜μ„Έμš”");
    assert_eq!(t.line_count(), 2);
}

#[test]
fn test_textarea_multiline_insert_cjk() {
    let mut t = textarea().focused(true);
    t.insert_str("첫째쀄\nλ‘˜μ§Έμ€„");
    assert_eq!(t.get_content(), "첫째쀄\nλ‘˜μ§Έμ€„");
    assert_eq!(t.line_count(), 2);
}