tastty-core 0.1.0

Sans-IO core of the tastty terminal session library: VT parser, screen buffer, and byte encoders.
use super::*;

#[test]
fn osc52_write_decodes_base64() {
    let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
    process(&mut parser, b"\x1b]52;c;aGVsbG8=\x1b\\");
    let events = parser.screen_mut().drain_events();
    assert_eq!(
        events,
        vec![ScreenEvent::ClipboardWrite {
            targets: vec![ClipboardTarget::Clipboard],
            data: b"hello".to_vec(),
        }]
    );
}

#[test]
fn osc52_query_emits_query_event() {
    let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
    process(&mut parser, b"\x1b]52;c;?\x1b\\");
    let events = parser.screen_mut().drain_events();
    assert_eq!(
        events,
        vec![ScreenEvent::ClipboardQuery {
            targets: vec![ClipboardTarget::Clipboard],
        }]
    );
}

#[test]
fn osc52_empty_payload_is_clear() {
    let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
    process(&mut parser, b"\x1b]52;c;\x1b\\");
    let events = parser.screen_mut().drain_events();
    assert_eq!(
        events,
        vec![ScreenEvent::ClipboardClear {
            targets: vec![ClipboardTarget::Clipboard],
        }]
    );
}

#[test]
fn osc52_primary_selection() {
    let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
    process(&mut parser, b"\x1b]52;p;dGVzdA==\x1b\\");
    let events = parser.screen_mut().drain_events();
    assert_eq!(
        events,
        vec![ScreenEvent::ClipboardWrite {
            targets: vec![ClipboardTarget::Primary],
            data: b"test".to_vec(),
        }]
    );
}

#[test]
fn osc52_bel_terminated() {
    let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
    process(&mut parser, b"\x1b]52;c;aGVsbG8=\x07");
    let events = parser.screen_mut().drain_events();
    assert_eq!(events.len(), 1);
}

#[test]
fn osc52_empty_pc_defaults_to_s0() {
    let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
    process(&mut parser, b"\x1b]52;;aGVsbG8=\x1b\\");
    let events = parser.screen_mut().drain_events();
    assert_eq!(
        events,
        vec![ScreenEvent::ClipboardWrite {
            targets: vec![ClipboardTarget::Select, ClipboardTarget::CutBuffer(0)],
            data: b"hello".to_vec(),
        }]
    );
}

#[test]
fn osc52_multi_letter_pc_preserves_order_and_dedupes() {
    let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
    process(&mut parser, b"\x1b]52;cpc3;aGVsbG8=\x1b\\");
    let events = parser.screen_mut().drain_events();
    assert_eq!(
        events,
        vec![ScreenEvent::ClipboardWrite {
            targets: vec![
                ClipboardTarget::Clipboard,
                ClipboardTarget::Primary,
                ClipboardTarget::CutBuffer(3),
            ],
            data: b"hello".to_vec(),
        }]
    );
}

#[test]
fn osc52_unknown_pc_letters_are_skipped() {
    let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
    process(&mut parser, b"\x1b]52;cXp;aGVsbG8=\x1b\\");
    let events = parser.screen_mut().drain_events();
    assert_eq!(
        events,
        vec![ScreenEvent::ClipboardWrite {
            targets: vec![ClipboardTarget::Clipboard, ClipboardTarget::Primary],
            data: b"hello".to_vec(),
        }]
    );
}

#[test]
fn osc52_invalid_base64_drops_event() {
    let mut parser = crate::Parser::new(TerminalSize { rows: 24, cols: 80 }, 0);
    process(&mut parser, b"\x1b]52;c;!!!not-base64!!!\x1b\\");
    let events = parser.screen_mut().drain_events();
    assert!(events.is_empty());
}