use super::*;
use serial_test::serial;
struct GlobalStateGuard;
impl Drop for GlobalStateGuard {
fn drop(&mut self) {
set_in_alternate_mode(false);
set_r_at_prompt(false);
}
}
#[test]
#[serial]
fn test_alternate_mode_flag_and_request_rejection() {
set_in_alternate_mode(false);
set_r_at_prompt(false);
let _guard = GlobalStateGuard;
assert!(!is_in_alternate_mode());
set_in_alternate_mode(true);
assert!(is_in_alternate_mode());
set_in_alternate_mode(false);
assert!(!is_in_alternate_mode());
set_r_at_prompt(true);
set_in_alternate_mode(true);
{
let (reply_tx, reply_rx) = tokio::sync::oneshot::channel();
let request = IpcRequest {
method: IpcMethod::UserInput {
code: "1+1".to_string(),
},
reply: reply_tx,
};
handle_request(request);
match reply_rx.blocking_recv().unwrap() {
IpcResponse::Error { code, .. } => assert_eq!(code, R_NOT_AT_PROMPT),
_ => panic!("Expected R_NOT_AT_PROMPT error for user_input"),
}
}
{
let (reply_tx, reply_rx) = tokio::sync::oneshot::channel();
let request = IpcRequest {
method: IpcMethod::Evaluate {
code: "1+1".to_string(),
visible: false,
timeout_ms: None,
},
reply: reply_tx,
};
handle_request(request);
match reply_rx.blocking_recv().unwrap() {
IpcResponse::Error { code, .. } => assert_eq!(code, R_NOT_AT_PROMPT),
_ => panic!("Expected R_NOT_AT_PROMPT error for evaluate"),
}
}
}
#[test]
#[serial]
fn test_session_returns_arf_only_in_various_states() {
set_in_alternate_mode(false);
set_r_at_prompt(false);
let _guard = GlobalStateGuard;
fn send_session() -> protocol::SessionResult {
let (reply_tx, reply_rx) = tokio::sync::oneshot::channel();
let request = IpcRequest {
method: IpcMethod::Session,
reply: reply_tx,
};
handle_request(request);
match reply_rx.blocking_recv().unwrap() {
IpcResponse::Session(result) => *result,
_ => panic!("Expected Session response"),
}
}
set_in_alternate_mode(true);
set_r_at_prompt(true);
{
let result = send_session();
assert!(result.r.is_none());
let reason = result.r_unavailable_reason.unwrap();
assert!(
reason.contains("alternate mode"),
"Expected alternate mode reason, got: {reason}"
);
}
set_in_alternate_mode(false);
set_r_at_prompt(false);
{
let result = send_session();
assert!(result.r.is_none());
assert!(result.r_unavailable_reason.is_some());
}
set_r_at_prompt(true);
{
let (dummy_tx, _dummy_rx) = tokio::sync::oneshot::channel();
*pending_ipc_operation()
.lock()
.unwrap_or_else(|e| e.into_inner()) = Some(PendingIpcOperation {
kind: PendingIpcKind::SilentEvaluate { reply: dummy_tx },
code: "dummy".to_string(),
});
let result = send_session();
assert!(result.r.is_none());
let reason = result.r_unavailable_reason.unwrap();
assert!(
reason.contains("pending"),
"Expected pending reason, got: {reason}"
);
let _ = take_pending_ipc_operation();
}
}