feat: add main features
Agents for developpement added + frontend add + backend added. Git viewer created + agent and template creator + layout and project creator
This commit is contained in:
90
crates/app-tauri/tests/pty_bridge.rs
Normal file
90
crates/app-tauri/tests/pty_bridge.rs
Normal file
@ -0,0 +1,90 @@
|
||||
//! L1 tests for [`PtyBridge`] — the PTY↔Channel registry — exercised with a
|
||||
//! real [`tauri::ipc::Channel`] built from a capturing closure (no Tauri runtime
|
||||
//! and no real PTY needed).
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use tauri::ipc::{Channel, InvokeResponseBody};
|
||||
|
||||
use app_tauri_lib::pty::PtyBridge;
|
||||
use domain::ids::SessionId;
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Builds a `Channel<Vec<u8>>` whose sent chunks are recorded into `sink`.
|
||||
///
|
||||
/// `Vec<u8>` is `Serialize`, so chunks arrive as a JSON array string in an
|
||||
/// `InvokeResponseBody::Json`; we parse them back to bytes for assertions.
|
||||
fn capturing_channel(sink: Arc<Mutex<Vec<Vec<u8>>>>) -> Channel<Vec<u8>> {
|
||||
Channel::new(move |body: InvokeResponseBody| {
|
||||
let bytes: Vec<u8> = match body {
|
||||
InvokeResponseBody::Json(s) => serde_json::from_str(&s).unwrap(),
|
||||
InvokeResponseBody::Raw(b) => b,
|
||||
};
|
||||
sink.lock().unwrap().push(bytes);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn sid() -> SessionId {
|
||||
SessionId::from_uuid(Uuid::new_v4())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn register_increases_active_sessions() {
|
||||
let bridge = PtyBridge::new();
|
||||
assert_eq!(bridge.active_sessions(), 0);
|
||||
|
||||
let sink = Arc::new(Mutex::new(Vec::new()));
|
||||
bridge.register(sid(), capturing_channel(sink));
|
||||
assert_eq!(bridge.active_sessions(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn send_output_delivers_bytes_to_registered_channel() {
|
||||
let bridge = PtyBridge::new();
|
||||
let session = sid();
|
||||
let sink = Arc::new(Mutex::new(Vec::new()));
|
||||
bridge.register(session, capturing_channel(Arc::clone(&sink)));
|
||||
|
||||
let delivered = bridge.send_output(&session, vec![104, 105]);
|
||||
assert!(delivered, "send_output should return true for a live session");
|
||||
|
||||
let captured = sink.lock().unwrap();
|
||||
assert_eq!(captured.as_slice(), &[vec![104, 105]]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn send_output_to_unknown_session_returns_false() {
|
||||
let bridge = PtyBridge::new();
|
||||
assert!(!bridge.send_output(&sid(), vec![0]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unregister_removes_session_and_stops_delivery() {
|
||||
let bridge = PtyBridge::new();
|
||||
let session = sid();
|
||||
let sink = Arc::new(Mutex::new(Vec::new()));
|
||||
bridge.register(session, capturing_channel(Arc::clone(&sink)));
|
||||
assert_eq!(bridge.active_sessions(), 1);
|
||||
|
||||
bridge.unregister(&session);
|
||||
assert_eq!(bridge.active_sessions(), 0);
|
||||
assert!(!bridge.send_output(&session, vec![1]));
|
||||
assert!(sink.lock().unwrap().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn register_same_session_twice_replaces_channel() {
|
||||
let bridge = PtyBridge::new();
|
||||
let session = sid();
|
||||
let first = Arc::new(Mutex::new(Vec::new()));
|
||||
let second = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
bridge.register(session, capturing_channel(Arc::clone(&first)));
|
||||
bridge.register(session, capturing_channel(Arc::clone(&second)));
|
||||
assert_eq!(bridge.active_sessions(), 1, "same id is replaced, not added");
|
||||
|
||||
bridge.send_output(&session, vec![9]);
|
||||
assert!(first.lock().unwrap().is_empty(), "old channel no longer used");
|
||||
assert_eq!(second.lock().unwrap().as_slice(), &[vec![9]]);
|
||||
}
|
||||
Reference in New Issue
Block a user