brlapi 0.4.1

Safe Rust bindings for the BrlAPI library
// SPDX-License-Identifier: LGPL-2.1

//! Common test utilities for BrlAPI high-level wrapper tests
//!
//! Note: Some functions may appear unused due to cross-test-file usage not being
//! detected by the compiler, but they are used by different test binaries.

#![allow(dead_code)] // Suppress false positive warnings for cross-test-file usage

use brlapi::{BrlApiError, Connection, ConnectionSettings, TtyMode};

/// Test helper to create a connection and handle expected failures gracefully
pub fn try_connect() -> Result<Connection, BrlApiError> {
    Connection::open()
}

/// Test helper to create a connection with specific settings
pub fn try_connect_with_settings(settings: &ConnectionSettings) -> Result<Connection, BrlApiError> {
    Connection::open_with_settings(Some(settings))
}

/// Create localhost connection settings for testing
pub fn localhost_settings() -> ConnectionSettings {
    ConnectionSettings::localhost()
}

/// Create IPv4 connection settings for testing
pub fn ipv4_settings() -> ConnectionSettings {
    ConnectionSettings::for_host("127.0.0.1")
}

/// Test helper that runs a test with a connection if available
pub fn with_connection<F, R>(test_fn: F) -> Option<R>
where
    F: FnOnce(Connection) -> R,
{
    match try_connect() {
        Ok(conn) => {
            println!("Connection established for test");
            Some(test_fn(conn))
        }
        Err(e) => {
            println!("No connection available for test: {e}");
            None
        }
    }
}

/// Test helper that runs a test with a connection in TTY mode if possible
pub fn with_tty_mode<F, R>(test_fn: F) -> Option<R>
where
    F: FnOnce(&Connection) -> Result<R, BrlApiError>,
{
    with_connection(|conn| {
        match TtyMode::try_from(&conn) {
            Ok(_tty_mode) => {
                println!("TTY mode entered for test");
                let result = test_fn(&conn);
                // TTY mode automatically cleaned up when _tty_mode drops
                result
            }
            Err(e) => {
                println!("TTY mode not available for test: {e}");
                Err(e)
            }
        }
    })
    .and_then(|r| r.ok())
}

/// Assert that a connection method returns reasonable values or expected errors
pub fn assert_reasonable_result<T: std::fmt::Debug>(
    result: Result<T, BrlApiError>,
    operation_name: &str,
) -> Option<T> {
    match result {
        Ok(value) => {
            println!("{operation_name}: Success");
            Some(value)
        }
        Err(BrlApiError::OperationNotSupported)
        | Err(BrlApiError::ConnectionRefused)
        | Err(BrlApiError::TTYBusy)
        | Err(BrlApiError::DeviceBusy) => {
            println!("{operation_name}: Expected error: {}", result.unwrap_err());
            None
        }
        Err(e) => {
            println!("{operation_name}: Unexpected error: {e}");
            None
        }
    }
}

/// Create test data for various scenarios
pub mod test_data {

    pub fn sample_texts() -> Vec<&'static str> {
        vec![
            "Hello BrlAPI",
            "Test message",
            "", // Empty text
            "This is a very long text that exceeds typical braille display width",
            "Unicode: 测试 العربية",
        ]
    }

    pub fn cursor_positions() -> Vec<i32> {
        vec![
            brlapi_sys::BRLAPI_CURSOR_LEAVE,
            brlapi_sys::BRLAPI_CURSOR_OFF as i32,
            0,
            5,
            10,
        ]
    }
}